commit 01a51477ede64bef061b6b83808a1c00b817b4a8 Author: TermiNexus Date: Mon Sep 28 17:26:22 2026 +0800 chore: 初始化 Viper 官网独立仓库 ViperWebSite 原被 SMANAGE 主仓 .gitignore 排除,现拆为独立仓库并接入 git.gvsds.com/GVSDS/ViperWebSite。 包含:Vue 3 + TS + Vite 官网源码(首屏巨字滚动飞行 / Features 卡片鼠标跟随光晕 / 跨 section 背景融合)、Lenis 平滑惯性滚动、暗黑模式(属性驱动 + 变量覆盖 + 防闪白)、deploy.ps1 部署脚本、.gitignore。 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6bb89ac --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +# 依赖与构建产物 +node_modules/ +dist/ + +# 日志与临时文件 +*.log +.DS_Store + +# 编辑器 +.vscode/ +.idea/ diff --git a/deploy.ps1 b/deploy.ps1 new file mode 100644 index 0000000..fd40ce2 --- /dev/null +++ b/deploy.ps1 @@ -0,0 +1,106 @@ +# ViperWebSite deploy script: build and sync dist to production dir (TempLate/Viper) +# +# IMPORTANT: keep this file pure ASCII. PS 5.1 parses BOM-less UTF-8 files +# using the ANSI codepage, so non-ASCII text would be garbled. +# +# Usage: +# 1. Clean old artifacts (dist and TempLate/Viper) so no stale hashes remain +# 2. Full rebuild (vue-tsc type check + vite build) +# 3. Sync dist to TempLate/Viper (index.html + assets) +# 4. Verify TempLate/Viper matches dist exactly +# +# Run: .\deploy.ps1 +# (if execution policy blocks: Set-ExecutionPolicy -Scope Process Bypass) + +$ErrorActionPreference = 'Stop' + +$ProjectRoot = Split-Path -Parent $MyInvocation.MyCommand.Path +$DistDir = Join-Path $ProjectRoot 'dist' +$ProdRoot = Join-Path (Split-Path -Parent $ProjectRoot) 'TempLate\Viper' +$ProdAssetsDir = Join-Path $ProdRoot 'assets' +$IndexHtml = Join-Path $ProdRoot 'index.html' + +Write-Host "`n===== VIPER DEPLOY START =====" -ForegroundColor Cyan +Write-Host "Project dir : $ProjectRoot" +Write-Host "Prod dir : $ProdRoot" +Write-Host "" + +# 1. Clean old artifacts +Write-Host '[1/4] Cleaning old build artifacts...' -ForegroundColor Yellow +if (Test-Path $DistDir) { + Remove-Item -Recurse -Force $DistDir + Write-Host " removed: $DistDir" +} +if (Test-Path $ProdAssetsDir) { + Remove-Item -Recurse -Force $ProdAssetsDir + Write-Host " removed: $ProdAssetsDir" +} +if (Test-Path $IndexHtml) { + Remove-Item -Force $IndexHtml + Write-Host " removed: $IndexHtml" +} +Write-Host '' + +# 2. Full build (vue-tsc type check + vite build) +Write-Host '[2/4] Running npm run build (type check + full build)...' -ForegroundColor Yellow +Push-Location $ProjectRoot +try { + npm run build + if ($LASTEXITCODE -ne 0) { + throw "Build failed, exit code = $LASTEXITCODE" + } +} finally { + Pop-Location +} +Write-Host ' Build OK' +Write-Host '' + +# 3. Sync artifacts to prod dir +Write-Host '[3/4] Syncing artifacts to prod dir...' -ForegroundColor Yellow +if (-not (Test-Path $ProdRoot)) { + New-Item -ItemType Directory -Path $ProdRoot -Force | Out-Null +} +Copy-Item -Recurse -Force (Join-Path $DistDir '*') $ProdRoot +Write-Host ' Sync done' +Write-Host '' + +# 4. Verify prod dir matches dist (file name sets) +Write-Host '[4/4] Verifying artifact consistency...' -ForegroundColor Yellow +function Get-AssetNames([string]$dir) { + if (-not (Test-Path $dir)) { return @() } + return @(Get-ChildItem -Path $dir -Recurse -File | ForEach-Object { $_.FullName.Substring($dir.Length) }) +} +$distNames = Get-AssetNames (Join-Path $DistDir 'assets') +$prodNames = Get-AssetNames $ProdAssetsDir +$distSet = @($distNames | Sort-Object -Unique) +$prodSet = @($prodNames | Sort-Object -Unique) + +$onlyDist = @($distSet | Where-Object { $_ -notin $prodSet }) +$onlyProd = @($prodSet | Where-Object { $_ -notin $distSet }) + +if ($onlyDist.Count -eq 0 -and $onlyProd.Count -eq 0) { + Write-Host " OK: $($distSet.Count) assets, prod matches dist exactly" -ForegroundColor Green +} else { + Write-Host ' MISMATCH:' -ForegroundColor Red + if ($onlyDist.Count) { Write-Host " only in dist: $onlyDist" -ForegroundColor Red } + if ($onlyProd.Count) { Write-Host " only in prod: $onlyProd" -ForegroundColor Red } + throw 'Artifact verification failed!' +} + +# Verify the entry JS referenced by index.html exists +$indexContent = Get-Content $IndexHtml -Raw +$entryMatch = [regex]::Match($indexContent, 'src="([^"]+\.js)"') +if ($entryMatch.Success) { + $entryPath = Join-Path $ProdRoot ($entryMatch.Groups[1].Value.TrimStart('/')) + if (Test-Path $entryPath) { + Write-Host " entry JS OK: $($entryMatch.Groups[1].Value)" -ForegroundColor Green + } else { + throw "index.html entry JS not found: $entryPath" + } +} else { + throw 'No entry JS reference found in index.html' +} + +Write-Host '' +Write-Host "===== VIPER DEPLOY DONE =====" -ForegroundColor Cyan +Write-Host 'Please hard-refresh the browser (Ctrl+F5) to load the new build.' -ForegroundColor Cyan diff --git a/env.d.ts b/env.d.ts new file mode 100644 index 0000000..8b53f84 --- /dev/null +++ b/env.d.ts @@ -0,0 +1,7 @@ +/// + +declare module '*.vue' { + import type { DefineComponent } from 'vue' + const component: DefineComponent, Record, unknown> + export default component +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..c0c06a7 --- /dev/null +++ b/index.html @@ -0,0 +1,32 @@ + + + + + + + + Viper · Python 语法,LLVM 语义 + + + + +
+ + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..18ef588 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1245 @@ +{ + "name": "viper-website", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "viper-website", + "version": "0.1.0", + "dependencies": { + "@fontsource/inter": "^5.3.0", + "@fontsource/playfair-display": "^5.3.0", + "lenis": "^1.3.26", + "vue": "^3.5.40" + }, + "devDependencies": { + "@types/node": "^24.13.3", + "@vitejs/plugin-vue": "^6.0.8", + "@vue/tsconfig": "^0.9.1", + "typescript": "~6.0.2", + "vite": "^8.2.0", + "vue-tsc": "^3.3.8" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.8", + "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.29.8.tgz", + "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.8" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.8", + "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@fontsource/inter": { + "version": "5.3.0", + "resolved": "https://registry.npmmirror.com/@fontsource/inter/-/inter-5.3.0.tgz", + "integrity": "sha512-RofMylZmjlJEfELXeNHFWBRcSs75rGU/6bV2S2jfnvv/3rPXPGe0LgUJTklcHZ9lM4OZmAVFhcJPnACfb91A3g==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, + "node_modules/@fontsource/playfair-display": { + "version": "5.3.0", + "resolved": "https://registry.npmmirror.com/@fontsource/playfair-display/-/playfair-display-5.3.0.tgz", + "integrity": "sha512-uJSABalvdWc10fEPppQjQocamT21LEyRfzzWfRfqbkPz+sRv+kKpYDKyluBUskvJREkJTos9epj1WjQROGu99Q==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", + "license": "MIT" + }, + "node_modules/@oxc-project/types": { + "version": "0.148.0", + "resolved": "https://registry.npmmirror.com/@oxc-project/types/-/types-0.148.0.tgz", + "integrity": "sha512-Nm4s/jB+4FpFsPhWGEC4h7rzksesmtnMXomo6rCMcg/b8zLQuOziRgkCS1fxDCXOlJB/6Q8oABOZ/OP6RIPj9A==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/oxc-project" + } + }, + "node_modules/@rolldown/binding-android-arm-eabi": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.7.tgz", + "integrity": "sha512-EypzgnYCwyVY4NDHKzGmNJT5b+XaQEBniHxsMdeIQLB/tcCzZnhqrzHpZFbX9iaxx+5RiB8caATBtfvZP7zVxQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.7.tgz", + "integrity": "sha512-l17HE9EweWaqJZhuUuNBN/FzM62xw+DECVnJyvMsxn8vJFAGLy5QfLDoYAcronkAN8VxKZHezDpulHDPx95vFw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.7.tgz", + "integrity": "sha512-8ED8ELFvHXc6OCETIn4gXObPiaR6bckM/ipXtbzlPVDRMBfEGjCKgO90F9YtfdpDatVx/ZQw7aZ1vUMf/+T3Mw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.7.tgz", + "integrity": "sha512-/WPripjtiAIZ2tWY7ddijORT0Ujg87wxWW/qcoFVCKAWVDPhtY0xr7Dj0M3GyNGz60jGwTElhro/mkF9dT7dDQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.7.tgz", + "integrity": "sha512-14DI4NcqpvbICxSnGLx3PmtDaWqRP/KGSGb6C+JLLVPeZRl6dKdHba3pGsqT3vpdTqhEYIPG0MMQ8c0xYqoJxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.7.tgz", + "integrity": "sha512-bxrWIRvHWQvbJwi+VIie/kDJmQxcNE6xxWwZdqF/ExVAigtHkv54WTLQPb+QsZdnFy18fg7JPfWGL0RH6vwIlQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.7.tgz", + "integrity": "sha512-toOY2BChBZyuxU7OYX6Tn389di4IzAqPTycVcci0O7FSfBqzRB3RZn+K5Is6ANf4tmgRd/K1yZTsNTXbkXsnLg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.7.tgz", + "integrity": "sha512-lAIXTH/aiLRLxsTgQvfhjo4K1ydWIp00+V0voOr9beb/9ZmkUFrSIb03dXNFRgMNvkE6oGsF10ioQ6UsI+vS5Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.7.tgz", + "integrity": "sha512-kdnwS28Pkenp/mZMRwjXXXwxQ7pIsm+bF919LUK93BOyhcLsrVKdP2p9fxpiPNPAbNuch8ypQt0pm2P2LYCAGg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.7.tgz", + "integrity": "sha512-516OdsyLdr5E65paF3yBF55t8mfm9+gmtCsK3xI7XKXIT7EfRlHhxL8K/NR6Hu8BWSgF5+1w74lTL0+nxcc8Qw==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.7.tgz", + "integrity": "sha512-r8/z8n7GFaYRln3xmP1Cxy0HH/HLM0uBUPkEuSVEfKGDA89M0FsZRZJRSwe/tJjRx+fpH/gjorfhB8tmEbSFLA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.7.tgz", + "integrity": "sha512-pAsE8iiDxUg1xBqdhrTfg45AVDVpirjz00sblEYClGNNcMnDb+e8beQgqIAw6LvauX/APvgxUnwrgun/YYGBhw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.7.tgz", + "integrity": "sha512-lTcIYmmnQQA8Or/2DatS6oSqcdLHvendjS+zLu+FwgToynWMRSmQdpM65fTANJgIS4mjbMOo5KT2lnT9SAb96w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.7.tgz", + "integrity": "sha512-e3Gu3WxbNk/UqQhxqU7YIYO+9ZBvWNz3U+h/qRFosscMFzdRPbXYSaSWgSnklv2fz1TgzBTcti2z35c/7irsHw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.7.tgz", + "integrity": "sha512-W/jg5qoRSqjsEv0+dZi4e687mcHqmVuU0P4fK6qS/xjetW2Gmc1W8j//z5nAeNcC8Ttm0hV46IjcYeuVwYhuiw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.13.3", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-24.13.3.tgz", + "integrity": "sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.18.0" + } + }, + "node_modules/@vitejs/plugin-vue": { + "version": "6.0.8", + "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-6.0.8.tgz", + "integrity": "sha512-0ZjgOg7oO6farnNGup7yvoM/YXZV84OZxHAwtflItNa/6zzQyVb5LNxyea3FEKEX2XlagIKzrlH7wwxkKgtiew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "^1.0.1" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@volar/language-core": { + "version": "2.4.28", + "resolved": "https://registry.npmmirror.com/@volar/language-core/-/language-core-2.4.28.tgz", + "integrity": "sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/source-map": "2.4.28" + } + }, + "node_modules/@volar/source-map": { + "version": "2.4.28", + "resolved": "https://registry.npmmirror.com/@volar/source-map/-/source-map-2.4.28.tgz", + "integrity": "sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@volar/typescript": { + "version": "2.4.28", + "resolved": "https://registry.npmmirror.com/@volar/typescript/-/typescript-2.4.28.tgz", + "integrity": "sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.28", + "path-browserify": "^1.0.1", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.42", + "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.42.tgz", + "integrity": "sha512-2Ye1ilMtKXxl8qZUrQ5j0CdgenFp/HFQmta6rfRyfEsTG69L6Wk+tWuNoHYHMx9E8tF2Slvdg1FuwDvAXdy1LQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.8", + "@vue/shared": "3.5.42", + "entities": "^7.0.1", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.42", + "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.42.tgz", + "integrity": "sha512-qbhQZEFmycr+ni/qyuccS4sucNN7VAbDfbkvNxWOX2VfgFm90MNs3/UhRNKoPMEIVn0F8gdlYjLPvqxHwHeQOA==", + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.42", + "@vue/shared": "3.5.42" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.42", + "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.42.tgz", + "integrity": "sha512-fkCAFB4okcAANGMThboWnScp/gzWjU0ZSkVnjTIiplmMDq2uq0tIB3j+xVu4rhv5rvOgBySCysudmbMd6xRRqw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.8", + "@vue/compiler-core": "3.5.42", + "@vue/compiler-dom": "3.5.42", + "@vue/compiler-ssr": "3.5.42", + "@vue/shared": "3.5.42", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.21", + "postcss": "^8.5.19", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.42", + "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.42.tgz", + "integrity": "sha512-xmLk3wLkbizPAiLyomjgFFosf2ys9b5Ghb+oh/k2tnvipNz8OFrQOiTcWCzyK7MpBp9KkyGtfvgfLUivbmuGYA==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.42", + "@vue/shared": "3.5.42" + } + }, + "node_modules/@vue/language-core": { + "version": "3.3.11", + "resolved": "https://registry.npmmirror.com/@vue/language-core/-/language-core-3.3.11.tgz", + "integrity": "sha512-QJmpliwAVpC/OxubIByPAhNzsQPRc8/gxlN2qnVzVfIMjMDz/9RnXRFoetjz5yEgXVXyp4LqhXq3V53PjmNzFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.28", + "@vue/compiler-dom": "^3.5.0", + "@vue/shared": "^3.5.0", + "alien-signals": "^3.2.1", + "muggle-string": "^0.4.1", + "path-browserify": "^1.0.1", + "picomatch": "^4.0.4" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.5.42", + "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.42.tgz", + "integrity": "sha512-TzNNfKpb7hDxbQltwAut8VDQA5YP+BuRlxntHUuRjyKwlMvmAPbs3unhCvieijifY6vFfVBwsS7wG/C7uq+bEQ==", + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.42" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.42", + "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.42.tgz", + "integrity": "sha512-9uACtuHs7vJGkm5Bp3xu4xRDLFTIYy5DgxpToVjqGIAhAEKwQfsaLvKINhM6nFVp6bZPRFGdDqd1g52MqKsotA==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.42", + "@vue/shared": "3.5.42" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.42", + "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.42.tgz", + "integrity": "sha512-rsCmhiWLaRxGltLwhlCWyYkFn7WAbKRh0q17eZ1A6Dq6eqc2ACQ61IIryxz0LrsvCzHSilLA9JHovVwM8CNE2g==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.42", + "@vue/runtime-core": "3.5.42", + "@vue/shared": "3.5.42", + "csstype": "^3.2.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.42", + "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.42.tgz", + "integrity": "sha512-2++5dUyYS4gvo7xQXSECUDhB7TS0aOl5SeVfC5qSq1Jgfhjvegw1zqhwTIR3imZ+QYPJQw9gfcFvXGAjGZ7ajQ==", + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.5.42", + "@vue/runtime-dom": "3.5.42", + "@vue/shared": "3.5.42" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.42", + "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.42.tgz", + "integrity": "sha512-2rPxex1jQf4jvl9MOHl6YaXCPcrNqz/FstMOEh3QWY+/OME9nQTvl9WYeCwhW7AFjaR0SnngZGlp/wkR6rkI6g==", + "license": "MIT" + }, + "node_modules/@vue/tsconfig": { + "version": "0.9.1", + "resolved": "https://registry.npmmirror.com/@vue/tsconfig/-/tsconfig-0.9.1.tgz", + "integrity": "sha512-buvjm+9NzLCJL29KY1j1991YYJ5e6275OiK+G4jtmfIb+z4POywbdm0wXusT9adVWqe0xqg70TbI7+mRx4uU9w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "typescript": ">= 5.8", + "vue": "^3.4.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "vue": { + "optional": true + } + } + }, + "node_modules/alien-signals": { + "version": "3.2.1", + "resolved": "https://registry.npmmirror.com/alien-signals/-/alien-signals-3.2.1.tgz", + "integrity": "sha512-I8FjmltrfnDFoZedi5CG8DghVYNhzb/Ijluz7tCSJH0xpd0484Kowhbb1XDYOxfJpU1p5wnM2X54dA+IfGyD1g==", + "dev": true, + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmmirror.com/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmmirror.com/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/lenis": { + "version": "1.3.26", + "resolved": "https://registry.npmmirror.com/lenis/-/lenis-1.3.26.tgz", + "integrity": "sha512-s/xTCZCxTFvHbAN1OzuhNaN5YPJH2ail0XAkctKW1b+RUAG4nUL5UHLXwNko1h8aEeT2jspBXegMgPJd8zcuag==", + "license": "MIT", + "workspaces": [ + "packages/*", + "playground", + "playground/*" + ], + "funding": { + "type": "github", + "url": "https://github.com/sponsors/darkroomengineering" + }, + "peerDependencies": { + "@nuxt/kit": ">=3.0.0", + "react": ">=17.0.0", + "vue": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@nuxt/kit": { + "optional": true + }, + "react": { + "optional": true + }, + "vue": { + "optional": true + } + } + }, + "node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmmirror.com/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmmirror.com/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmmirror.com/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmmirror.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmmirror.com/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmmirror.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmmirror.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmmirror.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmmirror.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmmirror.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmmirror.com/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmmirror.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/muggle-string": { + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/muggle-string/-/muggle-string-0.4.1.tgz", + "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.18", + "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.26", + "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.26.tgz", + "integrity": "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.17", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rolldown": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/rolldown/-/rolldown-1.2.7.tgz", + "integrity": "sha512-g0EtLvBjTUB7jhyV0S/TCup3v/XSVl45vUIGbOGU4QPiyjTenCe4mKuFvW9fEgYmS2Fo42AUssRmNuMziXdrig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.148.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm-eabi": "1.2.7", + "@rolldown/binding-android-arm64": "1.2.7", + "@rolldown/binding-darwin-arm64": "1.2.7", + "@rolldown/binding-darwin-x64": "1.2.7", + "@rolldown/binding-freebsd-x64": "1.2.7", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.7", + "@rolldown/binding-linux-arm64-gnu": "1.2.7", + "@rolldown/binding-linux-arm64-musl": "1.2.7", + "@rolldown/binding-linux-ppc64-gnu": "1.2.7", + "@rolldown/binding-linux-s390x-gnu": "1.2.7", + "@rolldown/binding-linux-x64-gnu": "1.2.7", + "@rolldown/binding-linux-x64-musl": "1.2.7", + "@rolldown/binding-openharmony-arm64": "1.2.7", + "@rolldown/binding-win32-arm64-msvc": "1.2.7", + "@rolldown/binding-win32-x64-msvc": "1.2.7" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmmirror.com/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.18.2", + "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite": { + "version": "8.2.2", + "resolved": "https://registry.npmmirror.com/vite/-/vite-8.2.2.tgz", + "integrity": "sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.33.0", + "picomatch": "^4.0.5", + "postcss": "^8.5.26", + "rolldown": "~1.2.4", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.4.0 || ^0.5.0", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vscode-uri": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/vscode-uri/-/vscode-uri-3.2.0.tgz", + "integrity": "sha512-m2gXo3bn0G1kT9InzMf07fTbqMbGtyckj3bH5ktLO+1Ssv+yiATZ4dhwaQv9UZWxJh6E9IFGnQyjgWVDWVBDrg==", + "dev": true, + "license": "MIT" + }, + "node_modules/vue": { + "version": "3.5.42", + "resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.42.tgz", + "integrity": "sha512-4RyHQTbQvOPs3MfvUO1Sg0YRrKNnA0mAVtvpd12Tg1fKDN7OHBUl1IqSn8zGJjK9nI3NkNp8cgTpVrSZC5TTcA==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.42", + "@vue/compiler-sfc": "3.5.42", + "@vue/runtime-dom": "3.5.42", + "@vue/server-renderer": "3.5.42", + "@vue/shared": "3.5.42" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue-tsc": { + "version": "3.3.11", + "resolved": "https://registry.npmmirror.com/vue-tsc/-/vue-tsc-3.3.11.tgz", + "integrity": "sha512-gOb0B9rtU2+f1dszwPqSH5kAieIF9ReeLhD3kSRNHv5WZZUQz/JdVXW0RTdqhNTMlQkqKzrTTviqKr/4FYZraQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/typescript": "2.4.28", + "@vue/language-core": "3.3.11" + }, + "bin": { + "vue-tsc": "bin/vue-tsc.js" + }, + "peerDependencies": { + "typescript": ">=5.0.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..defdae3 --- /dev/null +++ b/package.json @@ -0,0 +1,26 @@ +{ + "name": "viper-website", + "private": true, + "version": "0.1.0", + "type": "module", + "description": "Viper language official website (viper.gvsds.com)", + "scripts": { + "dev": "vite", + "build": "vue-tsc -b && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@fontsource/inter": "^5.3.0", + "@fontsource/playfair-display": "^5.3.0", + "lenis": "^1.3.26", + "vue": "^3.5.40" + }, + "devDependencies": { + "@types/node": "^24.13.3", + "@vitejs/plugin-vue": "^6.0.8", + "@vue/tsconfig": "^0.9.1", + "typescript": "~6.0.2", + "vite": "^8.2.0", + "vue-tsc": "^3.3.8" + } +} diff --git a/public/favicon.svg b/public/favicon.svg new file mode 100644 index 0000000..4d1a7d3 --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1,5 @@ + + + + diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..36eb752 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,81 @@ + + + diff --git a/src/assets/base.css b/src/assets/base.css new file mode 100644 index 0000000..3f1f2d9 --- /dev/null +++ b/src/assets/base.css @@ -0,0 +1,401 @@ +/* ============================================================ + Viper 官网 · 设计系统 + 一张暗色画布 + 单一强调色(青柠),双字体族,克制运动 + ============================================================ */ + +:root { + /* 色板 —— 浅色企业风格 */ + --bg: #ffffff; + --bg-soft: #f4f8f6; + --bg-deep: #0b1712; /* 深色区(代码窗 / 页脚) */ + --panel: rgba(16, 32, 26, 0.03); + --panel-strong: rgba(16, 32, 26, 0.05); + --line: rgba(13, 194, 96, 0.32); + --line-soft: #dceee3; + --text: #10201a; + --text-dim: #5b6e64; + --text-faint: #8da097; + --accent: #0dc260; /* 主题色 */ + --accent-rgb: 13, 194, 96; /* 主题色分量,供 rgba(var(--accent-rgb), α) 使用 */ + --accent-strong: #08994b; /* 深一档:正文与悬停,保证对比度 */ + --accent-ink: #ffffff; /* 压在主题色之上的文字:绿底一律配白字 */ + --lime: #b7e64b; /* 黄绿:次级强调 */ + --red: #f04438; /* 红:对比与警示 */ + --sky: #38bdf8; /* 浅蓝:对比强调 */ + --glow: rgba(13, 194, 96, 0.22); + --shadow-code: 0 26px 60px -30px rgba(15, 42, 32, 0.4); + + /* 语义色:需要随主题整体换色的中性色,避免组件里散落硬编码 */ + --glass: rgba(255, 255, 255, 0.88); /* 顶栏滚动后的毛玻璃底 */ + --glass-strong: rgba(255, 255, 255, 0.97); /* 移动端下拉菜单面板底 */ + --hover: rgba(16, 32, 26, 0.05); /* 中性悬浮底 */ + --badge-ink: #0369a1; /* 浅蓝徽章文字 */ + --badge-line: rgba(56, 189, 248, 0.55); /* 浅蓝徽章描边 */ + + /* 字体(本地栈,无外网依赖) + 中文优先 Noto Sans SC(思源黑体),未安装时回退微软雅黑 / 苹方 / 系统 UI 字体; + 英文与数字沿用 Segoe UI 前端栈。 + 等宽字体已弃用(用户反馈表现不佳):--font-mono 指向正文字体栈, + 因此 .mono / .eyebrow / 代码窗等处的旧引用全部回落到正文字体。 */ + --font-sans: 'Segoe UI', 'Noto Sans SC', 'Source Han Sans SC', 'Microsoft YaHei', + 'PingFang SC', 'Hiragino Sans GB', system-ui, -apple-system, sans-serif; + --font-mono: var(--font-sans); /* 弃用等宽(用户反馈表现不佳):指向正文字体栈,.mono 等旧引用自动回落 */ + --font-brand: 'Playfair Display', Georgia, 'Times New Roman', 'Songti SC', serif; /* 品牌字专用:自托管衬线(@fontsource/playfair-display 900) */ + + /* 代码高亮(深色代码块内使用) */ + --tok-kw: #ff7b72; + --tok-str: #a5d6ff; + --tok-num: #79c0ff; + --tok-type: #ffa657; + --tok-fn: #a8e063; + --tok-cmt: #6e8b79; + --tok-punc: #8b9f8f; + --tok-plain: #d5e3d8; + + --radius: 10px; + --radius-sm: 6px; + --container: 1140px; + --nav-h: 66px; + --ease-out: cubic-bezier(0.16, 1, 0.3, 1); +} + +*, +*::before, +*::after { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +/* ============================================================ + 暗黑模式 + 只覆盖颜色变量:结构、字体、动效、深色代码窗全部复用浅色规则, + 组件不需要写任何 @media 或主题分支。 + 由 触发;该属性由 index.html 的内联脚本 + 在首屏渲染前写入(localStorage 手动选择优先,否则跟随系统),避免闪白。 + ============================================================ */ +html[data-theme='dark'] { + --bg: #0c1512; + --bg-soft: #101d18; + --bg-deep: #060d0a; /* 比页面底色再深一档:代码窗 / 页脚继续读作"下沉"区域 */ + --panel: rgba(255, 255, 255, 0.04); + --panel-strong: rgba(255, 255, 255, 0.07); + --line: rgba(13, 194, 96, 0.38); + --line-soft: rgba(255, 255, 255, 0.12); + --text: #e7f2ec; + --text-dim: #9db9ab; + --text-faint: #6f8d7e; + /* 暗底必须换更亮的绿:浅色下的 --accent-strong(#08994b) 在深背景上几乎读不出来 */ + --accent-strong: #4ddb8a; + --glow: rgba(13, 194, 96, 0.3); + --shadow-code: 0 26px 60px -30px rgba(0, 0, 0, 0.75); + + --glass: rgba(12, 21, 18, 0.82); + --glass-strong: rgba(10, 18, 15, 0.96); + --hover: rgba(255, 255, 255, 0.07); + --badge-ink: #7dd3fc; + --badge-line: rgba(56, 189, 248, 0.45); +} + +html { + /* 横向裁剪放在 html(根元素)上直接对视口生效: + clip 不会把根元素变成滚动容器,Lenis 仍能接管纵向滚动; + 前置的 hidden 是不支持 clip 的浏览器的回退(放在 body 上则会把 body 的 overflow-y 算成 auto, + 让 Lenis 的 allowNestedScroll 误判 body 为嵌套滚动源)。 */ + overflow-x: hidden; + overflow-x: clip; + scroll-behavior: smooth; + scroll-padding-top: calc(var(--nav-h) + 12px); +} + +/* Lenis 接管滚动时关闭原生平滑,避免二次缓动叠加;锚点落位偏移由 Lenis anchors.offset 负责 */ +html.lenis { + scroll-behavior: auto; +} + +body { + background: var(--bg); + color: var(--text); + font-family: var(--font-sans); + font-size: 16px; + line-height: 1.7; + -webkit-font-smoothing: antialiased; +} + +::selection { + background: var(--accent); + color: var(--accent-ink); +} + +a { + color: inherit; + text-decoration: none; +} + +img, +svg { + display: block; + max-width: 100%; +} + +button { + font: inherit; + background: none; + border: none; + color: inherit; + cursor: pointer; +} + +/* 滚动条 */ +::-webkit-scrollbar { + width: 11px; + height: 11px; +} +::-webkit-scrollbar-thumb { + background: #c3d3cb; + border-radius: 6px; + border: 3px solid var(--bg); +} +::-webkit-scrollbar-thumb:hover { + background: #9db3a3; +} + +/* 暗色下滑块要跟着变深(浅灰滑块在深底上过于刺眼) */ +html[data-theme='dark'] ::-webkit-scrollbar-thumb { + background: #2c4038; +} +html[data-theme='dark'] ::-webkit-scrollbar-thumb:hover { + background: #3d584b; +} + +/* ------- 版式工具 ------- */ +.mono { + font-family: var(--font-mono); +} + +.container { + width: min(var(--container), 100% - 48px); + margin-inline: auto; +} + +/* 区块骨架:每个 section 一个职责 */ +.section { + padding: clamp(5rem, 10vw, 8.5rem) 0; + position: relative; +} + +.eyebrow { + font-family: var(--font-mono); + font-size: 0.78rem; + letter-spacing: 0.22em; + color: var(--accent); + text-transform: uppercase; + display: inline-flex; + align-items: center; + gap: 10px; +} + +.eyebrow::before { + content: ''; + width: 26px; + height: 1px; + background: var(--accent); + opacity: 0.7; +} + +.section-title { + font-size: clamp(1.9rem, 4vw, 2.9rem); + font-weight: 650; + letter-spacing: -0.02em; + line-height: 1.14; + margin: 18px 0 14px; +} + +.section-sub { + color: var(--text-dim); + max-width: 56ch; + font-size: 1.02rem; +} + +/* ------- 按钮 ------- */ +.btn { + display: inline-flex; + align-items: center; + gap: 9px; + padding: 12px 22px; + border-radius: 999px; + font-weight: 600; + font-size: 0.98rem; + transition: transform 0.22s var(--ease-out), box-shadow 0.25s var(--ease-out), + background 0.22s var(--ease-out), border-color 0.22s var(--ease-out); + will-change: transform; +} + +.btn:active { + transform: scale(0.97); +} + +.btn-primary { + background: var(--accent); + color: var(--accent-ink); + box-shadow: 0 0 0 1px var(--accent), 0 12px 28px -14px rgba(var(--accent-rgb), 0.75); +} + +.btn-primary:hover { + background: #16d96d; + transform: translateY(-2px); + box-shadow: 0 0 0 1px #16d96d, 0 18px 38px -14px rgba(var(--accent-rgb), 0.85); +} + +.btn-ghost { + border: 1px solid var(--line-soft); + color: var(--text); + background: transparent; +} + +.btn-ghost:hover { + border-color: var(--accent); + background: rgba(var(--accent-rgb), 0.08); + color: var(--accent-strong); + transform: translateY(-2px); +} + +/* ------- 进场 / 滚动揭示 ------- */ +@keyframes riseIn { + from { + opacity: 0; + transform: translateY(26px); + } + to { + opacity: 1; + transform: none; + } +} + +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +@keyframes caretBlink { + 0%, + 48% { + opacity: 1; + } + 50%, + 100% { + opacity: 0; + } +} + +[data-reveal] { + opacity: 0; + transform: translateY(26px); + transition: opacity 0.8s ease, transform 0.85s var(--ease-out); + transition-delay: var(--reveal-delay, 0ms); +} + +[data-reveal].in { + opacity: 1; + transform: none; +} + +/* 代码块基础(页面上保留深色代码窗,形成浅色页的对比锚点) */ +.code-win { + --line-soft: rgba(255, 255, 255, 0.08); + --text-faint: #6d8a7c; + background: var(--bg-deep); + border: 1px solid rgba(255, 255, 255, 0.08); + border-radius: var(--radius); + overflow: hidden; + box-shadow: var(--shadow-code); +} + +.code-win__bar { + display: flex; + align-items: center; + gap: 7px; + padding: 11px 16px; + border-bottom: 1px solid var(--line-soft); + background: rgba(255, 255, 255, 0.02); +} + +.code-win__dot { + width: 10px; + height: 10px; + border-radius: 50%; + background: #3c4a42; +} + +.code-win__dot:nth-child(1) { + background: #d2644f; +} +.code-win__dot:nth-child(2) { + background: #d0a542; +} +.code-win__dot:nth-child(3) { + background: #3e8f6c; +} + +.code-win__file { + margin-left: auto; + font-family: var(--font-mono); + font-size: 0.72rem; + color: var(--text-faint); + letter-spacing: 0.04em; +} + +.code-win pre { + padding: 20px 22px 22px; + overflow-x: auto; + font-family: var(--font-mono); + font-size: 0.86rem; + line-height: 1.75; + color: var(--tok-plain); + tab-size: 4; +} + +.code-win code { + display: block; + min-width: max-content; +} + +.tok-kw { color: var(--tok-kw); } +.tok-str { color: var(--tok-str); } +.tok-num { color: var(--tok-num); } +.tok-type { color: var(--tok-type); } +.tok-fn { color: var(--tok-fn); } +.tok-cmt { color: var(--tok-cmt); font-style: italic; } +.tok-punc { color: var(--tok-punc); } +.tok-plain { color: var(--tok-plain); } + +.caret { + display: inline-block; + width: 8px; + height: 1.05em; + margin-left: 3px; + vertical-align: text-bottom; + background: var(--accent); + animation: caretBlink 1.1s steps(1) infinite; +} + +@media (prefers-reduced-motion: reduce) { + html { + scroll-behavior: auto; + } + *, + *::before, + *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + } + [data-reveal] { + opacity: 1; + transform: none; + } +} diff --git a/src/components/CompilerSection.vue b/src/components/CompilerSection.vue new file mode 100644 index 0000000..ee08cec --- /dev/null +++ b/src/components/CompilerSection.vue @@ -0,0 +1,265 @@ + + + + + diff --git a/src/components/EcosystemSection.vue b/src/components/EcosystemSection.vue new file mode 100644 index 0000000..8cfcdc0 --- /dev/null +++ b/src/components/EcosystemSection.vue @@ -0,0 +1,138 @@ + + + + + diff --git a/src/components/FeaturesSection.vue b/src/components/FeaturesSection.vue new file mode 100644 index 0000000..c43efde --- /dev/null +++ b/src/components/FeaturesSection.vue @@ -0,0 +1,176 @@ + + + + + diff --git a/src/components/HeroSection.vue b/src/components/HeroSection.vue new file mode 100644 index 0000000..8988acb --- /dev/null +++ b/src/components/HeroSection.vue @@ -0,0 +1,459 @@ + + + + + diff --git a/src/components/MetaSection.vue b/src/components/MetaSection.vue new file mode 100644 index 0000000..8b22aac --- /dev/null +++ b/src/components/MetaSection.vue @@ -0,0 +1,135 @@ + + + + + diff --git a/src/components/OopSection.vue b/src/components/OopSection.vue new file mode 100644 index 0000000..545e1b2 --- /dev/null +++ b/src/components/OopSection.vue @@ -0,0 +1,121 @@ + + + + + diff --git a/src/components/QuickStartSection.vue b/src/components/QuickStartSection.vue new file mode 100644 index 0000000..338fbf0 --- /dev/null +++ b/src/components/QuickStartSection.vue @@ -0,0 +1,273 @@ + + + + + diff --git a/src/components/ReplSection.vue b/src/components/ReplSection.vue new file mode 100644 index 0000000..5e58164 --- /dev/null +++ b/src/components/ReplSection.vue @@ -0,0 +1,143 @@ + + + + + diff --git a/src/components/RoadmapSection.vue b/src/components/RoadmapSection.vue new file mode 100644 index 0000000..653f32a --- /dev/null +++ b/src/components/RoadmapSection.vue @@ -0,0 +1,171 @@ + + + + + diff --git a/src/components/SourceSection.vue b/src/components/SourceSection.vue new file mode 100644 index 0000000..6ce7e79 --- /dev/null +++ b/src/components/SourceSection.vue @@ -0,0 +1,143 @@ + + + + + diff --git a/src/components/TheFooter.vue b/src/components/TheFooter.vue new file mode 100644 index 0000000..5be1955 --- /dev/null +++ b/src/components/TheFooter.vue @@ -0,0 +1,238 @@ + + + + + diff --git a/src/components/TheHeader.vue b/src/components/TheHeader.vue new file mode 100644 index 0000000..dd4d437 --- /dev/null +++ b/src/components/TheHeader.vue @@ -0,0 +1,351 @@ + + + + + diff --git a/src/i18n/en.ts b/src/i18n/en.ts new file mode 100644 index 0000000..3893194 --- /dev/null +++ b/src/i18n/en.ts @@ -0,0 +1,339 @@ +// Viper official website · English dictionary +// Structure must mirror zh.ts (validated as typeof zh) +// Wording rule: all code samples use current syntax only (define / novirtual / const int* …), no legacy t.* forms. +import type zh from './zh' + +const en: typeof zh = { + nav: { + features: 'Features', + compiler: 'Compiler', + oop: 'Object Model', + meta: 'Compile-time', + repl: 'REPL', + source: 'Source Tour', + quickstart: 'Get Started', + ecosystem: 'Ecosystem', + roadmap: 'Roadmap', + repo: 'Repository', + }, + hero: { + kicker: 'A SYSTEM-LEVEL LANGUAGE', + statement: 'Low-level, yet simpler?', + lead: 'A system-level language written in the most readable syntax humans agree on — Python — compiling through LLVM IR down to native machine code. No interpreter, no GC, no runtime. The compiler itself is written in Viper.', + ctaStart: 'Get Started', + ctaSource: 'Source Code', + dataRows: ['Self-hosted', 'No runtime · no GC', 'Annotations are directives', 'Native machine code'], + }, + features: { + eyebrow: 'CORE DESIGN', + title: 'Why Viper', + sub: 'Not another Python implementation, not C sugar.', + cards: [ + { + term: 'Fully self-hosted', + code: 'App/**.vp → TransPyV.exe', + desc: 'The compiler is written in Viper: 76 files, 64,656 lines, compiling itself into a native executable.', + }, + { + term: 'Python syntax, LLVM semantics', + code: 'x: int = 42', + desc: 'Source stays valid Python, while annotations drive code generation — int is i32.', + }, + { + term: 'Annotations are directives', + code: 'ptr: const int*', + desc: 'const and * encode const-ness and pointer levels in the type; the rest is inferred.', + }, + { + term: 'Content-addressed modules', + code: '@".func"', + desc: 'A module is identified by the SHA1 of its own source, so symbols carry a prefix and cross-file collisions cannot happen.', + }, + { + term: 'Incremental builds', + code: '# hit → skip', + desc: 'Four cache checks — signature, declaration, implementation, standard library — so only affected modules are retranslated.', + }, + { + term: 'Zero runtime', + code: '# malloc · no GC', + desc: 'The output is native machine code: no GC, no bytecode interpreter, memory and lifetimes are yours.', + }, + { + term: 'Async and coroutines', + code: 's = s + await leaf(i)', + desc: 'async/await compile to a resumable state machine with suspension, exception propagation and destruction.', + }, + { + term: 'Matching and closures', + code: 'match ty:', + desc: 'match supports nesting and class-variant dispatch; closures capture on demand, nonlocal and lambda alike.', + }, + ], + }, + compiler: { + eyebrow: 'HOW IT COMPILES', + title: 'Two-phase compilation', + sub: 'Declarations first, translation after; modules are named by content hash and unchanged work is skipped.', + steps: [ + { tag: 'src/*.vp', desc: 'Imports discover reachable modules recursively — only referenced files are translated.' }, + { tag: 'Content SHA1', desc: 'The first 8 bytes of the content hash identify the module and its cache shard.' }, + { tag: 'Phase 1 · Declare', desc: 'Emits vpi signatures, stub declarations, text implementations and dependency lists.' }, + { tag: 'Skip check', desc: 'Any of four cache hits skips the work; only affected modules are retranslated.' }, + { tag: 'Phase 2 · Merge', desc: 'Merges declarations and implementations in topological order, deduping symbols and hoisting types.' }, + { tag: 'llc · -O0', desc: 'The complete IR is compiled to object files, in parallel.' }, + { tag: 'clang++ · lld', desc: 'Links a native executable.' }, + ], + cache: { + title: 'Build switches', + items: [ + { flag: '--phase 1|2|all', desc: 'Declare only / translate only / whole pipeline' }, + { flag: '--clean', desc: 'Drop caches and artifacts' }, + { flag: '--clear-cache', desc: 'Module caches only' }, + { flag: '--rebuild-includes', desc: 'Rebuild standard-library artifacts' }, + { flag: '--repl', desc: 'Enter the REPL' }, + { flag: '--asan', desc: 'ASan-instrumented build' }, + { flag: '--phase2command', desc: 'Export the phase-two command' }, + ], + }, + }, + oop: { + eyebrow: 'OBJECT MODEL', + title: 'Structs, with polymorphism on demand', + sub: 'No implicit boxing, no hidden allocation — a class is a struct layout, and the vtable is a pointer you can replace.', + codeTitle: 'Inheritance and dispatch', + code: [ + { t: 'virtual class Shape:' }, + { t: ' sides: int' }, + { t: ' def area(self) -> int:' }, + { t: ' return 0', c: 'default implementation' }, + { t: '' }, + { t: 'novirtual class Square(Shape):' }, + { t: ' size: int' }, + { t: ' def area(self) -> int:' }, + { t: ' return self.size * self.size', c: 'statically bound override, no vtable cost' }, + ], + notesTitle: 'Key points', + notes: [ + { key: 'vtable offset', value: 'First field of the object: copy 8 bytes to swap the dispatch table' }, + { key: 'Slot order', value: 'Parents before children, up to 32 slots, stable across modules' }, + { key: 'novirtual', value: 'Static binding plus this-adjustment — zero vtable cost, mixable with virtual' }, + { key: 'Multiple parents', value: 'Fields flattened, MRO flattened up to 64 layers' }, + { key: 'Layout control', value: 'union shares memory, packed drops padding, aligned(N) forces alignment' }, + { key: 'Operator overload', value: 'The full dunder set: __add__ / __eq__ / __lshift__ …' }, + { key: 'Construction', value: '__init__ / __new__ / __before_init__ / __sizeof__' }, + ], + }, + meta: { + eyebrow: 'COMPILE-TIME', + title: 'Compile-time facilities', + sub: 'Macros, conditional compilation, inline IR and assembly, function attributes — language syntax, not a preprocessor.', + codeTitle: 'Declarations and modifiers', + code: [ + { t: 'define MAX_SIZE = 4096', c: 'inlined at use sites, no global symbol' }, + { t: '' }, + { t: 'export def Init() -> int:', c: 'frees the symbol from the hash prefix for other modules or C' }, + { t: ' return 0' }, + { t: '' }, + { t: 'inline def Fast(x: int) -> int:', c: 'inlining hint' }, + { t: ' return x * 2' }, + { t: '' }, + { t: 'extern def LibCall(x: int) -> int:', c: 'declaration only' }, + { t: ' pass' }, + ], + chipsTitle: 'Go deeper', + chips: [ + { name: 'Inline LLVM IR', note: 'c.LLVMIR("add i32 …", int)' }, + { name: 'Inline assembly', note: 'c.Asm("nop") · register and memory constraints' }, + { name: 'Function attributes', note: 'always_inline · nounwind · packed' }, + { name: 'Structured conditionals', note: 'syntax instead of #ifdef' }, + ], + }, + repl: { + eyebrow: 'REPL', + title: 'Interactive REPL', + sub: 'Type line by line: each fragment compiles to a shared library and runs at once — variables, functions and types accumulate.', + points: [ + { + title: 'A fragment is a module', + desc: 'Each input is wrapped into a fragment function, translated to module IR, compiled, loaded, called and echoed back.', + }, + { + title: 'Variables across fragments', + desc: 'After x: int = 5 you can use x + 1 directly; session variables live in slots.', + }, + { + title: 'Functions across fragments', + desc: 'A top-level def in a block becomes an exported function (limits: single-line signature, no async def yet).', + }, + { + title: 'Types across fragments', + desc: 'A class defined in a block enters the session and can be constructed later.', + }, + { + title: 'Blocks and error recovery', + desc: 'A trailing colon continues the line, an empty line runs the block; errors recover without killing the session.', + }, + ], + sampleTitle: 'Session sample', + lines: [ + '>>> x: int = 5', + '>>> def twice(n: int) -> int:', + '... return n * 2', + '>>> twice(x) + 1', + '11', + ], + }, + source: { + eyebrow: 'SOURCE TOUR', + title: 'Source tour', + sub: 'The compiler lives in the repository — you can read it module by module.', + stats: [ + { value: '76', label: 'compiler sources (.vp)' }, + { value: '64,656', label: 'lines in the compiler' }, + { value: '52', label: 'translator core files · 49,978 lines' }, + { value: '39', label: 'self-tests' }, + { value: '22.1.8', label: 'LLVM version' }, + { value: 'Windows x64', label: 'current target' }, + ], + dirsTitle: 'Directory map', + dirs: [ + { path: 'App/main.vp', desc: 'CLI entry: arguments, phase scheduling, build orchestration' }, + { path: 'App/lib/Phase/', desc: 'Both phases and the build pipeline: scanning, topology, artifacts, parallel compile' }, + { path: 'App/lib/Stub/', desc: 'Declaration generation and merging: signatures, topological merge, dedup, type hoisting' }, + { path: 'App/lib/core/Gen/', desc: 'Translator and code generation core: types, expressions, statements, classes, calls' }, + { path: 'App/lib/Projectrans/', desc: 'Project config, path resolution, hash sharding and cache policy' }, + { path: 'Test/', desc: 'Self-test suite: syntax, pointers, OOP, async, negative cases, hash namespaces' }, + ], + }, + quickstart: { + eyebrow: 'GET STARTED', + title: 'Hello Viper in three minutes', + tagline: 'Hi, Viper — see you in three minutes.', + sub: 'The compiler is fully self-hosted — TransPyV is a native executable. Grab a Windows (mingw) + LLVM toolchain and you are ready.', + steps: [ + { + num: '01', + title: 'Clone compiler & template', + desc: 'TransPyC is the compiler repository — its self-hosted TransPyV already builds projects; ViperTemplateProject is a ready-to-run Windows template.', + }, + { + num: '02', + title: 'Build the project', + desc: 'Drive the two-phase build with the native TransPyV; the executable lands in the template output/.', + }, + { + num: '03', + title: 'Run the native binary', + desc: 'You get a real native app.exe — it prints "Hello, world".', + }, + ], + prereqs: ['TransPyV (native)', 'LLVM 22.1.8 · llc', 'mingw · clang++ / lld', 'git'], + cmdNote: '# Windows PowerShell · mingw + LLVM on PATH', + output: '你好,世界', + cliTitle: 'Common flags', + cli: [ + { flag: '--project ', desc: 'Build from a project file' }, + { flag: '--phase 1|2|all', desc: 'Declare only / translate only / whole pipeline' }, + { flag: '--repl', desc: 'Enter the interactive REPL' }, + { flag: '--clean', desc: 'Drop caches and artifacts — a clean rebuild' }, + { flag: '--asan', desc: 'ASan-instrumented build to hunt memory bugs' }, + { flag: '--phase2command', desc: 'Export the phase-two build command' }, + ], + }, + ecosystem: { + eyebrow: 'ECOSYSTEM', + title: 'From compiler to operating system', + sub: 'Viper is no island: a complete self-built toolchain and systems practice surrounds it.', + items: [ + { + name: 'TransPyV', + role: 'Compiler', + desc: 'The self-hosted compiler: two-phase declaration extraction and LLVM IR translation, written in Viper.', + href: 'https://git.gvsds.com/GVSDS/TransPyC', + badge: 'Self-hosted', + }, + { + name: 'includes/', + role: 'Standard library', + desc: 'Pure Viper: self-built parser, IR builder, coroutine runtime, buddy allocator, threads and Win32 bindings.', + href: '', + badge: '', + }, + { + name: 'testcheck', + role: 'Test framework', + desc: 'Compile-time assertions and grouping — the entry point of all 39 self-tests.', + href: '', + badge: '', + }, + { + name: 'ViperTemplateProject', + role: 'Template project', + desc: 'A ready-to-run Windows project skeleton: project file, build script and sample sources.', + href: '', + badge: '', + }, + { + name: 'Venom', + role: 'Package manager', + desc: 'The official package manager: distribution, installation and dependency resolution.', + href: 'https://venom.gvsds.com', + badge: 'WIP', + }, + { + name: 'ViperOS', + role: 'Operating system', + desc: 'An x86_64 kernel practice written in Viper, pushing the language to the bare metal.', + href: '', + badge: '', + }, + ], + }, + roadmap: { + eyebrow: 'ROADMAP', + title: 'Bootstrapped — ecosystem ahead', + sub: 'The compiler is fully self-hosted and free from the Python runtime. Next: make library sharing first-class.', + items: [ + { + phase: 'done', + title: 'Full bootstrap', + desc: 'The compiler is rewritten in Viper: 76 sources, 64,656 lines, compiling itself into a native TransPyV.exe; a self-built parser and IR library replaced third-party dependencies.', + }, + { + phase: 'done', + title: 'Interactive REPL', + desc: 'Session variables, cross-fragment functions and types: every fragment compiles to a shared library and runs at once, with recoverable errors.', + }, + { + phase: 'active', + title: 'Generic specialisation', + desc: 'Template registration and on-demand specialisation are in place; the self-test suite still masks it to isolate a known crash — generic containers come once fixed.', + }, + { + phase: 'next', + title: 'Venom packages', + desc: 'The official package manager ships — publishing, installing and resolving Viper libraries become first-class.', + }, + { + phase: 'next', + title: 'Cross-platform targets', + desc: 'Windows x64 only today (sources bind Win32 directly); Unix-like targets and toolchain adaptation come next.', + }, + ], + }, + cta: { + title: 'Ready to write your first native line?', + sub: 'Start from the template project and see your first Viper program run within minutes.', + start: 'Get Started', + source: 'Source Code', + }, + footer: { + tagline: 'Low-level, yet simpler?', + builtBy: 'Viper Website · GVSDS', + linksTitle: 'Navigation', + backTop: 'Back to top', + }, +} + +export default en diff --git a/src/i18n/index.ts b/src/i18n/index.ts new file mode 100644 index 0000000..ea7c1b4 --- /dev/null +++ b/src/i18n/index.ts @@ -0,0 +1,44 @@ +// 轻量 i18n:zh/en 双字典 + 响应式替换(无外部依赖) +import { reactive, computed } from 'vue' +import zh from './zh' +import en from './en' + +export type Lang = 'zh' | 'en' + +function deepCopyInto(target: Record, source: Record): void { + for (const key of Object.keys(source)) { + const srcVal = source[key] + const dstVal = target[key] + if ( + srcVal !== null && + typeof srcVal === 'object' && + !Array.isArray(srcVal) && + dstVal !== null && + typeof dstVal === 'object' + ) { + deepCopyInto(dstVal as Record, srcVal as Record) + } else { + target[key] = srcVal + } + } +} + +const state = reactive({ + lang: (localStorage.getItem('viper-lang') as Lang) || 'zh', +}) + +// 响应式文案对象:结构 = typeof zh(en.ts 已按同结构校验) +export const t = reactive(deepClone(zh)) + +function deepClone(value: T): T { + return JSON.parse(JSON.stringify(value)) as T +} + +export const currentLang = computed(() => state.lang) + +export function setLang(lang: Lang): void { + if (state.lang === lang) return + state.lang = lang + localStorage.setItem('viper-lang', lang) + deepCopyInto(t as unknown as Record, lang === 'zh' ? zh : en) +} diff --git a/src/i18n/zh.ts b/src/i18n/zh.ts new file mode 100644 index 0000000..ee2f1e4 --- /dev/null +++ b/src/i18n/zh.ts @@ -0,0 +1,335 @@ +// Viper 官网 · 中文文案字典 +// 注意:结构与 en.ts 完全一致(en.ts 以 typeof zh 校验) +// 文案口径:全站代码示例只使用现行语法(define / novirtual / const int* 等),不展示历史 t.* 写法 +export default { + nav: { + features: '特性', + compiler: '编译模型', + oop: '对象模型', + meta: '编译期', + repl: 'REPL', + source: '源码导览', + quickstart: '快速上手', + ecosystem: '生态', + roadmap: '路线图', + repo: '仓库', + }, + hero: { + kicker: 'A SYSTEM-LEVEL LANGUAGE', + statement: '底层,再简单一点吧?', + lead: '一门系统级编程语言:以 Python 语法书写,编译为 LLVM IR,直达原生机器码。没有解释器,没有 GC,没有运行时——编译器本身也由 Viper 写成。', + ctaStart: '快速上手', + ctaSource: '查看源码', + dataRows: ['完全自举', '零运行时 · 无 GC', '注解即编译指令', '原生机器码'], + }, + features: { + eyebrow: 'CORE DESIGN', + title: '为什么是 Viper', + sub: '不是 Python 的又一个实现,也不是 C 的语法糖。', + cards: [ + { + term: '完全自举', + code: 'App/**.vp → TransPyV.exe', + desc: '编译器由 Viper 写成,76 个文件、64,656 行,能编译自身并产出原生可执行文件。', + }, + { + term: 'Python 语法,LLVM 语义', + code: 'x: int = 42', + desc: '源码是合法的 Python 语法,而注解直接决定代码生成——int 就是 i32。', + }, + { + term: '注解即编译指令', + code: 'ptr: const int*', + desc: 'const 与 * 把常量性、指针层级编码进类型,无注解处由编译器推导。', + }, + { + term: '内容寻址的模块', + code: '@".func"', + desc: '模块标识取自源文件内容的 SHA1,符号自动带前缀,跨文件重名不可能冲突。', + }, + { + term: '增量编译', + code: '# 命中即跳过', + desc: '签名、声明、实现与标准库产物四处缓存判定,改一个文件只重译受影响模块。', + }, + { + term: '零运行时', + code: '# malloc · no GC', + desc: '产物是原生机器码,没有 GC 与字节码解释器,内存与生命周期自负。', + }, + { + term: '异步与协程', + code: 's = s + await leaf(i)', + desc: 'async/await 编译为可恢复状态机,含挂起、异常传播与销毁。', + }, + { + term: '匹配与闭包', + code: 'match ty:', + desc: 'match 支持嵌套与类变体分派;闭包按需捕获,nonlocal 与 lambda 同等对待。', + }, + ], + }, + compiler: { + eyebrow: 'HOW IT COMPILES', + title: '两阶段编译模型', + sub: '声明先行,翻译在后;模块以内容哈希命名,未变动的部分直接跳过。', + steps: [ + { tag: 'src/*.vp', desc: '按 import 递归发现可达模块,只翻译真正被引用的文件。' }, + { tag: '内容 SHA1', desc: '内容哈希前 8 字节即模块标识,决定缓存目录。' }, + { tag: '阶段一 · 声明', desc: '产出 vpi 签名、stub 声明、text 实现与依赖清单。' }, + { tag: '增量判定', desc: '四处缓存命中即跳过,只重译受影响模块。' }, + { tag: '阶段二 · 合并', desc: '按拓扑序合并声明与实现,去重符号、前移类型。' }, + { tag: 'llc · -O0', desc: '完整 IR 编译为目标文件,多模块并行。' }, + { tag: 'clang++ · lld', desc: '链接为原生可执行文件。' }, + ], + cache: { + title: '构建开关', + items: [ + { flag: '--phase 1|2|all', desc: '单跑声明 / 单跑翻译 / 全流程' }, + { flag: '--clean', desc: '清理缓存与产物' }, + { flag: '--clear-cache', desc: '只清模块缓存' }, + { flag: '--rebuild-includes', desc: '只重建标准库产物' }, + { flag: '--repl', desc: '进入交互式 REPL' }, + { flag: '--asan', desc: 'ASan 插桩构建' }, + { flag: '--phase2command', desc: '导出第二阶段命令' }, + ], + }, + }, + oop: { + eyebrow: 'OBJECT MODEL', + title: '结构体之上,多态可选', + sub: '没有隐式装箱,没有隐藏分配——class 就是结构体布局,虚表是一根可以替换的指针。', + codeTitle: '继承与分派', + code: [ + { t: 'virtual class Shape:' }, + { t: ' sides: int' }, + { t: ' def area(self) -> int:' }, + { t: ' return 0', c: '基类默认实现' }, + { t: '' }, + { t: 'novirtual class Square(Shape):' }, + { t: ' size: int' }, + { t: ' def area(self) -> int:' }, + { t: ' return self.size * self.size', c: '静态绑定覆盖,无虚表开销' }, + ], + notesTitle: '要点', + notes: [ + { key: 'vtable 位置', value: '对象首字段:偏移 0,复制 8 字节即可替换派发表' }, + { key: '槽位顺序', value: '父类在前、子类在后,上限 32,跨模块不错位' }, + { key: 'novirtual', value: '静态绑定 + this 调整,零虚表开销,可与 virtual 混用' }, + { key: '多继承', value: '字段展平,MRO 展平上限 64 层' }, + { key: '布局控制', value: 'union 共享内存、packed 去填充、aligned(N) 强对齐' }, + { key: '运算符重载', value: '__add__ / __eq__ / __lshift__ 等全套 dunder' }, + { key: '构造', value: '__init__ / __new__ / __before_init__ / __sizeof__' }, + ], + }, + meta: { + eyebrow: 'COMPILE-TIME', + title: '编译期设施', + sub: '宏、条件编译、内联 IR 与汇编、函数属性——都是语言内的语法,而不是预处理器。', + codeTitle: '声明与修饰', + code: [ + { t: 'define MAX_SIZE = 4096', c: '引用处内联,不生成全局符号' }, + { t: '' }, + { t: 'export def Init() -> int:', c: '豁免哈希前缀,供跨模块或 C 链接' }, + { t: ' return 0' }, + { t: '' }, + { t: 'inline def Fast(x: int) -> int:', c: '提示内联' }, + { t: ' return x * 2' }, + { t: '' }, + { t: 'extern def LibCall(x: int) -> int:', c: '只声明、不定义' }, + { t: ' pass' }, + ], + chipsTitle: '深入一层', + chips: [ + { name: '内联 LLVM IR', note: 'c.LLVMIR("add i32 …", int)' }, + { name: '内联汇编', note: 'c.Asm("nop") · 寄存器与内存约束' }, + { name: '函数属性', note: 'always_inline · nounwind · packed' }, + { name: '结构化条件编译', note: '语法结构取代 #ifdef' }, + ], + }, + repl: { + eyebrow: 'REPL', + title: '交互式 REPL', + sub: '一行行写,逐句编译到动态库并立即执行——变量、函数与类型都能跨片段累积。', + points: [ + { + title: '片段即模块', + desc: '每行输入被包成片段函数,翻译为模块 IR、编译为动态库、装载调用后读回结果。', + }, + { + title: '跨片段变量', + desc: 'x: int = 5 之后可直接用 x + 1,会话变量按槽位寻址、持续有效。', + }, + { + title: '跨片段函数', + desc: '块内顶格的 def 提升为导出函数(限制:签名单行、暂不支持 async def)。', + }, + { + title: '跨片段类型', + desc: '块里的 class 进入会话,后续片段可直接构造并调用其方法。', + }, + { + title: '多行块与错误恢复', + desc: '行尾冒号续行、空行执行;出错经统一出口恢复,不中断会话。', + }, + ], + sampleTitle: '会话示例', + lines: [ + '>>> x: int = 5', + '>>> def twice(n: int) -> int:', + '... return n * 2', + '>>> twice(x) + 1', + '11', + ], + }, + source: { + eyebrow: 'SOURCE TOUR', + title: '源码导览', + sub: '编译器就在仓库里,规模与分工一览——可以逐模块读完。', + stats: [ + { value: '76', label: '编译器源文件(.vp)' }, + { value: '64,656', label: '本体源码行数' }, + { value: '52', label: '翻译器核心文件 · 49,978 行' }, + { value: '39', label: '自测用例' }, + { value: '22.1.8', label: 'LLVM 版本' }, + { value: 'Windows x64', label: '当前目标平台' }, + ], + dirsTitle: '目录职责', + dirs: [ + { path: 'App/main.vp', desc: '命令行入口:参数解析、阶段调度与构建编排' }, + { path: 'App/lib/Phase/', desc: '两阶段实现与构建管线:扫描、拓扑、产物落盘、并行编译' }, + { path: 'App/lib/Stub/', desc: '声明生成与合并:签名读取、拓扑合并、符号去重、类型前移' }, + { path: 'App/lib/core/Gen/', desc: '翻译器与代码生成核心:类型、表达式、语句、类与调用' }, + { path: 'App/lib/Projectrans/', desc: '工程配置、路径解析、哈希切片与缓存策略' }, + { path: 'Test/', desc: '自测套件:语法、指针、OOP、异步、负向与哈希命名空间' }, + ], + }, + quickstart: { + eyebrow: 'GET STARTED', + title: '三分钟跑通 Hello Viper', + tagline: '你好,Viper,三分钟后见。', + sub: '编译器已完全自举——TransPyV 是原生可执行文件。准备 Windows(mingw)+ LLVM 工具链即可开跑。', + steps: [ + { + num: '01', + title: '克隆编译器与模板', + desc: 'TransPyC 仓库即编译器本体,其中自举实现 TransPyV 已能直接编译工程;ViperTemplateProject 是开箱即用的 Windows 模板。', + }, + { + num: '02', + title: '编译项目', + desc: '以原生 TransPyV 驱动两阶段编译,可执行文件产出到模板工程的 output/。', + }, + { + num: '03', + title: '运行原生程序', + desc: '得到一个真正的原生 app.exe——打印出「你好,世界」。', + }, + ], + prereqs: ['TransPyV · 原生编译器', 'LLVM 22.1.8 · llc', 'mingw · clang++ / lld', 'git'], + cmdNote: '# Windows PowerShell · mingw + LLVM 已加入 PATH', + output: '你好,世界', + cliTitle: '常用命令行参数', + cli: [ + { flag: '--project ', desc: '指定工程文件,按工程配置驱动编译' }, + { flag: '--phase 1|2|all', desc: '只跑声明阶段 / 只跑翻译阶段 / 全流程' }, + { flag: '--repl', desc: '进入交互式 REPL' }, + { flag: '--clean', desc: '清理缓存与产物,等价于干净重建' }, + { flag: '--asan', desc: '以 ASan 插桩构建,定位内存问题' }, + { flag: '--phase2command', desc: '导出第二阶段构建命令' }, + ], + }, + ecosystem: { + eyebrow: 'ECOSYSTEM', + title: '从编译器到操作系统', + sub: 'Viper 不是孤岛:围绕它的是完整的自研工具链与系统级实践。', + items: [ + { + name: 'TransPyV', + role: '编译器', + desc: '自举的编译器本体:两阶段声明提取与 LLVM IR 翻译,本身即以 Viper 写成。', + href: 'https://git.gvsds.com/GVSDS/TransPyC', + badge: '自举', + }, + { + name: 'includes/', + role: '标准库', + desc: '纯 Viper 的标准库:自研解析器、IR 构建、协程运行时、伙伴分配器、线程与 Win32 绑定。', + href: '', + badge: '', + }, + { + name: 'testcheck', + role: '测试框架', + desc: '编译期断言与分组框架,39 个自测用例的统一入口。', + href: '', + badge: '', + }, + { + name: 'ViperTemplateProject', + role: '模板工程', + desc: '开箱即用的 Windows 工程骨架:工程文件、构建脚本与示例源码。', + href: '', + badge: '', + }, + { + name: 'Venom', + role: '包管理', + desc: '官方包管理器:包的分发、安装与依赖解析。', + href: 'https://venom.gvsds.com', + badge: '开发中', + }, + { + name: 'ViperOS', + role: '操作系统', + desc: '以 Viper 构建的 x86_64 内核实践,检验语言在裸机上的极限。', + href: '', + badge: '', + }, + ], + }, + roadmap: { + eyebrow: 'ROADMAP', + title: '自举完成,生态启程', + sub: '编译器已完全自举、摆脱 Python 运行时——下一步是把库生态做成 Viper 的一等公民。', + items: [ + { + phase: 'done', + title: '完全自举', + desc: '编译器由 Viper 重写完成:76 个源文件、64,656 行,能编译自身并产出原生 TransPyV.exe;自研解析器与 IR 库取代了第三方依赖。', + }, + { + phase: 'done', + title: '交互式 REPL', + desc: '会话变量、跨片段函数与类型:每段输入编译为动态库后即时执行,错误可恢复。', + }, + { + phase: 'active', + title: '泛型特化', + desc: '类模板注册与按需特化已落地,自测套件暂将其屏蔽以隔离已知崩溃——修复后放出泛型容器。', + }, + { + phase: 'next', + title: 'Venom 包管理', + desc: '官方包管理器上线,Viper 库的发布、安装与依赖解析成为一等公民。', + }, + { + phase: 'next', + title: '跨平台目标', + desc: '当前仅支持 Windows x64(源码直接绑定 Win32),后续补齐类 Unix 目标与工具链适配。', + }, + ], + }, + cta: { + title: '准备好写第一行原生代码了吗?', + sub: '从模板工程出发,五分钟内看到你的第一个 Viper 程序运行。', + start: '快速上手', + source: '查看源码', + }, + footer: { + tagline: '底层,再简单一点吧?', + builtBy: 'Viper 官网 · GVSDS', + linksTitle: '导航', + backTop: '回到顶部', + }, +} diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..236c830 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,9 @@ +import { createApp } from 'vue' +import App from './App.vue' +// 品牌字专用字体:自托管衬线体 Playfair Display Black(latin 900 子集,内嵌 woff2,无外网依赖) +// 备选:若要切回无衬线,改成 '@fontsource/inter/latin-900.css'(其依赖仍保留在 package.json) +import '@fontsource/playfair-display/latin-900.css' +import 'lenis/dist/lenis.css' +import '@/assets/base.css' + +createApp(App).mount('#app') diff --git a/tsconfig.app.json b/tsconfig.app.json new file mode 100644 index 0000000..9e4d7f8 --- /dev/null +++ b/tsconfig.app.json @@ -0,0 +1,14 @@ +{ + "extends": "@vue/tsconfig/tsconfig.dom.json", + "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], + "exclude": ["src/**/__tests__/*"], + "compilerOptions": { + "composite": true, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "ignoreDeprecations": "6.0", + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..1ffef60 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 0000000..2968306 --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,9 @@ +{ + "extends": "@vue/tsconfig/tsconfig.json", + "include": ["vite.config.*"], + "compilerOptions": { + "composite": true, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "types": ["node"] + } +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..8c7ab1b --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,23 @@ +import { defineConfig } from 'vite' +import { fileURLToPath, URL } from 'node:url' +import vue from '@vitejs/plugin-vue' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [vue()], + resolve: { + alias: { + '@': fileURLToPath(new URL('./src', import.meta.url)), + }, + }, + server: { + host: '0.0.0.0', + port: 5175, + }, + build: { + outDir: 'dist', + sourcemap: false, + chunkSizeWarningLimit: 1500, + cssCodeSplit: false, + }, +})