diff --git a/.github/workflows/azure-deploy-docs.yml b/.github/workflows/azure-deploy-docs.yml new file mode 100644 index 0000000..6b2f381 --- /dev/null +++ b/.github/workflows/azure-deploy-docs.yml @@ -0,0 +1,64 @@ +name: Azure Static Web Apps CI/CD - Docs + +on: + push: + branches: + - main + pull_request: + types: [ opened, synchronize, reopened, closed ] + branches: + - main + +jobs: + build_and_deploy_job: + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') + runs-on: ubuntu-latest + name: Build and Deploy Job Docs + permissions: + contents: read + env: + NODE_VERSION: "20" + steps: + - uses: actions/checkout@v3 + with: + submodules: true + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "npm" + + - name: Install dependencies + run: npm ci + + - name: Install playwright browsers + run: npx playwright install --with-deps + + - name: Build docs + run: NODE_ENV=production npm run build + env: + CLARITY_PROJECT_ID: ${{ secrets.CLARITY_PROJECT_ID }} + + - name: Build And Deploy + id: builddeploy + uses: Azure/static-web-apps-deploy@v1 + with: + azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_ASHY_FLOWER_DOCS }} + repo_token: ${{ secrets.GITHUB_TOKEN }} + action: "upload" + app_location: "dist" + api_location: "" + skip_app_build: true + + close_pull_request_job: + if: github.event_name == 'pull_request' && github.event.action == 'closed' + runs-on: ubuntu-latest + name: Close Pull Request Job + steps: + - name: Close Pull Request + id: closepullrequest + uses: Azure/static-web-apps-deploy@v1 + with: + azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_ASHY_FLOWER_DOCS }} + action: "close" diff --git a/.github/workflows/version-monitor.yml b/.github/workflows/version-monitor.yml new file mode 100644 index 0000000..46228a5 --- /dev/null +++ b/.github/workflows/version-monitor.yml @@ -0,0 +1,232 @@ +name: Version Monitor + +# Trigger the workflow every 30 minutes and allow manual triggering +on: + push: + branches: + - main + schedule: + - cron: "*/30 * * * *" # Run every 30 minutes + workflow_dispatch: # Allow manual trigger from GitHub Actions UI + +# Set permissions for creating branches, commits, and pull requests +permissions: + contents: write + pull-requests: write + +jobs: + monitor: + name: Monitor Version Changes + runs-on: ubuntu-latest + outputs: + update_needed: ${{ steps.monitor.outputs.update_needed }} + new_version: ${{ steps.monitor.outputs.new_version }} + pr_created: ${{ steps.pr.outputs.pr_created }} + pr_url: ${{ steps.pr.outputs.pr_url }} + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + + - name: Display configuration + run: | + echo "Version Monitor Configuration" + echo "==========================" + echo "Source URL: ${{ vars.VERSION_SOURCE_URL || 'https://desktop.dl.hagicode.com/index.json' }}" + echo "Request Timeout: 30000ms" + echo "Max Retries: 3" + echo "Repository: ${{ github.repository }}" + + - name: Run version monitor + id: monitor + run: node scripts/version-monitor.js + env: + VERSION_SOURCE_URL: ${{ vars.VERSION_SOURCE_URL || 'https://desktop.dl.hagicode.com/index.json' }} + REQUEST_TIMEOUT: "30000" + MAX_RETRIES: "3" + + - name: Configure Git + if: steps.monitor.outputs.update_needed == 'true' + run: | + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + + - name: Check existing branch + id: check_branch + if: steps.monitor.outputs.update_needed == 'true' + run: | + BRANCH_NAME="version-update-${{ steps.monitor.outputs.new_version }}" + echo "Checking for existing branch: $BRANCH_NAME" + if git ls-remote --heads origin "$BRANCH_NAME" | grep -q "$BRANCH_NAME"; then + echo "branch_exists=true" >> $GITHUB_OUTPUT + echo "Branch $BRANCH_NAME already exists on remote" + else + echo "branch_exists=false" >> $GITHUB_OUTPUT + echo "Branch $BRANCH_NAME does not exist on remote" + fi + + - name: Create feature branch + if: steps.monitor.outputs.update_needed == 'true' && steps.check_branch.outputs.branch_exists != 'true' + run: | + BRANCH_NAME="version-update-${{ steps.monitor.outputs.new_version }}" + git checkout -b "$BRANCH_NAME" + echo "Created branch: $BRANCH_NAME" + + - name: Commit version changes + if: steps.monitor.outputs.update_needed == 'true' && steps.check_branch.outputs.branch_exists != 'true' + run: | + git add public/version-index.json + git commit -m "chore: update version to ${{ steps.monitor.outputs.new_version }}" + + - name: Push branch + if: steps.monitor.outputs.update_needed == 'true' && steps.check_branch.outputs.branch_exists != 'true' + run: | + BRANCH_NAME="version-update-${{ steps.monitor.outputs.new_version }}" + git push origin "$BRANCH_NAME" + + - name: Check existing PR + id: check_pr + if: steps.monitor.outputs.update_needed == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CURRENT_VERSION: ${{ steps.monitor.outputs.new_version }} + run: | + echo "Checking for existing PR for version: ${CURRENT_VERSION}" + EXISTING_PR=$(gh pr list \ + --search "chore: update version to ${CURRENT_VERSION} in:head" \ + --state open \ + --json number,title \ + --jq '.[0]') + + if [ -n "$EXISTING_PR" ]; then + PR_NUMBER=$(echo "$EXISTING_PR" | jq -r '.number') + PR_TITLE=$(echo "$EXISTING_PR" | jq -r '.title') + echo "pr_exists=true" >> $GITHUB_OUTPUT + echo "existing_pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT + echo "existing_pr_url=$(gh pr view $PR_NUMBER --json url -q .url)" >> $GITHUB_OUTPUT + echo "Found existing PR: #$PR_NUMBER - $PR_TITLE" + else + echo "pr_exists=false" >> $GITHUB_OUTPUT + echo "No existing PR found for version ${CURRENT_VERSION}" + fi + + - name: Close previous version PRs + id: close_prs + if: steps.monitor.outputs.update_needed == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CURRENT_VERSION: ${{ steps.monitor.outputs.new_version }} + run: | + echo "Closing previous version PRs (excluding current version: ${CURRENT_VERSION})..." + PREVIOUS_PRS=$(gh pr list \ + --search "chore: update version to in:head" \ + --state open \ + --json number,title \ + --jq '.[] | select(.title != "chore: update version to '"${CURRENT_VERSION}"'") | .number') + + if [ -n "$PREVIOUS_PRS" ]; then + echo "$PREVIOUS_PRS" | while read -r pr_number; do + echo "Closing PR #$pr_number" + gh pr close "$pr_number" --comment "由于新的版本更新 PR 自动关闭" + done + else + echo "No previous version PRs to close" + fi + + - name: Create Pull Request + id: pr + if: steps.monitor.outputs.update_needed == 'true' && steps.check_pr.outputs.pr_exists != 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + NEW_VERSION="${{ steps.monitor.outputs.new_version }}" + BRANCH_NAME="version-update-${NEW_VERSION}" + PR_BODY="## Version Update + + This PR updates the version index to reflect the new version detected from the official website. + + - **New Version**: ${NEW_VERSION} + - **Source**: ${{ vars.VERSION_SOURCE_URL || 'https://desktop.dl.hagicode.com/index.json' }} + - **Checked At**: $(date -u +"%Y-%m-%dT%H:%M:%SZ") + + ### Changes + - Updated \`public/version-index.json\` with the latest version data from online API + + ### Next Steps + After merging this PR, the CI/CD pipeline will automatically rebuild and deploy the documentation site with the updated version information. + + --- + _This PR was automatically created by the [Version Monitor](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) workflow._" + + gh pr create \ + --title "chore: update version to ${NEW_VERSION}" \ + --body "$PR_BODY" \ + --base main \ + --head "$BRANCH_NAME" \ + --label "automation,version" + + echo "pr_created=true" >> $GITHUB_OUTPUT + echo "pr_url=$(gh pr view --json url -q .url)" >> $GITHUB_OUTPUT + + - name: Display result + if: always() + run: | + echo "Version Monitor Result" + echo "======================" + echo "Update Needed: ${{ steps.monitor.outputs.update_needed }}" + echo "New Version: ${{ steps.monitor.outputs.new_version }}" + echo "Branch Exists: ${{ steps.check_branch.outputs.branch_exists }}" + echo "PR Exists: ${{ steps.check_pr.outputs.pr_exists }}" + echo "PR Created: ${{ steps.pr.outputs.pr_created }}" + if [ "${{ steps.check_pr.outputs.pr_exists }}" == "true" ]; then + echo "Existing PR: #${{ steps.check_pr.outputs.existing_pr_number }}" + echo "Existing PR URL: ${{ steps.check_pr.outputs.existing_pr_url }}" + else + echo "PR URL: ${{ steps.pr.outputs.pr_url }}" + fi + + notify-version-update: + needs: monitor + if: needs.monitor.outputs.pr_created == 'true' + runs-on: ubuntu-latest + steps: + - uses: HagiCode-org/haginotifier@v1 + with: + msg_type: 'post' + title: 'Version Monitor' + message: | + ## Version Monitor + + **状态**: 🔄 发现新版本 + **新版本**: ${{ needs.monitor.outputs.new_version }} + **仓库**: ${{ github.repository }} + **PR 链接**: ${{ needs.monitor.outputs.pr_url }} + **运行详情**: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + env: + FEISHU_WEBHOOK_URL: ${{ secrets.FEISHU_WEBHOOK_URL }} + + notify-failure: + needs: monitor + if: failure() + runs-on: ubuntu-latest + steps: + - uses: HagiCode-org/haginotifier@v1 + with: + msg_type: 'post' + title: 'Version Monitor' + message: | + ## Version Monitor + + **状态**: ❌ 失败 + **仓库**: ${{ github.repository }} + **触发者**: ${{ github.actor }} + **运行详情**: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + env: + FEISHU_WEBHOOK_URL: ${{ secrets.FEISHU_WEBHOOK_URL }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a51b2b2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,46 @@ +# Dependencies +node_modules/ +.pnp/ +.pnp.js + +# Turbo +.turbo/ + +# Testing +coverage/ + +# Production +build/ +.dist/ +dist/ + +# Misc +.DS_Store +*.pem + +# Debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Local env files +.env +.env.local +.env.*.local + +# Docusaurus +.docusaurus/ + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS +Thumbs.db + +.claude/skills/ui-ux-pro-max/scripts/__pycache__/ +.astro/ +tsconfig.tsbuildinfo diff --git a/README.md b/README.md index 1dc6372..5aaaf03 100644 --- a/README.md +++ b/README.md @@ -1 +1,83 @@ -# docs \ No newline at end of file +# HagiCode Documentation + +独立的 HagiCode 文档站点,使用 Astro 和 Starlight 构建。 + +## 仓库结构 + +``` +docs/ +├── src/ +│ ├── content/docs/ # 文档内容(Markdown 和 MDX 文件) +│ │ └── blog/ # 博客文章 +│ ├── components/ # 自定义 UI 组件 +│ ├── config/ # 导航和配置 +│ ├── integrations/ # Astro 集成 +│ ├── pages/ # 页面 +│ ├── styles/ # 样式文件 +│ └── utils/ # 工具函数 +├── public/ # 静态资源(图片、图标等) +├── .github/workflows/ # CI/CD 工作流 +├── astro.config.mjs # Astro 配置 +├── package.json # 依赖和脚本 +├── tsconfig.json # TypeScript 配置 +└── illustration-management.md # 配图管理指南 +``` + +## 快速开始 + +### 安装依赖 + +```bash +npm install +``` + +### 开发模式 + +```bash +npm run dev +``` + +文档站点将在 http://localhost:31265 启动。 + +### 构建 + +```bash +npm run build +``` + +构建输出将生成在 `dist/` 目录。 + +### 预览构建结果 + +```bash +npm run preview +``` + +## 贡献指南 + +### 编辑文档 + +文档内容位于 `src/content/docs/` 目录。编辑 Markdown 文件后,更改将自动在开发服务器中反映。 + +### 添加博客文章 + +1. 在 `src/content/docs/blog/` 创建新文件 +2. 使用日期前缀命名(例如:`2026-02-21-my-post.mdx`) +3. 添加 frontmatter 元数据 + +### 添加静态资源 + +将图片和其他静态文件放入 `public/` 目录。它们在构建时会被复制到 `dist/` 目录的根路径。 + +## CI/CD + +文档通过 GitHub Actions 自动部署到 Azure Static Web Apps。 + +- 推送到 `main` 分支会触发部署 +- Pull Requests 会触发构建验证 + +## 相关资源 + +- [Astro 文档](https://docs.astro.build) +- [Starlight 文档](https://starlight.astro.build) +- [配图管理指南](./illustration-management.md) diff --git a/astro.config.mjs b/astro.config.mjs new file mode 100644 index 0000000..b5c009e --- /dev/null +++ b/astro.config.mjs @@ -0,0 +1,153 @@ +import { defineConfig } from "astro/config"; +import starlight from "@astrojs/starlight"; +import starlightBlog from "starlight-blog"; +import sitemap from "@astrojs/sitemap"; +import mdx from "@astrojs/mdx"; +import partytown from "@astrojs/partytown"; +import robotsTxt from "astro-robots-txt"; +import react from "@astrojs/react"; +import linkValidator from "astro-link-validator"; + +import mermaidInjector from "./src/integrations/mermaid-injector.ts"; +import rehypeMermaid from "rehype-mermaid"; +// rehype-raw 暂时禁用,可能与 MDX 处理冲突 +// import rehypeRaw from "rehype-raw"; +import rehypeExternalLinks from "rehype-external-links"; + +// 获取 base 路径:文档站点独立部署在 docs.hagicode.com,开发和生产都使用根路径 +const getBasePath = () => { + // 文档站点现在独立部署在 docs.hagicode.com + // 不再需要 /docs 前缀,开发和生产都使用根路径 + return "/"; +}; + +// https://astro.build/config +export default defineConfig({ + // 站点完整 URL,用于生成 sitemap 和 canonical URL + site: "https://docs.hagicode.com", + // 文档站点部署路径:独立部署在 docs.hagicode.com,使用根路径 + base: getBasePath(), + markdown: { + syntaxHighlight: { + type: "shiki", + excludeLangs: ["mermaid", "math"], + }, + rehypePlugins: [ + // rehypeRaw 暂时禁用,可能与 MDX 处理冲突 + // rehypeRaw, + rehypeMermaid, + [ + rehypeExternalLinks, + { + target: "_blank", + rel: ["noopener", "noreferrer"], + }, + ], + ], + }, + // 配置 Vite 环境变量 + vite: { + resolve: { + alias: { + "@": new URL("./src", import.meta.url).pathname, + "@shared": new URL("./shared/src", import.meta.url).pathname, + }, + }, + define: { + 'import.meta.env.PROD': JSON.stringify( + process.env.NODE_ENV === 'production' + ), + "import.meta.env.VITE_CLARITY_PROJECT_ID": JSON.stringify( + process.env.VITE_CLARITY_PROJECT_ID || "", + ), + "import.meta.env.VITE_CLARITY_DEBUG": JSON.stringify( + process.env.VITE_CLARITY_DEBUG || "", + ), + // Baidu Analytics - Disabled, migrated to 51LA + // "import.meta.env.VITE_BAIDU_ANALYTICS_ID": JSON.stringify( + // process.env.BAIDU_ANALYTICS_ID || "", + // ), + // "import.meta.env.VITE_BAIDU_ANALYTICS_DEBUG": JSON.stringify( + // process.env.BAIDU_ANALYTICS_DEBUG || "", + // ), + "import.meta.env.VITE_51LA_ID": JSON.stringify( + process.env.LI_51LA_ID || "L6b88a5yK4h2Xnci", + ), + "import.meta.env.VITE_51LA_DEBUG": JSON.stringify( + process.env.LI_51LA_DEBUG || "", + ), + }, + }, + integrations: [ + // robots.txt 配置 - 使用 astro-robots-txt 插件 + robotsTxt({ + sitemap: "https://docs.hagicode.com/sitemap-index.xml", + }), + + starlight({ + title: "Hagicode Docs", + description: "Hagicode 项目文档", + favicon: "/favicon.ico", + social: [ + { + icon: "github", + label: "GitHub 仓库", + href: "https://github.com/HagiCode-org/site", + }, + ], + components: { + Header: "./src/components/StarlightHeader.astro", + Footer: "./src/components/StarlightFooter.astro", + MarkdownContent: './src/components/MarkdownContent.astro', + }, + sidebar: [ + { + label: "产品概述", + link: "/product-overview", + }, + { + label: "快速开始", + autogenerate: { directory: "quick-start" }, + }, + { + label: "安装指南", + autogenerate: { directory: "installation" }, + }, + { + label: "相关软件安装", + autogenerate: { directory: "related-software-installation" }, + }, + ], + customCss: ["./src/styles/starlight-override.css"], + editLink: { + baseUrl: "https://github.com/HagiCode-org/site/edit/main/", + }, + plugins: [ + starlightBlog({ + rss: false, + postCount: 20, + }), + ], + }), + sitemap(), + partytown(), + react(), + mermaidInjector(), + // 链接验证集成 - 在 CI 环境中启用外部链接检查 + linkValidator({ + // 仅在 CI 环境中启用外部链接检查,避免本地构建时间过长 + checkExternal: process.env.CI === "true", + // 外部链接超时时间(毫秒) + externalTimeout: 10000, + // 链接检查不再阻塞构建,仅发出警告 + // 独立的链接检查由 .github/workflows/link-check.yml 负责 + failOnBrokenLinks: false, + // 详细输出(用于调试) + verbose: process.env.CI === "true", + // 排除某些路径(如 API 端点、管理后台) + exclude: [], + }), + ], + // 添加 Mermaid 渲染脚本到所有页面 + scopedStyleStrategy: "where", +}); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..d6ff64e --- /dev/null +++ b/package-lock.json @@ -0,0 +1,10402 @@ +{ + "name": "@hagicode/docs", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@hagicode/docs", + "version": "0.0.1", + "dependencies": { + "@astrojs/mdx": "4.3.13", + "@astrojs/partytown": "^2.1.4", + "@astrojs/react": "^4.4.2", + "@astrojs/sitemap": "^3.7.0", + "@astrojs/starlight": "^0.37.4", + "@types/react": "^19.2.13", + "@types/react-dom": "^19.2.3", + "astro": "^5.6.1", + "astro-link-validator": "github:rodgtr1/astro-link-validator", + "astro-robots-txt": "^1.0.0", + "astro-seo": "^1.1.0", + "mermaid": "^11.12.2", + "playwright": "^1.58.2", + "react": "^19.2.4", + "react-dom": "^19.2.4", + "rehype-external-links": "^3.0.0", + "rehype-mermaid": "^3.0.0", + "rehype-raw": "^3.0.0", + "semver": "^7.7.4", + "sharp": "^0.34.2", + "starlight-blog": "^0.25.2" + } + }, + "node_modules/@antfu/install-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/@antfu/install-pkg/-/install-pkg-1.1.0.tgz", + "integrity": "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==", + "license": "MIT", + "dependencies": { + "package-manager-detector": "^1.3.0", + "tinyexec": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@astrojs/check": { + "version": "0.9.6", + "resolved": "https://registry.npmmirror.com/@astrojs/check/-/check-0.9.6.tgz", + "integrity": "sha512-jlaEu5SxvSgmfGIFfNgcn5/f+29H61NJzEMfAZ82Xopr4XBchXB1GVlcJsE+elUlsYSbXlptZLX+JMG3b/wZEA==", + "license": "MIT", + "dependencies": { + "@astrojs/language-server": "^2.16.1", + "chokidar": "^4.0.1", + "kleur": "^4.1.5", + "yargs": "^17.7.2" + }, + "bin": { + "astro-check": "bin/astro-check.js" + }, + "peerDependencies": { + "typescript": "^5.0.0" + } + }, + "node_modules/@astrojs/compiler": { + "version": "2.13.1", + "resolved": "https://registry.npmmirror.com/@astrojs/compiler/-/compiler-2.13.1.tgz", + "integrity": "sha512-f3FN83d2G/v32ipNClRKgYv30onQlMZX1vCeZMjPsMMPl1mDpmbl0+N5BYo4S/ofzqJyS5hvwacEo0CCVDn/Qg==", + "license": "MIT" + }, + "node_modules/@astrojs/internal-helpers": { + "version": "0.7.5", + "resolved": "https://registry.npmmirror.com/@astrojs/internal-helpers/-/internal-helpers-0.7.5.tgz", + "integrity": "sha512-vreGnYSSKhAjFJCWAwe/CNhONvoc5lokxtRoZims+0wa3KbHBdPHSSthJsKxPd8d/aic6lWKpRTYGY/hsgK6EA==", + "license": "MIT" + }, + "node_modules/@astrojs/language-server": { + "version": "2.16.3", + "resolved": "https://registry.npmmirror.com/@astrojs/language-server/-/language-server-2.16.3.tgz", + "integrity": "sha512-yO5K7RYCMXUfeDlnU6UnmtnoXzpuQc0yhlaCNZ67k1C/MiwwwvMZz+LGa+H35c49w5QBfvtr4w4Zcf5PcH8uYA==", + "license": "MIT", + "dependencies": { + "@astrojs/compiler": "^2.13.0", + "@astrojs/yaml2ts": "^0.2.2", + "@jridgewell/sourcemap-codec": "^1.5.5", + "@volar/kit": "~2.4.27", + "@volar/language-core": "~2.4.27", + "@volar/language-server": "~2.4.27", + "@volar/language-service": "~2.4.27", + "muggle-string": "^0.4.1", + "tinyglobby": "^0.2.15", + "volar-service-css": "0.0.68", + "volar-service-emmet": "0.0.68", + "volar-service-html": "0.0.68", + "volar-service-prettier": "0.0.68", + "volar-service-typescript": "0.0.68", + "volar-service-typescript-twoslash-queries": "0.0.68", + "volar-service-yaml": "0.0.68", + "vscode-html-languageservice": "^5.6.1", + "vscode-uri": "^3.1.0" + }, + "bin": { + "astro-ls": "bin/nodeServer.js" + }, + "peerDependencies": { + "prettier": "^3.0.0", + "prettier-plugin-astro": ">=0.11.0" + }, + "peerDependenciesMeta": { + "prettier": { + "optional": true + }, + "prettier-plugin-astro": { + "optional": true + } + } + }, + "node_modules/@astrojs/markdown-remark": { + "version": "6.3.10", + "resolved": "https://registry.npmmirror.com/@astrojs/markdown-remark/-/markdown-remark-6.3.10.tgz", + "integrity": "sha512-kk4HeYR6AcnzC4QV8iSlOfh+N8TZ3MEStxPyenyCtemqn8IpEATBFMTJcfrNW32dgpt6MY3oCkMM/Tv3/I4G3A==", + "license": "MIT", + "dependencies": { + "@astrojs/internal-helpers": "0.7.5", + "@astrojs/prism": "3.3.0", + "github-slugger": "^2.0.0", + "hast-util-from-html": "^2.0.3", + "hast-util-to-text": "^4.0.2", + "import-meta-resolve": "^4.2.0", + "js-yaml": "^4.1.1", + "mdast-util-definitions": "^6.0.0", + "rehype-raw": "^7.0.0", + "rehype-stringify": "^10.0.1", + "remark-gfm": "^4.0.1", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.1.2", + "remark-smartypants": "^3.0.2", + "shiki": "^3.19.0", + "smol-toml": "^1.5.2", + "unified": "^11.0.5", + "unist-util-remove-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "unist-util-visit-parents": "^6.0.2", + "vfile": "^6.0.3" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/hast-util-raw": { + "version": "9.1.0", + "resolved": "https://registry.npmmirror.com/hast-util-raw/-/hast-util-raw-9.1.0.tgz", + "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/hast-util-to-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmmirror.com/hast-util-to-parse5/-/hast-util-to-parse5-8.0.1.tgz", + "integrity": "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/markdown-remark/node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmmirror.com/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/mdx": { + "version": "4.3.13", + "resolved": "https://registry.npmmirror.com/@astrojs/mdx/-/mdx-4.3.13.tgz", + "integrity": "sha512-IHDHVKz0JfKBy3//52JSiyWv089b7GVSChIXLrlUOoTLWowG3wr2/8hkaEgEyd/vysvNQvGk+QhysXpJW5ve6Q==", + "license": "MIT", + "dependencies": { + "@astrojs/markdown-remark": "6.3.10", + "@mdx-js/mdx": "^3.1.1", + "acorn": "^8.15.0", + "es-module-lexer": "^1.7.0", + "estree-util-visit": "^2.0.0", + "hast-util-to-html": "^9.0.5", + "piccolore": "^0.1.3", + "rehype-raw": "^7.0.0", + "remark-gfm": "^4.0.1", + "remark-smartypants": "^3.0.2", + "source-map": "^0.7.6", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.3" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0" + }, + "peerDependencies": { + "astro": "^5.0.0" + } + }, + "node_modules/@astrojs/mdx/node_modules/hast-util-raw": { + "version": "9.1.0", + "resolved": "https://registry.npmmirror.com/hast-util-raw/-/hast-util-raw-9.1.0.tgz", + "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/mdx/node_modules/hast-util-to-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmmirror.com/hast-util-to-parse5/-/hast-util-to-parse5-8.0.1.tgz", + "integrity": "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/mdx/node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmmirror.com/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@astrojs/partytown": { + "version": "2.1.4", + "resolved": "https://registry.npmmirror.com/@astrojs/partytown/-/partytown-2.1.4.tgz", + "integrity": "sha512-loUrAu0cGYFDC6dHVRiomdsBJ41VjDYXPA+B3Br51V5hENFgDSOLju86OIj1TvBACcsB22UQV7BlppODDG5gig==", + "license": "MIT", + "dependencies": { + "@qwik.dev/partytown": "^0.11.0", + "mrmime": "^2.0.1" + } + }, + "node_modules/@astrojs/prism": { + "version": "3.3.0", + "resolved": "https://registry.npmmirror.com/@astrojs/prism/-/prism-3.3.0.tgz", + "integrity": "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ==", + "license": "MIT", + "dependencies": { + "prismjs": "^1.30.0" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0" + } + }, + "node_modules/@astrojs/react": { + "version": "4.4.2", + "resolved": "https://registry.npmmirror.com/@astrojs/react/-/react-4.4.2.tgz", + "integrity": "sha512-1tl95bpGfuaDMDn8O3x/5Dxii1HPvzjvpL2YTuqOOrQehs60I2DKiDgh1jrKc7G8lv+LQT5H15V6QONQ+9waeQ==", + "license": "MIT", + "dependencies": { + "@vitejs/plugin-react": "^4.7.0", + "ultrahtml": "^1.6.0", + "vite": "^6.4.1" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0" + }, + "peerDependencies": { + "@types/react": "^17.0.50 || ^18.0.21 || ^19.0.0", + "@types/react-dom": "^17.0.17 || ^18.0.6 || ^19.0.0", + "react": "^17.0.2 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.2 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@astrojs/rss": { + "version": "4.0.15", + "resolved": "https://registry.npmmirror.com/@astrojs/rss/-/rss-4.0.15.tgz", + "integrity": "sha512-uXO/k6AhRkIDXmRoc6xQpoPZrimQNUmS43X4+60yunfuMNHtSRN5e/FiSi7NApcZqmugSMc5+cJi8ovqgO+qIg==", + "license": "MIT", + "dependencies": { + "fast-xml-parser": "^5.3.3", + "piccolore": "^0.1.3" + } + }, + "node_modules/@astrojs/sitemap": { + "version": "3.7.0", + "resolved": "https://registry.npmmirror.com/@astrojs/sitemap/-/sitemap-3.7.0.tgz", + "integrity": "sha512-+qxjUrz6Jcgh+D5VE1gKUJTA3pSthuPHe6Ao5JCxok794Lewx8hBFaWHtOnN0ntb2lfOf7gvOi9TefUswQ/ZVA==", + "license": "MIT", + "dependencies": { + "sitemap": "^8.0.2", + "stream-replace-string": "^2.0.0", + "zod": "^3.25.76" + } + }, + "node_modules/@astrojs/starlight": { + "version": "0.37.6", + "resolved": "https://registry.npmmirror.com/@astrojs/starlight/-/starlight-0.37.6.tgz", + "integrity": "sha512-wQrKwH431q+8FsLBnNQeG+R36TMtEGxTQ2AuiVpcx9APcazvL3n7wVW8mMmYyxX0POjTnxlcWPkdMGR3Yj1L+w==", + "license": "MIT", + "dependencies": { + "@astrojs/markdown-remark": "^6.3.1", + "@astrojs/mdx": "^4.2.3", + "@astrojs/sitemap": "^3.3.0", + "@pagefind/default-ui": "^1.3.0", + "@types/hast": "^3.0.4", + "@types/js-yaml": "^4.0.9", + "@types/mdast": "^4.0.4", + "astro-expressive-code": "^0.41.1", + "bcp-47": "^2.1.0", + "hast-util-from-html": "^2.0.1", + "hast-util-select": "^6.0.2", + "hast-util-to-string": "^3.0.0", + "hastscript": "^9.0.0", + "i18next": "^23.11.5", + "js-yaml": "^4.1.0", + "klona": "^2.0.6", + "magic-string": "^0.30.17", + "mdast-util-directive": "^3.0.0", + "mdast-util-to-markdown": "^2.1.0", + "mdast-util-to-string": "^4.0.0", + "pagefind": "^1.3.0", + "rehype": "^13.0.1", + "rehype-format": "^5.0.0", + "remark-directive": "^3.0.0", + "ultrahtml": "^1.6.0", + "unified": "^11.0.5", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.2" + }, + "peerDependencies": { + "astro": "^5.5.0" + } + }, + "node_modules/@astrojs/telemetry": { + "version": "3.3.0", + "resolved": "https://registry.npmmirror.com/@astrojs/telemetry/-/telemetry-3.3.0.tgz", + "integrity": "sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ==", + "license": "MIT", + "dependencies": { + "ci-info": "^4.2.0", + "debug": "^4.4.0", + "dlv": "^1.1.3", + "dset": "^3.1.4", + "is-docker": "^3.0.0", + "is-wsl": "^3.1.0", + "which-pm-runs": "^1.1.0" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0" + } + }, + "node_modules/@astrojs/yaml2ts": { + "version": "0.2.2", + "resolved": "https://registry.npmmirror.com/@astrojs/yaml2ts/-/yaml2ts-0.2.2.tgz", + "integrity": "sha512-GOfvSr5Nqy2z5XiwqTouBBpy5FyI6DEe+/g/Mk5am9SjILN1S5fOEvYK0GuWHg98yS/dobP4m8qyqw/URW35fQ==", + "license": "MIT", + "dependencies": { + "yaml": "^2.5.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.0", + "resolved": "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.6", + "resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.28.6.tgz", + "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.0", + "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.6", + "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.28.6.tgz", + "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@braintree/sanitize-url": { + "version": "7.1.2", + "resolved": "https://registry.npmmirror.com/@braintree/sanitize-url/-/sanitize-url-7.1.2.tgz", + "integrity": "sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==", + "license": "MIT" + }, + "node_modules/@capsizecss/unpack": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/@capsizecss/unpack/-/unpack-4.0.0.tgz", + "integrity": "sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA==", + "license": "MIT", + "dependencies": { + "fontkitten": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@chevrotain/cst-dts-gen": { + "version": "11.1.1", + "resolved": "https://registry.npmmirror.com/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.1.1.tgz", + "integrity": "sha512-fRHyv6/f542qQqiRGalrfJl/evD39mAvbJLCekPazhiextEatq1Jx1K/i9gSd5NNO0ds03ek0Cbo/4uVKmOBcw==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/gast": "11.1.1", + "@chevrotain/types": "11.1.1", + "lodash-es": "4.17.23" + } + }, + "node_modules/@chevrotain/gast": { + "version": "11.1.1", + "resolved": "https://registry.npmmirror.com/@chevrotain/gast/-/gast-11.1.1.tgz", + "integrity": "sha512-Ko/5vPEYy1vn5CbCjjvnSO4U7GgxyGm+dfUZZJIWTlQFkXkyym0jFYrWEU10hyCjrA7rQtiHtBr0EaZqvHFZvg==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/types": "11.1.1", + "lodash-es": "4.17.23" + } + }, + "node_modules/@chevrotain/regexp-to-ast": { + "version": "11.1.1", + "resolved": "https://registry.npmmirror.com/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.1.1.tgz", + "integrity": "sha512-ctRw1OKSXkOrR8VTvOxrQ5USEc4sNrfwXHa1NuTcR7wre4YbjPcKw+82C2uylg/TEwFRgwLmbhlln4qkmDyteg==", + "license": "Apache-2.0" + }, + "node_modules/@chevrotain/types": { + "version": "11.1.1", + "resolved": "https://registry.npmmirror.com/@chevrotain/types/-/types-11.1.1.tgz", + "integrity": "sha512-wb2ToxG8LkgPYnKe9FH8oGn3TMCBdnwiuNC5l5y+CtlaVRbCytU0kbVsk6CGrqTL4ZN4ksJa0TXOYbxpbthtqw==", + "license": "Apache-2.0" + }, + "node_modules/@chevrotain/utils": { + "version": "11.1.1", + "resolved": "https://registry.npmmirror.com/@chevrotain/utils/-/utils-11.1.1.tgz", + "integrity": "sha512-71eTYMzYXYSFPrbg/ZwftSaSDld7UYlS8OQa3lNnn9jzNtpFbaReRRyghzqS7rI3CDaorqpPJJcXGHK+FE1TVQ==", + "license": "Apache-2.0" + }, + "node_modules/@ctrl/tinycolor": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-4.2.0.tgz", + "integrity": "sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/@emmetio/abbreviation": { + "version": "2.3.3", + "resolved": "https://registry.npmmirror.com/@emmetio/abbreviation/-/abbreviation-2.3.3.tgz", + "integrity": "sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA==", + "license": "MIT", + "dependencies": { + "@emmetio/scanner": "^1.0.4" + } + }, + "node_modules/@emmetio/css-abbreviation": { + "version": "2.1.8", + "resolved": "https://registry.npmmirror.com/@emmetio/css-abbreviation/-/css-abbreviation-2.1.8.tgz", + "integrity": "sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw==", + "license": "MIT", + "dependencies": { + "@emmetio/scanner": "^1.0.4" + } + }, + "node_modules/@emmetio/css-parser": { + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/@emmetio/css-parser/-/css-parser-0.4.1.tgz", + "integrity": "sha512-2bC6m0MV/voF4CTZiAbG5MWKbq5EBmDPKu9Sb7s7nVcEzNQlrZP6mFFFlIaISM8X6514H9shWMme1fCm8cWAfQ==", + "license": "MIT", + "dependencies": { + "@emmetio/stream-reader": "^2.2.0", + "@emmetio/stream-reader-utils": "^0.1.0" + } + }, + "node_modules/@emmetio/html-matcher": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/@emmetio/html-matcher/-/html-matcher-1.3.0.tgz", + "integrity": "sha512-NTbsvppE5eVyBMuyGfVu2CRrLvo7J4YHb6t9sBFLyY03WYhXET37qA4zOYUjBWFCRHO7pS1B9khERtY0f5JXPQ==", + "license": "ISC", + "dependencies": { + "@emmetio/scanner": "^1.0.0" + } + }, + "node_modules/@emmetio/scanner": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/@emmetio/scanner/-/scanner-1.0.4.tgz", + "integrity": "sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA==", + "license": "MIT" + }, + "node_modules/@emmetio/stream-reader": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/@emmetio/stream-reader/-/stream-reader-2.2.0.tgz", + "integrity": "sha512-fXVXEyFA5Yv3M3n8sUGT7+fvecGrZP4k6FnWWMSZVQf69kAq0LLpaBQLGcPR30m3zMmKYhECP4k/ZkzvhEW5kw==", + "license": "MIT" + }, + "node_modules/@emmetio/stream-reader-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmmirror.com/@emmetio/stream-reader-utils/-/stream-reader-utils-0.1.0.tgz", + "integrity": "sha512-ZsZ2I9Vzso3Ho/pjZFsmmZ++FWeEd/txqybHTm4OgaZzdS8V9V/YYWQwg5TC38Z7uLWUV1vavpLLbjJtKubR1A==", + "license": "MIT" + }, + "node_modules/@emnapi/runtime": { + "version": "1.8.1", + "resolved": "https://registry.npmmirror.com/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", + "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.27.3.tgz", + "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", + "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.27.3.tgz", + "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", + "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", + "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", + "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", + "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", + "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", + "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", + "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", + "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", + "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", + "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", + "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", + "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", + "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", + "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", + "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", + "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", + "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", + "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", + "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", + "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", + "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", + "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@expressive-code/core": { + "version": "0.41.6", + "resolved": "https://registry.npmmirror.com/@expressive-code/core/-/core-0.41.6.tgz", + "integrity": "sha512-FvJQP+hG0jWi/FLBSmvHInDqWR7jNANp9PUDjdMqSshHb0y7sxx3vHuoOr6SgXjWw+MGLqorZyPQ0aAlHEok6g==", + "license": "MIT", + "dependencies": { + "@ctrl/tinycolor": "^4.0.4", + "hast-util-select": "^6.0.2", + "hast-util-to-html": "^9.0.1", + "hast-util-to-text": "^4.0.1", + "hastscript": "^9.0.0", + "postcss": "^8.4.38", + "postcss-nested": "^6.0.1", + "unist-util-visit": "^5.0.0", + "unist-util-visit-parents": "^6.0.1" + } + }, + "node_modules/@expressive-code/plugin-frames": { + "version": "0.41.6", + "resolved": "https://registry.npmmirror.com/@expressive-code/plugin-frames/-/plugin-frames-0.41.6.tgz", + "integrity": "sha512-d+hkSYXIQot6fmYnOmWAM+7TNWRv/dhfjMsNq+mIZz8Tb4mPHOcgcfZeEM5dV9TDL0ioQNvtcqQNuzA1sRPjxg==", + "license": "MIT", + "dependencies": { + "@expressive-code/core": "^0.41.6" + } + }, + "node_modules/@expressive-code/plugin-shiki": { + "version": "0.41.6", + "resolved": "https://registry.npmmirror.com/@expressive-code/plugin-shiki/-/plugin-shiki-0.41.6.tgz", + "integrity": "sha512-Y6zmKBmsIUtWTzdefqlzm/h9Zz0Rc4gNdt2GTIH7fhHH2I9+lDYCa27BDwuBhjqcos6uK81Aca9dLUC4wzN+ng==", + "license": "MIT", + "dependencies": { + "@expressive-code/core": "^0.41.6", + "shiki": "^3.2.2" + } + }, + "node_modules/@expressive-code/plugin-text-markers": { + "version": "0.41.6", + "resolved": "https://registry.npmmirror.com/@expressive-code/plugin-text-markers/-/plugin-text-markers-0.41.6.tgz", + "integrity": "sha512-PBFa1wGyYzRExMDzBmAWC6/kdfG1oLn4pLpBeTfIRrALPjcGA/59HP3e7q9J0Smk4pC7U+lWkA2LHR8FYV8U7Q==", + "license": "MIT", + "dependencies": { + "@expressive-code/core": "^0.41.6" + } + }, + "node_modules/@fortawesome/fontawesome-free": { + "version": "6.7.2", + "resolved": "https://registry.npmmirror.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.7.2.tgz", + "integrity": "sha512-JUOtgFW6k9u4Y+xeIaEiLr3+cjoUPiAuLXoyKOJSia6Duzb7pq+A76P9ZdPDoAoxHdHzq6gE9/jKBGXlZT8FbA==", + "license": "(CC-BY-4.0 AND OFL-1.1 AND MIT)", + "engines": { + "node": ">=6" + } + }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "license": "MIT" + }, + "node_modules/@iconify/utils": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/@iconify/utils/-/utils-3.1.0.tgz", + "integrity": "sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==", + "license": "MIT", + "dependencies": { + "@antfu/install-pkg": "^1.1.0", + "@iconify/types": "^2.0.0", + "mlly": "^1.8.0" + } + }, + "node_modules/@img/colour": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/@img/colour/-/colour-1.0.0.tgz", + "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmmirror.com/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmmirror.com/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mdx-js/mdx": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/@mdx-js/mdx/-/mdx-3.1.1.tgz", + "integrity": "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "acorn": "^8.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-scope": "^1.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "recma-build-jsx": "^1.0.0", + "recma-jsx": "^1.0.0", + "recma-stringify": "^1.0.0", + "rehype-recma": "^1.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mermaid-js/parser": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/@mermaid-js/parser/-/parser-1.0.0.tgz", + "integrity": "sha512-vvK0Hi/VWndxoh03Mmz6wa1KDriSPjS2XMZL/1l19HFwygiObEEoEwSDxOqyLzzAI6J2PU3261JjTMTO7x+BPw==", + "license": "MIT", + "dependencies": { + "langium": "^4.0.0" + } + }, + "node_modules/@oslojs/encoding": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/@oslojs/encoding/-/encoding-1.1.0.tgz", + "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==", + "license": "MIT" + }, + "node_modules/@pagefind/darwin-arm64": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/@pagefind/darwin-arm64/-/darwin-arm64-1.4.0.tgz", + "integrity": "sha512-2vMqkbv3lbx1Awea90gTaBsvpzgRs7MuSgKDxW0m9oV1GPZCZbZBJg/qL83GIUEN2BFlY46dtUZi54pwH+/pTQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@pagefind/darwin-x64": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/@pagefind/darwin-x64/-/darwin-x64-1.4.0.tgz", + "integrity": "sha512-e7JPIS6L9/cJfow+/IAqknsGqEPjJnVXGjpGm25bnq+NPdoD3c/7fAwr1OXkG4Ocjx6ZGSCijXEV4ryMcH2E3A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@pagefind/default-ui": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/@pagefind/default-ui/-/default-ui-1.4.0.tgz", + "integrity": "sha512-wie82VWn3cnGEdIjh4YwNESyS1G6vRHwL6cNjy9CFgNnWW/PGRjsLq300xjVH5sfPFK3iK36UxvIBymtQIEiSQ==", + "license": "MIT" + }, + "node_modules/@pagefind/freebsd-x64": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/@pagefind/freebsd-x64/-/freebsd-x64-1.4.0.tgz", + "integrity": "sha512-WcJVypXSZ+9HpiqZjFXMUobfFfZZ6NzIYtkhQ9eOhZrQpeY5uQFqNWLCk7w9RkMUwBv1HAMDW3YJQl/8OqsV0Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@pagefind/linux-arm64": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/@pagefind/linux-arm64/-/linux-arm64-1.4.0.tgz", + "integrity": "sha512-PIt8dkqt4W06KGmQjONw7EZbhDF+uXI7i0XtRLN1vjCUxM9vGPdtJc2mUyVPevjomrGz5M86M8bqTr6cgDp1Uw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@pagefind/linux-x64": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/@pagefind/linux-x64/-/linux-x64-1.4.0.tgz", + "integrity": "sha512-z4oddcWwQ0UHrTHR8psLnVlz6USGJ/eOlDPTDYZ4cI8TK8PgwRUPQZp9D2iJPNIPcS6Qx/E4TebjuGJOyK8Mmg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@pagefind/windows-x64": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/@pagefind/windows-x64/-/windows-x64-1.4.0.tgz", + "integrity": "sha512-NkT+YAdgS2FPCn8mIA9bQhiBs+xmniMGq1LFPDhcFn0+2yIUEiIG06t7bsZlhdjknEQRTSdT7YitP6fC5qwP0g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@qwik.dev/partytown": { + "version": "0.11.2", + "resolved": "https://registry.npmmirror.com/@qwik.dev/partytown/-/partytown-0.11.2.tgz", + "integrity": "sha512-795y49CqBiKiwKAD+QBZlzlqEK275hVcazZ7wBPSfgC23L+vWuA7PJmMpgxojOucZHzYi5rAAQ+IP1I3BKVZxw==", + "license": "MIT", + "dependencies": { + "dotenv": "^16.4.7" + }, + "bin": { + "partytown": "bin/partytown.cjs" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmmirror.com/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", + "license": "MIT" + }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/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/@rollup/rollup-android-arm-eabi": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.58.0.tgz", + "integrity": "sha512-mr0tmS/4FoVk1cnaeN244A/wjvGDNItZKR8hRhnmCzygyRXYtKF5jVDSIILR1U97CTzAYmbgIj/Dukg62ggG5w==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.58.0.tgz", + "integrity": "sha512-+s++dbp+/RTte62mQD9wLSbiMTV+xr/PeRJEc/sFZFSBRlHPNPVaf5FXlzAL77Mr8FtSfQqCN+I598M8U41ccQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.58.0.tgz", + "integrity": "sha512-MFWBwTcYs0jZbINQBXHfSrpSQJq3IUOakcKPzfeSznONop14Pxuqa0Kg19GD0rNBMPQI2tFtu3UzapZpH0Uc1Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.58.0.tgz", + "integrity": "sha512-yiKJY7pj9c9JwzuKYLFaDZw5gma3fI9bkPEIyofvVfsPqjCWPglSHdpdwXpKGvDeYDms3Qal8qGMEHZ1M/4Udg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.58.0.tgz", + "integrity": "sha512-x97kCoBh5MOevpn/CNK9W1x8BEzO238541BGWBc315uOlN0AD/ifZ1msg+ZQB05Ux+VF6EcYqpiagfLJ8U3LvQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.58.0.tgz", + "integrity": "sha512-Aa8jPoZ6IQAG2eIrcXPpjRcMjROMFxCt1UYPZZtCxRV68WkuSigYtQ/7Zwrcr2IvtNJo7T2JfDXyMLxq5L4Jlg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.58.0.tgz", + "integrity": "sha512-Ob8YgT5kD/lSIYW2Rcngs5kNB/44Q2RzBSPz9brf2WEtcGR7/f/E9HeHn1wYaAwKBni+bdXEwgHvUd0x12lQSA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.58.0.tgz", + "integrity": "sha512-K+RI5oP1ceqoadvNt1FecL17Qtw/n9BgRSzxif3rTL2QlIu88ccvY+Y9nnHe/cmT5zbH9+bpiJuG1mGHRVwF4Q==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.58.0.tgz", + "integrity": "sha512-T+17JAsCKUjmbopcKepJjHWHXSjeW7O5PL7lEFaeQmiVyw4kkc5/lyYKzrv6ElWRX/MrEWfPiJWqbTvfIvjM1Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.58.0.tgz", + "integrity": "sha512-cCePktb9+6R9itIJdeCFF9txPU7pQeEHB5AbHu/MKsfH/k70ZtOeq1k4YAtBv9Z7mmKI5/wOLYjQ+B9QdxR6LA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.58.0.tgz", + "integrity": "sha512-iekUaLkfliAsDl4/xSdoCJ1gnnIXvoNz85C8U8+ZxknM5pBStfZjeXgB8lXobDQvvPRCN8FPmmuTtH+z95HTmg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.58.0.tgz", + "integrity": "sha512-68ofRgJNl/jYJbxFjCKE7IwhbfxOl1muPN4KbIqAIe32lm22KmU7E8OPvyy68HTNkI2iV/c8y2kSPSm2mW/Q9Q==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.58.0.tgz", + "integrity": "sha512-dpz8vT0i+JqUKuSNPCP5SYyIV2Lh0sNL1+FhM7eLC457d5B9/BC3kDPp5BBftMmTNsBarcPcoz5UGSsnCiw4XQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.58.0.tgz", + "integrity": "sha512-4gdkkf9UJ7tafnweBCR/mk4jf3Jfl0cKX9Np80t5i78kjIH0ZdezUv/JDI2VtruE5lunfACqftJ8dIMGN4oHew==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.58.0.tgz", + "integrity": "sha512-YFS4vPnOkDTD/JriUeeZurFYoJhPf9GQQEF/v4lltp3mVcBmnsAdjEWhr2cjUCZzZNzxCG0HZOvJU44UGHSdzw==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.58.0.tgz", + "integrity": "sha512-x2xgZlFne+QVNKV8b4wwaCS8pwq3y14zedZ5DqLzjdRITvreBk//4Knbcvm7+lWmms9V9qFp60MtUd0/t/PXPw==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.58.0.tgz", + "integrity": "sha512-jIhrujyn4UnWF8S+DHSkAkDEO3hLX0cjzxJZPLF80xFyzyUIYgSMRcYQ3+uqEoyDD2beGq7Dj7edi8OnJcS/hg==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.58.0.tgz", + "integrity": "sha512-+410Srdoh78MKSJxTQ+hZ/Mx+ajd6RjjPwBPNd0R3J9FtL6ZA0GqiiyNjCO9In0IzZkCNrpGymSfn+kgyPQocg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.58.0.tgz", + "integrity": "sha512-ZjMyby5SICi227y1MTR3VYBpFTdZs823Rs/hpakufleBoufoOIB6jtm9FEoxn/cgO7l6PM2rCEl5Kre5vX0QrQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.58.0.tgz", + "integrity": "sha512-ds4iwfYkSQ0k1nb8LTcyXw//ToHOnNTJtceySpL3fa7tc/AsE+UpUFphW126A6fKBGJD5dhRvg8zw1rvoGFxmw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.58.0.tgz", + "integrity": "sha512-fd/zpJniln4ICdPkjWFhZYeY/bpnaN9pGa6ko+5WD38I0tTqk9lXMgXZg09MNdhpARngmxiCg0B0XUamNw/5BQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.58.0.tgz", + "integrity": "sha512-YpG8dUOip7DCz3nr/JUfPbIUo+2d/dy++5bFzgi4ugOGBIox+qMbbqt/JoORwvI/C9Kn2tz6+Bieoqd5+B1CjA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.58.0.tgz", + "integrity": "sha512-b9DI8jpFQVh4hIXFr0/+N/TzLdpBIoPzjt0Rt4xJbW3mzguV3mduR9cNgiuFcuL/TeORejJhCWiAXe3E/6PxWA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.58.0.tgz", + "integrity": "sha512-CSrVpmoRJFN06LL9xhkitkwUcTZtIotYAF5p6XOR2zW0Zz5mzb3IPpcoPhB02frzMHFNo1reQ9xSF5fFm3hUsQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.58.0.tgz", + "integrity": "sha512-QFsBgQNTnh5K0t/sBsjJLq24YVqEIVkGpfN2VHsnN90soZyhaiA9UUHufcctVNL4ypJY0wrwad0wslx2KJQ1/w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@shikijs/core": { + "version": "3.22.0", + "resolved": "https://registry.npmmirror.com/@shikijs/core/-/core-3.22.0.tgz", + "integrity": "sha512-iAlTtSDDbJiRpvgL5ugKEATDtHdUVkqgHDm/gbD2ZS9c88mx7G1zSYjjOxp5Qa0eaW0MAQosFRmJSk354PRoQA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.22.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.5" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "3.22.0", + "resolved": "https://registry.npmmirror.com/@shikijs/engine-javascript/-/engine-javascript-3.22.0.tgz", + "integrity": "sha512-jdKhfgW9CRtj3Tor0L7+yPwdG3CgP7W+ZEqSsojrMzCjD1e0IxIbwUMDDpYlVBlC08TACg4puwFGkZfLS+56Tw==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.22.0", + "@shikijs/vscode-textmate": "^10.0.2", + "oniguruma-to-es": "^4.3.4" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "3.22.0", + "resolved": "https://registry.npmmirror.com/@shikijs/engine-oniguruma/-/engine-oniguruma-3.22.0.tgz", + "integrity": "sha512-DyXsOG0vGtNtl7ygvabHd7Mt5EY8gCNqR9Y7Lpbbd/PbJvgWrqaKzH1JW6H6qFkuUa8aCxoiYVv8/YfFljiQxA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.22.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@shikijs/langs": { + "version": "3.22.0", + "resolved": "https://registry.npmmirror.com/@shikijs/langs/-/langs-3.22.0.tgz", + "integrity": "sha512-x/42TfhWmp6H00T6uwVrdTJGKgNdFbrEdhaDwSR5fd5zhQ1Q46bHq9EO61SCEWJR0HY7z2HNDMaBZp8JRmKiIA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.22.0" + } + }, + "node_modules/@shikijs/themes": { + "version": "3.22.0", + "resolved": "https://registry.npmmirror.com/@shikijs/themes/-/themes-3.22.0.tgz", + "integrity": "sha512-o+tlOKqsr6FE4+mYJG08tfCFDS+3CG20HbldXeVoyP+cYSUxDhrFf3GPjE60U55iOkkjbpY2uC3It/eeja35/g==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.22.0" + } + }, + "node_modules/@shikijs/types": { + "version": "3.22.0", + "resolved": "https://registry.npmmirror.com/@shikijs/types/-/types-3.22.0.tgz", + "integrity": "sha512-491iAekgKDBFE67z70Ok5a8KBMsQ2IJwOWw3us/7ffQkIBCyOQfm/aNwVMBUriP02QshIfgHCBSIYAl3u2eWjg==", + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmmirror.com/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "license": "MIT" + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmmirror.com/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmmirror.com/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmmirror.com/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmmirror.com/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/d3": { + "version": "7.4.3", + "resolved": "https://registry.npmmirror.com/@types/d3/-/d3-7.4.3.tgz", + "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", + "license": "MIT", + "dependencies": { + "@types/d3-array": "*", + "@types/d3-axis": "*", + "@types/d3-brush": "*", + "@types/d3-chord": "*", + "@types/d3-color": "*", + "@types/d3-contour": "*", + "@types/d3-delaunay": "*", + "@types/d3-dispatch": "*", + "@types/d3-drag": "*", + "@types/d3-dsv": "*", + "@types/d3-ease": "*", + "@types/d3-fetch": "*", + "@types/d3-force": "*", + "@types/d3-format": "*", + "@types/d3-geo": "*", + "@types/d3-hierarchy": "*", + "@types/d3-interpolate": "*", + "@types/d3-path": "*", + "@types/d3-polygon": "*", + "@types/d3-quadtree": "*", + "@types/d3-random": "*", + "@types/d3-scale": "*", + "@types/d3-scale-chromatic": "*", + "@types/d3-selection": "*", + "@types/d3-shape": "*", + "@types/d3-time": "*", + "@types/d3-time-format": "*", + "@types/d3-timer": "*", + "@types/d3-transition": "*", + "@types/d3-zoom": "*" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.2", + "resolved": "https://registry.npmmirror.com/@types/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==", + "license": "MIT" + }, + "node_modules/@types/d3-axis": { + "version": "3.0.6", + "resolved": "https://registry.npmmirror.com/@types/d3-axis/-/d3-axis-3.0.6.tgz", + "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-brush": { + "version": "3.0.6", + "resolved": "https://registry.npmmirror.com/@types/d3-brush/-/d3-brush-3.0.6.tgz", + "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-chord": { + "version": "3.0.6", + "resolved": "https://registry.npmmirror.com/@types/d3-chord/-/d3-chord-3.0.6.tgz", + "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==", + "license": "MIT" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-contour": { + "version": "3.0.6", + "resolved": "https://registry.npmmirror.com/@types/d3-contour/-/d3-contour-3.0.6.tgz", + "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", + "license": "MIT", + "dependencies": { + "@types/d3-array": "*", + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmmirror.com/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", + "license": "MIT" + }, + "node_modules/@types/d3-dispatch": { + "version": "3.0.7", + "resolved": "https://registry.npmmirror.com/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz", + "integrity": "sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==", + "license": "MIT" + }, + "node_modules/@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://registry.npmmirror.com/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-dsv": { + "version": "3.0.7", + "resolved": "https://registry.npmmirror.com/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", + "license": "MIT" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "license": "MIT" + }, + "node_modules/@types/d3-fetch": { + "version": "3.0.7", + "resolved": "https://registry.npmmirror.com/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", + "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", + "license": "MIT", + "dependencies": { + "@types/d3-dsv": "*" + } + }, + "node_modules/@types/d3-force": { + "version": "3.0.10", + "resolved": "https://registry.npmmirror.com/@types/d3-force/-/d3-force-3.0.10.tgz", + "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==", + "license": "MIT" + }, + "node_modules/@types/d3-format": { + "version": "3.0.4", + "resolved": "https://registry.npmmirror.com/@types/d3-format/-/d3-format-3.0.4.tgz", + "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==", + "license": "MIT" + }, + "node_modules/@types/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/@types/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-hierarchy": { + "version": "3.1.7", + "resolved": "https://registry.npmmirror.com/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", + "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==", + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmmirror.com/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@types/d3-polygon": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", + "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==", + "license": "MIT" + }, + "node_modules/@types/d3-quadtree": { + "version": "3.0.6", + "resolved": "https://registry.npmmirror.com/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", + "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==", + "license": "MIT" + }, + "node_modules/@types/d3-random": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/@types/d3-random/-/d3-random-3.0.3.tgz", + "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==", + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmmirror.com/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==", + "license": "MIT" + }, + "node_modules/@types/d3-selection": { + "version": "3.0.11", + "resolved": "https://registry.npmmirror.com/@types/d3-selection/-/d3-selection-3.0.11.tgz", + "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", + "license": "MIT" + }, + "node_modules/@types/d3-shape": { + "version": "3.1.8", + "resolved": "https://registry.npmmirror.com/@types/d3-shape/-/d3-shape-3.1.8.tgz", + "integrity": "sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmmirror.com/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" + }, + "node_modules/@types/d3-time-format": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", + "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==", + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" + }, + "node_modules/@types/d3-transition": { + "version": "3.0.9", + "resolved": "https://registry.npmmirror.com/@types/d3-transition/-/d3-transition-3.0.9.tgz", + "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmmirror.com/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "license": "MIT", + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmmirror.com/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/geojson": { + "version": "7946.0.16", + "resolved": "https://registry.npmmirror.com/@types/geojson/-/geojson-7946.0.16.tgz", + "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", + "license": "MIT" + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmmirror.com/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/js-yaml": { + "version": "4.0.9", + "resolved": "https://registry.npmmirror.com/@types/js-yaml/-/js-yaml-4.0.9.tgz", + "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", + "license": "MIT" + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmmirror.com/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmmirror.com/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", + "license": "MIT" + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/nlcst": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/@types/nlcst/-/nlcst-2.0.3.tgz", + "integrity": "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/node": { + "version": "25.3.0", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-25.3.0.tgz", + "integrity": "sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.18.0" + } + }, + "node_modules/@types/react": { + "version": "19.2.14", + "resolved": "https://registry.npmmirror.com/@types/react/-/react-19.2.14.tgz", + "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmmirror.com/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@types/sax": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/@types/sax/-/sax-1.2.7.tgz", + "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmmirror.com/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "license": "ISC" + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.7.0", + "resolved": "https://registry.npmmirror.com/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.27", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/@volar/kit": { + "version": "2.4.28", + "resolved": "https://registry.npmmirror.com/@volar/kit/-/kit-2.4.28.tgz", + "integrity": "sha512-cKX4vK9dtZvDRaAzeoUdaAJEew6IdxHNCRrdp5Kvcl6zZOqb6jTOfk3kXkIkG3T7oTFXguEMt5+9ptyqYR84Pg==", + "license": "MIT", + "dependencies": { + "@volar/language-service": "2.4.28", + "@volar/typescript": "2.4.28", + "typesafe-path": "^0.2.2", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-uri": "^3.0.8" + }, + "peerDependencies": { + "typescript": "*" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "@volar/source-map": "2.4.28" + } + }, + "node_modules/@volar/language-server": { + "version": "2.4.28", + "resolved": "https://registry.npmmirror.com/@volar/language-server/-/language-server-2.4.28.tgz", + "integrity": "sha512-NqcLnE5gERKuS4PUFwlhMxf6vqYo7hXtbMFbViXcbVkbZ905AIVWhnSo0ZNBC2V127H1/2zP7RvVOVnyITFfBw==", + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.28", + "@volar/language-service": "2.4.28", + "@volar/typescript": "2.4.28", + "path-browserify": "^1.0.1", + "request-light": "^0.7.0", + "vscode-languageserver": "^9.0.1", + "vscode-languageserver-protocol": "^3.17.5", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/@volar/language-service": { + "version": "2.4.28", + "resolved": "https://registry.npmmirror.com/@volar/language-service/-/language-service-2.4.28.tgz", + "integrity": "sha512-Rh/wYCZJrI5vCwMk9xyw/Z+MsWxlJY1rmMZPsxUoJKfzIRjS/NF1NmnuEcrMbEVGja00aVpCsInJfixQTMdvLw==", + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.28", + "vscode-languageserver-protocol": "^3.17.5", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-uri": "^3.0.8" + } + }, + "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==", + "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==", + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.28", + "path-browserify": "^1.0.1", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/@vscode/emmet-helper": { + "version": "2.11.0", + "resolved": "https://registry.npmmirror.com/@vscode/emmet-helper/-/emmet-helper-2.11.0.tgz", + "integrity": "sha512-QLxjQR3imPZPQltfbWRnHU6JecWTF1QSWhx3GAKQpslx7y3Dp6sIIXhKjiUJ/BR9FX8PVthjr9PD6pNwOJfAzw==", + "license": "MIT", + "dependencies": { + "emmet": "^2.4.3", + "jsonc-parser": "^2.3.0", + "vscode-languageserver-textdocument": "^1.0.1", + "vscode-languageserver-types": "^3.15.1", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/@vscode/l10n": { + "version": "0.0.18", + "resolved": "https://registry.npmmirror.com/@vscode/l10n/-/l10n-0.0.18.tgz", + "integrity": "sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==", + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-draft-04": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", + "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", + "license": "MIT", + "peerDependencies": { + "ajv": "^8.5.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "license": "ISC", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmmirror.com/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmmirror.com/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-iterate": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/array-iterate/-/array-iterate-2.0.1.tgz", + "integrity": "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/astring": { + "version": "1.9.0", + "resolved": "https://registry.npmmirror.com/astring/-/astring-1.9.0.tgz", + "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", + "license": "MIT", + "bin": { + "astring": "bin/astring" + } + }, + "node_modules/astro": { + "version": "5.17.3", + "resolved": "https://registry.npmmirror.com/astro/-/astro-5.17.3.tgz", + "integrity": "sha512-69dcfPe8LsHzklwj+hl+vunWUbpMB6pmg35mACjetxbJeUNNys90JaBM8ZiwsPK689SAj/4Zqb1ayaANls9/MA==", + "license": "MIT", + "dependencies": { + "@astrojs/compiler": "^2.13.0", + "@astrojs/internal-helpers": "0.7.5", + "@astrojs/markdown-remark": "6.3.10", + "@astrojs/telemetry": "3.3.0", + "@capsizecss/unpack": "^4.0.0", + "@oslojs/encoding": "^1.1.0", + "@rollup/pluginutils": "^5.3.0", + "acorn": "^8.15.0", + "aria-query": "^5.3.2", + "axobject-query": "^4.1.0", + "boxen": "8.0.1", + "ci-info": "^4.3.1", + "clsx": "^2.1.1", + "common-ancestor-path": "^1.0.1", + "cookie": "^1.1.1", + "cssesc": "^3.0.0", + "debug": "^4.4.3", + "deterministic-object-hash": "^2.0.2", + "devalue": "^5.6.2", + "diff": "^8.0.3", + "dlv": "^1.1.3", + "dset": "^3.1.4", + "es-module-lexer": "^1.7.0", + "esbuild": "^0.27.3", + "estree-walker": "^3.0.3", + "flattie": "^1.1.1", + "fontace": "~0.4.0", + "github-slugger": "^2.0.0", + "html-escaper": "3.0.3", + "http-cache-semantics": "^4.2.0", + "import-meta-resolve": "^4.2.0", + "js-yaml": "^4.1.1", + "magic-string": "^0.30.21", + "magicast": "^0.5.1", + "mrmime": "^2.0.1", + "neotraverse": "^0.6.18", + "p-limit": "^6.2.0", + "p-queue": "^8.1.1", + "package-manager-detector": "^1.6.0", + "piccolore": "^0.1.3", + "picomatch": "^4.0.3", + "prompts": "^2.4.2", + "rehype": "^13.0.2", + "semver": "^7.7.3", + "shiki": "^3.21.0", + "smol-toml": "^1.6.0", + "svgo": "^4.0.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tsconfck": "^3.1.6", + "ultrahtml": "^1.6.0", + "unifont": "~0.7.3", + "unist-util-visit": "^5.0.0", + "unstorage": "^1.17.4", + "vfile": "^6.0.3", + "vite": "^6.4.1", + "vitefu": "^1.1.1", + "xxhash-wasm": "^1.1.0", + "yargs-parser": "^21.1.1", + "yocto-spinner": "^0.2.3", + "zod": "^3.25.76", + "zod-to-json-schema": "^3.25.1", + "zod-to-ts": "^1.2.0" + }, + "bin": { + "astro": "astro.js" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/astrodotbuild" + }, + "optionalDependencies": { + "sharp": "^0.34.0" + } + }, + "node_modules/astro-expressive-code": { + "version": "0.41.6", + "resolved": "https://registry.npmmirror.com/astro-expressive-code/-/astro-expressive-code-0.41.6.tgz", + "integrity": "sha512-l47tb1uhmVIebHUkw+HEPtU/av0G4O8Q34g2cbkPvC7/e9ZhANcjUUciKt9Hp6gSVDdIuXBBLwJQn2LkeGMOAw==", + "license": "MIT", + "dependencies": { + "rehype-expressive-code": "^0.41.6" + }, + "peerDependencies": { + "astro": "^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta" + } + }, + "node_modules/astro-link-validator": { + "version": "1.0.0", + "resolved": "git+ssh://git@github.com/rodgtr1/astro-link-validator.git#025a27b2582234084b3676bc725418b5fc429dcd", + "license": "MIT", + "dependencies": { + "cheerio": "^1.0.0-rc.12", + "picocolors": "^1.0.0" + }, + "peerDependencies": { + "astro": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/astro-remote": { + "version": "0.3.4", + "resolved": "https://registry.npmmirror.com/astro-remote/-/astro-remote-0.3.4.tgz", + "integrity": "sha512-jL5skNQLA0YBc1R3bVGXyHew3FqGqsT7AgLzWAVeTLzFkwVMUYvs4/lKJSmS7ygcF1GnHnoKG6++8GL9VtWwGQ==", + "license": "MIT", + "dependencies": { + "entities": "^4.5.0", + "marked": "^12.0.0", + "marked-footnote": "^1.2.2", + "marked-smartypants": "^1.1.6", + "ultrahtml": "^1.5.3" + }, + "engines": { + "node": ">=18.14.1" + } + }, + "node_modules/astro-remote/node_modules/marked": { + "version": "12.0.2", + "resolved": "https://registry.npmmirror.com/marked/-/marked-12.0.2.tgz", + "integrity": "sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/astro-robots-txt": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/astro-robots-txt/-/astro-robots-txt-1.0.0.tgz", + "integrity": "sha512-6JQSLid4gMhoWjOm85UHLkgrw0+hHIjnJVIUqxjU2D6feKlVyYukMNYjH44ZDZBK1P8hNxd33PgWlHzCASvedA==", + "license": "MIT", + "dependencies": { + "valid-filename": "^4.0.0", + "zod": "^3.22.2" + } + }, + "node_modules/astro-seo": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/astro-seo/-/astro-seo-1.1.0.tgz", + "integrity": "sha512-G6LDNDyga30o+52v58jU7C35n3cORUzk7RSuY+xf/ZRbW6JiNplyaOO1VoYVKO+xzYNaBcxqNln2RFRR/wgJNQ==", + "license": "MIT", + "dependencies": { + "@astrojs/check": "^0.9.0" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/base-64": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/base-64/-/base-64-1.0.0.tgz", + "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==", + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.0", + "resolved": "https://registry.npmmirror.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", + "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/bcp-47": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/bcp-47/-/bcp-47-2.1.0.tgz", + "integrity": "sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/bcp-47-match": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/bcp-47-match/-/bcp-47-match-2.0.3.tgz", + "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/boxen": { + "version": "8.0.1", + "resolved": "https://registry.npmmirror.com/boxen/-/boxen-8.0.1.tgz", + "integrity": "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==", + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^8.0.0", + "chalk": "^5.3.0", + "cli-boxes": "^3.0.0", + "string-width": "^7.2.0", + "type-fest": "^4.21.0", + "widest-line": "^5.0.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/camelcase": { + "version": "8.0.0", + "resolved": "https://registry.npmmirror.com/camelcase/-/camelcase-8.0.0.tgz", + "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001770", + "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001770.tgz", + "integrity": "sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/cheerio": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/cheerio/-/cheerio-1.2.0.tgz", + "integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "encoding-sniffer": "^0.2.1", + "htmlparser2": "^10.1.0", + "parse5": "^7.3.0", + "parse5-htmlparser2-tree-adapter": "^7.1.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^7.19.0", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=20.18.1" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/chevrotain": { + "version": "11.1.1", + "resolved": "https://registry.npmmirror.com/chevrotain/-/chevrotain-11.1.1.tgz", + "integrity": "sha512-f0yv5CPKaFxfsPTBzX7vGuim4oIC1/gcS7LUGdBSwl2dU6+FON6LVUksdOo1qJjoUvXNn45urgh8C+0a24pACQ==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/cst-dts-gen": "11.1.1", + "@chevrotain/gast": "11.1.1", + "@chevrotain/regexp-to-ast": "11.1.1", + "@chevrotain/types": "11.1.1", + "@chevrotain/utils": "11.1.1", + "lodash-es": "4.17.23" + } + }, + "node_modules/chevrotain-allstar": { + "version": "0.3.1", + "resolved": "https://registry.npmmirror.com/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz", + "integrity": "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==", + "license": "MIT", + "dependencies": { + "lodash-es": "^4.17.21" + }, + "peerDependencies": { + "chevrotain": "^11.0.0" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmmirror.com/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmmirror.com/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/collapse-white-space": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/common-ancestor-path": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", + "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==", + "license": "ISC" + }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmmirror.com/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cookie-es": { + "version": "1.2.2", + "resolved": "https://registry.npmmirror.com/cookie-es/-/cookie-es-1.2.2.tgz", + "integrity": "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==", + "license": "MIT" + }, + "node_modules/cose-base": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/cose-base/-/cose-base-1.0.3.tgz", + "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", + "license": "MIT", + "dependencies": { + "layout-base": "^1.0.0" + } + }, + "node_modules/crossws": { + "version": "0.3.5", + "resolved": "https://registry.npmmirror.com/crossws/-/crossws-0.3.5.tgz", + "integrity": "sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==", + "license": "MIT", + "dependencies": { + "uncrypto": "^0.1.3" + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmmirror.com/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-selector-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmmirror.com/css-selector-parser/-/css-selector-parser-3.3.0.tgz", + "integrity": "sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT" + }, + "node_modules/css-tree": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.12.2", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmmirror.com/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmmirror.com/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmmirror.com/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmmirror.com/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "license": "CC0-1.0" + }, + "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/cytoscape": { + "version": "3.33.1", + "resolved": "https://registry.npmmirror.com/cytoscape/-/cytoscape-3.33.1.tgz", + "integrity": "sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/cytoscape-cose-bilkent": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", + "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", + "license": "MIT", + "dependencies": { + "cose-base": "^1.0.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz", + "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==", + "license": "MIT", + "dependencies": { + "cose-base": "^2.2.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/cose-base": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/cose-base/-/cose-base-2.2.0.tgz", + "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==", + "license": "MIT", + "dependencies": { + "layout-base": "^2.0.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/layout-base": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/layout-base/-/layout-base-2.0.1.tgz", + "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==", + "license": "MIT" + }, + "node_modules/d3": { + "version": "7.9.0", + "resolved": "https://registry.npmmirror.com/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "license": "ISC", + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmmirror.com/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "license": "ISC", + "dependencies": { + "d3-path": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "license": "ISC", + "dependencies": { + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmmirror.com/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "license": "ISC", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "license": "ISC", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "license": "ISC", + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/d3-format/-/d3-format-3.1.2.tgz", + "integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-sankey": { + "version": "0.12.3", + "resolved": "https://registry.npmmirror.com/d3-sankey/-/d3-sankey-0.12.3.tgz", + "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-array": "1 - 2", + "d3-shape": "^1.2.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmmirror.com/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "license": "BSD-3-Clause", + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-path": { + "version": "1.0.9", + "resolved": "https://registry.npmmirror.com/d3-path/-/d3-path-1.0.9.tgz", + "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==", + "license": "BSD-3-Clause" + }, + "node_modules/d3-sankey/node_modules/d3-shape": { + "version": "1.3.7", + "resolved": "https://registry.npmmirror.com/d3-shape/-/d3-shape-1.3.7.tgz", + "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-path": "1" + } + }, + "node_modules/d3-sankey/node_modules/internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==", + "license": "ISC" + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dagre-d3-es": { + "version": "7.0.13", + "resolved": "https://registry.npmmirror.com/dagre-d3-es/-/dagre-d3-es-7.0.13.tgz", + "integrity": "sha512-efEhnxpSuwpYOKRm/L5KbqoZmNNukHa/Flty4Wp62JRvgH2ojwVgPgdYyr4twpieZnyRDdIH7PY2mopX26+j2Q==", + "license": "MIT", + "dependencies": { + "d3": "^7.9.0", + "lodash-es": "^4.17.21" + } + }, + "node_modules/dayjs": { + "version": "1.11.19", + "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.19.tgz", + "integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmmirror.com/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "license": "MIT" + }, + "node_modules/delaunator": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "license": "ISC", + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/destr": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/destr/-/destr-2.0.5.tgz", + "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", + "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==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/deterministic-object-hash": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/deterministic-object-hash/-/deterministic-object-hash-2.0.2.tgz", + "integrity": "sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==", + "license": "MIT", + "dependencies": { + "base-64": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/devalue": { + "version": "5.6.3", + "resolved": "https://registry.npmmirror.com/devalue/-/devalue-5.6.3.tgz", + "integrity": "sha512-nc7XjUU/2Lb+SvEFVGcWLiKkzfw8+qHI7zn8WYXKkLMgfGSHbgCEaR6bJpev8Cm6Rmrb19Gfd/tZvGqx9is3wg==", + "license": "MIT" + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/diff": { + "version": "8.0.3", + "resolved": "https://registry.npmmirror.com/diff/-/diff-8.0.3.tgz", + "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/direction": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/direction/-/direction-2.0.1.tgz", + "integrity": "sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==", + "license": "MIT", + "bin": { + "direction": "cli.js" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "license": "MIT" + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmmirror.com/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/dompurify": { + "version": "3.3.1", + "resolved": "https://registry.npmmirror.com/dompurify/-/dompurify-3.3.1.tgz", + "integrity": "sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmmirror.com/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dset": { + "version": "3.1.4", + "resolved": "https://registry.npmmirror.com/dset/-/dset-3.1.4.tgz", + "integrity": "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.302", + "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.302.tgz", + "integrity": "sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==", + "license": "ISC" + }, + "node_modules/emmet": { + "version": "2.4.11", + "resolved": "https://registry.npmmirror.com/emmet/-/emmet-2.4.11.tgz", + "integrity": "sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ==", + "license": "MIT", + "workspaces": [ + "./packages/scanner", + "./packages/abbreviation", + "./packages/css-abbreviation", + "./" + ], + "dependencies": { + "@emmetio/abbreviation": "^2.3.3", + "@emmetio/css-abbreviation": "^2.1.8" + } + }, + "node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT" + }, + "node_modules/encoding-sniffer": { + "version": "0.2.1", + "resolved": "https://registry.npmmirror.com/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmmirror.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "license": "MIT" + }, + "node_modules/esast-util-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz", + "integrity": "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esast-util-from-js": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz", + "integrity": "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "acorn": "^8.0.0", + "esast-util-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esbuild": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.27.3.tgz", + "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/estree-util-attach-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", + "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-build-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", + "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-walker": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-scope": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/estree-util-scope/-/estree-util-scope-1.0.0.tgz", + "integrity": "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", + "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-visit": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/estree-util-visit/-/estree-util-visit-2.0.0.tgz", + "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" + }, + "node_modules/expressive-code": { + "version": "0.41.6", + "resolved": "https://registry.npmmirror.com/expressive-code/-/expressive-code-0.41.6.tgz", + "integrity": "sha512-W/5+IQbrpCIM5KGLjO35wlp1NCwDOOVQb+PAvzEoGkW1xjGM807ZGfBKptNWH6UECvt6qgmLyWolCMYKh7eQmA==", + "license": "MIT", + "dependencies": { + "@expressive-code/core": "^0.41.6", + "@expressive-code/plugin-frames": "^0.41.6", + "@expressive-code/plugin-shiki": "^0.41.6", + "@expressive-code/plugin-text-markers": "^0.41.6" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fast-xml-parser": { + "version": "5.3.7", + "resolved": "https://registry.npmmirror.com/fast-xml-parser/-/fast-xml-parser-5.3.7.tgz", + "integrity": "sha512-JzVLro9NQv92pOM/jTCR6mHlJh2FGwtomH8ZQjhFj/R29P2Fnj38OgPJVtcvYw6SuKClhgYuwUZf5b3rd8u2mA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^2.1.2" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmmirror.com/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/filename-reserved-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/filename-reserved-regex/-/filename-reserved-regex-3.0.0.tgz", + "integrity": "sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flattie": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/flattie/-/flattie-1.1.1.tgz", + "integrity": "sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/fontace": { + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/fontace/-/fontace-0.4.1.tgz", + "integrity": "sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw==", + "license": "MIT", + "dependencies": { + "fontkitten": "^1.0.2" + } + }, + "node_modules/fontkitten": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/fontkitten/-/fontkitten-1.0.2.tgz", + "integrity": "sha512-piJxbLnkD9Xcyi7dWJRnqszEURixe7CrF/efBfbffe2DPyabmuIuqraruY8cXTs19QoM8VJzx47BDRVNXETM7Q==", + "license": "MIT", + "dependencies": { + "tiny-inflate": "^1.0.3" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.5.0", + "resolved": "https://registry.npmmirror.com/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", + "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "license": "ISC" + }, + "node_modules/h3": { + "version": "1.15.5", + "resolved": "https://registry.npmmirror.com/h3/-/h3-1.15.5.tgz", + "integrity": "sha512-xEyq3rSl+dhGX2Lm0+eFQIAzlDN6Fs0EcC4f7BNUmzaRX/PTzeuM+Tr2lHB8FoXggsQIeXLj8EDVgs5ywxyxmg==", + "license": "MIT", + "dependencies": { + "cookie-es": "^1.2.2", + "crossws": "^0.3.5", + "defu": "^6.1.4", + "destr": "^2.0.5", + "iron-webcrypto": "^1.2.1", + "node-mock-http": "^1.0.4", + "radix3": "^1.1.2", + "ufo": "^1.6.3", + "uncrypto": "^0.1.3" + } + }, + "node_modules/hachure-fill": { + "version": "0.5.2", + "resolved": "https://registry.npmmirror.com/hachure-fill/-/hachure-fill-0.5.2.tgz", + "integrity": "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==", + "license": "MIT" + }, + "node_modules/hast-to-hyperscript": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/hast-to-hyperscript/-/hast-to-hyperscript-5.0.0.tgz", + "integrity": "sha512-DLl3eYTz8uwwzEubDUdCChsR5t5b2ne+yvHrA2h58Suq/JnN3+Gsb9Tc4iZoCCsykmFUc6UUpwxTmQXs0akSeg==", + "license": "MIT", + "dependencies": { + "comma-separated-tokens": "^1.0.0", + "property-information": "^4.0.0", + "space-separated-tokens": "^1.0.0", + "style-to-object": "^0.2.1", + "unist-util-is": "^2.0.0", + "web-namespaces": "^1.1.2" + } + }, + "node_modules/hast-to-hyperscript/node_modules/comma-separated-tokens": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", + "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-to-hyperscript/node_modules/property-information": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/property-information/-/property-information-4.2.0.tgz", + "integrity": "sha512-TlgDPagHh+eBKOnH2VYvk8qbwsCG/TAJdmTL7f1PROUcSO8qt/KSmShEQ/OKvock8X9tFjtqjCScyOkkkvIKVQ==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.1" + } + }, + "node_modules/hast-to-hyperscript/node_modules/space-separated-tokens": { + "version": "1.1.5", + "resolved": "https://registry.npmmirror.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", + "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-to-hyperscript/node_modules/unist-util-is": { + "version": "2.1.3", + "resolved": "https://registry.npmmirror.com/unist-util-is/-/unist-util-is-2.1.3.tgz", + "integrity": "sha512-4WbQX2iwfr/+PfM4U3zd2VNXY+dWtZsN1fLnWEi2QQXA4qyDYAZcDMfXUX0Cu6XZUHHAO9q4nyxxLT4Awk1qUA==", + "license": "MIT" + }, + "node_modules/hast-to-hyperscript/node_modules/web-namespaces": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/web-namespaces/-/web-namespaces-1.1.4.tgz", + "integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-embedded": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/hast-util-embedded/-/hast-util-embedded-3.0.0.tgz", + "integrity": "sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-is-element": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-format": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/hast-util-format/-/hast-util-format-1.1.0.tgz", + "integrity": "sha512-yY1UDz6bC9rDvCWHpx12aIBGRG7krurX0p0Fm6pT547LwDIZZiNr8a+IHDogorAdreULSEzP82Nlv5SZkHZcjA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-embedded": "^3.0.0", + "hast-util-minify-whitespace": "^1.0.0", + "hast-util-phrasing": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "html-whitespace-sensitive-tag-names": "^3.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-dom": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/hast-util-from-dom/-/hast-util-from-dom-5.0.1.tgz", + "integrity": "sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q==", + "license": "ISC", + "dependencies": { + "@types/hast": "^3.0.0", + "hastscript": "^9.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-html": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz", + "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.1.0", + "hast-util-from-parse5": "^8.0.0", + "parse5": "^7.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-html-isomorphic": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/hast-util-from-html-isomorphic/-/hast-util-from-html-isomorphic-2.0.0.tgz", + "integrity": "sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-from-dom": "^5.0.0", + "hast-util-from-html": "^2.0.0", + "unist-util-remove-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.3", + "resolved": "https://registry.npmmirror.com/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", + "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^7.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-has-property": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/hast-util-has-property/-/hast-util-has-property-3.0.0.tgz", + "integrity": "sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-body-ok-link": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/hast-util-is-body-ok-link/-/hast-util-is-body-ok-link-3.0.1.tgz", + "integrity": "sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-minify-whitespace": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/hast-util-minify-whitespace/-/hast-util-minify-whitespace-1.0.1.tgz", + "integrity": "sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-embedded": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-phrasing": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/hast-util-phrasing/-/hast-util-phrasing-3.0.1.tgz", + "integrity": "sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-embedded": "^3.0.0", + "hast-util-has-property": "^3.0.0", + "hast-util-is-body-ok-link": "^3.0.0", + "hast-util-is-element": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/hast-util-raw/-/hast-util-raw-4.0.0.tgz", + "integrity": "sha512-5xYHyEJMCf8lX/NT4iA5z6N43yoFsrJqXJ5GWwAbLn815URbIz+UNNFEgid33F9paZuDlqVKvB+K3Aqu5+DdSw==", + "license": "MIT", + "dependencies": { + "hast-util-from-parse5": "^4.0.2", + "hast-util-to-parse5": "^4.0.1", + "html-void-elements": "^1.0.1", + "parse5": "^5.0.0", + "unist-util-position": "^3.0.0", + "web-namespaces": "^1.0.0", + "xtend": "^4.0.1", + "zwitch": "^1.0.0" + } + }, + "node_modules/hast-util-raw/node_modules/ccount": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/ccount/-/ccount-1.1.0.tgz", + "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-raw/node_modules/comma-separated-tokens": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", + "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-raw/node_modules/hast-util-from-parse5": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/hast-util-from-parse5/-/hast-util-from-parse5-4.0.2.tgz", + "integrity": "sha512-I6dtjsGtDqz4fmGSiFClFyiXdKhj5bPceS6intta7k/VDuiKz9P61C6hO6WMiNNmEm1b/EtBH8f+juvz4o0uwQ==", + "license": "MIT", + "dependencies": { + "ccount": "^1.0.3", + "hastscript": "^4.0.0", + "property-information": "^4.0.0", + "web-namespaces": "^1.1.2", + "xtend": "^4.0.1" + } + }, + "node_modules/hast-util-raw/node_modules/hast-util-parse-selector": { + "version": "2.2.5", + "resolved": "https://registry.npmmirror.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", + "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw/node_modules/hastscript": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/hastscript/-/hastscript-4.1.0.tgz", + "integrity": "sha512-bOTn9hEfzewvHyXdbYGKqOr/LOz+2zYhKbC17U2YAjd16mnjqB1BQ0nooM/RdMy/htVyli0NAznXiBtwDi1cmQ==", + "license": "MIT", + "dependencies": { + "comma-separated-tokens": "^1.0.0", + "hast-util-parse-selector": "^2.2.0", + "property-information": "^4.0.0", + "space-separated-tokens": "^1.0.0" + } + }, + "node_modules/hast-util-raw/node_modules/html-void-elements": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/html-void-elements/-/html-void-elements-1.0.5.tgz", + "integrity": "sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-raw/node_modules/parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "license": "MIT" + }, + "node_modules/hast-util-raw/node_modules/property-information": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/property-information/-/property-information-4.2.0.tgz", + "integrity": "sha512-TlgDPagHh+eBKOnH2VYvk8qbwsCG/TAJdmTL7f1PROUcSO8qt/KSmShEQ/OKvock8X9tFjtqjCScyOkkkvIKVQ==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.1" + } + }, + "node_modules/hast-util-raw/node_modules/space-separated-tokens": { + "version": "1.1.5", + "resolved": "https://registry.npmmirror.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", + "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-raw/node_modules/unist-util-position": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/unist-util-position/-/unist-util-position-3.1.0.tgz", + "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw/node_modules/web-namespaces": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/web-namespaces/-/web-namespaces-1.1.4.tgz", + "integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-raw/node_modules/zwitch": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/zwitch/-/zwitch-1.0.5.tgz", + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-select": { + "version": "6.0.4", + "resolved": "https://registry.npmmirror.com/hast-util-select/-/hast-util-select-6.0.4.tgz", + "integrity": "sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "bcp-47-match": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "css-selector-parser": "^3.0.0", + "devlop": "^1.0.0", + "direction": "^2.0.0", + "hast-util-has-property": "^3.0.0", + "hast-util-to-string": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "nth-check": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-estree": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/hast-util-to-estree/-/hast-util-to-estree-3.1.3.tgz", + "integrity": "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-attach-comments": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "resolved": "https://registry.npmmirror.com/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", + "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.6", + "resolved": "https://registry.npmmirror.com/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", + "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/hast-util-to-parse5/-/hast-util-to-parse5-4.0.1.tgz", + "integrity": "sha512-U/61W+fsNfBpCyJBB5Pt3l5ypIfgXqEyW9pyrtxF7XrqDJHzcFrYpnC94d0JDYjvobLpYCzcU9srhMRPEO1YXw==", + "license": "MIT", + "dependencies": { + "hast-to-hyperscript": "^5.0.0", + "property-information": "^4.0.0", + "web-namespaces": "^1.0.0", + "xtend": "^4.0.1", + "zwitch": "^1.0.0" + } + }, + "node_modules/hast-util-to-parse5/node_modules/property-information": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/property-information/-/property-information-4.2.0.tgz", + "integrity": "sha512-TlgDPagHh+eBKOnH2VYvk8qbwsCG/TAJdmTL7f1PROUcSO8qt/KSmShEQ/OKvock8X9tFjtqjCScyOkkkvIKVQ==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.1" + } + }, + "node_modules/hast-util-to-parse5/node_modules/web-namespaces": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/web-namespaces/-/web-namespaces-1.1.4.tgz", + "integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-to-parse5/node_modules/zwitch": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/zwitch/-/zwitch-1.0.5.tgz", + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-to-string": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz", + "integrity": "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-text": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", + "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unist-util-find-after": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "9.0.1", + "resolved": "https://registry.npmmirror.com/hastscript/-/hastscript-9.0.1.tgz", + "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/html-escaper": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/html-escaper/-/html-escaper-3.0.3.tgz", + "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==", + "license": "MIT" + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/html-whitespace-sensitive-tag-names": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/html-whitespace-sensitive-tag-names/-/html-whitespace-sensitive-tag-names-3.0.1.tgz", + "integrity": "sha512-q+310vW8zmymYHALr1da4HyXUQ0zgiIwIicEfotYPWGN0OJVEN/58IJ3A4GBYcEq3LGAZqKb+ugvP0GNB9CEAA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/htmlparser2": { + "version": "10.1.0", + "resolved": "https://registry.npmmirror.com/htmlparser2/-/htmlparser2-10.1.0.tgz", + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "entities": "^7.0.1" + } + }, + "node_modules/htmlparser2/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/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "license": "BSD-2-Clause" + }, + "node_modules/i18next": { + "version": "23.16.8", + "resolved": "https://registry.npmmirror.com/i18next/-/i18next-23.16.8.tgz", + "integrity": "sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmmirror.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==", + "license": "MIT" + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/iron-webcrypto": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz", + "integrity": "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/brc-dd" + } + }, + "node_modules/is-absolute-url": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/is-absolute-url/-/is-absolute-url-4.0.1.tgz", + "integrity": "sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/is-wsl/-/is-wsl-3.1.1.tgz", + "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/jsonc-parser/-/jsonc-parser-2.3.1.tgz", + "integrity": "sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==", + "license": "MIT" + }, + "node_modules/katex": { + "version": "0.16.28", + "resolved": "https://registry.npmmirror.com/katex/-/katex-0.16.28.tgz", + "integrity": "sha512-YHzO7721WbmAL6Ov1uzN/l5mY5WWWhJBSW+jq4tkfZfsxmo1hu6frS0EOswvjBUnWE6NtjEs48SFn5CQESRLZg==", + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmmirror.com/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/khroma": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/khroma/-/khroma-2.1.0.tgz", + "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmmirror.com/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/klona": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/langium": { + "version": "4.2.1", + "resolved": "https://registry.npmmirror.com/langium/-/langium-4.2.1.tgz", + "integrity": "sha512-zu9QWmjpzJcomzdJQAHgDVhLGq5bLosVak1KVa40NzQHXfqr4eAHupvnPOVXEoLkg6Ocefvf/93d//SB7du4YQ==", + "license": "MIT", + "dependencies": { + "chevrotain": "~11.1.1", + "chevrotain-allstar": "~0.3.1", + "vscode-languageserver": "~9.0.1", + "vscode-languageserver-textdocument": "~1.0.11", + "vscode-uri": "~3.1.0" + }, + "engines": { + "node": ">=20.10.0", + "npm": ">=10.2.3" + } + }, + "node_modules/layout-base": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/layout-base/-/layout-base-1.0.2.tgz", + "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==", + "license": "MIT" + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash-es": { + "version": "4.17.23", + "resolved": "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.23.tgz", + "integrity": "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==", + "license": "MIT" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "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/magicast": { + "version": "0.5.2", + "resolved": "https://registry.npmmirror.com/magicast/-/magicast-0.5.2.tgz", + "integrity": "sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "source-map-js": "^1.2.1" + } + }, + "node_modules/markdown-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/markdown-extensions/-/markdown-extensions-2.0.0.tgz", + "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmmirror.com/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/marked": { + "version": "16.4.2", + "resolved": "https://registry.npmmirror.com/marked/-/marked-16.4.2.tgz", + "integrity": "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/marked-footnote": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/marked-footnote/-/marked-footnote-1.4.0.tgz", + "integrity": "sha512-fZTxAhI1TcLEs5UOjCfYfTHpyKGaWQevbxaGTEA68B51l7i87SctPFtHETYqPkEN0ka5opvy4Dy1l/yXVC+hmg==", + "license": "MIT", + "peerDependencies": { + "marked": ">=7.0.0" + } + }, + "node_modules/marked-plaintify": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/marked-plaintify/-/marked-plaintify-1.1.1.tgz", + "integrity": "sha512-r3kMKArhfo2H3lD4ctFq/OJTzM0uNvXHh7FBTI1hMDpf4Ac1djjtq4g8NfTBWMxWLmaEz3KL1jCkLygik3gExA==", + "license": "MIT", + "peerDependencies": { + "marked": ">=13.0.0" + } + }, + "node_modules/marked-smartypants": { + "version": "1.1.11", + "resolved": "https://registry.npmmirror.com/marked-smartypants/-/marked-smartypants-1.1.11.tgz", + "integrity": "sha512-Jt0eq/6rf9oXDfEKPzQ0z7UzVWcEAK3L6QBBQzbwV8bT304OvPVLTqpH3yvkSung9foOM4s120TMHEHP76Metg==", + "license": "MIT", + "dependencies": { + "smartypants": "^0.2.2" + }, + "peerDependencies": { + "marked": ">=4 <18" + } + }, + "node_modules/mdast-util-definitions": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz", + "integrity": "sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-directive": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz", + "integrity": "sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", + "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", + "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", + "resolved": "https://registry.npmmirror.com/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.12.2", + "resolved": "https://registry.npmmirror.com/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", + "license": "CC0-1.0" + }, + "node_modules/mermaid": { + "version": "11.12.3", + "resolved": "https://registry.npmmirror.com/mermaid/-/mermaid-11.12.3.tgz", + "integrity": "sha512-wN5ZSgJQIC+CHJut9xaKWsknLxaFBwCPwPkGTSUYrTiHORWvpT8RxGk849HPnpUAQ+/9BPRqYb80jTpearrHzQ==", + "license": "MIT", + "dependencies": { + "@braintree/sanitize-url": "^7.1.1", + "@iconify/utils": "^3.0.1", + "@mermaid-js/parser": "^1.0.0", + "@types/d3": "^7.4.3", + "cytoscape": "^3.29.3", + "cytoscape-cose-bilkent": "^4.1.0", + "cytoscape-fcose": "^2.2.0", + "d3": "^7.9.0", + "d3-sankey": "^0.12.3", + "dagre-d3-es": "7.0.13", + "dayjs": "^1.11.18", + "dompurify": "^3.2.5", + "katex": "^0.16.22", + "khroma": "^2.1.0", + "lodash-es": "^4.17.23", + "marked": "^16.2.1", + "roughjs": "^4.6.6", + "stylis": "^4.3.6", + "ts-dedent": "^2.2.0", + "uuid": "^11.1.0" + } + }, + "node_modules/mermaid-isomorphic": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/mermaid-isomorphic/-/mermaid-isomorphic-3.1.0.tgz", + "integrity": "sha512-mzrvfEVjnJIkJlEqxp3eMuR1wS0TeLCH1VK5E/T5yzWaBwI3JqjJuw70yUIThSCDJ5bRs6O3rgfp00oBAbvSeQ==", + "license": "MIT", + "dependencies": { + "@fortawesome/fontawesome-free": "^6.0.0", + "katex": "^0.16.0", + "mermaid": "^11.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + }, + "peerDependencies": { + "playwright": "1" + }, + "peerDependenciesMeta": { + "playwright": { + "optional": true + } + } + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz", + "integrity": "sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-expression": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz", + "integrity": "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.2.tgz", + "integrity": "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-md": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", + "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", + "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", + "license": "MIT", + "dependencies": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "micromark-extension-mdx-expression": "^3.0.0", + "micromark-extension-mdx-jsx": "^3.0.0", + "micromark-extension-mdx-md": "^2.0.0", + "micromark-extension-mdxjs-esm": "^3.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", + "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz", + "integrity": "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-events-to-acorn": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz", + "integrity": "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/mini-svg-data-uri": { + "version": "1.4.4", + "resolved": "https://registry.npmmirror.com/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", + "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", + "license": "MIT", + "bin": { + "mini-svg-data-uri": "cli.js" + } + }, + "node_modules/mlly": { + "version": "1.8.0", + "resolved": "https://registry.npmmirror.com/mlly/-/mlly-1.8.0.tgz", + "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==", + "license": "MIT", + "dependencies": { + "acorn": "^8.15.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.1" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "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==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "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/neotraverse": { + "version": "0.6.18", + "resolved": "https://registry.npmmirror.com/neotraverse/-/neotraverse-0.6.18.tgz", + "integrity": "sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/nlcst-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/nlcst-to-string/-/nlcst-to-string-4.0.0.tgz", + "integrity": "sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/node-fetch-native": { + "version": "1.6.7", + "resolved": "https://registry.npmmirror.com/node-fetch-native/-/node-fetch-native-1.6.7.tgz", + "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", + "license": "MIT" + }, + "node_modules/node-mock-http": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/node-mock-http/-/node-mock-http-1.0.4.tgz", + "integrity": "sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==", + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/ofetch": { + "version": "1.5.1", + "resolved": "https://registry.npmmirror.com/ofetch/-/ofetch-1.5.1.tgz", + "integrity": "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==", + "license": "MIT", + "dependencies": { + "destr": "^2.0.5", + "node-fetch-native": "^1.6.7", + "ufo": "^1.6.1" + } + }, + "node_modules/ohash": { + "version": "2.0.11", + "resolved": "https://registry.npmmirror.com/ohash/-/ohash-2.0.11.tgz", + "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", + "license": "MIT" + }, + "node_modules/oniguruma-parser": { + "version": "0.12.1", + "resolved": "https://registry.npmmirror.com/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz", + "integrity": "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==", + "license": "MIT" + }, + "node_modules/oniguruma-to-es": { + "version": "4.3.4", + "resolved": "https://registry.npmmirror.com/oniguruma-to-es/-/oniguruma-to-es-4.3.4.tgz", + "integrity": "sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA==", + "license": "MIT", + "dependencies": { + "oniguruma-parser": "^0.12.1", + "regex": "^6.0.1", + "regex-recursion": "^6.0.2" + } + }, + "node_modules/p-limit": { + "version": "6.2.0", + "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-6.2.0.tgz", + "integrity": "sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "8.1.1", + "resolved": "https://registry.npmmirror.com/p-queue/-/p-queue-8.1.1.tgz", + "integrity": "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^5.0.1", + "p-timeout": "^6.1.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "6.1.4", + "resolved": "https://registry.npmmirror.com/p-timeout/-/p-timeout-6.1.4.tgz", + "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-manager-detector": { + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/package-manager-detector/-/package-manager-detector-1.6.0.tgz", + "integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==", + "license": "MIT" + }, + "node_modules/pagefind": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/pagefind/-/pagefind-1.4.0.tgz", + "integrity": "sha512-z2kY1mQlL4J8q5EIsQkLzQjilovKzfNVhX8De6oyE6uHpfFtyBaqUpcl/XzJC/4fjD8vBDyh1zolimIcVrCn9g==", + "license": "MIT", + "bin": { + "pagefind": "lib/runner/bin.cjs" + }, + "optionalDependencies": { + "@pagefind/darwin-arm64": "1.4.0", + "@pagefind/darwin-x64": "1.4.0", + "@pagefind/freebsd-x64": "1.4.0", + "@pagefind/linux-arm64": "1.4.0", + "@pagefind/linux-x64": "1.4.0", + "@pagefind/windows-x64": "1.4.0" + } + }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmmirror.com/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/parse-latin": { + "version": "7.0.0", + "resolved": "https://registry.npmmirror.com/parse-latin/-/parse-latin-7.0.0.tgz", + "integrity": "sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "@types/unist": "^3.0.0", + "nlcst-to-string": "^4.0.0", + "unist-util-modify-children": "^4.0.0", + "unist-util-visit-children": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmmirror.com/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmmirror.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmmirror.com/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=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==", + "license": "MIT" + }, + "node_modules/path-data-parser": { + "version": "0.1.0", + "resolved": "https://registry.npmmirror.com/path-data-parser/-/path-data-parser-0.1.0.tgz", + "integrity": "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==", + "license": "MIT" + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "license": "MIT" + }, + "node_modules/piccolore": { + "version": "0.1.3", + "resolved": "https://registry.npmmirror.com/piccolore/-/piccolore-0.1.3.tgz", + "integrity": "sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==", + "license": "ISC" + }, + "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.3", + "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmmirror.com/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/playwright": { + "version": "1.58.2", + "resolved": "https://registry.npmmirror.com/playwright/-/playwright-1.58.2.tgz", + "integrity": "sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==", + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.58.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.58.2", + "resolved": "https://registry.npmmirror.com/playwright-core/-/playwright-core-1.58.2.tgz", + "integrity": "sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==", + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/points-on-curve": { + "version": "0.2.0", + "resolved": "https://registry.npmmirror.com/points-on-curve/-/points-on-curve-0.2.0.tgz", + "integrity": "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==", + "license": "MIT" + }, + "node_modules/points-on-path": { + "version": "0.2.1", + "resolved": "https://registry.npmmirror.com/points-on-path/-/points-on-path-0.2.1.tgz", + "integrity": "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==", + "license": "MIT", + "dependencies": { + "path-data-parser": "0.1.0", + "points-on-curve": "0.2.0" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "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.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmmirror.com/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/prettier": { + "version": "3.8.1", + "resolved": "https://registry.npmmirror.com/prettier/-/prettier-3.8.1.tgz", + "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmmirror.com/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmmirror.com/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prompts/node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/property-information": { + "version": "7.1.0", + "resolved": "https://registry.npmmirror.com/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/radix3": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/radix3/-/radix3-1.1.2.tgz", + "integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==", + "license": "MIT" + }, + "node_modules/react": { + "version": "19.2.4", + "resolved": "https://registry.npmmirror.com/react/-/react-19.2.4.tgz", + "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.4", + "resolved": "https://registry.npmmirror.com/react-dom/-/react-dom-19.2.4.tgz", + "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.4" + } + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmmirror.com/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/recma-build-jsx": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz", + "integrity": "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-build-jsx": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-jsx": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/recma-jsx/-/recma-jsx-1.0.1.tgz", + "integrity": "sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==", + "license": "MIT", + "dependencies": { + "acorn-jsx": "^5.0.0", + "estree-util-to-js": "^2.0.0", + "recma-parse": "^1.0.0", + "recma-stringify": "^1.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/recma-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/recma-parse/-/recma-parse-1.0.0.tgz", + "integrity": "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "esast-util-from-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/recma-stringify/-/recma-stringify-1.0.0.tgz", + "integrity": "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-to-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/regex": { + "version": "6.1.0", + "resolved": "https://registry.npmmirror.com/regex/-/regex-6.1.0.tgz", + "integrity": "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-recursion": { + "version": "6.0.2", + "resolved": "https://registry.npmmirror.com/regex-recursion/-/regex-recursion-6.0.2.tgz", + "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-utilities": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/regex-utilities/-/regex-utilities-2.3.0.tgz", + "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", + "license": "MIT" + }, + "node_modules/rehype": { + "version": "13.0.2", + "resolved": "https://registry.npmmirror.com/rehype/-/rehype-13.0.2.tgz", + "integrity": "sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "rehype-parse": "^9.0.0", + "rehype-stringify": "^10.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-expressive-code": { + "version": "0.41.6", + "resolved": "https://registry.npmmirror.com/rehype-expressive-code/-/rehype-expressive-code-0.41.6.tgz", + "integrity": "sha512-aBMX8kxPtjmDSFUdZlAWJkMvsQ4ZMASfee90JWIAV8tweltXLzkWC3q++43ToTelI8ac5iC0B3/S/Cl4Ql1y2g==", + "license": "MIT", + "dependencies": { + "expressive-code": "^0.41.6" + } + }, + "node_modules/rehype-external-links": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/rehype-external-links/-/rehype-external-links-3.0.0.tgz", + "integrity": "sha512-yp+e5N9V3C6bwBeAC4n796kc86M4gJCdlVhiMTxIrJG5UHDMh+PJANf9heqORJbt1nrCbDwIlAZKjANIaVBbvw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-is-element": "^3.0.0", + "is-absolute-url": "^4.0.0", + "space-separated-tokens": "^2.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-format": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/rehype-format/-/rehype-format-5.0.1.tgz", + "integrity": "sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-format": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-mermaid": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/rehype-mermaid/-/rehype-mermaid-3.0.0.tgz", + "integrity": "sha512-fxrD5E4Fa1WXUjmjNDvLOMT4XB1WaxcfycFIWiYU0yEMQhcTDElc9aDFnbDFRLxG1Cfo1I3mfD5kg4sjlWaB+Q==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-from-html-isomorphic": "^2.0.0", + "hast-util-to-text": "^4.0.0", + "mermaid-isomorphic": "^3.0.0", + "mini-svg-data-uri": "^1.0.0", + "space-separated-tokens": "^2.0.0", + "unified": "^11.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + }, + "peerDependencies": { + "playwright": "1" + }, + "peerDependenciesMeta": { + "playwright": { + "optional": true + } + } + }, + "node_modules/rehype-parse": { + "version": "9.0.1", + "resolved": "https://registry.npmmirror.com/rehype-parse/-/rehype-parse-9.0.1.tgz", + "integrity": "sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-from-html": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-raw": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/rehype-raw/-/rehype-raw-3.0.0.tgz", + "integrity": "sha512-U8OBB1DwrsxK5trvrhZLaJWrFkTFtOaLV7z8O7OAnwJ/+VTNBEaTUgJfMihSxB063m7/eNVA4+yZnDVuTxeTrQ==", + "license": "MIT", + "dependencies": { + "hast-util-raw": "^4.0.0" + } + }, + "node_modules/rehype-recma": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/rehype-recma/-/rehype-recma-1.0.0.tgz", + "integrity": "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "hast-util-to-estree": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-stringify": { + "version": "10.0.1", + "resolved": "https://registry.npmmirror.com/rehype-stringify/-/rehype-stringify-10.0.1.tgz", + "integrity": "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-to-html": "^9.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-directive": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/remark-directive/-/remark-directive-3.0.1.tgz", + "integrity": "sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-directive": "^3.0.0", + "micromark-extension-directive": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-mdx": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/remark-mdx/-/remark-mdx-3.1.1.tgz", + "integrity": "sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==", + "license": "MIT", + "dependencies": { + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmmirror.com/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.2", + "resolved": "https://registry.npmmirror.com/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-smartypants": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/remark-smartypants/-/remark-smartypants-3.0.2.tgz", + "integrity": "sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==", + "license": "MIT", + "dependencies": { + "retext": "^9.0.0", + "retext-smartypants": "^6.0.0", + "unified": "^11.0.4", + "unist-util-visit": "^5.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmmirror.com/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/request-light": { + "version": "0.7.0", + "resolved": "https://registry.npmmirror.com/request-light/-/request-light-0.7.0.tgz", + "integrity": "sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q==", + "license": "MIT" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/retext": { + "version": "9.0.0", + "resolved": "https://registry.npmmirror.com/retext/-/retext-9.0.0.tgz", + "integrity": "sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "retext-latin": "^4.0.0", + "retext-stringify": "^4.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-latin": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/retext-latin/-/retext-latin-4.0.0.tgz", + "integrity": "sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "parse-latin": "^7.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-smartypants": { + "version": "6.2.0", + "resolved": "https://registry.npmmirror.com/retext-smartypants/-/retext-smartypants-6.2.0.tgz", + "integrity": "sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "nlcst-to-string": "^4.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-stringify": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/retext-stringify/-/retext-stringify-4.0.0.tgz", + "integrity": "sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "nlcst-to-string": "^4.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==", + "license": "Unlicense" + }, + "node_modules/rollup": { + "version": "4.58.0", + "resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.58.0.tgz", + "integrity": "sha512-wbT0mBmWbIvvq8NeEYWWvevvxnOyhKChir47S66WCxw1SXqhw7ssIYejnQEVt7XYQpsj2y8F9PM+Cr3SNEa0gw==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.58.0", + "@rollup/rollup-android-arm64": "4.58.0", + "@rollup/rollup-darwin-arm64": "4.58.0", + "@rollup/rollup-darwin-x64": "4.58.0", + "@rollup/rollup-freebsd-arm64": "4.58.0", + "@rollup/rollup-freebsd-x64": "4.58.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.58.0", + "@rollup/rollup-linux-arm-musleabihf": "4.58.0", + "@rollup/rollup-linux-arm64-gnu": "4.58.0", + "@rollup/rollup-linux-arm64-musl": "4.58.0", + "@rollup/rollup-linux-loong64-gnu": "4.58.0", + "@rollup/rollup-linux-loong64-musl": "4.58.0", + "@rollup/rollup-linux-ppc64-gnu": "4.58.0", + "@rollup/rollup-linux-ppc64-musl": "4.58.0", + "@rollup/rollup-linux-riscv64-gnu": "4.58.0", + "@rollup/rollup-linux-riscv64-musl": "4.58.0", + "@rollup/rollup-linux-s390x-gnu": "4.58.0", + "@rollup/rollup-linux-x64-gnu": "4.58.0", + "@rollup/rollup-linux-x64-musl": "4.58.0", + "@rollup/rollup-openbsd-x64": "4.58.0", + "@rollup/rollup-openharmony-arm64": "4.58.0", + "@rollup/rollup-win32-arm64-msvc": "4.58.0", + "@rollup/rollup-win32-ia32-msvc": "4.58.0", + "@rollup/rollup-win32-x64-gnu": "4.58.0", + "@rollup/rollup-win32-x64-msvc": "4.58.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/roughjs": { + "version": "4.6.6", + "resolved": "https://registry.npmmirror.com/roughjs/-/roughjs-4.6.6.tgz", + "integrity": "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==", + "license": "MIT", + "dependencies": { + "hachure-fill": "^0.5.2", + "path-data-parser": "^0.1.0", + "points-on-curve": "^0.2.0", + "points-on-path": "^0.2.1" + } + }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmmirror.com/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "license": "BSD-3-Clause" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/sax": { + "version": "1.4.4", + "resolved": "https://registry.npmmirror.com/sax/-/sax-1.4.4.tgz", + "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmmirror.com/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmmirror.com/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/shiki": { + "version": "3.22.0", + "resolved": "https://registry.npmmirror.com/shiki/-/shiki-3.22.0.tgz", + "integrity": "sha512-LBnhsoYEe0Eou4e1VgJACes+O6S6QC0w71fCSp5Oya79inkwkm15gQ1UF6VtQ8j/taMDh79hAB49WUk8ALQW3g==", + "license": "MIT", + "dependencies": { + "@shikijs/core": "3.22.0", + "@shikijs/engine-javascript": "3.22.0", + "@shikijs/engine-oniguruma": "3.22.0", + "@shikijs/langs": "3.22.0", + "@shikijs/themes": "3.22.0", + "@shikijs/types": "3.22.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, + "node_modules/sitemap": { + "version": "8.0.2", + "resolved": "https://registry.npmmirror.com/sitemap/-/sitemap-8.0.2.tgz", + "integrity": "sha512-LwktpJcyZDoa0IL6KT++lQ53pbSrx2c9ge41/SeLTyqy2XUNA6uR4+P9u5IVo5lPeL2arAcOKn1aZAxoYbCKlQ==", + "license": "MIT", + "dependencies": { + "@types/node": "^17.0.5", + "@types/sax": "^1.2.1", + "arg": "^5.0.0", + "sax": "^1.4.1" + }, + "bin": { + "sitemap": "dist/cli.js" + }, + "engines": { + "node": ">=14.0.0", + "npm": ">=6.0.0" + } + }, + "node_modules/sitemap/node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", + "license": "MIT" + }, + "node_modules/smartypants": { + "version": "0.2.2", + "resolved": "https://registry.npmmirror.com/smartypants/-/smartypants-0.2.2.tgz", + "integrity": "sha512-TzobUYoEft/xBtb2voRPryAUIvYguG0V7Tt3de79I1WfXgCwelqVsGuZSnu3GFGRZhXR90AeEYIM+icuB/S06Q==", + "license": "BSD-3-Clause", + "bin": { + "smartypants": "bin/smartypants.js", + "smartypantsu": "bin/smartypantsu.js" + } + }, + "node_modules/smol-toml": { + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/smol-toml/-/smol-toml-1.6.0.tgz", + "integrity": "sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 18" + }, + "funding": { + "url": "https://github.com/sponsors/cyyynthia" + } + }, + "node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "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/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/starlight-blog": { + "version": "0.25.2", + "resolved": "https://registry.npmmirror.com/starlight-blog/-/starlight-blog-0.25.2.tgz", + "integrity": "sha512-YsNXI1fT0w9CdgVGRJGR8KxNWJgKuHsad/avo9Z+FU9k9EWJVdr/Ret7tm0HbFFbOGJ8/JY/U64EHYdCAtxQhg==", + "license": "MIT", + "dependencies": { + "@astrojs/markdown-remark": "^6.3.1", + "@astrojs/mdx": "^4.0.8", + "@astrojs/rss": "^4.0.11", + "astro-remote": "^0.3.3", + "github-slugger": "^2.0.0", + "hast-util-from-html": "^2.0.3", + "hast-util-to-html": "^9.0.5", + "hast-util-to-string": "^3.0.1", + "marked": "^15.0.4", + "marked-plaintify": "^1.1.1", + "mdast-util-mdx-expression": "^2.0.1", + "unist-util-is": "^6.0.0", + "unist-util-remove": "^4.0.0", + "unist-util-visit": "^5.0.0" + }, + "engines": { + "node": ">=18.20.8" + }, + "peerDependencies": { + "@astrojs/starlight": ">=0.33.0" + } + }, + "node_modules/starlight-blog/node_modules/marked": { + "version": "15.0.12", + "resolved": "https://registry.npmmirror.com/marked/-/marked-15.0.12.tgz", + "integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/stream-replace-string": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/stream-replace-string/-/stream-replace-string-2.0.0.tgz", + "integrity": "sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==", + "license": "MIT" + }, + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmmirror.com/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strnum": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/strnum/-/strnum-2.1.2.tgz", + "integrity": "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, + "node_modules/style-to-js": { + "version": "1.1.21", + "resolved": "https://registry.npmmirror.com/style-to-js/-/style-to-js-1.1.21.tgz", + "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==", + "license": "MIT", + "dependencies": { + "style-to-object": "1.0.14" + } + }, + "node_modules/style-to-js/node_modules/inline-style-parser": { + "version": "0.2.7", + "resolved": "https://registry.npmmirror.com/inline-style-parser/-/inline-style-parser-0.2.7.tgz", + "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", + "license": "MIT" + }, + "node_modules/style-to-js/node_modules/style-to-object": { + "version": "1.0.14", + "resolved": "https://registry.npmmirror.com/style-to-object/-/style-to-object-1.0.14.tgz", + "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.7" + } + }, + "node_modules/style-to-object": { + "version": "0.2.3", + "resolved": "https://registry.npmmirror.com/style-to-object/-/style-to-object-0.2.3.tgz", + "integrity": "sha512-1d/k4EY2N7jVLOqf2j04dTc37TPOv/hHxZmvpg8Pdh8UYydxeu/C1W1U4vD8alzf5V2Gt7rLsmkr4dxAlDm9ng==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.1.1" + } + }, + "node_modules/stylis": { + "version": "4.3.6", + "resolved": "https://registry.npmmirror.com/stylis/-/stylis-4.3.6.tgz", + "integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==", + "license": "MIT" + }, + "node_modules/svgo": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/svgo/-/svgo-4.0.0.tgz", + "integrity": "sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==", + "license": "MIT", + "dependencies": { + "commander": "^11.1.0", + "css-select": "^5.1.0", + "css-tree": "^3.0.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.1.1", + "sax": "^1.4.1" + }, + "bin": { + "svgo": "bin/svgo.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/svgo/node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmmirror.com/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/tiny-inflate": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "license": "MIT", + "engines": { + "node": ">=6.10" + } + }, + "node_modules/tsconfck": { + "version": "3.1.6", + "resolved": "https://registry.npmmirror.com/tsconfck/-/tsconfck-3.1.6.tgz", + "integrity": "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==", + "license": "MIT", + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD", + "optional": true + }, + "node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typesafe-path": { + "version": "0.2.2", + "resolved": "https://registry.npmmirror.com/typesafe-path/-/typesafe-path-0.2.2.tgz", + "integrity": "sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA==", + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-auto-import-cache": { + "version": "0.3.6", + "resolved": "https://registry.npmmirror.com/typescript-auto-import-cache/-/typescript-auto-import-cache-0.3.6.tgz", + "integrity": "sha512-RpuHXrknHdVdK7wv/8ug3Fr0WNsNi5l5aB8MYYuXhq2UH5lnEB1htJ1smhtD5VeCsGr2p8mUDtd83LCQDFVgjQ==", + "license": "MIT", + "dependencies": { + "semver": "^7.3.8" + } + }, + "node_modules/ufo": { + "version": "1.6.3", + "resolved": "https://registry.npmmirror.com/ufo/-/ufo-1.6.3.tgz", + "integrity": "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==", + "license": "MIT" + }, + "node_modules/ultrahtml": { + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/ultrahtml/-/ultrahtml-1.6.0.tgz", + "integrity": "sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==", + "license": "MIT" + }, + "node_modules/uncrypto": { + "version": "0.1.3", + "resolved": "https://registry.npmmirror.com/uncrypto/-/uncrypto-0.1.3.tgz", + "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==", + "license": "MIT" + }, + "node_modules/undici": { + "version": "7.22.0", + "resolved": "https://registry.npmmirror.com/undici/-/undici-7.22.0.tgz", + "integrity": "sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==", + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmmirror.com/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unifont": { + "version": "0.7.4", + "resolved": "https://registry.npmmirror.com/unifont/-/unifont-0.7.4.tgz", + "integrity": "sha512-oHeis4/xl42HUIeHuNZRGEvxj5AaIKR+bHPNegRq5LV1gdc3jundpONbjglKpihmJf+dswygdMJn3eftGIMemg==", + "license": "MIT", + "dependencies": { + "css-tree": "^3.1.0", + "ofetch": "^1.5.1", + "ohash": "^2.0.11" + } + }, + "node_modules/unist-util-find-after": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", + "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-modify-children": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/unist-util-modify-children/-/unist-util-modify-children-4.0.0.tgz", + "integrity": "sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "array-iterate": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", + "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/unist-util-remove/-/unist-util-remove-4.0.0.tgz", + "integrity": "sha512-b4gokeGId57UVRX/eVKej5gXqGlc9+trkORhFJpu9raqZkZhU0zm8Doi05+HaiBsMEIJowL+2WtQ5ItjsngPXg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-children": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/unist-util-visit-children/-/unist-util-visit-children-3.0.0.tgz", + "integrity": "sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmmirror.com/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unstorage": { + "version": "1.17.4", + "resolved": "https://registry.npmmirror.com/unstorage/-/unstorage-1.17.4.tgz", + "integrity": "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw==", + "license": "MIT", + "dependencies": { + "anymatch": "^3.1.3", + "chokidar": "^5.0.0", + "destr": "^2.0.5", + "h3": "^1.15.5", + "lru-cache": "^11.2.0", + "node-fetch-native": "^1.6.7", + "ofetch": "^1.5.1", + "ufo": "^1.6.3" + }, + "peerDependencies": { + "@azure/app-configuration": "^1.8.0", + "@azure/cosmos": "^4.2.0", + "@azure/data-tables": "^13.3.0", + "@azure/identity": "^4.6.0", + "@azure/keyvault-secrets": "^4.9.0", + "@azure/storage-blob": "^12.26.0", + "@capacitor/preferences": "^6 || ^7 || ^8", + "@deno/kv": ">=0.9.0", + "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", + "@planetscale/database": "^1.19.0", + "@upstash/redis": "^1.34.3", + "@vercel/blob": ">=0.27.1", + "@vercel/functions": "^2.2.12 || ^3.0.0", + "@vercel/kv": "^1 || ^2 || ^3", + "aws4fetch": "^1.0.20", + "db0": ">=0.2.1", + "idb-keyval": "^6.2.1", + "ioredis": "^5.4.2", + "uploadthing": "^7.4.4" + }, + "peerDependenciesMeta": { + "@azure/app-configuration": { + "optional": true + }, + "@azure/cosmos": { + "optional": true + }, + "@azure/data-tables": { + "optional": true + }, + "@azure/identity": { + "optional": true + }, + "@azure/keyvault-secrets": { + "optional": true + }, + "@azure/storage-blob": { + "optional": true + }, + "@capacitor/preferences": { + "optional": true + }, + "@deno/kv": { + "optional": true + }, + "@netlify/blobs": { + "optional": true + }, + "@planetscale/database": { + "optional": true + }, + "@upstash/redis": { + "optional": true + }, + "@vercel/blob": { + "optional": true + }, + "@vercel/functions": { + "optional": true + }, + "@vercel/kv": { + "optional": true + }, + "aws4fetch": { + "optional": true + }, + "db0": { + "optional": true + }, + "idb-keyval": { + "optional": true + }, + "ioredis": { + "optional": true + }, + "uploadthing": { + "optional": true + } + } + }, + "node_modules/unstorage/node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "license": "MIT", + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/unstorage/node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/unstorage/node_modules/readdirp": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmmirror.com/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, + "node_modules/valid-filename": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/valid-filename/-/valid-filename-4.0.0.tgz", + "integrity": "sha512-VEYTpTVPMgO799f2wI7zWf0x2C54bPX6NAfbZ2Z8kZn76p+3rEYCTYVYzMUcVSMvakxMQTriBf24s3+WeXJtEg==", + "license": "MIT", + "dependencies": { + "filename-reserved-regex": "^3.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmmirror.com/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmmirror.com/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vite": { + "version": "6.4.1", + "resolved": "https://registry.npmmirror.com/vite/-/vite-6.4.1.tgz", + "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "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/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/vitefu": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/vitefu/-/vitefu-1.1.1.tgz", + "integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==", + "license": "MIT", + "workspaces": [ + "tests/deps/*", + "tests/projects/*", + "tests/projects/workspace/packages/*" + ], + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/volar-service-css": { + "version": "0.0.68", + "resolved": "https://registry.npmmirror.com/volar-service-css/-/volar-service-css-0.0.68.tgz", + "integrity": "sha512-lJSMh6f3QzZ1tdLOZOzovLX0xzAadPhx8EKwraDLPxBndLCYfoTvnNuiFFV8FARrpAlW5C0WkH+TstPaCxr00Q==", + "license": "MIT", + "dependencies": { + "vscode-css-languageservice": "^6.3.0", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-uri": "^3.0.8" + }, + "peerDependencies": { + "@volar/language-service": "~2.4.0" + }, + "peerDependenciesMeta": { + "@volar/language-service": { + "optional": true + } + } + }, + "node_modules/volar-service-emmet": { + "version": "0.0.68", + "resolved": "https://registry.npmmirror.com/volar-service-emmet/-/volar-service-emmet-0.0.68.tgz", + "integrity": "sha512-nHvixrRQ83EzkQ4G/jFxu9Y4eSsXS/X2cltEPDM+K9qZmIv+Ey1w0tg1+6caSe8TU5Hgw4oSTwNMf/6cQb3LzQ==", + "license": "MIT", + "dependencies": { + "@emmetio/css-parser": "^0.4.1", + "@emmetio/html-matcher": "^1.3.0", + "@vscode/emmet-helper": "^2.9.3", + "vscode-uri": "^3.0.8" + }, + "peerDependencies": { + "@volar/language-service": "~2.4.0" + }, + "peerDependenciesMeta": { + "@volar/language-service": { + "optional": true + } + } + }, + "node_modules/volar-service-html": { + "version": "0.0.68", + "resolved": "https://registry.npmmirror.com/volar-service-html/-/volar-service-html-0.0.68.tgz", + "integrity": "sha512-fru9gsLJxy33xAltXOh4TEdi312HP80hpuKhpYQD4O5hDnkNPEBdcQkpB+gcX0oK0VxRv1UOzcGQEUzWCVHLfA==", + "license": "MIT", + "dependencies": { + "vscode-html-languageservice": "^5.3.0", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-uri": "^3.0.8" + }, + "peerDependencies": { + "@volar/language-service": "~2.4.0" + }, + "peerDependenciesMeta": { + "@volar/language-service": { + "optional": true + } + } + }, + "node_modules/volar-service-prettier": { + "version": "0.0.68", + "resolved": "https://registry.npmmirror.com/volar-service-prettier/-/volar-service-prettier-0.0.68.tgz", + "integrity": "sha512-grUmWHkHlebMOd6V8vXs2eNQUw/bJGJMjekh/EPf/p2ZNTK0Uyz7hoBRngcvGfJHMsSXZH8w/dZTForIW/4ihw==", + "license": "MIT", + "dependencies": { + "vscode-uri": "^3.0.8" + }, + "peerDependencies": { + "@volar/language-service": "~2.4.0", + "prettier": "^2.2 || ^3.0" + }, + "peerDependenciesMeta": { + "@volar/language-service": { + "optional": true + }, + "prettier": { + "optional": true + } + } + }, + "node_modules/volar-service-typescript": { + "version": "0.0.68", + "resolved": "https://registry.npmmirror.com/volar-service-typescript/-/volar-service-typescript-0.0.68.tgz", + "integrity": "sha512-z7B/7CnJ0+TWWFp/gh2r5/QwMObHNDiQiv4C9pTBNI2Wxuwymd4bjEORzrJ/hJ5Yd5+OzeYK+nFCKevoGEEeKw==", + "license": "MIT", + "dependencies": { + "path-browserify": "^1.0.1", + "semver": "^7.6.2", + "typescript-auto-import-cache": "^0.3.5", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-nls": "^5.2.0", + "vscode-uri": "^3.0.8" + }, + "peerDependencies": { + "@volar/language-service": "~2.4.0" + }, + "peerDependenciesMeta": { + "@volar/language-service": { + "optional": true + } + } + }, + "node_modules/volar-service-typescript-twoslash-queries": { + "version": "0.0.68", + "resolved": "https://registry.npmmirror.com/volar-service-typescript-twoslash-queries/-/volar-service-typescript-twoslash-queries-0.0.68.tgz", + "integrity": "sha512-NugzXcM0iwuZFLCJg47vI93su5YhTIweQuLmZxvz5ZPTaman16JCvmDZexx2rd5T/75SNuvvZmrTOTNYUsfe5w==", + "license": "MIT", + "dependencies": { + "vscode-uri": "^3.0.8" + }, + "peerDependencies": { + "@volar/language-service": "~2.4.0" + }, + "peerDependenciesMeta": { + "@volar/language-service": { + "optional": true + } + } + }, + "node_modules/volar-service-yaml": { + "version": "0.0.68", + "resolved": "https://registry.npmmirror.com/volar-service-yaml/-/volar-service-yaml-0.0.68.tgz", + "integrity": "sha512-84XgE02LV0OvTcwfqhcSwVg4of3MLNUWPMArO6Aj8YXqyEVnPu8xTEMY2btKSq37mVAPuaEVASI4e3ptObmqcA==", + "license": "MIT", + "dependencies": { + "vscode-uri": "^3.0.8", + "yaml-language-server": "~1.19.2" + }, + "peerDependencies": { + "@volar/language-service": "~2.4.0" + }, + "peerDependenciesMeta": { + "@volar/language-service": { + "optional": true + } + } + }, + "node_modules/vscode-css-languageservice": { + "version": "6.3.9", + "resolved": "https://registry.npmmirror.com/vscode-css-languageservice/-/vscode-css-languageservice-6.3.9.tgz", + "integrity": "sha512-1tLWfp+TDM5ZuVWht3jmaY5y7O6aZmpeXLoHl5bv1QtRsRKt4xYGRMmdJa5Pqx/FTkgRbsna9R+Gn2xE+evVuA==", + "license": "MIT", + "dependencies": { + "@vscode/l10n": "^0.0.18", + "vscode-languageserver-textdocument": "^1.0.12", + "vscode-languageserver-types": "3.17.5", + "vscode-uri": "^3.1.0" + } + }, + "node_modules/vscode-html-languageservice": { + "version": "5.6.1", + "resolved": "https://registry.npmmirror.com/vscode-html-languageservice/-/vscode-html-languageservice-5.6.1.tgz", + "integrity": "sha512-5Mrqy5CLfFZUgkyhNZLA1Ye5g12Cb/v6VM7SxUzZUaRKWMDz4md+y26PrfRTSU0/eQAl3XpO9m2og+GGtDMuaA==", + "license": "MIT", + "dependencies": { + "@vscode/l10n": "^0.0.18", + "vscode-languageserver-textdocument": "^1.0.12", + "vscode-languageserver-types": "^3.17.5", + "vscode-uri": "^3.1.0" + } + }, + "node_modules/vscode-json-languageservice": { + "version": "4.1.8", + "resolved": "https://registry.npmmirror.com/vscode-json-languageservice/-/vscode-json-languageservice-4.1.8.tgz", + "integrity": "sha512-0vSpg6Xd9hfV+eZAaYN63xVVMOTmJ4GgHxXnkLCh+9RsQBkWKIghzLhW2B9ebfG+LQQg8uLtsQ2aUKjTgE+QOg==", + "license": "MIT", + "dependencies": { + "jsonc-parser": "^3.0.0", + "vscode-languageserver-textdocument": "^1.0.1", + "vscode-languageserver-types": "^3.16.0", + "vscode-nls": "^5.0.0", + "vscode-uri": "^3.0.2" + }, + "engines": { + "npm": ">=7.0.0" + } + }, + "node_modules/vscode-json-languageservice/node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmmirror.com/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "license": "MIT" + }, + "node_modules/vscode-jsonrpc": { + "version": "8.2.0", + "resolved": "https://registry.npmmirror.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", + "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vscode-languageserver": { + "version": "9.0.1", + "resolved": "https://registry.npmmirror.com/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", + "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", + "license": "MIT", + "dependencies": { + "vscode-languageserver-protocol": "3.17.5" + }, + "bin": { + "installServerIntoExtension": "bin/installServerIntoExtension" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.17.5", + "resolved": "https://registry.npmmirror.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", + "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "license": "MIT", + "dependencies": { + "vscode-jsonrpc": "8.2.0", + "vscode-languageserver-types": "3.17.5" + } + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.12", + "resolved": "https://registry.npmmirror.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", + "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==", + "license": "MIT" + }, + "node_modules/vscode-languageserver-types": { + "version": "3.17.5", + "resolved": "https://registry.npmmirror.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", + "license": "MIT" + }, + "node_modules/vscode-nls": { + "version": "5.2.0", + "resolved": "https://registry.npmmirror.com/vscode-nls/-/vscode-nls-5.2.0.tgz", + "integrity": "sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==", + "license": "MIT" + }, + "node_modules/vscode-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/vscode-uri/-/vscode-uri-3.1.0.tgz", + "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==", + "license": "MIT" + }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/which-pm-runs": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/which-pm-runs/-/which-pm-runs-1.1.0.tgz", + "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/widest-line": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/widest-line/-/widest-line-5.0.0.tgz", + "integrity": "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==", + "license": "MIT", + "dependencies": { + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/xxhash-wasm": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz", + "integrity": "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==", + "license": "MIT" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.8.2", + "resolved": "https://registry.npmmirror.com/yaml/-/yaml-2.8.2.tgz", + "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/yaml-language-server": { + "version": "1.19.2", + "resolved": "https://registry.npmmirror.com/yaml-language-server/-/yaml-language-server-1.19.2.tgz", + "integrity": "sha512-9F3myNmJzUN/679jycdMxqtydPSDRAarSj3wPiF7pchEPnO9Dg07Oc+gIYLqXR4L+g+FSEVXXv2+mr54StLFOg==", + "license": "MIT", + "dependencies": { + "@vscode/l10n": "^0.0.18", + "ajv": "^8.17.1", + "ajv-draft-04": "^1.0.0", + "lodash": "4.17.21", + "prettier": "^3.5.0", + "request-light": "^0.5.7", + "vscode-json-languageservice": "4.1.8", + "vscode-languageserver": "^9.0.0", + "vscode-languageserver-textdocument": "^1.0.1", + "vscode-languageserver-types": "^3.16.0", + "vscode-uri": "^3.0.2", + "yaml": "2.7.1" + }, + "bin": { + "yaml-language-server": "bin/yaml-language-server" + } + }, + "node_modules/yaml-language-server/node_modules/request-light": { + "version": "0.5.8", + "resolved": "https://registry.npmmirror.com/request-light/-/request-light-0.5.8.tgz", + "integrity": "sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg==", + "license": "MIT" + }, + "node_modules/yaml-language-server/node_modules/yaml": { + "version": "2.7.1", + "resolved": "https://registry.npmmirror.com/yaml/-/yaml-2.7.1.tgz", + "integrity": "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmmirror.com/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yocto-spinner": { + "version": "0.2.3", + "resolved": "https://registry.npmmirror.com/yocto-spinner/-/yocto-spinner-0.2.3.tgz", + "integrity": "sha512-sqBChb33loEnkoXte1bLg45bEBsOP9N1kzQh5JZNKj/0rik4zAPTNSAVPj3uQAdc6slYJ0Ksc403G2XgxsJQFQ==", + "license": "MIT", + "dependencies": { + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": ">=18.19" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/yoctocolors/-/yoctocolors-2.1.2.tgz", + "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmmirror.com/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.25.1", + "resolved": "https://registry.npmmirror.com/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", + "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.25 || ^4" + } + }, + "node_modules/zod-to-ts": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/zod-to-ts/-/zod-to-ts-1.2.0.tgz", + "integrity": "sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==", + "peerDependencies": { + "typescript": "^4.9.4 || ^5.0.2", + "zod": "^3" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..1090faf --- /dev/null +++ b/package.json @@ -0,0 +1,38 @@ +{ + "name": "@hagicode/docs", + "version": "0.0.1", + "private": true, + "type": "module", + "description": "HagiCode documentation site - built with Astro and Starlight", + "scripts": { + "dev": "astro dev --port ${PORT_DOCS:-31265}", + "start": "astro dev", + "build": "astro build", + "preview": "astro preview --port ${PORT_DOCS:-31265}", + "astro": "astro", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@astrojs/mdx": "4.3.13", + "@astrojs/partytown": "^2.1.4", + "@astrojs/react": "^4.4.2", + "@astrojs/sitemap": "^3.7.0", + "@astrojs/starlight": "^0.37.4", + "@types/react": "^19.2.13", + "@types/react-dom": "^19.2.3", + "astro": "^5.6.1", + "astro-link-validator": "github:rodgtr1/astro-link-validator", + "astro-robots-txt": "^1.0.0", + "astro-seo": "^1.1.0", + "mermaid": "^11.12.2", + "playwright": "^1.58.2", + "react": "^19.2.4", + "react-dom": "^19.2.4", + "rehype-external-links": "^3.0.0", + "rehype-mermaid": "^3.0.0", + "rehype-raw": "^3.0.0", + "semver": "^7.7.4", + "sharp": "^0.34.2", + "starlight-blog": "^0.25.2" + } +} diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 0000000..662d552 --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,30 @@ +# Cache Configuration for Static Resources +# This file configures HTTP cache headers for GitHub Pages deployment + +# Enable Expires module for cache expiration + + ExpiresActive On + ExpiresByType text/css "access plus 1 year" + ExpiresByType application/javascript "access plus 1 year" + ExpiresByType text/javascript "access plus 1 year" + + +# Enable Headers module for Cache-Control + + # Hashed resources in _astro directory - 1 year immutable cache + # These files contain content hashes in their filenames, so they never change + + Header set Cache-Control "public, max-age=31536000, immutable" + + + # Static assets (images, fonts, icons) - 1 day cache + + Header set Cache-Control "public, max-age=86400" + + + # HTML documents - no cache, must revalidate + # HTML content changes frequently and should always be fresh + + Header set Cache-Control "public, max-age=0, must-revalidate" + + diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..4531a81 Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/img/README.md b/public/img/README.md new file mode 100644 index 0000000..21b4931 --- /dev/null +++ b/public/img/README.md @@ -0,0 +1,94 @@ +# Static Images Directory + +This directory contains static image files that are served directly by the Astro site. + +## ⚠️ Important Note + +**Document images have been migrated!** + +As part of the image migration to Content Collections, all documentation-related images have been moved to `src/content/docs/img/`. This directory now only contains: + +- **home/** - Images used by the root README.md (project homepage) +- **docusaurus-social-card.jpg** - Social media preview image + +## Current Contents + +``` +public/img/ +├── home/ # Root README.md images +│ ├── 亮色主题主界面.png +│ ├── 暗色主题主界面.png +│ ├── 使用 AI 的效率提升报告.png +│ ├── 每日成就报告.png +│ └── 每日编写代码获得的成就.png +├── docusaurus-social-card.jpg # Social media preview +└── README.md # This file +``` + +## Image Management Policy + +### For Documentation Content + +**DO NOT** add new documentation images to this directory. + +Instead, use the new Content Collections image directory: + +``` +src/content/docs/img/ +├── quick-start/ # Quick start guide images +├── installation/ # Installation guide images +├── related-software-installation/ # Related software images +├── product-overview/ # Product overview images +└── shared/ # Shared documentation images +``` + +**Reference images in Markdown using relative paths:** + +```markdown + + + + + + + + +``` + +### For Static Site Assets + +This directory is appropriate for: + +- **Site-wide assets**: favicons, logos, social media images +- **Root README images**: images displayed on the project homepage +- **Public resources**: assets referenced from non-content pages + +Reference these using absolute paths: + +```markdown + +``` + +## Supported Formats + +Common image formats are supported: +- PNG (.png) +- JPEG (.jpg, .jpeg) +- GIF (.gif) +- SVG (.svg) +- WebP (.webp) + +## Best Practices + +1. **Optimize images** - Compress images before adding them +2. **Use descriptive names** - Name files clearly (e.g., `installation-screenshot.png`) +3. **Choose the right location** - Documentation images → `src/content/docs/img/`, site assets → `public/img/` + +## Migration Info + +This directory was cleaned up as part of the astro-image-migration proposal. See the migration scripts in `scripts/image-migration/` for details. + +--- + +**Last Updated**: 2025-02-17 +**Migration**: astro-image-migration diff --git a/public/img/docusaurus-social-card.jpg b/public/img/docusaurus-social-card.jpg new file mode 100644 index 0000000..e69de29 diff --git "a/public/img/home/\344\272\256\350\211\262\344\270\273\351\242\230\344\270\273\347\225\214\351\235\242.png" "b/public/img/home/\344\272\256\350\211\262\344\270\273\351\242\230\344\270\273\347\225\214\351\235\242.png" new file mode 100644 index 0000000..c0276d8 Binary files /dev/null and "b/public/img/home/\344\272\256\350\211\262\344\270\273\351\242\230\344\270\273\347\225\214\351\235\242.png" differ diff --git "a/public/img/home/\344\275\277\347\224\250 AI \347\232\204\346\225\210\347\216\207\346\217\220\345\215\207\346\212\245\345\221\212.png" "b/public/img/home/\344\275\277\347\224\250 AI \347\232\204\346\225\210\347\216\207\346\217\220\345\215\207\346\212\245\345\221\212.png" new file mode 100644 index 0000000..9a83d67 Binary files /dev/null and "b/public/img/home/\344\275\277\347\224\250 AI \347\232\204\346\225\210\347\216\207\346\217\220\345\215\207\346\212\245\345\221\212.png" differ diff --git "a/public/img/home/\345\256\236\346\227\266token\346\266\210\350\200\227\346\212\245\345\221\212.png" "b/public/img/home/\345\256\236\346\227\266token\346\266\210\350\200\227\346\212\245\345\221\212.png" new file mode 100644 index 0000000..2432503 Binary files /dev/null and "b/public/img/home/\345\256\236\346\227\266token\346\266\210\350\200\227\346\212\245\345\221\212.png" differ diff --git "a/public/img/home/\346\232\227\350\211\262\344\270\273\351\242\230\344\270\273\347\225\214\351\235\242.png" "b/public/img/home/\346\232\227\350\211\262\344\270\273\351\242\230\344\270\273\347\225\214\351\235\242.png" new file mode 100644 index 0000000..782ef36 Binary files /dev/null and "b/public/img/home/\346\232\227\350\211\262\344\270\273\351\242\230\344\270\273\347\225\214\351\235\242.png" differ diff --git "a/public/img/home/\346\257\217\346\227\245\346\210\220\345\260\261\346\212\245\345\221\212.png" "b/public/img/home/\346\257\217\346\227\245\346\210\220\345\260\261\346\212\245\345\221\212.png" new file mode 100644 index 0000000..473050e Binary files /dev/null and "b/public/img/home/\346\257\217\346\227\245\346\210\220\345\260\261\346\212\245\345\221\212.png" differ diff --git "a/public/img/home/\346\257\217\346\227\245\347\274\226\345\206\231\344\273\243\347\240\201\350\216\267\345\276\227\347\232\204\346\210\220\345\260\261.png" "b/public/img/home/\346\257\217\346\227\245\347\274\226\345\206\231\344\273\243\347\240\201\350\216\267\345\276\227\347\232\204\346\210\220\345\260\261.png" new file mode 100644 index 0000000..c2644a9 Binary files /dev/null and "b/public/img/home/\346\257\217\346\227\245\347\274\226\345\206\231\344\273\243\347\240\201\350\216\267\345\276\227\347\232\204\346\210\220\345\260\261.png" differ diff --git a/public/logo.png b/public/logo.png new file mode 100644 index 0000000..38a586b Binary files /dev/null and b/public/logo.png differ diff --git a/public/logo.svg b/public/logo.svg new file mode 100644 index 0000000..6c70e6b --- /dev/null +++ b/public/logo.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/staticwebapp.config.json b/public/staticwebapp.config.json new file mode 100644 index 0000000..b679371 --- /dev/null +++ b/public/staticwebapp.config.json @@ -0,0 +1,90 @@ +{ + "navigationFallback": { + "rewrite": "index.html" + }, + "globalOverrides": { + "headers": { + "cache-control": "public, max-age=0, must-revalidate" + } + }, + "overrides": [ + { + "route": "/_astro/*", + "headers": { + "cache-control": "public, max-age=31536000, immutable" + } + }, + { + "route": "/*.jpg", + "headers": { + "cache-control": "public, max-age=86400" + } + }, + { + "route": "/*.jpeg", + "headers": { + "cache-control": "public, max-age=86400" + } + }, + { + "route": "/*.png", + "headers": { + "cache-control": "public, max-age=86400" + } + }, + { + "route": "/*.gif", + "headers": { + "cache-control": "public, max-age=86400" + } + }, + { + "route": "/*.ico", + "headers": { + "cache-control": "public, max-age=86400" + } + }, + { + "route": "/*.svg", + "headers": { + "cache-control": "public, max-age=86400" + } + }, + { + "route": "/*.webp", + "headers": { + "cache-control": "public, max-age=86400" + } + }, + { + "route": "/*.woff", + "headers": { + "cache-control": "public, max-age=86400" + } + }, + { + "route": "/*.woff2", + "headers": { + "cache-control": "public, max-age=86400" + } + }, + { + "route": "/*.ttf", + "headers": { + "cache-control": "public, max-age=86400" + } + }, + { + "route": "/*.eot", + "headers": { + "cache-control": "public, max-age=86400" + } + }, + { + "route": "/*.otf", + "headers": { + "cache-control": "public, max-age=86400" + } + } + ] +} diff --git a/public/version-index.json b/public/version-index.json new file mode 100644 index 0000000..effaac8 --- /dev/null +++ b/public/version-index.json @@ -0,0 +1,863 @@ +{ + "updatedAt": "2026-02-16T10:11:22.0529559Z", + "versions": [ + { + "version": "v0.1.9", + "files": [ + { + "name": "Hagicode.Desktop-0.1.9-arm64-mac.zip", + "path": "v0.1.9/Hagicode.Desktop-0.1.9-arm64-mac.zip", + "size": 170041122, + "lastModified": "2026-02-14T01:28:29.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.9-arm64.dmg", + "path": "v0.1.9/Hagicode.Desktop-0.1.9-arm64.dmg", + "size": 177671092, + "lastModified": "2026-02-14T01:28:40.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.9-mac.zip", + "path": "v0.1.9/Hagicode.Desktop-0.1.9-mac.zip", + "size": 175490577, + "lastModified": "2026-02-14T01:28:50.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.9.AppImage", + "path": "v0.1.9/Hagicode.Desktop-0.1.9.AppImage", + "size": 183906385, + "lastModified": "2026-02-14T01:29:03.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.9.dmg", + "path": "v0.1.9/Hagicode.Desktop-0.1.9.dmg", + "size": 183158560, + "lastModified": "2026-02-14T01:29:15.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.9.appx", + "path": "v0.1.9/Hagicode.Desktop.0.1.9.appx", + "size": 211820379, + "lastModified": "2026-02-14T01:29:35.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.9.exe", + "path": "v0.1.9/Hagicode.Desktop.0.1.9.exe", + "size": 106955432, + "lastModified": "2026-02-14T01:29:42.0000000" + }, + { + "name": "Hagicode.Desktop.Setup.0.1.9.exe", + "path": "v0.1.9/Hagicode.Desktop.Setup.0.1.9.exe", + "size": 107154361, + "lastModified": "2026-02-14T01:29:51.0000000" + }, + { + "name": "hagicode-desktop-0.1.9.tar.gz", + "path": "v0.1.9/hagicode-desktop-0.1.9.tar.gz", + "size": 171850761, + "lastModified": "2026-02-14T01:30:08.0000000" + }, + { + "name": "hagicode-desktop_0.1.9_amd64.deb", + "path": "v0.1.9/hagicode-desktop_0.1.9_amd64.deb", + "size": 117423904, + "lastModified": "2026-02-14T01:30:17.0000000" + } + ] + }, + { + "version": "v0.1.8", + "files": [ + { + "name": "Hagicode.Desktop-0.1.8-arm64-mac.zip", + "path": "v0.1.8/Hagicode.Desktop-0.1.8-arm64-mac.zip", + "size": 170039416, + "lastModified": "2026-02-13T12:28:02.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.8-arm64.dmg", + "path": "v0.1.8/Hagicode.Desktop-0.1.8-arm64.dmg", + "size": 177668972, + "lastModified": "2026-02-13T12:28:17.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.8-mac.zip", + "path": "v0.1.8/Hagicode.Desktop-0.1.8-mac.zip", + "size": 175488879, + "lastModified": "2026-02-13T12:34:07.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.8.AppImage", + "path": "v0.1.8/Hagicode.Desktop-0.1.8.AppImage", + "size": 183902403, + "lastModified": "2026-02-13T12:35:21.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.8.dmg", + "path": "v0.1.8/Hagicode.Desktop-0.1.8.dmg", + "size": 183156977, + "lastModified": "2026-02-13T12:37:19.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.8.appx", + "path": "v0.1.8/Hagicode.Desktop.0.1.8.appx", + "size": 211820948, + "lastModified": "2026-02-13T12:38:22.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.8.exe", + "path": "v0.1.8/Hagicode.Desktop.0.1.8.exe", + "size": 106954896, + "lastModified": "2026-02-13T12:38:32.0000000" + }, + { + "name": "Hagicode.Desktop.Setup.0.1.8.exe", + "path": "v0.1.8/Hagicode.Desktop.Setup.0.1.8.exe", + "size": 107153833, + "lastModified": "2026-02-13T12:38:49.0000000" + }, + { + "name": "hagicode-desktop-0.1.8.tar.gz", + "path": "v0.1.8/hagicode-desktop-0.1.8.tar.gz", + "size": 171848729, + "lastModified": "2026-02-13T12:40:37.0000000" + }, + { + "name": "hagicode-desktop_0.1.8_amd64.deb", + "path": "v0.1.8/hagicode-desktop_0.1.8_amd64.deb", + "size": 117422480, + "lastModified": "2026-02-13T12:41:15.0000000" + } + ] + }, + { + "version": "v0.1.7", + "files": [ + { + "name": "Hagicode.Desktop-0.1.7-arm64-mac.zip", + "path": "v0.1.7/Hagicode.Desktop-0.1.7-arm64-mac.zip", + "size": 170037490, + "lastModified": "2026-02-11T09:48:02.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.7-arm64.dmg", + "path": "v0.1.7/Hagicode.Desktop-0.1.7-arm64.dmg", + "size": 177698646, + "lastModified": "2026-02-11T09:49:32.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.7-mac.zip", + "path": "v0.1.7/Hagicode.Desktop-0.1.7-mac.zip", + "size": 175486938, + "lastModified": "2026-02-11T09:49:50.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.7.AppImage", + "path": "v0.1.7/Hagicode.Desktop-0.1.7.AppImage", + "size": 183898559, + "lastModified": "2026-02-11T09:50:41.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.7.dmg", + "path": "v0.1.7/Hagicode.Desktop-0.1.7.dmg", + "size": 183166189, + "lastModified": "2026-02-11T09:50:58.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.7.appx", + "path": "v0.1.7/Hagicode.Desktop.0.1.7.appx", + "size": 211817212, + "lastModified": "2026-02-11T09:53:29.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.7.exe", + "path": "v0.1.7/Hagicode.Desktop.0.1.7.exe", + "size": 106955293, + "lastModified": "2026-02-11T09:53:40.0000000" + }, + { + "name": "Hagicode.Desktop.Setup.0.1.7.exe", + "path": "v0.1.7/Hagicode.Desktop.Setup.0.1.7.exe", + "size": 107154226, + "lastModified": "2026-02-11T09:53:51.0000000" + }, + { + "name": "hagicode-desktop-0.1.7.tar.gz", + "path": "v0.1.7/hagicode-desktop-0.1.7.tar.gz", + "size": 171847222, + "lastModified": "2026-02-11T09:55:09.0000000" + }, + { + "name": "hagicode-desktop_0.1.7_amd64.deb", + "path": "v0.1.7/hagicode-desktop_0.1.7_amd64.deb", + "size": 117484676, + "lastModified": "2026-02-11T09:55:21.0000000" + } + ] + }, + { + "version": "v0.1.6", + "files": [ + { + "name": "Hagicode.Desktop-0.1.6-arm64-mac.zip", + "path": "v0.1.6/Hagicode.Desktop-0.1.6-arm64-mac.zip", + "size": 170088015, + "lastModified": "2026-02-10T13:08:44.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.6-arm64.dmg", + "path": "v0.1.6/Hagicode.Desktop-0.1.6-arm64.dmg", + "size": 177753633, + "lastModified": "2026-02-10T13:09:08.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.6-mac.zip", + "path": "v0.1.6/Hagicode.Desktop-0.1.6-mac.zip", + "size": 175541033, + "lastModified": "2026-02-10T13:12:47.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.6.AppImage", + "path": "v0.1.6/Hagicode.Desktop-0.1.6.AppImage", + "size": 183935599, + "lastModified": "2026-02-10T13:15:59.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.6.dmg", + "path": "v0.1.6/Hagicode.Desktop-0.1.6.dmg", + "size": 183199829, + "lastModified": "2026-02-10T13:17:39.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.6.appx", + "path": "v0.1.6/Hagicode.Desktop.0.1.6.appx", + "size": 211871579, + "lastModified": "2026-02-10T13:19:03.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.6.exe", + "path": "v0.1.6/Hagicode.Desktop.0.1.6.exe", + "size": 106969879, + "lastModified": "2026-02-10T13:19:52.0000000" + }, + { + "name": "Hagicode.Desktop.Setup.0.1.6.exe", + "path": "v0.1.6/Hagicode.Desktop.Setup.0.1.6.exe", + "size": 107168817, + "lastModified": "2026-02-10T13:21:18.0000000" + }, + { + "name": "hagicode-desktop-0.1.6.tar.gz", + "path": "v0.1.6/hagicode-desktop-0.1.6.tar.gz", + "size": 171901250, + "lastModified": "2026-02-10T13:21:44.0000000" + }, + { + "name": "hagicode-desktop_0.1.6_amd64.deb", + "path": "v0.1.6/hagicode-desktop_0.1.6_amd64.deb", + "size": 117517600, + "lastModified": "2026-02-10T13:21:53.0000000" + } + ] + }, + { + "version": "v0.1.5", + "files": [ + { + "name": "Hagicode.Desktop-0.1.5-arm64-mac.zip", + "path": "v0.1.5/Hagicode.Desktop-0.1.5-arm64-mac.zip", + "size": 169573000, + "lastModified": "2026-02-10T01:55:51.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.5-arm64.dmg", + "path": "v0.1.5/Hagicode.Desktop-0.1.5-arm64.dmg", + "size": 177184332, + "lastModified": "2026-02-10T01:56:57.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.5-mac.zip", + "path": "v0.1.5/Hagicode.Desktop-0.1.5-mac.zip", + "size": 175026018, + "lastModified": "2026-02-10T01:59:07.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.5.AppImage", + "path": "v0.1.5/Hagicode.Desktop-0.1.5.AppImage", + "size": 183415071, + "lastModified": "2026-02-10T01:59:38.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.5.dmg", + "path": "v0.1.5/Hagicode.Desktop-0.1.5.dmg", + "size": 182674856, + "lastModified": "2026-02-10T02:00:04.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.5.appx", + "path": "v0.1.5/Hagicode.Desktop.0.1.5.appx", + "size": 211332709, + "lastModified": "2026-02-10T02:03:37.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.5.exe", + "path": "v0.1.5/Hagicode.Desktop.0.1.5.exe", + "size": 106650005, + "lastModified": "2026-02-10T02:05:00.0000000" + }, + { + "name": "Hagicode.Desktop.Setup.0.1.5.exe", + "path": "v0.1.5/Hagicode.Desktop.Setup.0.1.5.exe", + "size": 106848938, + "lastModified": "2026-02-10T02:06:14.0000000" + }, + { + "name": "hagicode-desktop-0.1.5.tar.gz", + "path": "v0.1.5/hagicode-desktop-0.1.5.tar.gz", + "size": 171384559, + "lastModified": "2026-02-10T02:07:46.0000000" + }, + { + "name": "hagicode-desktop_0.1.5_amd64.deb", + "path": "v0.1.5/hagicode-desktop_0.1.5_amd64.deb", + "size": 117147644, + "lastModified": "2026-02-10T02:08:28.0000000" + } + ] + }, + { + "version": "v0.1.4", + "files": [ + { + "name": "Hagicode.Desktop-0.1.4-arm64-mac.zip", + "path": "v0.1.4/Hagicode.Desktop-0.1.4-arm64-mac.zip", + "size": 169552579, + "lastModified": "2026-02-09T05:52:37.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.4-arm64.dmg", + "path": "v0.1.4/Hagicode.Desktop-0.1.4-arm64.dmg", + "size": 177172358, + "lastModified": "2026-02-09T05:53:11.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.4-mac.zip", + "path": "v0.1.4/Hagicode.Desktop-0.1.4-mac.zip", + "size": 175005602, + "lastModified": "2026-02-09T05:53:25.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.4.AppImage", + "path": "v0.1.4/Hagicode.Desktop-0.1.4.AppImage", + "size": 183392705, + "lastModified": "2026-02-09T05:53:48.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.4.dmg", + "path": "v0.1.4/Hagicode.Desktop-0.1.4.dmg", + "size": 182658262, + "lastModified": "2026-02-09T05:54:55.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.4.appx", + "path": "v0.1.4/Hagicode.Desktop.0.1.4.appx", + "size": 211316058, + "lastModified": "2026-02-09T05:55:53.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.4.exe", + "path": "v0.1.4/Hagicode.Desktop.0.1.4.exe", + "size": 106632810, + "lastModified": "2026-02-09T05:56:05.0000000" + }, + { + "name": "Hagicode.Desktop.Setup.0.1.4.exe", + "path": "v0.1.4/Hagicode.Desktop.Setup.0.1.4.exe", + "size": 106831741, + "lastModified": "2026-02-09T05:56:32.0000000" + }, + { + "name": "hagicode-desktop-0.1.4.tar.gz", + "path": "v0.1.4/hagicode-desktop-0.1.4.tar.gz", + "size": 171364758, + "lastModified": "2026-02-09T05:56:47.0000000" + }, + { + "name": "hagicode-desktop_0.1.4_amd64.deb", + "path": "v0.1.4/hagicode-desktop_0.1.4_amd64.deb", + "size": 117128468, + "lastModified": "2026-02-09T05:59:43.0000000" + } + ] + }, + { + "version": "v0.1.3", + "files": [ + { + "name": "Hagicode.Desktop-0.1.3-arm64-mac.zip", + "path": "v0.1.3/Hagicode.Desktop-0.1.3-arm64-mac.zip", + "size": 169552209, + "lastModified": "2026-02-09T02:10:30.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.3-arm64.dmg", + "path": "v0.1.3/Hagicode.Desktop-0.1.3-arm64.dmg", + "size": 177172483, + "lastModified": "2026-02-09T02:12:10.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.3-mac.zip", + "path": "v0.1.3/Hagicode.Desktop-0.1.3-mac.zip", + "size": 175005235, + "lastModified": "2026-02-09T02:14:09.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.3.AppImage", + "path": "v0.1.3/Hagicode.Desktop-0.1.3.AppImage", + "size": 183393029, + "lastModified": "2026-02-09T02:15:11.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.3.dmg", + "path": "v0.1.3/Hagicode.Desktop-0.1.3.dmg", + "size": 182658124, + "lastModified": "2026-02-09T02:16:30.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.3.appx", + "path": "v0.1.3/Hagicode.Desktop.0.1.3.appx", + "size": 211316260, + "lastModified": "2026-02-09T02:17:45.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.3.exe", + "path": "v0.1.3/Hagicode.Desktop.0.1.3.exe", + "size": 106634737, + "lastModified": "2026-02-09T02:17:57.0000000" + }, + { + "name": "Hagicode.Desktop.Setup.0.1.3.exe", + "path": "v0.1.3/Hagicode.Desktop.Setup.0.1.3.exe", + "size": 106833663, + "lastModified": "2026-02-09T02:18:51.0000000" + } + ] + }, + { + "version": "v0.1.2", + "files": [ + { + "name": "Hagicode.Desktop-0.1.2-arm64-mac.zip", + "path": "v0.1.2/Hagicode.Desktop-0.1.2-arm64-mac.zip", + "size": 162579879, + "lastModified": "2026-02-08T15:37:56.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.2-arm64.dmg", + "path": "v0.1.2/Hagicode.Desktop-0.1.2-arm64.dmg", + "size": 170120413, + "lastModified": "2026-02-08T15:38:12.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.2-mac.zip", + "path": "v0.1.2/Hagicode.Desktop-0.1.2-mac.zip", + "size": 168032899, + "lastModified": "2026-02-08T15:39:12.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.2.AppImage", + "path": "v0.1.2/Hagicode.Desktop-0.1.2.AppImage", + "size": 176343947, + "lastModified": "2026-02-08T15:39:51.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.2.dmg", + "path": "v0.1.2/Hagicode.Desktop-0.1.2.dmg", + "size": 175610708, + "lastModified": "2026-02-08T15:40:03.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.2.appx", + "path": "v0.1.2/Hagicode.Desktop.0.1.2.appx", + "size": 204239264, + "lastModified": "2026-02-08T15:41:18.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.2.exe", + "path": "v0.1.2/Hagicode.Desktop.0.1.2.exe", + "size": 104001212, + "lastModified": "2026-02-08T15:41:46.0000000" + }, + { + "name": "Hagicode.Desktop.Setup.0.1.2.exe", + "path": "v0.1.2/Hagicode.Desktop.Setup.0.1.2.exe", + "size": 104200135, + "lastModified": "2026-02-08T15:41:54.0000000" + }, + { + "name": "hagicode-desktop-0.1.2.tar.gz", + "path": "v0.1.2/hagicode-desktop-0.1.2.tar.gz", + "size": 164396699, + "lastModified": "2026-02-08T15:42:10.0000000" + }, + { + "name": "hagicode-desktop_0.1.2_amd64.deb", + "path": "v0.1.2/hagicode-desktop_0.1.2_amd64.deb", + "size": 114481460, + "lastModified": "2026-02-08T15:42:21.0000000" + } + ] + }, + { + "version": "v0.1.12", + "files": [ + { + "name": "Hagicode.Desktop-0.1.12-arm64-mac.zip", + "path": "v0.1.12/Hagicode.Desktop-0.1.12-arm64-mac.zip", + "size": 170349093, + "lastModified": "2026-02-16T10:09:04.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.12-arm64.dmg", + "path": "v0.1.12/Hagicode.Desktop-0.1.12-arm64.dmg", + "size": 178031336, + "lastModified": "2026-02-16T10:04:39.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.12-mac.zip", + "path": "v0.1.12/Hagicode.Desktop-0.1.12-mac.zip", + "size": 175794345, + "lastModified": "2026-02-16T10:10:12.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.12.AppImage", + "path": "v0.1.12/Hagicode.Desktop-0.1.12.AppImage", + "size": 184201931, + "lastModified": "2026-02-16T10:10:57.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.12.dmg", + "path": "v0.1.12/Hagicode.Desktop-0.1.12.dmg", + "size": 183473427, + "lastModified": "2026-02-16T10:08:14.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.12.appx", + "path": "v0.1.12/Hagicode.Desktop.0.1.12.appx", + "size": 212119074, + "lastModified": "2026-02-16T10:11:21.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.12.exe", + "path": "v0.1.12/Hagicode.Desktop.0.1.12.exe", + "size": 107055666, + "lastModified": "2026-02-16T10:08:26.0000000" + }, + { + "name": "Hagicode.Desktop.Setup.0.1.12.exe", + "path": "v0.1.12/Hagicode.Desktop.Setup.0.1.12.exe", + "size": 107254615, + "lastModified": "2026-02-16T10:08:36.0000000" + }, + { + "name": "hagicode-desktop-0.1.12.tar.gz", + "path": "v0.1.12/hagicode-desktop-0.1.12.tar.gz", + "size": 172153799, + "lastModified": "2026-02-16T10:06:13.0000000" + }, + { + "name": "hagicode-desktop_0.1.12_amd64.deb", + "path": "v0.1.12/hagicode-desktop_0.1.12_amd64.deb", + "size": 117568176, + "lastModified": "2026-02-16T10:03:08.0000000" + } + ] + }, + { + "version": "v0.1.11-beta.1", + "files": [ + { + "name": "Hagicode.Desktop-0.1.11-beta.1-arm64-mac.zip", + "path": "v0.1.11-beta.1/Hagicode.Desktop-0.1.11-beta.1-arm64-mac.zip", + "size": 170041893, + "lastModified": "2026-02-15T10:50:39.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.11-beta.1-arm64.dmg", + "path": "v0.1.11-beta.1/Hagicode.Desktop-0.1.11-beta.1-arm64.dmg", + "size": 177664522, + "lastModified": "2026-02-15T10:51:48.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.11-beta.1-mac.zip", + "path": "v0.1.11-beta.1/Hagicode.Desktop-0.1.11-beta.1-mac.zip", + "size": 175491348, + "lastModified": "2026-02-15T10:45:38.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.11-beta.1.AppImage", + "path": "v0.1.11-beta.1/Hagicode.Desktop-0.1.11-beta.1.AppImage", + "size": 183906552, + "lastModified": "2026-02-15T10:48:51.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.11-beta.1.dmg", + "path": "v0.1.11-beta.1/Hagicode.Desktop-0.1.11-beta.1.dmg", + "size": 183151530, + "lastModified": "2026-02-15T10:46:59.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.11-beta.1.appx", + "path": "v0.1.11-beta.1/Hagicode.Desktop.0.1.11-beta.1.appx", + "size": 211823280, + "lastModified": "2026-02-15T10:49:35.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.11-beta.1.exe", + "path": "v0.1.11-beta.1/Hagicode.Desktop.0.1.11-beta.1.exe", + "size": 106940638, + "lastModified": "2026-02-15T10:43:42.0000000" + }, + { + "name": "Hagicode.Desktop.Setup.0.1.11-beta.1.exe", + "path": "v0.1.11-beta.1/Hagicode.Desktop.Setup.0.1.11-beta.1.exe", + "size": 107139593, + "lastModified": "2026-02-15T10:49:00.0000000" + }, + { + "name": "hagicode-desktop-0.1.11-beta.1.tar.gz", + "path": "v0.1.11-beta.1/hagicode-desktop-0.1.11-beta.1.tar.gz", + "size": 171852599, + "lastModified": "2026-02-15T10:44:24.0000000" + }, + { + "name": "hagicode-desktop_0.1.11-beta.1_amd64.deb", + "path": "v0.1.11-beta.1/hagicode-desktop_0.1.11-beta.1_amd64.deb", + "size": 117424336, + "lastModified": "2026-02-15T10:51:06.0000000" + } + ] + }, + { + "version": "v0.1.11", + "files": [ + { + "name": "Hagicode.Desktop-0.1.11-arm64-mac.zip", + "path": "v0.1.11/Hagicode.Desktop-0.1.11-arm64-mac.zip", + "size": 170347208, + "lastModified": "2026-02-15T11:58:21.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.11-arm64.dmg", + "path": "v0.1.11/Hagicode.Desktop-0.1.11-arm64.dmg", + "size": 178032237, + "lastModified": "2026-02-15T11:55:36.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.11-mac.zip", + "path": "v0.1.11/Hagicode.Desktop-0.1.11-mac.zip", + "size": 175792449, + "lastModified": "2026-02-15T11:55:07.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.11.AppImage", + "path": "v0.1.11/Hagicode.Desktop-0.1.11.AppImage", + "size": 184193524, + "lastModified": "2026-02-15T11:55:52.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.11.dmg", + "path": "v0.1.11/Hagicode.Desktop-0.1.11.dmg", + "size": 183466887, + "lastModified": "2026-02-15T11:57:39.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.11.appx", + "path": "v0.1.11/Hagicode.Desktop.0.1.11.appx", + "size": 212112126, + "lastModified": "2026-02-15T11:54:25.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.11.exe", + "path": "v0.1.11/Hagicode.Desktop.0.1.11.exe", + "size": 107053093, + "lastModified": "2026-02-15T11:55:27.0000000" + }, + { + "name": "Hagicode.Desktop.Setup.0.1.11.exe", + "path": "v0.1.11/Hagicode.Desktop.Setup.0.1.11.exe", + "size": 107252032, + "lastModified": "2026-02-15T11:58:42.0000000" + }, + { + "name": "hagicode-desktop-0.1.11.tar.gz", + "path": "v0.1.11/hagicode-desktop-0.1.11.tar.gz", + "size": 172151821, + "lastModified": "2026-02-15T11:56:14.0000000" + }, + { + "name": "hagicode-desktop_0.1.11_amd64.deb", + "path": "v0.1.11/hagicode-desktop_0.1.11_amd64.deb", + "size": 117566700, + "lastModified": "2026-02-15T11:56:49.0000000" + } + ] + }, + { + "version": "v0.1.10", + "files": [ + { + "name": "Hagicode.Desktop-0.1.10-arm64-mac.zip", + "path": "v0.1.10/Hagicode.Desktop-0.1.10-arm64-mac.zip", + "size": 170041588, + "lastModified": "2026-02-14T09:11:50.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.10-arm64.dmg", + "path": "v0.1.10/Hagicode.Desktop-0.1.10-arm64.dmg", + "size": 177668393, + "lastModified": "2026-02-14T09:12:49.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.10-mac.zip", + "path": "v0.1.10/Hagicode.Desktop-0.1.10-mac.zip", + "size": 175491042, + "lastModified": "2026-02-14T09:13:27.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.10.AppImage", + "path": "v0.1.10/Hagicode.Desktop-0.1.10.AppImage", + "size": 183906373, + "lastModified": "2026-02-14T09:13:42.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.10.dmg", + "path": "v0.1.10/Hagicode.Desktop-0.1.10.dmg", + "size": 183154128, + "lastModified": "2026-02-14T09:14:02.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.10.appx", + "path": "v0.1.10/Hagicode.Desktop.0.1.10.appx", + "size": 211821981, + "lastModified": "2026-02-14T09:14:37.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.10.exe", + "path": "v0.1.10/Hagicode.Desktop.0.1.10.exe", + "size": 106956175, + "lastModified": "2026-02-14T09:14:48.0000000" + }, + { + "name": "Hagicode.Desktop.Setup.0.1.10.exe", + "path": "v0.1.10/Hagicode.Desktop.Setup.0.1.10.exe", + "size": 107155113, + "lastModified": "2026-02-14T09:14:57.0000000" + }, + { + "name": "hagicode-desktop-0.1.10.tar.gz", + "path": "v0.1.10/hagicode-desktop-0.1.10.tar.gz", + "size": 171851051, + "lastModified": "2026-02-14T09:15:56.0000000" + }, + { + "name": "hagicode-desktop_0.1.10_amd64.deb", + "path": "v0.1.10/hagicode-desktop_0.1.10_amd64.deb", + "size": 117424180, + "lastModified": "2026-02-14T09:16:11.0000000" + } + ] + }, + { + "version": "v0.1.1", + "files": [ + { + "name": "Hagicode.Desktop-0.1.1-arm64-mac.zip", + "path": "v0.1.1/Hagicode.Desktop-0.1.1-arm64-mac.zip", + "size": 162545310, + "lastModified": "2026-02-07T11:39:04.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.1-arm64.dmg", + "path": "v0.1.1/Hagicode.Desktop-0.1.1-arm64.dmg", + "size": 170092225, + "lastModified": "2026-02-07T11:40:53.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.1-mac.zip", + "path": "v0.1.1/Hagicode.Desktop-0.1.1-mac.zip", + "size": 167998328, + "lastModified": "2026-02-07T11:43:45.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.1.AppImage", + "path": "v0.1.1/Hagicode.Desktop-0.1.1.AppImage", + "size": 176282807, + "lastModified": "2026-02-07T11:44:01.0000000" + }, + { + "name": "Hagicode.Desktop-0.1.1.dmg", + "path": "v0.1.1/Hagicode.Desktop-0.1.1.dmg", + "size": 175587483, + "lastModified": "2026-02-07T11:47:29.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.1.appx", + "path": "v0.1.1/Hagicode.Desktop.0.1.1.appx", + "size": 204191260, + "lastModified": "2026-02-07T11:48:27.0000000" + }, + { + "name": "Hagicode.Desktop.0.1.1.exe", + "path": "v0.1.1/Hagicode.Desktop.0.1.1.exe", + "size": 103976995, + "lastModified": "2026-02-07T11:48:37.0000000" + }, + { + "name": "Hagicode.Desktop.Setup.0.1.1.exe", + "path": "v0.1.1/Hagicode.Desktop.Setup.0.1.1.exe", + "size": 104175915, + "lastModified": "2026-02-07T11:49:23.0000000" + }, + { + "name": "hagicode-desktop-0.1.1.tar.gz", + "path": "v0.1.1/hagicode-desktop-0.1.1.tar.gz", + "size": 164362850, + "lastModified": "2026-02-07T11:49:39.0000000" + }, + { + "name": "hagicode-desktop_0.1.1_amd64.deb", + "path": "v0.1.1/hagicode-desktop_0.1.1_amd64.deb", + "size": 114449768, + "lastModified": "2026-02-07T11:49:52.0000000" + } + ] + } + ], + "channels": { + "stable": { + "latest": "v0.1.12", + "versions": [ + "v0.1.9", + "v0.1.8", + "v0.1.7", + "v0.1.6", + "v0.1.5", + "v0.1.4", + "v0.1.3", + "v0.1.2", + "v0.1.12", + "v0.1.11", + "v0.1.10", + "v0.1.1" + ] + }, + "beta": { + "latest": "v0.1.11-beta.1", + "versions": [ + "v0.1.11-beta.1" + ] + } + } +} \ No newline at end of file diff --git a/redirects.json b/redirects.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/redirects.json @@ -0,0 +1 @@ +{} diff --git a/scripts/version-monitor.js b/scripts/version-monitor.js new file mode 100644 index 0000000..1f97945 --- /dev/null +++ b/scripts/version-monitor.js @@ -0,0 +1,458 @@ +#!/usr/bin/env node + +/** + * Version Monitor Script for Docs Repository + * + * This script monitors the version from the official website URL and updates + * the local version index file for the documentation site. + * Pull Request creation is handled by the workflow. + * + * Multi-Channel Support: + * - Supports channels field (stable/beta) in version data + * - Prioritizes stable channel by default + * - Can be configured to monitor beta channel via PREFERRED_CHANNEL env var + * - Automatically detects version channel from version string (beta/alpha/rc indicators) + * + * Updates the following file: + * - public/version-index.json + * + * Environment Variables: + * - VERSION_SOURCE_URL: URL to fetch version data (default: https://desktop.dl.hagicode.com/index.json) + * - REQUEST_TIMEOUT: HTTP request timeout in milliseconds (default: 30000) + * - MAX_RETRIES: Maximum number of retry attempts (default: 3) + * - PREFERRED_CHANNEL: Preferred channel to monitor ('stable' or 'beta', default: 'stable') + * + * GitHub Outputs: + * - update_needed: Set to 'true' when version changes + * - new_version: The new version string + * - version_channel: The channel of the new version ('stable' or 'beta') + * - version_source: The source of the version data (e.g., 'channels.stable.latest') + */ + +import { promises as fs } from 'fs'; + +// Logger with levels +const logger = { + debug: (msg) => console.log(`[DEBUG] ${msg}`), + info: (msg) => console.log(`[INFO] ${msg}`), + warn: (msg) => console.log(`[WARN] ${msg}`), + error: (msg) => console.log(`[ERROR] ${msg}`) +}; + +// Configuration from environment variables +const config = { + sourceUrl: process.env.VERSION_SOURCE_URL || 'https://desktop.dl.hagicode.com/index.json', + timeout: parseInt(process.env.REQUEST_TIMEOUT || '30000', 10), + maxRetries: parseInt(process.env.MAX_RETRIES || '3', 10), + retryDelay: 1000 // Base retry delay in milliseconds +}; + +// Local version data file path +const VERSION_INDEX_FILE = 'public/version-index.json'; + +/** + * Sleep utility for retry delays + */ +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +/** + * Fetch with retry mechanism using exponential backoff + */ +async function fetchWithRetry(url, options = {}, maxRetries = config.maxRetries) { + const { timeout = config.timeout, ...fetchOptions } = options; + + for (let i = 0; i < maxRetries; i++) { + try { + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), timeout); + + const response = await fetch(url, { + ...fetchOptions, + signal: controller.signal + }); + + clearTimeout(timeoutId); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); + } + + return response; + } catch (error) { + if (error.name === 'AbortError') { + logger.warn(`Request timeout (${timeout}ms), attempt ${i + 1}/${maxRetries}`); + } else { + logger.warn(`Request failed: ${error.message}, attempt ${i + 1}/${maxRetries}`); + } + + if (i === maxRetries - 1) { + throw error; + } + + const waitTime = Math.pow(2, i) * config.retryDelay; + logger.debug(`Waiting ${waitTime}ms before retry...`); + await sleep(waitTime); + } + } +} + +/** + * Fetch current version from the official website URL + */ +async function fetchCurrentVersion(url, preferredChannel = 'stable') { + const targetUrl = url || config.sourceUrl; + logger.info(`Fetching version from: ${targetUrl} (preferred channel: ${preferredChannel})`); + + try { + const response = await fetchWithRetry(targetUrl, { + headers: { + 'User-Agent': 'Version-Monitor/1.0' + } + }); + + const data = await response.json(); + + if (!data || typeof data !== 'object') { + throw new Error('Invalid response: not an object'); + } + + let versionInfo; + + if (data.version) { + const isBeta = data.version.includes('beta') || data.version.includes('alpha') || data.version.includes('rc'); + versionInfo = { + version: data.version, + channel: isBeta ? 'beta' : 'stable', + source: 'direct version field' + }; + } else { + versionInfo = extractVersionFromData(data, preferredChannel); + } + + if (!versionInfo.version) { + throw new Error('No version found in response data'); + } + + logger.info(`Current version from source: ${versionInfo.version} (channel: ${versionInfo.channel}, source: ${versionInfo.source})`); + return { ...versionInfo, raw: data }; + } catch (error) { + logger.error(`Failed to fetch version data: ${error.message}`); + throw error; + } +} + +/** + * Extract version from various data structures + */ +function extractVersionFromData(data, preferredChannel = 'stable') { + // Common patterns for version data (legacy support) + if (data.latestVersion) return { version: data.latestVersion, channel: 'stable', source: 'latestVersion' }; + if (data.currentVersion) return { version: data.currentVersion, channel: 'stable', source: 'currentVersion' }; + if (data.release && data.release.version) return { version: data.release.version, channel: 'stable', source: 'release.version' }; + + // Check for channels field (new multi-channel format) + if (data.channels) { + logger.info(`Found channels field in data`); + + if (data.channels[preferredChannel] && data.channels[preferredChannel].latest) { + const version = data.channels[preferredChannel].latest; + logger.info(`Using ${preferredChannel} channel latest: ${version}`); + return { version, channel: preferredChannel, source: `channels.${preferredChannel}.latest` }; + } + + if (preferredChannel !== 'stable' && data.channels.stable && data.channels.stable.latest) { + const version = data.channels.stable.latest; + logger.info(`Preferred channel not available, using stable channel: ${version}`); + return { version, channel: 'stable', source: 'channels.stable.latest (fallback)' }; + } + + if (data.channels.beta && data.channels.beta.latest) { + const version = data.channels.beta.latest; + logger.info(`Only beta channel available: ${version}`); + return { version, channel: 'beta', source: 'channels.beta.latest (fallback)' }; + } + } + + // For versions array, find the latest version + if (Array.isArray(data.versions) && data.versions.length > 0) { + logger.info(`Found ${data.versions.length} versions in array`); + + let latestVersion = data.versions[0]; + let latestVersionObj = data.versions[0]; + + for (const versionObj of data.versions) { + const v1 = versionObj.version || versionObj; + const v2 = latestVersionObj.version || latestVersionObj; + + const comparison = compareVersions(v1, v2); + + if (comparison === 1) { + latestVersion = v1; + latestVersionObj = versionObj; + } + } + + const isBeta = latestVersion.includes('beta') || latestVersion.includes('alpha') || latestVersion.includes('rc'); + + logger.info(`Latest version from array: ${latestVersion} (${isBeta ? 'beta' : 'stable'})`); + return { version: latestVersion, channel: isBeta ? 'beta' : 'stable', source: 'versions array (auto-detected)' }; + } + + logger.warn('No version found in data'); + return { version: null, channel: null, source: null }; +} + +/** + * Load local version from version-index.json + */ +async function loadLocalVersion() { + try { + const content = await fs.readFile(VERSION_INDEX_FILE, 'utf-8'); + const data = JSON.parse(content); + + // Check for channels field first (new format) + if (data.channels && data.channels.stable && data.channels.stable.latest) { + logger.info('Found channels field in local file'); + const version = data.channels.stable.latest; + logger.info(`Local version (from stable channel): ${version}`); + return { version, channel: 'stable', source: 'local channels.stable.latest' }; + } + + if (Array.isArray(data.versions) && data.versions.length > 0) { + if (data.versions.length === 1) { + const localVersion = data.versions[0].version; + logger.info(`Local version (only one): ${localVersion}`); + return { version: localVersion, channel: 'stable', source: 'local single version' }; + } + + logger.info(`Found ${data.versions.length} versions in local file`); + + let latestVersion = data.versions[0].version; + let latestVersionObj = data.versions[0]; + + for (const versionObj of data.versions) { + const v1 = versionObj.version; + const v2 = latestVersionObj.version; + + const comparison = compareVersions(v1, v2); + + if (comparison === 1) { + latestVersion = v1; + latestVersionObj = versionObj; + } + } + + const isBeta = latestVersion.includes('beta') || latestVersion.includes('alpha') || latestVersion.includes('rc'); + + logger.info(`Latest version from local file: ${latestVersion} (${isBeta ? 'beta' : 'stable'})`); + return { version: latestVersion, channel: isBeta ? 'beta' : 'stable', source: 'local versions array' }; + } + + logger.warn('Local version file exists but contains no versions'); + return null; + } catch (error) { + if (error.code === 'ENOENT') { + logger.info('Local version file not found, treating as empty state'); + return null; + } + logger.error(`Failed to load local version: ${error.message}`); + return null; + } +} + +/** + * Update local version index file + */ +async function updateLocalVersionIndex(versionData) { + const content = JSON.stringify(versionData, null, 2); + + try { + // Ensure directory exists + const dirPath = 'public'; + await fs.mkdir(dirPath, { recursive: true }); + + // Write file + await fs.writeFile(VERSION_INDEX_FILE, content, 'utf-8'); + logger.info(`Version index updated: ${VERSION_INDEX_FILE}`); + } catch (error) { + logger.error(`Failed to update version index file: ${error.message}`); + throw error; + } +} + +/** + * Parse a semver version string + */ +function parseSemver(version) { + const v = version.replace(/^v/, ''); + const versionParts = v.split('-'); + const versionNumbers = versionParts[0].split('.'); + + const major = parseInt(versionNumbers[0], 10) || 0; + const minor = parseInt(versionNumbers[1] || '0', 10) || 0; + const patch = parseInt(versionNumbers[2] || '0', 10) || 0; + + let prerelease = []; + if (versionParts.length > 1) { + prerelease = versionParts.slice(1).join('-').split('.').map(id => { + const num = parseInt(id, 10); + return isNaN(num) ? id : num; + }); + } + + return { major, minor, patch, prerelease }; +} + +/** + * Pre-release identifier priority + */ +const PRERELEASE_PRIORITY = { + 'alpha': 1, + 'beta': 2, + 'preview': 3, + 'rc': 4, + 'pre': 1 +}; + +/** + * Compare two pre-release identifier arrays + */ +function comparePrerelease(a, b) { + if (a.length === 0 && b.length === 0) return 0; + if (a.length === 0) return 1; + if (b.length === 0) return -1; + + const maxLength = Math.max(a.length, b.length); + for (let i = 0; i < maxLength; i++) { + const idA = a[i] === undefined ? null : a[i]; + const idB = b[i] === undefined ? null : b[i]; + + if (idA === null && idB === null) return 0; + if (idA === null) return -1; + if (idB === null) return 1; + + if (typeof idA === 'number' && typeof idB === 'number') { + if (idA < idB) return -1; + if (idA > idB) return 1; + } else if (typeof idA === 'string' && typeof idB === 'string') { + const priorityA = PRERELEASE_PRIORITY[idA] ?? 999; + const priorityB = PRERELEASE_PRIORITY[idB] ?? 999; + + if (priorityA !== 999 && priorityB !== 999) { + if (priorityA < priorityB) return -1; + if (priorityA > priorityB) return 1; + } else if (priorityA !== 999) { + return -1; + } else if (priorityB !== 999) { + return 1; + } else { + const cmp = idA.localeCompare(idB); + if (cmp !== 0) return cmp < 0 ? -1 : 1; + } + } else if (typeof idA === 'number') { + return -1; + } else { + return 1; + } + } + + return 0; +} + +/** + * Compare two version strings + */ +function compareVersions(v1, v2) { + const semver1 = parseSemver(v1); + const semver2 = parseSemver(v2); + + if (semver1.major !== semver2.major) { + return semver1.major < semver2.major ? -1 : 1; + } + if (semver1.minor !== semver2.minor) { + return semver1.minor < semver2.minor ? -1 : 1; + } + if (semver1.patch !== semver2.patch) { + return semver1.patch < semver2.patch ? -1 : 1; + } + + return comparePrerelease(semver1.prerelease, semver2.prerelease); +} + +/** + * Main execution function + */ +async function main() { + try { + logger.info('Starting version monitor...'); + logger.debug(`Configuration: ${JSON.stringify({ + sourceUrl: config.sourceUrl, + timeout: config.timeout, + maxRetries: config.maxRetries + })}`); + + const preferredChannel = process.env.PREFERRED_CHANNEL || 'stable'; + logger.info(`Preferred channel: ${preferredChannel}`); + + const { version: currentVersion, channel: currentChannel, source: currentSource, raw: versionData } = await fetchCurrentVersion(null, preferredChannel); + + const localInfo = await loadLocalVersion(); + const localVersion = localInfo?.version; + const localChannel = localInfo?.channel; + + const hasEmptyState = !localVersion; + + if (!hasEmptyState) { + logger.info('='.repeat(60)); + logger.info('VERSION COMPARISON START'); + logger.info('='.repeat(60)); + logger.info(`Local version: "${localVersion}" (channel: ${localChannel || 'unknown'}, source: ${localInfo?.source || 'unknown'})`); + logger.info(`Current version: "${currentVersion}" (channel: ${currentChannel}, source: ${currentSource})`); + logger.info('-'.repeat(60)); + + const versionComparison = compareVersions(currentVersion, localVersion); + + logger.info('-'.repeat(60)); + if (versionComparison === 0) { + logger.info('✅ Version unchanged - no update needed'); + logger.info('='.repeat(60)); + return; + } + + const comparisonSymbol = versionComparison === -1 ? '<' : '>'; + logger.info(`📊 Version comparison result: "${currentVersion}" ${comparisonSymbol} "${localVersion}"`); + logger.info(`🔄 Version changed: ${localVersion} -> ${currentVersion}`); + logger.info(`📡 Channel info: ${localChannel || 'unknown'} -> ${currentChannel}`); + logger.info('='.repeat(60)); + } else { + logger.info('Empty state detected - treating as new version scenario'); + logger.info(`📡 Current channel: ${currentChannel}`); + } + + await updateLocalVersionIndex(versionData); + + if (process.env.GITHUB_OUTPUT) { + const outputs = [ + `update_needed=true`, + `new_version=${currentVersion}`, + `version_channel=${currentChannel}`, + `version_source=${currentSource}` + ]; + await fs.appendFile(process.env.GITHUB_OUTPUT, outputs.join('\n') + '\n'); + logger.info(`Set outputs: update_needed=true, new_version=${currentVersion}, version_channel=${currentChannel}, version_source=${currentSource}`); + } + + logger.info('Version monitor completed successfully - version index updated'); + + } catch (error) { + logger.error(`Version monitor failed: ${error.message}`); + throw error; + } +} + +main().catch(error => { + logger.error(`Fatal error: ${error.message}`); + process.exit(1); +}); diff --git a/shared/package.json b/shared/package.json new file mode 100644 index 0000000..1bc5d89 --- /dev/null +++ b/shared/package.json @@ -0,0 +1,11 @@ +{ + "name": "shared", + "version": "0.0.1", + "private": true, + "type": "module", + "main": "./src/index.ts", + "types": "./src/index.ts", + "exports": { + ".": "./src/index.ts" + } +} diff --git a/shared/src/desktop-context.tsx b/shared/src/desktop-context.tsx new file mode 100644 index 0000000..20c1845 --- /dev/null +++ b/shared/src/desktop-context.tsx @@ -0,0 +1,224 @@ +/** + * Desktop 版本数据的 React Context + * + * 提供 React Context 和 Hook 用于在组件树中共享版本数据 + * 这是可选的功能,用于需要 React 状态管理的场景 + */ + +import React, { createContext, useContext, useEffect, useState } from 'react'; +import type { + DesktopVersion, + PlatformGroup, + DesktopIndexResponse, +} from './types/desktop'; +import type { DesktopVersionData } from './version-manager'; +import { + setDesktopServerData, + getDesktopVersionData, + isDesktopVersionInitialized, +} from './version-manager'; + +/** + * Context 数据接口 + */ +interface DesktopVersionContextValue { + /** 最新版本 */ + latest: DesktopVersion | null; + /** 平台分组 */ + platforms: PlatformGroup[]; + /** 错误信息 */ + error: string | null; + /** 是否正在加载 */ + loading: boolean; + /** 稳定版数据 */ + stable: { + latest: DesktopVersion | null; + all: DesktopVersion[]; + }; + /** 测试版数据 */ + beta: { + latest: DesktopVersion | null; + all: DesktopVersion[]; + }; +} + +/** + * Context 默认值 + */ +const defaultValue: DesktopVersionContextValue = { + latest: null, + platforms: [], + error: null, + loading: true, + stable: { latest: null, all: [] }, + beta: { latest: null, all: [] }, +}; + +/** + * Desktop 版本 Context + */ +export const DesktopVersionContext = createContext( + defaultValue +); + +/** + * Provider Props + */ +export interface DesktopVersionProviderProps { + /** 子组件 */ + children: React.ReactNode; + /** 渠道选择(可选) */ + channel?: 'stable' | 'beta'; + /** 服务端数据(用于 SSR) */ + serverData?: DesktopIndexResponse; +} + +/** + * Desktop 版本数据 Provider + * + * 使用示例: + * ```tsx + * // 客户端模式 + * + * + * + * + * // 服务端模式 + * + * + * + * + * // 指定渠道 + * + * + * + * ``` + */ +export const DesktopVersionProvider: React.FC = ({ + children, + channel, + serverData, +}) => { + const [data, setData] = useState(defaultValue); + + useEffect(() => { + let isMounted = true; + + const loadData = async () => { + // 如果有服务端数据,先注入 + if (serverData) { + setDesktopServerData(serverData); + } + + try { + const versionData = await getDesktopVersionData(); + + if (!isMounted) return; + + setData({ + latest: versionData.latest, + platforms: versionData.platforms, + error: versionData.error, + loading: false, + stable: { + latest: versionData.channels.stable.latest, + all: versionData.channels.stable.all, + }, + beta: { + latest: versionData.channels.beta.latest, + all: versionData.channels.beta.all, + }, + }); + } catch (error) { + if (!isMounted) return; + + setData({ + latest: null, + platforms: [], + error: error instanceof Error ? error.message : 'Unknown error', + loading: false, + stable: { latest: null, all: [] }, + beta: { latest: null, all: [] }, + }); + } + }; + + // 如果已经初始化且有服务端数据,直接使用 + if (isDesktopVersionInitialized() && !serverData) { + getDesktopVersionData().then((versionData) => { + if (isMounted) { + setData({ + latest: versionData.latest, + platforms: versionData.platforms, + error: versionData.error, + loading: false, + stable: { + latest: versionData.channels.stable.latest, + all: versionData.channels.stable.all, + }, + beta: { + latest: versionData.channels.beta.latest, + all: versionData.channels.beta.all, + }, + }); + } + }); + } else { + loadData(); + } + + return () => { + isMounted = false; + }; + }, [serverData]); + + const contextValue: DesktopVersionContextValue = { + ...data, + // 如果指定了渠道,优先返回该渠道的数据 + ...(channel && { + latest: data[channel].latest || data.latest, + platforms: data.platforms, + }), + }; + + return ( + + {children} + + ); +}; + +/** + * 使用 Desktop 版本数据的 Hook + * + * 使用示例: + * ```tsx + * function MyComponent() { + * const { latest, platforms, loading, error } = useDesktopVersion(); + * + * if (loading) return Loading...; + * if (error) return Error: {error}; + * + * return ( + * + * Latest: {latest?.version} + * {platforms.map(p => ( + * {p.platform} + * ))} + * + * ); + * } + * ``` + */ +export const useDesktopVersion = (): DesktopVersionContextValue => { + const context = useContext(DesktopVersionContext); + + if (context === defaultValue) { + console.warn( + 'useDesktopVersion used outside of DesktopVersionProvider, ' + + 'data will be fetched but not shared across components' + ); + } + + return context; +}; diff --git a/shared/src/desktop-utils.ts b/shared/src/desktop-utils.ts new file mode 100644 index 0000000..59a2def --- /dev/null +++ b/shared/src/desktop-utils.ts @@ -0,0 +1,456 @@ +/** + * Hagicode Desktop 工具函数 + * 用于获取和处理版本数据 + */ + +import type { + DesktopAsset, + DesktopIndexResponse, + PlatformDownload, + PlatformGroup, + DesktopVersion, +} from './types/desktop'; +import { AssetType } from './types/desktop'; +import semver from 'semver'; + +const INDEX_JSON_URL = "https://desktop.dl.hagicode.com/index.json"; +const LOCAL_VERSION_INDEX = "/version-index.json"; +const DOWNLOAD_BASE_URL = "https://desktop.dl.hagicode.com/"; +const TIMEOUT_MS = 30000; + +/** + * 平台推荐配置 + */ +export const PLATFORM_RECOMMENDATIONS: Record< + "windows" | "macos" | "linux", + { recommendedType: AssetType; label: string; icon: string } +> = { + windows: { + recommendedType: AssetType.WindowsSetup, + label: "Windows", + icon: "seti:windows", + }, + macos: { + recommendedType: AssetType.MacOSApple, + label: "macOS", + icon: "seti:apple", + }, + linux: { + recommendedType: AssetType.LinuxAppImage, + label: "Linux", + icon: "seti:linux", + }, +}; + +/** + * 比较两个版本字符串 + * @param v1 - 第一个版本 + * @param v2 - 第二个版本 + * @returns -1 如果 v1 < v2, 0 如果 v1 = v2, 1 如果 v1 > v2 + */ +function compareVersions(v1: string, v2: string): number { + const cleaned1 = v1.replace(/^v/, ''); + const cleaned2 = v2.replace(/^v/, ''); + + const cmp = semver.compare(cleaned1, cleaned2); + // semver.compare 返回:负数如果 a < b, 0 如果相等, 正数如果 a > b + if (cmp < 0) return -1; + if (cmp > 0) return 1; + return 0; +} + +/** + * 从文件名推断资源类型 + * @param filename - 文件名 + * @returns 资源类型枚举值 + */ +export function inferAssetType(filename: string): AssetType { + const name = filename.toLowerCase(); + + // Windows + if (name.includes("setup") && name.endsWith(".exe")) { + return AssetType.WindowsSetup; + } + if (name.endsWith(".exe")) { + return AssetType.WindowsPortable; + } + if (name.endsWith(".appx")) { + return AssetType.WindowsStore; + } + + // macOS + if (name.includes("arm64") && name.endsWith(".dmg")) { + return AssetType.MacOSApple; + } + if (name.includes("arm64-mac.zip")) { + return AssetType.MacOSApple; + } + if (name.endsWith(".dmg")) { + return AssetType.MacOSIntel; + } + if (name.includes("-mac.zip")) { + return AssetType.MacOSIntel; + } + + // Linux + if (name.endsWith(".appimage")) { + return AssetType.LinuxAppImage; + } + if (name.includes("_amd64.deb")) { + return AssetType.LinuxDeb; + } + if (name.includes(".tar.gz")) { + return AssetType.LinuxTarball; + } + + return AssetType.Unknown; +} + +/** + * 格式化文件大小 + * @param bytes - 文件大小(字节) + * @returns 格式化后的文件大小字符串 + */ +export function formatFileSize(bytes: number): string { + const gb = bytes / (1024 * 1024 * 1024); + if (gb >= 1) { + return `${gb.toFixed(1)} GB`; + } + const mb = bytes / (1024 * 1024); + return `${mb.toFixed(0)} MB`; +} + +/** + * 平台图标常量(用于 UI 显示) + */ +export const PLATFORM_ICONS: Record = { + macos: '🍎', + windows: '🪟', + linux: '🐧', +}; + +/** + * 获取资源类型的架构标签 + * @param assetType - 资源类型枚举值 + * @returns 架构标签(如 ARM64、x64) + */ +export function getArchitectureLabel(assetType: AssetType): string { + const archLabels: Record = { + [AssetType.MacOSApple]: 'ARM64', + [AssetType.MacOSIntel]: 'x64', + [AssetType.WindowsSetup]: 'x64', + [AssetType.WindowsPortable]: 'x64', + [AssetType.WindowsStore]: '', + [AssetType.LinuxAppImage]: '通用', + [AssetType.LinuxDeb]: 'amd64', + [AssetType.LinuxTarball]: '通用', + [AssetType.Source]: '', + [AssetType.Unknown]: '', + }; + return archLabels[assetType] || ''; +} + +/** + * 获取资源类型的文件扩展名 + * @param assetType - 资源类型枚举值 + * @returns 文件扩展名(包含点号,如 .exe、.dmg) + */ +export function getFileExtension(assetType: AssetType): string { + const extensions: Record = { + [AssetType.WindowsSetup]: '.exe', + [AssetType.WindowsPortable]: '.exe', + [AssetType.WindowsStore]: '.appx', + [AssetType.MacOSApple]: '.dmg', + [AssetType.MacOSIntel]: '.dmg', + [AssetType.LinuxAppImage]: '.AppImage', + [AssetType.LinuxDeb]: '.deb', + [AssetType.LinuxTarball]: '.tar.gz', + [AssetType.Source]: '.zip', + [AssetType.Unknown]: '', + }; + return extensions[assetType] || ''; +} + +/** + * 获取资源类型的显示名称 + * @param assetType - 资源类型枚举值 + * @returns 显示名称 + */ +export function getAssetTypeLabel(assetType: AssetType): string { + const labels: Record = { + [AssetType.WindowsSetup]: "安装程序", + [AssetType.WindowsPortable]: "便携版", + [AssetType.WindowsStore]: "Microsoft Store", + [AssetType.MacOSApple]: "Apple Silicon", + [AssetType.MacOSIntel]: "Intel 版", + [AssetType.LinuxAppImage]: "AppImage", + [AssetType.LinuxDeb]: "Debian 包", + [AssetType.LinuxTarball]: "压缩包", + [AssetType.Source]: "源代码", + [AssetType.Unknown]: "其他", + }; + return labels[assetType] || "未知"; +} + +/** + * 获取版本数据 + * 优先使用本地文件,确保构建过程不依赖外部服务 + * 返回的版本数组已按版本号从高到低排序 + * @returns 版本数据响应 + * @throws 当请求失败或超时时抛出错误,或在非浏览器环境调用时抛出错误 + */ +export async function fetchDesktopVersions(): Promise { + // 检查是否在浏览器环境中 + const isBrowser = typeof window !== 'undefined' && typeof fetch !== 'undefined'; + + if (!isBrowser) { + // 在 SSR/构建环境中,抛出错误而不是返回空数据 + // 这样可以避免水合不匹配的问题 + throw new Error("fetchDesktopVersions cannot be called in SSR environment"); + } + + // Try to load from local file first + try { + const response = await fetch(LOCAL_VERSION_INDEX); + if (response.ok) { + const data: DesktopIndexResponse = await response.json(); + + // 验证数据结构 + if (!Array.isArray(data.versions)) { + throw new Error("Invalid data structure: missing versions array"); + } + + // 按版本号排序(从高到低) + data.versions.sort((a, b) => compareVersions(b.version, a.version)); + + return data; + } + } catch (error) { + // Local file not available, fall back to online API + console.warn("Local version index not available, falling back to online API"); + } + + // Fallback to online API + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS); + + try { + const response = await fetch(INDEX_JSON_URL, { + signal: controller.signal, + }); + clearTimeout(timeoutId); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); + } + + const data: DesktopIndexResponse = await response.json(); + + // 验证数据结构 + if (!Array.isArray(data.versions)) { + throw new Error("Invalid data structure: missing versions array"); + } + + // 按版本号排序(从高到低) + data.versions.sort((a, b) => compareVersions(b.version, a.version)); + + return data; + } catch (error) { + if (error instanceof Error && error.name === "AbortError") { + throw new Error("Request timeout: failed to fetch version data"); + } + throw error; + } +} + +/** + * 获取指定渠道的最新版本 + * @param channel - 渠道名称 ('stable' | 'beta') + * @returns 该渠道的最新 DesktopVersion 对象 + * @throws 当渠道数据不存在或版本未找到时抛出错误 + */ +export async function getChannelLatestVersion( + channel: 'stable' | 'beta' +): Promise { + const data = await fetchDesktopVersions(); + + // 检查 channels 字段是否存在 + if (!data.channels || !data.channels[channel]) { + throw new Error(`Channel '${channel}' not available in version data`); + } + + const channelInfo = data.channels[channel]; + const latestVersion = channelInfo.latest; + + // 在 versions 数组中查找对应的版本对象 + const latestVersionObj = data.versions.find(v => v.version === latestVersion); + + if (!latestVersionObj) { + throw new Error(`Version '${latestVersion}' not found in versions array for channel '${channel}'`); + } + + return latestVersionObj; +} + +/** + * 获取指定渠道的所有版本 + * @param channel - 渠道名称 ('stable' | 'beta') + * @returns 该渠道的 DesktopVersion 对象数组 + * @throws 当渠道数据不存在时抛出错误 + */ +export async function getAllChannelVersions( + channel: 'stable' | 'beta' +): Promise { + const data = await fetchDesktopVersions(); + + // 检查 channels 字段是否存在 + if (!data.channels || !data.channels[channel]) { + throw new Error(`Channel '${channel}' not available in version data`); + } + + const channelInfo = data.channels[channel]; + const channelVersions = channelInfo.versions; + + // 在 versions 数组中查找对应的版本对象 + const versionObjects = data.versions.filter(v => + channelVersions.includes(v.version) + ); + + // 按版本号排序(从高到低) + versionObjects.sort((a, b) => compareVersions(b.version, a.version)); + + return versionObjects; +} + +/** + * 将资源按平台分组 + * @param assets - 文件资源数组 + * @returns 按平台分组的资源 + */ +export function groupAssetsByPlatform( + assets: DesktopAsset[] | undefined +): PlatformGroup[] { + if (!assets || !Array.isArray(assets)) { + return []; + } + + const platformGroups = new Map(); + + for (const asset of assets) { + const assetType = inferAssetType(asset.name); + if (assetType === AssetType.Unknown) { + continue; + } + + let platform: "windows" | "macos" | "linux" | null = null; + switch (assetType) { + case AssetType.WindowsSetup: + case AssetType.WindowsPortable: + case AssetType.WindowsStore: + platform = "windows"; + break; + case AssetType.MacOSApple: + case AssetType.MacOSIntel: + platform = "macos"; + break; + case AssetType.LinuxAppImage: + case AssetType.LinuxDeb: + case AssetType.LinuxTarball: + platform = "linux"; + break; + default: + continue; + } + + if (!platform) continue; + + if (!platformGroups.has(platform)) { + platformGroups.set(platform, []); + } + + platformGroups.get(platform)!.push({ + url: `${DOWNLOAD_BASE_URL}${asset.path}`, + size: formatFileSize(asset.size), + filename: asset.name, + assetType, + }); + } + + // 转换为数组并按推荐类型排序 + const result: PlatformGroup[] = []; + for (const [platform, downloads] of platformGroups.entries()) { + const recommendation = PLATFORM_RECOMMENDATIONS[ + platform as "windows" | "macos" | "linux" + ]; + + // 将推荐类型排在前面 + downloads.sort((a, b) => { + if (a.assetType === recommendation.recommendedType) return -1; + if (b.assetType === recommendation.recommendedType) return 1; + return 0; + }); + + result.push({ + platform: platform as "windows" | "macos" | "linux", + downloads, + }); + } + + return result; +} + +/** + * 获取平台的推荐下载项 + * @param platform - 平台名称 + * @param downloads - 下载资源列表 + * @returns 推荐的下载项,如果没有则返回第一个 + */ +export function getRecommendedDownload( + platform: "windows" | "macos" | "linux", + downloads: PlatformDownload[] +): PlatformDownload | null { + const recommendation = PLATFORM_RECOMMENDATIONS[platform]; + const recommended = downloads.find( + (d) => d.assetType === recommendation.recommendedType + ); + return recommended || downloads[0] || null; +} + +/** + * 检测用户操作系统 + * 支持查询字符串覆盖 ?os=windows|macos|linux + * @returns 检测到的操作系统 + */ +export function detectOS(): "windows" | "macos" | "linux" | "unknown" { + // 优先检查 URL 查询参数 + if (typeof window !== "undefined") { + const urlParams = new URLSearchParams(window.location.search); + const osParam = urlParams.get("os"); + if (osParam) { + const validOS = ["windows", "macos", "linux"]; + const normalizedParam = osParam.toLowerCase(); + if (validOS.includes(normalizedParam)) { + return normalizedParam as "windows" | "macos" | "linux"; + } + } + + // 基于 UserAgent 检测 + const userAgent = navigator.userAgent; + if (userAgent.includes("Windows")) { + return "windows"; + } + if ( + userAgent.includes("Mac") || + userAgent.includes("iPhone") || + userAgent.includes("iPad") || + userAgent.includes("Mac OS") + ) { + return "macos"; + } + if (userAgent.includes("Linux")) { + return "linux"; + } + } + + return "unknown"; +} diff --git a/shared/src/desktop.ts b/shared/src/desktop.ts new file mode 100644 index 0000000..303427f --- /dev/null +++ b/shared/src/desktop.ts @@ -0,0 +1,9 @@ +/** + * Hagicode Desktop 相关类型定义 + * 基于 desktop.dl.hagicode.com/index.json 的实际数据结构 + * + * @deprecated 请直接从 '@shared/types/desktop' 导入类型 + * 此文件保留用于向后兼容 + */ + +export * from './types/desktop'; diff --git a/shared/src/index.ts b/shared/src/index.ts new file mode 100644 index 0000000..ac240e7 --- /dev/null +++ b/shared/src/index.ts @@ -0,0 +1,9 @@ +// Shared utilities and types +export * from './links'; +export * from './desktop'; +export * from './desktop-utils'; +export * from './version'; + +// Desktop version management +export * from './version-manager'; +export * from './desktop-context'; diff --git a/shared/src/links.ts b/shared/src/links.ts new file mode 100644 index 0000000..17efd70 --- /dev/null +++ b/shared/src/links.ts @@ -0,0 +1,229 @@ +/** + * 公共链接管理库 + * + * 统一管理站点间的跳转链接和公共链接 + * 根据环境自动切换开发/生产环境的链接 + * + * 开发环境链接配置 + * + * 端口可通过环境变量配置: + * - PORT_DOCS: 文档站点端口(默认 31265) + * - PORT_WEBSITE: 营销站点端口(默认 31264) + * + * 如需自定义端口,请在 .env.local 中设置对应的环境变量 + */ + +/** + * 获取当前环境类型 + * 使用 NODE_ENV 环境变量来区分开发/生产环境 + * @returns 'development' | 'production' + */ +export function getEnvironment(): 'development' | 'production' { + // 优先使用 NODE_ENV 环境变量 + // 如果没有设置,则根据 import.meta.env.MODE 判断(Astro 内置) + const nodeEnv = import.meta.env.NODE_ENV || import.meta.env.MODE; + if (nodeEnv === 'development') { + return 'development'; + } + return 'production'; +} + +/** + * 获取文档站点的 base 路径 + * 开发环境为根路径,生产环境为根路径(独立部署在 docs.hagicode.com) + * @returns base 路径 + */ +export function getDocsBasePath(): string { + return '/'; +} + +/** + * 链接配置接口 + */ +export interface LinkConfig { + /** 开发环境链接 */ + dev: string; + /** 生产环境链接 */ + prod: string; + /** 是否为外部链接(新窗口打开) */ + external?: boolean; + /** 是否为相对路径(需要添加 base 前缀) */ + relative?: boolean; +} + +/** + * 站点间链接配置 + */ +export const SITE_LINKS = { + /** 文档站点 */ + docs: { + dev: 'http://localhost:31265/', // docs 应用开发环境端口 + prod: 'https://docs.hagicode.com/', + external: false, + } as LinkConfig, + + /** 官方营销站点 */ + website: { + dev: 'http://localhost:31264/', // website 应用开发环境端口 + prod: 'https://hagicode.com/', + external: false, + } as LinkConfig, + + /** GitHub 仓库 */ + github: { + dev: 'https://github.com/HagiCode-org/site', + prod: 'https://github.com/HagiCode-org/site', + external: true, + } as LinkConfig, + + /** 技术支持群 QQ */ + qqGroup: { + dev: 'https://qm.qq.com/q/Fwb0o094kw', + prod: 'https://qm.qq.com/q/Fwb0o094kw', + external: true, + } as LinkConfig, + + /** 博客页面(相对于文档站点) */ + blog: { + dev: 'http://localhost:31265/blog/', + prod: 'https://docs.hagicode.com/blog/', + external: false, + } as LinkConfig, + + /** 产品概述(相对于文档站点) */ + productOverview: { + dev: 'http://localhost:31265/product-overview/', + prod: 'https://docs.hagicode.com/product-overview/', + external: false, + } as LinkConfig, + + /** 桌面应用下载页 */ + desktop: { + dev: 'http://localhost:31264/desktop/', + prod: 'https://hagicode.com/desktop/', + external: false, + } as LinkConfig, + + /** Docker Compose 安装指南(相对于文档站点) */ + dockerCompose: { + dev: 'http://localhost:31265/installation/docker-compose/', + prod: 'https://docs.hagicode.com/installation/docker-compose/', + external: false, + } as LinkConfig, + + /** 容器部署落地页 */ + container: { + dev: 'http://localhost:31264/container/', + prod: 'https://hagicode.com/container/', + external: false, + } as LinkConfig, + + /** 博客 RSS 订阅(相对于文档站点) */ + rss: { + dev: 'http://localhost:31265/blog/rss.xml', + prod: 'https://docs.hagicode.com/blog/rss.xml', + external: false, + } as LinkConfig, +} as const; + +/** + * GLM(智谱 AI)推广链接配置 + * 用于博客广告区域和其他推广位置 + */ +export const GLM_PROMO_LINKS = { + /** 智谱 GLM Coding 订阅链接(带推广码) */ + glmCoding: { + url: 'https://www.bigmodel.cn/glm-coding?ic=14BY54APZA', + label: '立即开拼', + title: '智谱 GLM Coding: 20+ 大编程工具无缝支持', + description: 'Claude Code、Cline 等 20+ 大编程工具无缝支持,"码力"全开,越拼越爽!', + discount: '10% 优惠', + }, + + /** Docker Compose 部署指南链接 */ + dockerComposeGuide: { + url: '/installation/docker-compose/', + label: '查看部署指南', + title: 'Docker Compose 部署: 一键部署 Hagicode', + description: '一键部署 Hagicode,快速体验 AI 编程助手', + isInternal: true, + }, +} as const; + +/** + * 获取 GLM Coding 推广链接 + * @returns GLM Coding 推广链接 URL + */ +export function getGlmCodingUrl(): string { + return GLM_PROMO_LINKS.glmCoding.url; +} + +/** + * 获取 Docker Compose 指南链接(带 base 路径) + * @returns Docker Compose 指南完整 URL + */ +export function getDockerComposeGuideUrl(): string { + const basePath = getDocsBasePath(); + const path = GLM_PROMO_LINKS.dockerComposeGuide.url; + // 确保 base 路径和链接路径正确拼接 + if (basePath === '/') { + return path; + } + return `${basePath}${path}`.replace(/\/+/g, '/'); +} + +/** + * 公共链接类型 + */ +export type PublicLinkKey = keyof typeof SITE_LINKS; + +/** + * 获取指定链接的当前环境 URL + * @param key - 链接键名 + * @returns 当前环境下的完整 URL + */ +export function getLink(key: PublicLinkKey): string { + const config = SITE_LINKS[key]; + const env = getEnvironment(); + + if (env === 'development') { + return config.dev; + } + return config.prod; +} + +/** + * 获取指定链接的配置信息 + * @param key - 链接键名 + * @returns 链接配置对象 + */ +export function getLinkConfig(key: PublicLinkKey): LinkConfig { + return SITE_LINKS[key]; +} + +/** + * 判断链接是否为外部链接 + * @param key - 链接键名 + * @returns 是否为外部链接 + */ +export function isExternalLink(key: PublicLinkKey): boolean { + return SITE_LINKS[key].external === true; +} + +/** + * 获取链接的打开方式属性 + * @param key - 链接键名 + * @returns target 属性值 + */ +export function getLinkTarget(key: PublicLinkKey): '_blank' | undefined { + return isExternalLink(key) ? '_blank' : undefined; +} + +/** + * 获取链接的 rel 属性(用于外部链接的安全) + * @param key - 链接键名 + * @returns rel 属性值 + */ +export function getLinkRel(key: PublicLinkKey): 'noopener noreferrer' | undefined { + return isExternalLink(key) ? 'noopener noreferrer' : undefined; +} diff --git a/shared/src/types/desktop.ts b/shared/src/types/desktop.ts new file mode 100644 index 0000000..d32d5da --- /dev/null +++ b/shared/src/types/desktop.ts @@ -0,0 +1,115 @@ +/** + * Hagicode Desktop 相关类型定义 + * 基于 desktop.dl.hagicode.com/index.json 的实际数据结构 + */ + +/** + * 资源类型枚举 + * 从文件名推断的平台和类型 + */ +export enum AssetType { + WindowsSetup = "windows-setup", // Windows 安装程序 (推荐) + WindowsPortable = "windows-portable", // Windows 便携版 + WindowsStore = "windows-store", // Microsoft Store + MacOSApple = "macos-apple", // macOS Apple Silicon (推荐) + MacOSIntel = "macos-intel", // macOS Intel/通用 + LinuxAppImage = "linux-appimage", // Linux AppImage (推荐) + LinuxDeb = "linux-deb", // Linux Debian 包 + LinuxTarball = "linux-tarball", // Linux 压缩包 + Source = "source", // 源代码 + Unknown = "unknown", +} + +/** + * 文件资源信息 + * 来自 index.json 的 assets 数组 + */ +export interface DesktopAsset { + /** 文件名 */ + name: string; + /** 相对路径 */ + path: string; + /** 文件大小 (字节) */ + size: number; + /** 最后修改时间 (Unix 时间戳) */ + lastModified: number | null; +} + +/** + * 版本信息 + * 来自 index.json 的 versions 数组 + */ +export interface DesktopVersion { + /** 版本号 (如 "v0.1.1") */ + version: string; + /** 文件详细信息数组 */ + files: DesktopAsset[]; +} + +/** + * 渠道信息 + */ +export interface ChannelInfo { + /** 该渠道最新版本号 */ + latest: string; + /** 该渠道包含的版本号列表 */ + versions: string[]; +} + +/** + * index.json 响应结构(更新后) + */ +export interface DesktopIndexResponse { + /** Unix 时间戳或 ISO 时间戳字符串 */ + updatedAt: number | string; + /** 版本列表(完整历史) */ + versions: DesktopVersion[]; + /** 渠道信息(可选,向后兼容) */ + channels?: { + /** 稳定版渠道 */ + stable: ChannelInfo; + /** 测试版渠道 */ + beta: ChannelInfo; + }; +} + +/** + * 应用层使用的平台分类下载信息 + * 从文件名推断并格式化后的数据 + */ +export interface PlatformDownload { + /** 完整下载链接 */ + url: string; + /** 格式化的文件大小 */ + size: string; + /** 文件名 */ + filename: string; + /** 资源类型 */ + assetType: AssetType; +} + +/** + * 平台分组信息 + * 按平台分组的下载资源 + */ +export interface PlatformGroup { + /** 平台名称 */ + platform: "windows" | "macos" | "linux"; + /** 该平台的下载资源列表 */ + downloads: PlatformDownload[]; +} + +/** + * 平台推荐配置 + * 定义每个平台的推荐下载类型 + */ +export interface PlatformRecommendation { + /** 平台名称 */ + platform: string; + /** 推荐的资源类型 */ + recommendedType: AssetType; + /** 平台显示名称 */ + label: string; + /** Starlight 图标名称 */ + icon: string; +} diff --git a/shared/src/version-manager.ts b/shared/src/version-manager.ts new file mode 100644 index 0000000..e3c8aaf --- /dev/null +++ b/shared/src/version-manager.ts @@ -0,0 +1,322 @@ +/** + * Desktop 版本数据管理器 + * + * 提供单例模式的版本数据管理,支持服务端注入和客户端获取 + * 用于统一管理 Desktop 版本信息,避免重复请求 + */ + +import type { + DesktopIndexResponse, + DesktopVersion, + PlatformGroup, + ChannelInfo, +} from './types/desktop'; +import { + fetchDesktopVersions, + groupAssetsByPlatform, +} from './desktop-utils'; + +/** + * 版本数据接口 + * 包含最新版本、平台分组、错误信息和渠道数据 + */ +export interface DesktopVersionData { + /** 最新版本信息 */ + latest: DesktopVersion | null; + /** 按平台分组的下载资源 */ + platforms: PlatformGroup[]; + /** 错误信息 */ + error: string | null; + /** 渠道信息 */ + channels: { + /** 稳定版渠道 */ + stable: { + /** 最新版本 */ + latest: DesktopVersion | null; + /** 所有版本 */ + all: DesktopVersion[]; + }; + /** 测试版渠道 */ + beta: { + /** 最新版本 */ + latest: DesktopVersion | null; + /** 所有版本 */ + all: DesktopVersion[]; + }; + }; +} + +/** + * 版本管理器类 + * 单例模式,确保全局只有一个实例 + */ +class VersionManager { + private static instance: VersionManager | null = null; + private data: DesktopVersionData | null = null; + private initialized: boolean = false; + private fetching: boolean = false; + private pendingPromises: Array<{ + resolve: (data: DesktopVersionData) => void; + reject: (error: Error) => void; + }> = []; + + private constructor() { + // 私有构造函数,防止直接实例化 + } + + /** + * 获取单例实例 + */ + static getInstance(): VersionManager { + if (!VersionManager.instance) { + VersionManager.instance = new VersionManager(); + } + return VersionManager.instance; + } + + /** + * 设置服务端注入的数据(用于 SSR) + * 在 Astro 页面的服务端调用此方法,将版本数据注入到客户端 + * + * @param data - 从服务端获取的版本数据 + */ + setServerData(data: DesktopIndexResponse): void { + const versionData = this.transformToVersionData(data); + this.data = versionData; + this.initialized = true; + + // 解析所有等待的 Promise + for (const { resolve } of this.pendingPromises) { + resolve(versionData); + } + this.pendingPromises = []; + } + + /** + * 获取版本数据 + * 如果数据已初始化,直接返回缓存数据 + * 否则发起请求获取数据 + * + * @returns 版本数据 + */ + async getVersionData(): Promise { + // 如果数据已初始化,直接返回 + if (this.initialized && this.data) { + return this.data; + } + + // 检查是否有服务端注入的全局数据 + if (typeof window !== 'undefined' && (window as any).__DESKTOP_VERSION_DATA__) { + const serverData = (window as any).__DESKTOP_VERSION_DATA__; + if (serverData) { + const versionData = this.transformToVersionData(serverData); + this.data = versionData; + this.initialized = true; + // 清除全局数据以避免内存泄漏 + delete (window as any).__DESKTOP_VERSION_DATA__; + return versionData; + } + } + + // 如果正在获取数据,等待结果 + if (this.fetching) { + return new Promise((resolve, reject) => { + this.pendingPromises.push({ resolve, reject }); + }); + } + + // 开始获取数据 + this.fetching = true; + + try { + const responseData = await fetchDesktopVersions(); + const versionData = this.transformToVersionData(responseData); + + this.data = versionData; + this.initialized = true; + + // 解析所有等待的 Promise + for (const { resolve } of this.pendingPromises) { + resolve(versionData); + } + this.pendingPromises = []; + + return versionData; + } catch (error) { + const errorMessage = error instanceof Error ? error.message : 'Unknown error'; + const errorData: DesktopVersionData = { + latest: null, + platforms: [], + error: errorMessage, + channels: { + stable: { latest: null, all: [] }, + beta: { latest: null, all: [] }, + }, + }; + + // 拒绝所有等待的 Promise + for (const { reject } of this.pendingPromises) { + reject(error instanceof Error ? error : new Error(errorMessage)); + } + this.pendingPromises = []; + + throw error; + } finally { + this.fetching = false; + } + } + + /** + * 获取指定渠道的版本数据 + * + * @param channel - 渠道名称 ('stable' | 'beta') + * @returns 渠道版本数据 + */ + async getChannelVersionData( + channel: 'stable' | 'beta' + ): Promise<{ + latest: DesktopVersion | null; + all: DesktopVersion[]; + platforms: PlatformGroup[]; + error: string | null; + }> { + const data = await this.getVersionData(); + + return { + latest: data.channels[channel].latest, + all: data.channels[channel].all, + platforms: data.platforms, + error: data.error, + }; + } + + /** + * 检查是否已初始化 + * + * @returns 是否已初始化 + */ + isInitialized(): boolean { + return this.initialized; + } + + /** + * 清除缓存 + * 主要用于测试或手动刷新场景 + */ + clearCache(): void { + this.data = null; + this.initialized = false; + this.fetching = false; + + // 拒绝所有等待的 Promise + for (const { reject } of this.pendingPromises) { + reject(new Error('Cache cleared')); + } + this.pendingPromises = []; + } + + /** + * 将 DesktopIndexResponse 转换为 DesktopVersionData + * + * @param data - 原始版本数据响应 + * @returns 转换后的版本数据 + */ + private transformToVersionData( + data: DesktopIndexResponse + ): DesktopVersionData { + // 优先使用 stable 渠道的最新版本作为默认 latest + let latest: DesktopVersion | null = null; + + if (data.channels && data.channels.stable && data.channels.stable.latest) { + // 如果有 channels.stable.latest,使用它 + const stableLatestVersion = data.channels.stable.latest; + latest = data.versions.find(v => v.version === stableLatestVersion) || null; + } + + // 如果没有找到 stable 版本,则使用最新的版本 + if (!latest && data.versions.length > 0) { + latest = data.versions[0]; + } + + // 获取平台分组(基于 latest 版本) + const platforms = latest + ? groupAssetsByPlatform(latest.files) + : []; + + // 处理渠道数据 + const channels = { + stable: this.processChannel(data, 'stable'), + beta: this.processChannel(data, 'beta'), + }; + + return { + latest, + platforms, + error: null, + channels, + }; + } + + /** + * 处理单个渠道的数据 + * + * @param data - 原始版本数据响应 + * @param channel - 渠道名称 + * @returns 渠道版本数据 + */ + private processChannel( + data: DesktopIndexResponse, + channel: 'stable' | 'beta' + ): { latest: DesktopVersion | null; all: DesktopVersion[] } { + if (!data.channels || !data.channels[channel]) { + return { latest: null, all: [] }; + } + + const channelInfo = data.channels[channel]; + const channelVersions = data.versions.filter((v) => + channelInfo.versions.includes(v.version) + ); + + // 查找最新版本 + const latestVersion = + channelVersions.find((v) => v.version === channelInfo.latest) || null; + + return { + latest: latestVersion, + all: channelVersions, + }; + } +} + +// 导出单例获取方法 +export const getVersionManager = (): VersionManager => { + return VersionManager.getInstance(); +}; + +// 导出便捷方法 +export const setDesktopServerData = (data: DesktopIndexResponse): void => { + getVersionManager().setServerData(data); +}; + +export const getDesktopVersionData = (): Promise => { + return getVersionManager().getVersionData(); +}; + +export const getDesktopChannelData = ( + channel: 'stable' | 'beta' +): Promise<{ + latest: DesktopVersion | null; + all: DesktopVersion[]; + platforms: PlatformGroup[]; + error: string | null; +}> => { + return getVersionManager().getChannelVersionData(channel); +}; + +export const isDesktopVersionInitialized = (): boolean => { + return getVersionManager().isInitialized(); +}; + +export const clearDesktopVersionCache = (): void => { + getVersionManager().clearCache(); +}; diff --git a/shared/src/version.ts b/shared/src/version.ts new file mode 100644 index 0000000..193fada --- /dev/null +++ b/shared/src/version.ts @@ -0,0 +1,201 @@ +/** + * Version utilities for accessing desktop app version information + * from the Docs application's version-index.json file + */ + +import { promises as fs } from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; +import semver from 'semver'; + +// Import types from desktop.ts +import type { + DesktopIndexResponse, + DesktopVersion, + DesktopAsset +} from './desktop'; + +// Re-export types from desktop.ts for convenience +export type { + DesktopIndexResponse, + DesktopVersion, + DesktopAsset +}; + +/** + * Get the path to the version-index.json file in the Docs app + * This function resolves the path relative to the shared package location + * + * @returns {string} Absolute path to version-index.json + */ +function getVersionIndexPath(): string { + // Get the directory of the current module (packages/shared/src/) + const __filename = fileURLToPath(import.meta.url); + const __dirname = path.dirname(__filename); + const sharedDir = path.dirname(__dirname); // packages/shared/ + + // Navigate from packages/shared/ to apps/docs/public/ + return path.join(sharedDir, '..', '..', 'apps', 'docs', 'public', 'version-index.json'); +} + +/** + * Load and parse the version-index.json file from the Docs app + * + * @returns {Promise} Version index data + * @throws {Error} If the file cannot be read or parsed + */ +export async function getVersionIndex(): Promise { + try { + const versionPath = getVersionIndexPath(); + const content = await fs.readFile(versionPath, 'utf-8'); + return JSON.parse(content) as DesktopIndexResponse; + } catch (error) { + if (error instanceof Error) { + throw new Error(`Failed to load version index: ${error.message}`); + } + throw new Error('Failed to load version index: Unknown error'); + } +} + +/** + * Get the latest version string from the version index + * + * @returns {Promise} The latest version number (e.g., "v0.1.4") + * @throws {Error} If no versions are available or the file cannot be read + */ +export async function getLatestVersion(): Promise { + try { + const data = await getVersionIndex(); + + if (!data.versions || data.versions.length === 0) { + throw new Error('No versions found in version index'); + } + + const latest = getLatestVersionFromVersions(data.versions); + return latest.version; + } catch (error) { + if (error instanceof Error) { + throw new Error(`Failed to get latest version: ${error.message}`); + } + throw new Error('Failed to get latest version: Unknown error'); + } +} + +/** + * Get version data for a specific version string + * + * @param {string} version - Version string to look up (e.g., "v0.1.4") + * @returns {Promise} Version data or undefined if not found + */ +export async function getVersion(version: string): Promise { + try { + const data = await getVersionIndex(); + return data.versions.find(v => v.version === version); + } catch (error) { + if (error instanceof Error) { + throw new Error(`Failed to get version ${version}: ${error.message}`); + } + throw new Error(`Failed to get version ${version}: Unknown error`); + } +} + +/** + * Get all available versions + * + * @returns {Promise} Array of version strings + */ +export async function getAllVersions(): Promise { + try { + const data = await getVersionIndex(); + return data.versions.map(v => v.version); + } catch (error) { + if (error instanceof Error) { + throw new Error(`Failed to get all versions: ${error.message}`); + } + throw new Error('Failed to get all versions: Unknown error'); + } +} + +/** + * Get the latest version from a version array by comparing all versions using semver + * This is a utility function that can be used with any DesktopVersion array + * + * @param {DesktopVersion[]} versions - Array of DesktopVersion objects to search + * @returns {DesktopVersion} The latest DesktopVersion object + * @throws {Error} If versions array is empty + */ +export function getLatestVersionFromVersions( + versions: DesktopVersion[] +): DesktopVersion { + if (!versions || versions.length === 0) { + throw new Error('Versions array is empty'); + } + + // Find the latest version by comparing all versions using semver + return versions.reduce((latest, current) => { + const comparison = compareVersions(current.version, latest.version); + return comparison > 0 ? current : latest; + }); +} + +/** + * Parsed semantic version components + */ +export interface Semver { + /** Major version number */ + major: number; + /** Minor version number */ + minor: number; + /** Patch version number */ + patch: number; + /** Pre-release identifiers (e.g., ["beta", "1"] for "v1.2.3-beta.1") */ + prerelease: Array; +} + +/** + * Parse a semver version string into its components using the semver library + * @param {string} version - Version string (e.g., "v1.2.3", "v1.2.3-beta", "v1.2.3-beta.1", "v1.2", "v1") + * @returns {Semver | null} Parsed Semver interface or null if invalid + */ +export function parseSemver(version: string): Semver | null { + // Remove 'v' prefix if present and parse + const cleaned = version.replace(/^v/, ''); + + // Try to parse with strict mode first + try { + const sem = new semver.SemVer(cleaned); + return { + major: sem.major, + minor: sem.minor, + patch: sem.patch, + prerelease: sem.prerelease as Array + }; + } catch { + // If strict parsing fails, try coerce for partial versions like "1.2" or "1" + const sem = semver.coerce(cleaned); + if (!sem) return null; + return { + major: sem.major, + minor: sem.minor, + patch: sem.patch, + prerelease: sem.prerelease as Array + }; + } +} + +/** + * Compare two version strings using semver specification (via semver library) + * @param {string} v1 - First version + * @param {string} v2 - Second version + * @returns {number} -1 if v1 < v2, 0 if v1 = v2, 1 if v1 > v2 + */ +export function compareVersions(v1: string, v2: string): number { + const cleaned1 = v1.replace(/^v/, ''); + const cleaned2 = v2.replace(/^v/, ''); + + const cmp = semver.compare(cleaned1, cleaned2); + // semver.compare returns: negative if a < b, 0 if equal, positive if a > b + if (cmp < 0) return -1; + if (cmp > 0) return 1; + return 0; +} diff --git a/shared/tsconfig.json b/shared/tsconfig.json new file mode 100644 index 0000000..2ffe910 --- /dev/null +++ b/shared/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "moduleResolution": "bundler", + "resolveJsonModule": true, + "allowJs": true, + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "composite": true, + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["**/*"], + "exclude": ["dist", "node_modules"] +} diff --git a/src/components/51LAAnalytics.astro b/src/components/51LAAnalytics.astro new file mode 100644 index 0000000..49b50da --- /dev/null +++ b/src/components/51LAAnalytics.astro @@ -0,0 +1,37 @@ +--- +/** + * 51LA Analytics 用户行为分析集成组件 + * 仅在生产环境加载 51LA 脚本 + * + * @see https://www.51.la/ + */ +// Astro 组件在服务端执行时可以直接访问 process.env +// 对于构建时静态生成,process.env 在构建时可用 +// 默认使用硬编码的 ID,环境变量可覆盖 +const default51LAId = 'L6b88a5yK4h2Xnci'; +const laId = import.meta.env.VITE_51LA_ID || default51LAId; +const isProduction = import.meta.env.PROD; + +// 在构建时检查是否应该加载 51LA Analytics +// 仅在生产环境加载(使用默认 ID 或环境变量提供的 ID) +const shouldLoad51LA = isProduction; + +// 可选的构建时调试日志 +if (import.meta.env.VITE_51LA_DEBUG) { + console.log('[51LA Analytics] Build-time state:', { + isProduction, + laId: laId ? '***' + laId.slice(-4) : 'not set', + shouldLoad51LA: !!shouldLoad51LA, + NODE_ENV: process.env.NODE_ENV, + }); +} +--- + +{shouldLoad51LA && ( + <> + + + > +)} diff --git a/src/components/BaiduAnalytics.astro b/src/components/BaiduAnalytics.astro new file mode 100644 index 0000000..1303010 --- /dev/null +++ b/src/components/BaiduAnalytics.astro @@ -0,0 +1,39 @@ +--- +/** + * Baidu Analytics 用户行为分析集成组件 + * 仅在生产环境加载 Baidu Analytics 脚本 + * + * @see https://tongji.baidu.com/ + */ +// Astro 组件在服务端执行时可以直接访问 process.env +// 对于构建时静态生成,process.env 在构建时可用 +// 默认使用硬编码的 ID,环境变量可覆盖 +const defaultBaiduAnalyticsId = '04ac03637b01a1f4cc0bdfa376387fe5'; +const baiduAnalyticsId = import.meta.env.VITE_BAIDU_ANALYTICS_ID || defaultBaiduAnalyticsId; +const isProduction = import.meta.env.PROD; + +// 在构建时检查是否应该加载 Baidu Analytics +// 仅在生产环境加载(使用默认 ID 或环境变量提供的 ID) +const shouldLoadBaiduAnalytics = isProduction; + +// 可选的构建时调试日志 +if (import.meta.env.VITE_BAIDU_ANALYTICS_DEBUG) { + console.log('[Baidu Analytics] Build-time state:', { + isProduction, + baiduAnalyticsId: baiduAnalyticsId ? '***' + baiduAnalyticsId.slice(-4) : 'not set', + shouldLoadBaiduAnalytics: !!shouldLoadBaiduAnalytics, + NODE_ENV: process.env.NODE_ENV, + }); +} +--- + +{shouldLoadBaiduAnalytics && ( + +)} diff --git a/src/components/BlogFooterAd.astro b/src/components/BlogFooterAd.astro new file mode 100644 index 0000000..61e3916 --- /dev/null +++ b/src/components/BlogFooterAd.astro @@ -0,0 +1,204 @@ +--- +/** + * 博客文章结尾广告组件 + * 在博客文章正文之后显示扩展的链接列表区域 + */ +import { GLM_PROMO_LINKS, getLink } from '@shared/links'; + +interface Props { + /** 是否隐藏广告 */ + hideAd?: boolean; +} + +const { hideAd = false } = Astro.props; + +// 如果设置隐藏广告,则不渲染 +if (hideAd) { + return null; +} + +const { glmCoding, dockerComposeGuide } = GLM_PROMO_LINKS; +--- + + + + diff --git a/src/components/BlogHeaderAd.astro b/src/components/BlogHeaderAd.astro new file mode 100644 index 0000000..3b33046 --- /dev/null +++ b/src/components/BlogHeaderAd.astro @@ -0,0 +1,158 @@ +--- +/** + * 博客文章开头广告组件 + * 在博客文章标题之后、正文之前显示 GLM 推广卡片 + */ +import { GLM_PROMO_LINKS } from '@shared/links'; + +interface Props { + /** 是否隐藏广告 */ + hideAd?: boolean; +} + +const { hideAd = false } = Astro.props; + +// 如果设置隐藏广告,则不渲染 +if (hideAd) { + return null; +} + +const { glmCoding } = GLM_PROMO_LINKS; +--- + + + + + + + + + + + + + 速来拼好模,智谱 GLM Coding 超值订阅 + (本项目同样使用智谱 AI 开发) + + + {glmCoding.description}立即开拼,享限时惊喜价! + + + + {glmCoding.label} + + + + + + + + diff --git a/src/components/Clarity.astro b/src/components/Clarity.astro new file mode 100644 index 0000000..a968bbe --- /dev/null +++ b/src/components/Clarity.astro @@ -0,0 +1,36 @@ +--- +/** + * Microsoft Clarity 用户行为分析集成组件 + * 仅在生产环境加载 Clarity 脚本 + * + * @see https://learn.microsoft.com/en-us/clarity/ + */ +// Astro 组件在服务端执行时可以直接访问 process.env +// 对于构建时静态生成,process.env 在构建时可用 +const clarityProjectId = process.env.VITE_CLARITY_PROJECT_ID || process.env.CLARITY_PROJECT_ID; +const isProduction = import.meta.env.PROD; + +// 在构建时检查是否应该加载 Clarity +// 仅在生产环境且配置了 Project ID 时加载 +const shouldLoadClarity = isProduction && clarityProjectId; + +// 可选的构建时调试日志 +if (process.env.VITE_CLARITY_DEBUG || process.env.CLARITY_DEBUG) { + console.log('[Clarity] Build-time state:', { + isProduction, + clarityProjectId: clarityProjectId ? '***' + clarityProjectId.slice(-4) : 'not set', + shouldLoadClarity: !!shouldLoadClarity, + NODE_ENV: process.env.NODE_ENV, + }); +} +--- + +{shouldLoadClarity && ( + +)} diff --git a/src/components/ClarityDebug.astro b/src/components/ClarityDebug.astro new file mode 100644 index 0000000..0b34f90 --- /dev/null +++ b/src/components/ClarityDebug.astro @@ -0,0 +1,19 @@ +--- +// 调试组件 - 输出环境变量状态 +const clarityProjectId = import.meta.env.VITE_CLARITY_PROJECT_ID; +const isProduction = import.meta.env.PROD; +const clarityDebug = import.meta.env.CLARITY_DEBUG; + +console.log('[ClarityDebug] Build-time state:', { + clarityProjectId, + isProduction, + clarityDebug, + shouldLoad: isProduction && clarityProjectId, +}); +--- + diff --git a/src/components/InstallButton.tsx b/src/components/InstallButton.tsx new file mode 100644 index 0000000..1e16a2e --- /dev/null +++ b/src/components/InstallButton.tsx @@ -0,0 +1,336 @@ +/** + * InstallButton 组件 - 文档站点版本 (React) + * 支持自动平台检测、下拉菜单选择版本、Docker 版本跳转 + * 用于 Header 导航栏 + */ +import React, { useState, useMemo, useEffect } from 'react'; +import { getLink } from '@shared/links'; +import { + groupAssetsByPlatform, + detectOS, + getAssetTypeLabel, + inferAssetType, + getArchitectureLabel, + PLATFORM_ICONS, + getFileExtension +} from '@shared/desktop-utils'; +import { getDesktopVersionData } from '@shared/version-manager'; +import type { DesktopVersion, PlatformGroup } from '@shared/desktop'; + +interface DownloadOption { + label: string; + url: string; + size?: string; + assetType: string; +} + +interface PlatformDownloads { + platform: 'windows' | 'macos' | 'linux'; + platformLabel: string; + options: DownloadOption[]; +} + +interface InstallButtonProps { + /** + * 显示模式 + * - full: 完整模式(预留) + * - compact: 紧凑模式,用于 Header 导航栏 + */ + variant?: 'full' | 'compact'; + + /** + * 可选的额外类名 + */ + className?: string; + + /** + * 版本数据(服务端传入,优先使用) + */ + initialVersion?: DesktopVersion | null; + + /** + * 平台数据(服务端传入,优先使用) + */ + initialPlatforms?: PlatformGroup[]; + + /** + * 错误信息 + */ + versionError?: string | null; + + /** + * 版本渠道(默认 'stable') + * - stable: 稳定版 + * - beta: 测试版 + */ + channel?: 'stable' | 'beta'; +} + +/** + * 将 PlatformGroup[] 转换为 PlatformDownloads[] 格式 + */ +function convertPlatformGroups(platforms: PlatformGroup[]): PlatformDownloads[] { + const platformLabels = { windows: 'Windows', macos: 'macOS', linux: 'Linux' }; + + return platforms.map(platform => ({ + platform: platform.platform, + platformLabel: platformLabels[platform.platform], + options: platform.downloads.map(download => ({ + label: download.filename, + url: download.url, + size: download.size, + assetType: download.assetType + })) + })); +} + +export default function InstallButton({ + variant = 'compact', + className = '', + initialVersion = null, + initialPlatforms = [], + versionError = null, + channel = 'stable' +}: InstallButtonProps) { + const [isDropdownOpen, setIsDropdownOpen] = useState(false); + const [version, setVersion] = useState(initialVersion); + const [platforms, setPlatforms] = useState(initialPlatforms); + const [error, setError] = useState(versionError); + + // 客户端数据获取(如果服务端没有提供数据) + useEffect(() => { + if (initialVersion || initialPlatforms.length > 0 || versionError) { + return; // 已有数据或错误,无需重新获取 + } + + let mounted = true; + getDesktopVersionData() + .then((data) => { + if (!mounted) return; + + // 根据渠道选择最新版本 + let latest = data.latest; + if (channel && data.channels[channel]?.latest) { + latest = data.channels[channel].latest; + } else if (data.channels.stable?.latest) { + latest = data.channels.stable.latest; + } + + if (latest) { + setVersion(latest); + setPlatforms(data.platforms); + } + }) + .catch((err) => { + if (!mounted) return; + console.error('Failed to fetch desktop versions:', err); + setError(err.message); + }); + + return () => { + mounted = false; + }; + }, [initialVersion, initialPlatforms, versionError, channel]); + + // 生成唯一的组件 ID + const buttonId = useMemo(() => `install-button-${Math.random().toString(36).substring(2, 11)}`, []); + + // 转换平台数据格式 + const platformData = useMemo(() => { + if (!platforms || platforms.length === 0) return []; + return convertPlatformGroups(platforms); + }, [platforms]); + + // 根据用户系统设置默认下载链接 + const currentUrl = useMemo(() => { + if (platformData.length === 0) { + return getLink('desktop'); + } + + const userOS = detectOS(); + const userPlatform = platformData.find(p => p.platform === userOS); + + if (userPlatform) { + // 优先选择推荐版本 + const recommended = userPlatform.options.find(opt => { + const label = opt.label.toLowerCase(); + if (userOS === 'windows') return label.includes('setup'); + if (userOS === 'macos') return label.includes('arm64'); + if (userOS === 'linux') return label.includes('appimage'); + return false; + }); + return recommended ? recommended.url : userPlatform.options[0].url; + } + + return platformData[0].options[0].url; + }, [platformData]); + + // 点击外部关闭下拉菜单 + useEffect(() => { + const handleClickOutside = () => { + setIsDropdownOpen(false); + }; + + if (isDropdownOpen) { + document.addEventListener('click', handleClickOutside); + return () => document.removeEventListener('click', handleClickOutside); + } + }, [isDropdownOpen]); + + // ESC 键关闭下拉菜单 + useEffect(() => { + const handleEscape = (e: KeyboardEvent) => { + if (e.key === 'Escape') { + setIsDropdownOpen(false); + } + }; + + document.addEventListener('keydown', handleEscape); + return () => document.removeEventListener('keydown', handleEscape); + }, []); + + const handleToggleDropdown = (e: React.MouseEvent) => { + e.stopPropagation(); + setIsDropdownOpen(!isDropdownOpen); + }; + + // 点击下拉菜单中的链接后关闭菜单 + const handleLinkClick = () => { + setIsDropdownOpen(false); + }; + + // 如果有错误或没有数据,显示降级链接 + if (error || !version || platformData.length === 0) { + return ( + + + + + + + 立即安装 + + + + ); + } + + return ( + + + {/* 主下载按钮 */} + + + + + 立即安装 + + + {/* 下拉切换按钮 */} + {platformData.length > 0 && ( + <> + + + + + + + {/* 下拉菜单 */} + + {platformData.map((platformGroup) => ( + + {/* 平台分组标签 - 带图标和版本号 */} + + {PLATFORM_ICONS[platformGroup.platform]} + {platformGroup.platformLabel} + {version?.version && ( + {version.version} + )} + + {platformGroup.options.map((option, idx) => { + const archLabel = getArchitectureLabel(option.assetType); + const fileExt = getFileExtension(option.assetType); + const isRecommended = idx === 0; + return ( + + + + {getAssetTypeLabel(option.assetType)} + {archLabel && ({archLabel})} + {fileExt && {fileExt}} + {isRecommended && ⭐推荐} + + {option.size && ( + {option.size} + )} + + + ); + })} + + ))} + {/* Docker 版本选项 - 带分隔线 */} + + + + + + + 容器部署 + + + + + + + + + > + )} + + + ); +} diff --git a/src/components/MarkdownContent.astro b/src/components/MarkdownContent.astro new file mode 100644 index 0000000..62a0685 --- /dev/null +++ b/src/components/MarkdownContent.astro @@ -0,0 +1,56 @@ +--- +/** + * 自定义 MarkdownContent 组件 + * 覆盖 starlight-blog 的 MarkdownContent 组件,添加广告支持 + * + * 此组件基于 starlight-blog 的原始实现,添加了以下功能: + * - 在博客文章开头显示 BlogHeaderAd 广告 + * - 在博客文章结尾显示 BlogFooterAd 广告 + * - 支持通过 frontmatter 的 hideAd 属性控制广告显示 + */ +import Default from '@astrojs/starlight/components/MarkdownContent.astro' +import StarlightBlogMarkdownContent from 'starlight-blog/components/MarkdownContent.astro' + +import BlogHeaderAd from './BlogHeaderAd.astro' +import BlogFooterAd from './BlogFooterAd.astro' + +const { id, locale } = Astro.locals.starlightRoute + +// 检查是否为博客文章页面 +// 博客文章的 id 格式为 "blog/YYYY-MM-DD-xxx" +const isBlogPost = id?.startsWith('blog/') && !id.endsWith('blog/') && !id.endsWith('blog') + +// 获取 hideAd 设置 +// 从 starlightBlog 数据中查找当前文章,然后获取 hideAd 属性 +let hideAd = false +if (isBlogPost && Astro.locals.starlightBlog) { + const blogData = Astro.locals.starlightBlog + // 查找匹配当前 id 的博客文章 + const currentPost = blogData.posts.find(post => post.entry.id === id) + if (currentPost) { + hideAd = currentPost.entry.data.hideAd ?? false + } +} +--- + +{ + isBlogPost ? ( + + + + + + + + ) : ( + + + + ) +} + + diff --git a/src/components/MermaidInjector.astro b/src/components/MermaidInjector.astro new file mode 100644 index 0000000..6da599d --- /dev/null +++ b/src/components/MermaidInjector.astro @@ -0,0 +1,11 @@ +--- +/** + * Mermaid 注入器组件 + * 用作 Starlight 的 Logo 组件,在渲染 Logo 的同时注入 Mermaid 渲染脚本 + */ +import { Logo as DefaultLogo } from '@astrojs/starlight/components'; +import MermaidRenderer from '../scripts/mermaid-renderer.astro'; +--- + + + diff --git a/src/components/StarlightFooter.astro b/src/components/StarlightFooter.astro new file mode 100644 index 0000000..aa1d7bc --- /dev/null +++ b/src/components/StarlightFooter.astro @@ -0,0 +1,412 @@ +--- +/** + * Starlight 自定义 Footer - 三栏高栏布局 + * 统一首页和文档区的 Footer 设计 + * 使用共享链接库管理所有外部链接 + */ +import EditLink from 'virtual:starlight/components/EditLink'; +import LastUpdated from 'virtual:starlight/components/LastUpdated'; +import Pagination from 'virtual:starlight/components/Pagination'; +import config from 'virtual:starlight/user-config'; +import { Icon } from '@astrojs/starlight/components'; +import Clarity from './Clarity.astro'; +// import BaiduAnalytics from './BaiduAnalytics.astro'; // Disabled, migrated to 51LA +import Analytics51LA from './51LAAnalytics.astro'; +import { getLink, getLinkTarget, getLinkRel } from '@shared/links'; +import type { PublicLinkKey } from '@shared/links'; + +// 从共享库获取链接 +const desktopLink = getLink('desktop'); +const websiteLink = getLink('website'); +const githubLink = getLink('github'); +const qqGroupLink = getLink('qqGroup'); +const blogLink = getLink('blog'); +const productOverviewLink = getLink('productOverview'); +const rssLink = getLink('rss'); + +// 外部链接的 target 和 rel 属性 +const externalLinkTarget = getLinkTarget('github'); +const externalLinkRel = getLinkRel('github'); +const qqGroupTarget = getLinkTarget('qqGroup'); +const qqGroupRel = getLinkRel('qqGroup'); +--- + + + + +{/* */} {/* Disabled, migrated to 51LA */} + + + diff --git a/src/components/StarlightHead.astro b/src/components/StarlightHead.astro new file mode 100644 index 0000000..8aa5775 --- /dev/null +++ b/src/components/StarlightHead.astro @@ -0,0 +1,55 @@ +--- +/** + * Starlight 自定义 Head 组件 + * 使用 astro-seo 插件添加完整的 SEO meta 标签 + */ +import { SEO } from 'astro-seo'; + +// 站点默认信息 +const siteTitle = 'Hagicode Docs - 智能 · 便捷 · 有趣的 AI 编码助手'; +const siteDescription = 'Hagicode 项目文档 - 用 AI 重新定义代码开发体验。OpenSpec 工作流、多线程会话管理、成就系统,让编码更高效、更有趣'; + +// 构建完整的 URL +const url = new URL(Astro.url.pathname, Astro.site); +const canonicalUrl = url.href; + +// 完整的图片 URL +const baseUrl = import.meta.env.VITE_SITE_BASE || ''; +const fullImageUrl = `https://hagicode.com${baseUrl}/img/docusaurus-social-card.jpg`; + +// 只对有效页面应用 SEO,跳过404等特殊页面 +const isValidPage = Astro.url.pathname !== '/404'; +--- + +{isValidPage && ( + <> + + + + > +)} diff --git a/src/components/StarlightHeader.astro b/src/components/StarlightHeader.astro new file mode 100644 index 0000000..0ce2758 --- /dev/null +++ b/src/components/StarlightHeader.astro @@ -0,0 +1,170 @@ +--- +/** + * 自定义 Starlight Header 组件 + * 在文档页面的 header 中添加导航链接和安装按钮,同时保留所有原有功能 + */ +import config from 'virtual:starlight/user-config'; +import LanguageSelect from 'virtual:starlight/components/LanguageSelect'; +import Search from 'virtual:starlight/components/Search'; +import SiteTitle from 'virtual:starlight/components/SiteTitle'; +import SocialIcons from 'virtual:starlight/components/SocialIcons'; +import ThemeSelect from 'virtual:starlight/components/ThemeSelect'; +import { Icon } from '@astrojs/starlight/components'; +import { navLinks } from '@/config/navigation'; +import InstallButton from './InstallButton'; + +/** + * Render the `Search` component if Pagefind is enabled or the default search component has been overridden. + */ +const shouldRenderSearch = + config.pagefind || config.components.Search !== '@astrojs/starlight/components/Search.astro'; +--- + + + + + + + + + + {shouldRenderSearch && } + + + + {/* 安装按钮 */} + + {navLinks.map((link) => ( + + {link.icon && } + {link.label} + + ))} + + + + + + + + + + diff --git a/src/components/StructuredData.astro b/src/components/StructuredData.astro new file mode 100644 index 0000000..67df7f8 --- /dev/null +++ b/src/components/StructuredData.astro @@ -0,0 +1,44 @@ +--- +/** + * Schema.org 结构化数据组件 + * 为页面添加 JSON-LD 格式的结构化数据 + */ + +interface StructuredDataProps { + type: 'WebPage' | 'Article' | 'BlogPosting' | 'Organization'; + data: { + name?: string; + headline?: string; + description: string; + url?: string; + datePublished?: string; + dateModified?: string; + author?: { + name: string; + url?: string; + }; + image?: string; + inLanguage?: string; + publisher?: { + name: string; + logo?: string; + }; + }; + canonicalUrl: string; +} + +const { type, data, canonicalUrl } = Astro.props; + +// 构建结构化数据对象 +const structuredData = { + '@context': 'https://schema.org', + '@type': type, + url: canonicalUrl, + ...data, +}; + +// 转换为 JSON 字符串 +const jsonLd = JSON.stringify(structuredData); +--- + + diff --git a/src/config/navigation.ts b/src/config/navigation.ts new file mode 100644 index 0000000..e211e75 --- /dev/null +++ b/src/config/navigation.ts @@ -0,0 +1,67 @@ +/** + * 导航链接配置 + * 站点导航链接的统一数据源,确保所有组件使用相同的链接配置 + * 使用共享链接库管理站点间跳转和公共链接 + */ +import { getLink, getLinkTarget, getLinkRel, type PublicLinkKey } from '@shared/links'; + +/** + * 导航链接接口 + * 定义导航链接的基本结构 + */ +export interface NavLink { + /** 链接显示文本 */ + label: string; + + /** 链接地址 (支持相对路径和绝对 URL) */ + href: string; + + /** 是否为外部链接 (可选) */ + external?: boolean; + + /** Starlight 图标名称 (可选) */ + icon?: string; + + /** 链接键名 (用于从共享库获取环境相关链接) */ + linkKey?: PublicLinkKey; +} + +/** + * 站点导航链接配置 + * 使用共享链接库,自动根据环境切换开发/生产链接 + */ +export const navLinks: NavLink[] = [ + { + label: "首页", + href: getLink('website'), + linkKey: 'website', + }, + { + label: "博客", + href: getLink('blog'), + linkKey: 'blog', + }, + { + label: "技术支持群", + href: getLink('qqGroup'), + external: true, + icon: "comment", + linkKey: 'qqGroup', + }, +]; + +/** + * 获取链接的完整属性 + * @param link - 导航链接对象 + * @returns 包含 target 和 rel 属性的对象 + */ +export function getLinkAttributes(link: NavLink) { + const attributes: { target?: string; rel?: string } = {}; + + if (link.external) { + attributes.target = '_blank'; + attributes.rel = 'noopener noreferrer'; + } + + return attributes; +} diff --git a/src/content.config.ts b/src/content.config.ts new file mode 100644 index 0000000..1a28c94 --- /dev/null +++ b/src/content.config.ts @@ -0,0 +1,16 @@ +import { defineCollection, z } from 'astro:content'; +import { docsLoader } from '@astrojs/starlight/loaders'; +import { docsSchema } from '@astrojs/starlight/schema'; +import { blogSchema } from 'starlight-blog/schema' + +export const collections = { + docs: defineCollection({ + loader: docsLoader(), + schema: docsSchema({ + extend: (context) => blogSchema(context).extend({ + /** 隐藏博客文章中的广告区域 */ + hideAd: z.boolean().optional().default(false), + }), + }) + }), +}; diff --git "a/src/content/docs/blog/2026-01-22-github-issues-\351\233\206\346\210\220.mdx" "b/src/content/docs/blog/2026-01-22-github-issues-\351\233\206\346\210\220.mdx" new file mode 100644 index 0000000..52863c3 --- /dev/null +++ "b/src/content/docs/blog/2026-01-22-github-issues-\351\233\206\346\210\220.mdx" @@ -0,0 +1,340 @@ +--- +title: "GitHub Issues 集成" +date: 2026-01-22 +truncate: true +--- + +# 从零构建 GitHub Issues 集成:HagiCode 的前端直连实践 + +> 本文记录了在 HagiCode 平台中集成 GitHub Issues 的全过程。我们将探讨如何通过"前端直连 + 后端最小化"的架构,在保持后端轻量的同时,实现安全的 OAuth 认证与高效的 Issues 同步。 + +## 背景:为什么要集成 GitHub? + +HagiCode 作为一个 AI 辅助开发平台,核心价值在于连接想法与实现。但在实际使用中,我们发现用户在 HagiCode 中完成了 Proposal(提案)后,往往需要手动将内容复制到 GitHub Issues 中进行项目跟踪。 + +这带来了几个明显的痛点: + +1. **工作流割裂**:用户需要在两个系统之间来回切换,体验不仅不流畅,还容易导致关键信息在复制粘贴的过程中丢失。 +2. **协作不便**:团队其他成员习惯在 GitHub 上查看任务,无法直接看到 HagiCode 中的提案进展。 +3. **重复劳动**:每当提案更新,就要人工去 GitHub 更新对应的 Issue,增加不必要的维护成本。 + +为了解决这个问题,我们决定引入 **GitHub Issues Integration** 功能,打通 HagiCode 会话与 GitHub 仓库的连接,实现"一键同步"。 + +## 关于 HagiCode + +> 嘿,介绍一下我们正在做的东西 + +我们正在开发 **HagiCode** —— 一款 AI 驱动的代码智能助手,让开发体验变得更智能、更便捷、更有趣。 + +**智能** —— AI 全程辅助,从想法到代码,让编码效率提升数倍。**便捷** —— 多线程并发操作,充分利用资源,开发流程顺畅无阻。**有趣** —— 游戏化机制和成就系统,让编码不再枯燥,充满成就感。 + +项目正在快速迭代中,如果你对技术写作、知识管理或者 AI 辅助开发感兴趣,欢迎来 [GitHub](https://github.com/HagiCode-org/site) 看看~ + +--- + +## 技术选型:前端直连 vs 后端代理 + +在设计集成方案时,摆在我们面前的有两条路:传统的"后端代理模式"和更激进的"前端直连模式"。 + +### 方案对比 + +在传统的**后端代理模式**中,前端所有的请求都要先经过我们的后端,再由后端去调用 GitHub API。这虽然逻辑集中,但给后端带来了不小的负担: + +1. **后端臃肿**:需要编写专门的 GitHub API 客户端封装,还要处理 OAuth 的复杂状态机。 +2. **Token 风险**:用户的 GitHub Token 必须存储在后端数据库中,虽然可以加密,但毕竟增加了安全风险面。 +3. **开发成本**:需要数据库迁移来存储 Token,还需要维护一套额外的同步服务。 + +而**前端直连模式**则要轻量得多。在这个方案中,我们只利用后端来处理最敏感的"密钥交换"环节(OAuth callback),获取到 Token 后,直接存在浏览器的 localStorage 里。后续创建 Issue、更新评论等操作,直接由前端发 HTTP 请求到 GitHub。 + +| 对比维度 | 后端代理模式 | 前端直连模式 | +| :--- | :--- | :--- | +| **后端复杂度** | 需要完整的 OAuth 服务和 GitHub API 客户端 | 仅需一个 OAuth 回调端点 | +| **Token 管理** | 需加密存储在数据库,有泄露风险 | 存储在浏览器,仅用户自己可见 | +| **实施成本** | 需数据库迁移、多服务开发 | 主要是前端工作量 | +| **用户体验** | 逻辑统一,但服务器延迟可能稍高 | 响应极快,直接与 GitHub 交互 | + +考虑到我们要的是快速集成和最小化后端改动,**最终我们采用了"前端直连模式"**。这就像给浏览器发了一张"临时通行证",拿到证之后,浏览器就可以自己去 GitHub 办事了,不需要每次都找后端管理员批准。 + +--- + +## 核心设计:数据流与安全 + +在确定架构后,我们需要设计具体的数据流。整个同步流程的核心在于如何安全地获取 Token 并高效地利用它。 + +### 整体架构图 + +整个系统可以抽象为三个角色:浏览器(前端)、HagiCode 后端、GitHub。 + +```text ++--------------+ +--------------+ +--------------+ +| 前端 React | | 后端 | | GitHub | +| | | ASP.NET | | REST API | +| +--------+ | | | | | +| | OAuth |--+--------> /callback | | | +| | 流程 | | | | | | +| +--------+ | | | | | +| | | | | | +| +--------+ | | +--------+ | | +--------+ | +| |GitHub | +------------>Session | +----------> Issues | | +| |API | | | |Metadata| | | | | | +| |直连 | | | +--------+ | | +--------+ | +| +--------+ | | | | | ++--------------+ +--------------+ +--------------+ +``` + +**关键点在于**:只有 OAuth 的一小步(获取 code 换 token)需要经过后端,之后的粗活累活(创建 Issue)都是前端直接跟 GitHub 打交道。 + +### 同步数据流详解 + +当用户点击 HagiCode 界面上的"Sync to GitHub"按钮时,会发生一系列复杂的动作: + +```text +用户点击 "Sync to GitHub" + │ + ▼ +1. 前端检查 localStorage 获取 GitHub Token + │ + ▼ +2. 格式化 Issue 内容(将 Proposal 转换为 Markdown) + │ + ▼ +3. 前端直接调用 GitHub API 创建/更新 Issue + │ + ▼ +4. 调用 HagiCode 后端 API 更新 Session.metadata (存储 Issue URL 等信息) + │ + ▼ +5. 后端通过 SignalR 广播 SessionUpdated 事件 + │ + ▼ +6. 前端接收事件,更新 UI 显示"已同步"状态 +``` + +### 安全设计 + +安全问题始终是集成第三方服务的重中之重。我们做了以下考量: + +1. **防 CSRF 攻击**:在 OAuth 跳转时,生成随机的 `state` 参数并存入 sessionStorage。回调时严格验证 state,防止请求被伪造。 +2. **Token 存储隔离**:Token 仅存储在浏览器的 `localStorage` 中,利用同源策略(Same-Origin Policy),只有 HagiCode 的脚本才能读取,避免了服务器端数据库泄露波及用户。 +3. **错误边界**:针对 GitHub API 常见的错误(如 401 Token 过期、422 验证失败、429 速率限制),设计了专门的错误处理逻辑,给用户以友好的提示。 + +--- + +## 实践:代码实现细节 + +纸上得来终觉浅,咱们来看看具体的代码是怎么实现的。 + +### 1. 后端最小化改动 + +后端只需要做两件事:存储同步信息、处理 OAuth 回调。 + +**数据库变更** +我们只需要在 `Sessions` 表增加一个 `Metadata` 列,用来存储 JSON 格式的扩展信息。 + +```sql +-- 添加 metadata 列到 Sessions 表 +ALTER TABLE "Sessions" ADD COLUMN "Metadata" text NULL; +``` + +**实体与 DTO 定义** + +```csharp +// src/HagiCode.DomainServices.Contracts/Entities/Session.cs +public class Session : AuditedAggregateRoot +{ + // ... 其他属性 ... + + /// + /// JSON metadata for storing extension data like GitHub integration + /// + public string? Metadata { get; set; } +} + +// DTO 定义,方便前端序列化 +public class GitHubIssueMetadata +{ + public required string Owner { get; set; } + public required string Repo { get; set; } + public int IssueNumber { get; set; } + public required string IssueUrl { get; set; } + public DateTime SyncedAt { get; set; } + public string LastSyncStatus { get; set; } = "success"; +} + +public class SessionMetadata +{ + public GitHubIssueMetadata? GitHubIssue { get; set; } +} +``` + +### 2. 前端 OAuth 流程 + +这是连接的入口。我们使用标准的 Authorization Code Flow。 + +```typescript +// src/HagiCode.Client/src/services/githubOAuth.ts + +// 生成授权 URL 并跳转 +export async function generateAuthUrl(): Promise { + const state = generateRandomString(); // 生成防 CSRF 的随机串 + sessionStorage.setItem('hagicode_github_state', state); + + const params = new URLSearchParams({ + client_id: clientId, + redirect_uri: window.location.origin + '/settings?tab=github&oauth=callback', + scope: ['repo', 'public_repo'].join(' '), + state: state, + }); + + return `https://github.com/login/oauth/authorize?${params.toString()}`; +} + +// 在回调页面处理 Code 换取 Token +export async function exchangeCodeForToken(code: string, state: string): Promise { + // 1. 验证 State 防止 CSRF + const savedState = sessionStorage.getItem('hagicode_github_state'); + if (state !== savedState) throw new Error('Invalid state parameter'); + + // 2. 调用后端 API 进行 Token 交换 + // 注意:这里必须经过后端,因为需要 ClientSecret,不能暴露在前端 + const response = await fetch('/api/GitHubOAuth/callback', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ code, state, redirectUri: window.location.origin + '/settings?tab=github&oauth=callback' }), + }); + + if (!response.ok) throw new Error('Failed to exchange token'); + + const token = await response.json(); + + // 3. 存入 LocalStorage + saveToken(token); + return token; +} +``` + +### 3. GitHub API 客户端封装 + +有了 Token 之后,我们就需要一个强有力的工具来调 GitHub API。 + +```typescript +// src/HagiCode.Client/src/services/githubApiClient.ts + +const GITHUB_API_BASE = 'https://api.github.com'; + +// 核心请求封装 +async function githubApi(endpoint: string, options: RequestInit = {}): Promise { + const token = localStorage.getItem('gh_token'); + if (!token) throw new Error('Not connected to GitHub'); + + const response = await fetch(`${GITHUB_API_BASE}${endpoint}`, { + ...options, + headers: { + ...options.headers, + Authorization: `Bearer ${token}`, + Accept: 'application/vnd.github.v3+json', // 指定 API 版本 + }, + }); + + // 错误处理逻辑 + if (!response.ok) { + if (response.status === 401) throw new Error('GitHub Token 失效,请重新连接'); + if (response.status === 403) throw new Error('无权访问该仓库或超出速率限制'); + if (response.status === 422) throw new Error('Issue 验证失败,可能标题重复'); + throw new Error(`GitHub API Error: ${response.statusText}`); + } + + return response.json(); +} + +// 创建 Issue +export async function createIssue(owner: string, repo: string, data: { title: string, body: string, labels: string[] }) { + return githubApi(`/repos/${owner}/${repo}/issues`, { + method: 'POST', + body: JSON.stringify(data), + }); +} +``` + +### 4. 内容格式化与同步 + +最后一步,就是把 HagiCode 的 Session 数据转换成 GitHub Issue 的格式。这有点像"翻译"工作。 + +```typescript +// 将 Session 对象转换为 Markdown 字符串 +function formatIssueForSession(session: Session): string { + let content = `# ${session.title}\n\n`; + content += `**> HagiCode Session:** #${session.code}\n`; + content += `**> Status:** ${session.status}\n\n`; + content += `## Description\n\n${session.description || 'No description provided.'}\n\n`; + + // 如果是 Proposal 类型,添加额外字段 + if (session.type === 'proposal') { + content += `## Chief Complaint\n\n${session.chiefComplaint || ''}\n\n`; + // 添加一个深链接,方便从 GitHub 跳回 HagiCode + content += `---\n\n**[View in HagiCode](hagicode://sessions/${session.id})**\n`; + } + + return content; +} + +// 点击同步按钮的主逻辑 +const handleSync = async (session: Session) => { + try { + const repoInfo = parseRepositoryFromUrl(session.repoUrl); // 解析仓库 URL + if (!repoInfo) throw new Error('Invalid repository URL'); + + toast.loading('正在同步到 GitHub...'); + + // 1. 格式化内容 + const issueBody = formatIssueForSession(session); + + // 2. 调用 API + const issue = await githubApiClient.createIssue(repoInfo.owner, repoInfo.repo, { + title: `[HagiCode] ${session.title}`, + body: issueBody, + labels: ['hagicode', 'proposal', `status:${session.status}`], + }); + + // 3. 更新 Session Metadata (保存 Issue 链接) + await SessionsService.patchApiSessionsSessionId(session.id, { + metadata: { + githubIssue: { + owner: repoInfo.owner, + repo: repoInfo.repo, + issueNumber: issue.number, + issueUrl: issue.html_url, + syncedAt: new Date().toISOString(), + } + } + }); + + toast.success('同步成功!'); + } catch (err) { + console.error(err); + toast.error('同步失败,请检查 Token 或网络'); + } +}; +``` + +--- + +## 总结与展望 + +通过这套"前端直连"方案,我们用最少的后端代码实现了 GitHub Issues 的无缝集成。 + +### 收获 +1. **开发效率高**:后端改动极小,主要是数据库加一个字段和一个简单的 OAuth 回调接口,大部分逻辑都在前端完成。 +2. **安全性好**:Token 不经过服务器数据库,降低了泄露风险。 +3. **用户体验佳**:直接从前端发起请求,响应速度快,不需要经过后端中转。 + +### 注意事项 +在实际部署时,有几个坑大家要注意: +- **OAuth App 设置**:记得在 GitHub OAuth App 设置里填正确的 `Authorization callback URL`(通常是 `http://localhost:3000/settings?tab=github&oauth=callback`)。 +- **速率限制**:GitHub API 对未认证请求限制较严,但用 Token 后通常足够(5000次/小时)。 +- **URL 解析**:用户输入的 Repo URL 千奇百怪,记得正则要匹配 `.git` 后缀、SSH 格式等情况。 + +### 后续增强 +目前的功能还是单向同步(HagiCode -> GitHub)。未来我们计划通过 GitHub Webhooks 实现双向同步,比如在 GitHub 里关闭 Issue,HagiCode 这边的会话状态也能自动更新。这需要我们在后端暴露一个 Webhook 接收端点,这也是下一步要做的有趣工作。 + +希望这篇文章能给你的第三方集成开发带来一点灵感!如果有问题,欢迎在 [HagiCode GitHub](https://github.com/HagiCode-org/site) 上提 Issue 讨论。 \ No newline at end of file diff --git a/src/content/docs/blog/2026-01-25-how-to-sync-docker-hub-to-azure-acr-with-github.mdx b/src/content/docs/blog/2026-01-25-how-to-sync-docker-hub-to-azure-acr-with-github.mdx new file mode 100644 index 0000000..d71892e --- /dev/null +++ b/src/content/docs/blog/2026-01-25-how-to-sync-docker-hub-to-azure-acr-with-github.mdx @@ -0,0 +1,391 @@ +--- +title: "如何使用 GitHub Actions + image-syncer 实现 Docker Hub 到 Azure ACR 的自动化镜像同步" +date: 2026-01-25 +truncate: true +englishSlug: "how-to-sync-docker-hub-to-azure-acr-with-github" +--- + +# 实现 Docker Hub 到 Azure ACR 的自动化镜像同步 + +> 本文介绍了如何使用 GitHub Actions 和 image-syncer 工具,实现 Docker Hub 镜像到 Azure Container Registry 的自动化同步,解决了国内及部分 Azure 区域访问 Docker Hub 速度慢的问题,提升了镜像的可用性和 Azure 环境的部署效率。 + +## 背景/引言 + +HagiCode 项目使用 Docker 镜像作为核心运行时组件,主要镜像托管在 Docker Hub。随着项目发展和 Azure 环境部署需求的增加,我们遇到了以下痛点: +- 镜像拉取速度慢,Docker Hub 在国内及部分 Azure 区域访问受限 +- 依赖单一镜像源存在单点故障风险 +- Azure 环境下使用 Azure Container Registry 能获得更好的网络性能和集成体验 + +为解决这些问题,我们需要建立一个自动化的镜像同步机制,将 Docker Hub 的镜像定期同步到 Azure ACR,确保用户能够在 Azure 环境中获得更快的镜像拉取速度和更高的可用性。 + +## 关于 HagiCode + +我们正在开发 HagiCode——一款 AI 驱动的代码智能助手,让开发体验变得更智能、更便捷、更有趣。 + +智能——AI 全程辅助,从想法到代码,让编码效率提升数倍。便捷——多线程并发操作,充分利用资源,开发流程顺畅无阻。有趣——游戏化机制和成就系统,让编码不再枯燥,充满成就感。 + +项目正在快速迭代中,如果你对技术写作、知识管理或者 AI 辅助开发感兴趣,欢迎来 GitHub 看看。 + +## 技术方案对比 + +在制定解决方案时,我们对比了多种技术方案: + +### 1. image-syncer(最终选择) +- 增量同步:仅同步变更的镜像层,显著减少网络传输 +- 断点续传:网络中断后可恢复同步 +- 并发控制:支持配置并发线程数,提升大镜像同步效率 +- 完善的错误处理:内置失败重试机制(默认 3 次) +- 轻量级部署:单二进制文件,无依赖 +- 多仓库支持:兼容 Docker Hub、Azure ACR、Harbor 等 + +### 2. Docker CLI +- 不支持增量同步:每次都需要拉取完整的镜像内容 +- 效率较低:网络传输量大,时间长 +- 简单易用:使用熟悉的 docker pull/push 命令 + +### 3. Azure CLI +- 复杂度高:需要配置 Azure CLI 认证 +- 功能限制:az acr import 功能相对单一 +- 原生集成:与 Azure 服务集成良好 + +## 架构设计决策 + +### 决策 1:同步频率设置为每日 UTC 00:00 +- 平衡镜像新鲜度和资源消耗 +- 避开业务高峰期,减少对其他操作的影响 +- Docker Hub 镜像通常在每日构建后更新 + +### 决策 2:同步所有镜像标签 +- 保持与 Docker Hub 的完全一致性 +- 为用户提供灵活的版本选择 +- 简化同步逻辑,避免复杂的标签过滤规则 + +### 决策 3:使用 GitHub Secrets 存储认证信息 +- GitHub Actions 原生支持,安全性高 +- 配置简单,易于管理和维护 +- 支持仓库级别的访问控制 + +## 风险评估与缓解 + +### 风险 1:Azure ACR 认证信息泄露 +- 使用 GitHub Secrets 加密存储 +- 定期轮换 ACR 密码 +- 限制 ACR 用户权限为仅推送 +- 监控 ACR 访问日志 + +### 风险 2:同步失败导致镜像不一致 +- image-syncer 内置增量同步机制 +- 自动失败重试(默认 3 次) +- 详细的错误日志和失败通知 +- 断点续传功能 + +### 风险 3:资源消耗过大 +- 增量同步减少网络传输 +- 可配置并发线程数(当前设置为 10) +- 监控同步的镜像数量和大小 +- 在非高峰时段运行同步 + +## 核心解决方案 + +我们采用 GitHub Actions + image-syncer 的自动化方案,实现从 Docker Hub 到 Azure ACR 的镜像同步。 + +## 实施步骤 + +### 1. 准备阶段 +- 在 Azure Portal 中创建或确认 Azure Container Registry +- 创建 ACR 访问密钥(用户名和密码) +- 确认 Docker Hub 镜像仓库访问权限 + +### 2. 配置 GitHub Secrets +在 GitHub 仓库设置中添加以下 Secrets: +- AZURE_ACR_USERNAME: Azure ACR 用户名 +- AZURE_ACR_PASSWORD: Azure ACR 密码 + +### 3. 创建 GitHub Actions 工作流 +在 .github/workflows/sync-docker-acr.yml 中配置工作流: +- 定时触发:每天 UTC 00:00 +- 手动触发:支持 workflow_dispatch +- 额外触发:publish 分支推送时触发(用于快速同步) + +### 4. 工作流执行流程 +```mermaid +sequenceDiagram + participant GH as GitHub Actions + participant IS as image-syncer + participant DH as Docker Hub + participant ACR as Azure ACR + + Note over GH: 触发工作流 + GH->>IS: 下载并执行 image-syncer + IS->>DH: 获取镜像 manifest 和标签列表 + DH-->>IS: 返回镜像元数据 + IS->>ACR: 获取已存在的镜像信息 + ACR-->>IS: 返回目标镜像信息 + IS->>IS: 对比差异,识别变更的镜像层 + Note over IS: 增量同步:仅传输变更的镜像层 + IS->>DH: 拉取变更的镜像层 + DH-->>IS: 返回镜像层内容 + IS->>ACR: 推送变更的镜像层到 ACR + ACR-->>IS: 返回推送结果 + IS-->>GH: 返回同步统计信息 + GH->>GH: 记录同步日志并上传 artifact +``` + +## GitHub Actions 工作流实现 + +以下是实际运行的工作流配置(.github/workflows/sync-docker-acr.yml): + +```yaml +name: Sync Docker Image to Azure ACR + +on: + schedule: + - cron: "0 0 * * *" # 每天 UTC 00:00 + workflow_dispatch: # 手动触发 + push: + branches: [publish] + +permissions: + contents: read + +jobs: + sync: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Download image-syncer + run: | + # 下载 image-syncer 二进制文件 + wget https://github.com/AliyunContainerService/image-syncer/releases/download/v1.5.5/image-syncer-v1.5.5-linux-amd64.tar.gz + tar -zxvf image-syncer-v1.5.5-linux-amd64.tar.gz + chmod +x image-syncer + + - name: Create auth config + run: | + # 生成认证配置文件 (YAML 格式) + cat > auth.yaml < images.yaml < images.yaml +``` + +### 3. 添加同步统计报告 +```yaml +- name: Generate report + if: always() + run: | + echo "## Sync Report" >> $GITHUB_STEP_SUMMARY + echo "- Total tags: $(grep -c 'synced' image-syncer-*.log)" >> $GITHUB_STEP_SUMMARY + echo "- Sync time: ${{ steps.sync.outputs.duration }}" >> $GITHUB_STEP_SUMMARY +``` + +## 总结 + +通过本文介绍的方法,我们成功实现了从 Docker Hub 到 Azure ACR 的自动化镜像同步。这个方案利用 GitHub Actions 的定时触发和手动触发功能,结合 image-syncer 的增量同步和错误处理机制,确保了镜像的及时同步和一致性。 + +我们还讨论了安全最佳实践、性能优化、故障排查等方面的内容,帮助用户更好地管理和维护这个同步机制。希望本文能够为需要在 Azure 环境中部署 Docker 镜像的开发者提供有价值的参考。 + +## 参考资料 +- [HagiCode 项目 GitHub 仓库](https://github.com/HagiCode-org/site) +- [image-syncer 官方文档](https://github.com/AliyunContainerService/image-syncer) +- [Azure Container Registry 官方文档](https://learn.microsoft.com/zh-cn/azure/container-registry/) +- [GitHub Actions 官方文档](https://docs.github.com/zh-cn/actions) + +--- + +## 互动引导 + +感谢您的阅读,如果您觉得本文有用,快点击下方点赞按钮👍,让更多的人看到本文。 + +## AI 辅助声明 + +本内容采用人工智能辅助协作,经本人审核,符合本人观点与立场。 + +## 元信息 + +- **本文作者:** [newbe36524](https://www.newbe.pro) +- **本文链接:** [https://hagicode.com/blog/2026/01/25/how-to-sync-docker-hub-to-azure-acr-with-github](https://hagicode.com/blog/2026/01/25/how-to-sync-docker-hub-to-azure-acr-with-github) +- **版权声明:** 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处! \ No newline at end of file diff --git a/src/content/docs/blog/2026-01-26-docusaurus-auto-deployment-with-github-actions.mdx b/src/content/docs/blog/2026-01-26-docusaurus-auto-deployment-with-github-actions.mdx new file mode 100644 index 0000000..823e85a --- /dev/null +++ b/src/content/docs/blog/2026-01-26-docusaurus-auto-deployment-with-github-actions.mdx @@ -0,0 +1,204 @@ +--- +title: "HagiCode 实践:如何利用 GitHub Actions 实现 Docusaurus 自动部署" +date: 2026-01-26 +truncate: true +englishSlug: "docusaurus-auto-deployment-with-github-actions" +--- + +# 为 HagiCode 添加 GitHub Pages 自动部署支持 + +> 本项目早期代号为 PCode,现已正式更名为 HagiCode。本文记录了如何为项目引入自动化静态站点部署能力,让内容发布像喝水一样简单。 + +## 背景/引言 + +在 HagiCode 的开发过程中,我们遇到了一个很现实的问题:随着文档和提案越来越多,如何高效地管理和展示这些内容成了当务之急。我们决定引入 GitHub Pages 来托管我们的静态站点,但是手动构建和部署实在是太麻烦了——每次改动都要本地构建、打包,然后手动推送到 `gh-pages` 分支。这不仅效率低下,还容易出错。 + +为了解决这个问题(主要是为了偷懒),我们需要一套自动化的部署流程。本文将详细记录如何为 HagiCode 项目添加 GitHub Actions 自动部署支持,让我们只需专注于内容创作,剩下的交给自动化流程。 + +## 关于 HagiCode + +> 嘿,介绍一下我们正在做的东西 + +我们正在开发 **HagiCode**——一款 AI 驱动的代码智能助手,让开发体验变得更智能、更便捷、更有趣。 + +**智能**——AI 全程辅助,从想法到代码,让编码效率提升数倍。**便捷**——多线程并发操作,充分利用资源,开发流程顺畅无阻。**有趣**——游戏化机制和成就系统,让编码不再枯燥,充满成就感。 + +项目正在快速迭代中,如果你对技术写作、知识管理或者 AI 辅助开发感兴趣,欢迎来 [GitHub](https://github.com/HagiCode-org/site) 看看~ + +## 目标分析 + +在动手之前,我们得先明确这次任务到底要干啥。毕竟(这里打错了,应该是毕竟)磨刀不误砍柴工嘛。 + +### 核心需求 + +1. **自动化构建**:当代码推送到 `main` 分支时,自动触发构建流程。 +2. **自动部署**:构建成功后,自动将生成的静态文件部署到 GitHub Pages。 +3. **环境一致性**:确保 CI 环境和本地构建环境一致,避免"本地能跑,线上报错"的尴尬。 + +### 技术选型 + +考虑到 HagiCode 是基于 Docusaurus 构建的(一种非常流行的 React 静态站点生成器),我们可以利用 GitHub Actions 来实现这一目标。 + +## 配置 GitHub Actions 工作流 + +GitHub Actions 是 GitHub 提供的 CI/CD 服务。通过在代码仓库中定义 YAML 格式的工作流文件,我们可以定制各种自动化任务。 + +### 创建工作流文件 + +我们需要在项目根目录下的 `.github/workflows` 文件夹中创建一个新的配置文件,比如叫 `deploy.yml`。如果文件夹不存在,记得先手动创建一下。 + +这个配置文件的核心逻辑如下: + +1. **触发条件**:监听 `main` 分支的 `push` 事件。 +2. **运行环境**:最新版的 Ubuntu。 +3. **构建步骤**: + - 检出代码 + - 安装 Node.js + - 安装依赖 (`npm install`) + - 构建静态文件 (`npm run build`) +4. **部署步骤**:使用官方提供的 `action-gh-pages` 将构建产物推送到 `gh-pages` 分支。 + +### 关键配置代码 + +以下是我们最终采用的配置模板: + +```yaml +name: Deploy to GitHub Pages + +# 触发条件:当推送到 main 分支时 +on: + push: + branches: + - main + # 可以根据需要添加路径过滤,比如只有文档变动才构建 + # paths: + # - 'docs/**' + # - 'package.json' + +# 设置权限,这对于部署到 GitHub Pages 很重要 +permissions: + contents: read + pages: write + id-token: write + +# 并发控制:取消同一分支的旧构建 +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + # 注意:必须设置 fetch-depth: 0,否则可能导致构建版本号不准确 + with: + fetch-depth: 0 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 # 建议与本地开发环境保持一致 + cache: 'npm' # 启用缓存可以加速构建过程 + + - name: Install dependencies + run: npm ci + # 使用 npm ci 而不是 npm install,因为它更快、更严格,适合 CI 环境 + + - name: Build website + run: npm run build + env: + # 如果你的站点构建需要环境变量,在这里配置 + # NODE_ENV: production + # PUBLIC_URL: /your-repo-name + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: ./build # Docusaurus 默认输出目录 + + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 +``` + +## 实施过程中的坑点 + +在实际操作中,我们遇到了一些问题,这里分享出来希望大家能避开(或者提前准备好解决方案)。 + +### 1. GitHub Token 权限问题 + +最开始配置的时候,部署总是报错 403 (Forbidden)。查了好久才发现,是因为 GitHub 默认的 `GITHUB_TOKEN` 并没有写入 Pages 的权限。 + +**解决方案**:在仓库的 `Settings` -> `Actions` -> `General` -> `Workflow permissions` 中,务必选择 **"Read and write permissions"**。 + +### 2. 构建目录路径错误 + +Docusaurus 默认把构建好的静态文件放在 `build` 目录。但是有些项目(比如 Create React App 默认是 `build`,Vite 默认是 `dist`)可能配置不一样。如果在 Actions 中报错找不到文件,记得去 `docusaurus.config.js` 里检查一下输出路径配置。 + +### 3. 子路径问题 + +如果你的仓库不是用户主页(即不是 `username.github.io`),而是项目主页(比如 `username.github.io/project-name`),你需要配置 `baseUrl`。 + +在 `docusaurus.config.js` 中: + +```javascript +module.exports = { + // ... + url: 'https://hagicode.com', // 你的 Hagicode URL + baseUrl: '/', // 根路径部署 + // ... +}; +``` +这一点很容易被忽略,配置不对会导致页面打开全是白屏,因为资源路径加载不到。 + +## 验证成果 + +配置完所有东西并推送代码后,我们就可以去 GitHub 仓库的 **Actions** 标签页看戏了。 + +你会看到黄色的圆圈(工作流正在运行),变绿就代表成功啦!如果变红了,点击进去查看日志,通常都能排查出问题(大部分时候是拼写错误或者路径配置不对)。 + +构建成功后,访问 `https://<你的用户名>.github.io/<仓库名>/` 就能看到崭新的站点了。 + +## 总结 + +通过引入 GitHub Actions,我们成功实现了 HagiCode 文档站的自动化部署。这不仅节省了手动操作的时间,更重要的是保证了发布流程的标准化。现在不管是哪位小伙伴更新了文档,只要合并到 `main` 分支,几分钟后就能在线上看到最新的内容。 + +**核心收益**: +- **效率提升**:从"手动打包、手动上传"变成"代码即发布"。 +- **降低错误**:消除了人为操作失误的可能性。 +- **体验优化**:让开发者更专注于内容质量,而不是被繁琐的部署流程困扰。 + +虽然配置 CI/CD 刚开始有点麻烦(尤其是各种权限和路径问题),但这是一次性投入,长期回报巨大的工作。强烈建议所有静态站点项目都接入类似的自动化流程。 + +## 参考资料 + +- [GitHub Actions 官方文档](https://docs.github.com/en/actions) +- [Docusaurus 部署指南](https://docusaurus.io/docs/deployment) +- [actions-gh-pages Action 使用说明](https://github.com peaceiris/actions-gh-pages) + + + +--- + +## 互动引导 + +感谢您的阅读,如果您觉得本文有用,快点击下方点赞按钮👍,让更多的人看到本文。 + +## AI 辅助声明 + +本内容采用人工智能辅助协作,经本人审核,符合本人观点与立场。 + +## 元信息 + +- **本文作者:** [newbe36524](https://www.newbe.pro) +- **本文链接:** [https://hagicode.com/blog/2026/01/25/docusaurus-auto-deployment-with-github-actions](https://hagicode.com/blog/2026/01/25/docusaurus-auto-deployment-with-github-actions) +- **版权声明:** 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处! \ No newline at end of file diff --git a/src/content/docs/blog/2026-01-26-modern-build-system-with-csharp-and-nuke.mdx b/src/content/docs/blog/2026-01-26-modern-build-system-with-csharp-and-nuke.mdx new file mode 100644 index 0000000..4ee2496 --- /dev/null +++ b/src/content/docs/blog/2026-01-26-modern-build-system-with-csharp-and-nuke.mdx @@ -0,0 +1,173 @@ +--- +title: "基于 C# 和 Nuke 打造现代化构建系统的最佳实践" +date: 2026-01-26 +truncate: true +englishSlug: "modern-build-system-with-csharp-and-nuke" +--- + +# 告别脚本地狱:为什么我们选择用 C# 打造现代化构建系统 + +> 揭秘 HagiCode 项目如何利用 Nuke 实现类型安全、跨平台且高度可扩展的自动化构建流程,彻底解决传统构建脚本的维护痛点。 + +## 背景 + +在软件开发的漫长旅途中,"构建"这个词往往让人又爱又恨。爱的是,一键点击,代码变成产品,那是程序员最迷人的时刻;恨的是,维护那一堆乱糟糟的构建脚本,简直是噩梦。 + +在很多项目中,我们习惯了用 Python 写脚本,或者用 XML 配置文件(想象一下那段被 `` 支配的恐惧)。但随着项目复杂度的提升,尤其是像 HagiCode 这样涉及前后端、多平台、多语言混合开发的项目,传统的构建方式开始显得力不从心。脚本逻辑分散、缺乏类型检查、IDE 支持弱……这些问题像一个个小坑,时不时就让开发团队绊个跟头。 + +为了解决这些痛点,在 HagiCode 项目中,我们决定引入 **Nuke** —— 一个基于 C# 的现代化构建系统。它不仅仅是一个工具,更像是一种对构建流程的重新思考。今天,我们就来聊聊为什么选择它,以及它是如何让我们的开发体验"起飞"的。 + +## 关于 HagiCode + +> 嘿,介绍一下我们正在做的东西 + +我们正在开发 **HagiCode** —— 一款 AI 驱动的代码智能助手,让开发体验变得更智能、更便捷、更有趣。 + +**智能** —— AI 全程辅助,从想法到代码,让编码效率提升数倍。**便捷** —— 多线程并发操作,充分利用资源,开发流程顺畅无阻。**有趣** —— 游戏化机制和成就系统,让编码不再枯燥,充满成就感。 + +项目正在快速迭代中,如果你对技术写作、知识管理或者 AI 辅助开发感兴趣,欢迎来 [GitHub](https://github.com/HagiCode-org/site) 看看~ + +## 核心剖析:为什么是 Nuke? + +你可能心里会犯嘀咕:"哎呀,构建系统那么多,比如 Make、Gradle,甚至直接用 Shell 脚本不行吗?为啥非得整一个 C# 的?" + +这其实是个好问题。Nuke 的核心魅力在于它把我们最熟悉的编程语言特性带进了构建脚本的世界。 + +### 1. 将构建流程模块化:Target 的艺术 + +Nuke 的设计理念非常清晰:**一切皆为目标**。 + +在传统的脚本里,我们可能会写出几百行线性执行的代码,逻辑错综复杂。而在 Nuke 中,我们将构建流程分解为独立的 `Target`(目标)。每个目标只负责一件事,比如: + +- `Clean`: 清理输出目录 +- `Restore`: 还原依赖包 +- `Compile`: 编译代码 +- `Test`: 运行单元测试 + +这种设计非常符合单一职责原则。就像搭积木一样,我们可以随意组合这些 Target。更重要的是,Nuke 允许我们定义 Target 之间的依赖关系。比如,你想要 `Test`,那系统会自动检查你是否先执行了 `Compile`;想要 `Compile`,自然得先 `Restore`。 + +这种依赖关系图不仅让逻辑更清晰,还极大地提高了执行效率,Nuke 会自动分析最优执行路径。 + +### 2. 类型安全:告别拼写错误的噩梦 + +用过 Python 写构建脚本的朋友肯定遇到过这种尴尬:脚本跑了五分钟,最后报错说 `Confi.guration` 拼写错了,或者传了一个字符串给了一个本该是数字的参数。 + +使用 C# 编写构建脚本最大的优势就是 **类型安全**。这意味着: + +- **编译时检查**:你在敲代码的时候,IDE 就会告诉你哪里错了,不用等到运行时才发现。 +- **重构无忧**:如果你想改个变量名或者方法名,IDE 的重构功能一键搞定,不用全局搜索替换提心吊胆。 +- **智能提示**:强大的 IntelliSense 会自动补全代码,你不需要去翻文档记那些生僻的 API。 + +### 3. 跨平台:统一的构建体验 + +以前在 Windows 上写 `.bat`,在 Linux 上写 `.sh`,为了兼容两者,还得写个 Python 脚本。现在,只要是 .NET Core(现 .NET 5+)能跑的地方,Nuke 就能跑。 + +这意味着无论团队成员是使用 Windows、Linux 还是 macOS,无论是用 Visual Studio、VS Code 还是 Rider,大家执行的都是同一套逻辑。这就极大地消除了"在我机器上能跑"这类环境差异导致的问题。 + +### 4. 参数与配置管理 + +Nuke 提供了一套非常优雅的参数解析机制。你不需要手动去解析 `string[] args`,只需要定义一个属性,加上 `[Parameter]` 特性,Nuke 就会自动处理命令行参数和配置文件的映射。 + +比如,我们可以轻松定义构建配置: + +```csharp +[Parameter("Configuration to build - Default is 'Debug'")] +readonly Configuration BuildConfiguration = IsLocalBuild ? Configuration.Debug : Configuration.Release; + +Target Compile => _ => _ + .DependsOn(Restore) + .Executes(() => + { + // 在这里使用 BuildConfiguration,它是类型安全的 + DotNetBuild(s => s + .SetConfiguration(BuildConfiguration) + .SetProjectFile(SolutionFile)); + }); +``` + +这种写法既直观又不容易出错。 + +## 实践指南:如何在项目中落地 + +空谈误国,实干兴邦。让我们看看在 HagiCode 项目中,具体是怎么落地这套方案的。 + +### 1. 规划项目结构 + +我们不想让构建脚本污染项目根目录,也不想搞得像某些 Java 项目那样目录结构深不见底。所以,我们将所有与 Nuke 相关的构建文件统一放置在 `nukeBuild/` 文件夹中。 + +这样做的好处是: +- 项目根目录保持清爽。 +- 构建逻辑内聚,方便管理。 +- 新成员加入时,一眼就能看到"哦,这是构建相关的逻辑"。 + +### 2. 设计清晰的 Target 依赖链 + +在设计 Target 时,我们遵循了一个原则:**原子化 + 依赖流**。 + +每个 Target 应该足够小,只做一件事。比如 `Clean` 就只管删文件,不要在里面顺便做打包。 + +推荐的依赖流大概是这个样子的: + +`Clean` -> `Restore` -> `Compile` -> `Test` -> `Pack` + +当然,这不是绝对的。比如如果你只想跑个测试,不想打包,Nuke 允许你直接执行 `nuke Test`,它会自动处理好前置的 Restore 和 Compile 步骤。 + +### 3. 完善的错误处理与日志 + +构建脚本最怕的是什么?是报错信息不明确。比如构建失败了,日志只显示 "Error: 1",这就让人很抓狂。 + +在 Nuke 中,由于我们可以直接使用 C# 的异常处理机制,因此可以非常精确地捕获和报告错误。 + +```csharp +Target Publish => _ => _ + .DependsOn(Test) + .Executes(() => + { + try + { + // 尝试发布到 NuGet + DotNetNuGetPush(s => s + .SetTargetPath(ArtifactPath) + .SetSource("https://api.nuget.org/v3/index.json") + .SetApiKey(ApiKey)); + } + catch (Exception ex) + { + Log.Error($"发布失败了,兄弟们检查一下 Key 对不对: {ex.Message}"); + throw; // 确保构建进程以非零退出码结束 + } + }); +``` + +### 4. 集成测试保障质量 + +构建脚本本身也是代码,也需要测试。Nuke 允许我们为构建流程编写测试,确保当我们修改了构建逻辑后,不会破坏现有的发布流程。这在持续集成(CI)流水线中尤为重要。 + +## 总结 + +通过引入 Nuke,HagiCode 的构建流程变得前所未有的顺畅。它不仅仅是一个工具的替换,更是工程化思维的提升。 + +**我们收获了什么?** +- **可维护性**:代码即配置,逻辑清晰,新人也能快速上手。 +- **稳定性**:强类型检查减少了 90% 以上的低级错误。 +- **一致性**:跨平台的统一体验,消除了环境差异。 + +如果说以前写构建脚本是"在黑暗中摸索",那么使用 Nuke 就像是"开着灯走夜路"。如果你受够了维护那些难以调试的脚本语言,不妨试试把构建逻辑也搬到 C# 的世界里来,也许你会发现,原来构建也可以这么优雅。 + +## 参考资料 + +- [Nuke 官方文档](https://nuke.build/) +- [HagiCode 项目地址](https://github.com/HagiCode-org/site) +- [关于 C# Scripting 的更多细节](https://learn.microsoft.com/en-us/archive/csharp-team/introducing-csharp-scripting) + + + +--- + +感谢您的阅读,如果您觉得本文有用,快点击下方点赞按钮👍,让更多的人看到本文。 + +本内容采用人工智能辅助协作,经本人审核,符合本人观点与立场。 + +- **本文作者:** [newbe36524](https://www.newbe.pro) +- **本文链接:** [https://hagicode.com/blog/2026/01/26/modern-build-system-with-csharp-and-nuke](https://hagicode.com/blog/2026/01/26/modern-build-system-with-csharp-and-nuke) +- **版权声明:** 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处! \ No newline at end of file diff --git a/src/content/docs/blog/2026-01-28-streamjsonrpc-integration-in-hagicode.mdx b/src/content/docs/blog/2026-01-28-streamjsonrpc-integration-in-hagicode.mdx new file mode 100644 index 0000000..2c6c3e7 --- /dev/null +++ b/src/content/docs/blog/2026-01-28-streamjsonrpc-integration-in-hagicode.mdx @@ -0,0 +1,326 @@ +--- +title: "StreamJsonRpc 在 HagiCode 中的深度集成与实践" +date: 2026-01-28 +truncate: true +englishSlug: "streamjsonrpc-integration-in-hagicode" +--- + +# StreamJsonRpc 在 HagiCode 中的深度集成与实践 + +> 本文详细介绍了 HagiCode(原 PCode)项目如何成功集成 Microsoft 的 StreamJsonRpc 通信库,以替换原有的自定义 JSON-RPC 实现,并解决了集成过程中的技术痛点与架构挑战。 + +## 背景 + +StreamJsonRpc 是微软官方维护的用于 .NET 和 TypeScript 的 JSON-RPC 通信库,以其强大的类型安全、自动代理生成和成熟的异常处理机制著称。在 HagiCode 项目中,为了通过 ACP (Agent Communication Protocol) 与外部 AI 工具(如 iflow CLI、OpenCode CLI)进行通信,并消除早期自定义 JSON-RPC 实现带来的维护成本和潜在 Bug,项目决定集成 StreamJsonRpc。然而,在集成过程中遇到了流式 JSON-RPC 特有的挑战,特别是在处理代理目标绑定和泛型参数识别时。 + +为了解决这些痛点,我们做了一个大胆的决定:整个构建系统推倒重来。这个决定带来的变化,可能比你想象的还要大——稍后我会具体说。 + +## 关于 HagiCode + +> 先介绍一下本文的"主角项目" + +如果你在开发中遇到过这些烦恼: +- 多项目、多技术栈,构建脚本维护成本高 +- CI/CD 流水线配置繁琐,每次改都要查文档 +- 跨平台兼容性问题层出不穷 +- 想让 AI 帮忙写代码,但现有工具不够智能 + +那么我们正在做的 HagiCode 可能你会感兴趣。 + +**HagiCode 是什么?** +- 一款 AI 驱动的代码智能助手 +- 支持多语言、跨平台的代码生成与优化 +- 内置游戏化机制,让编码不再枯燥 + +**为什么在这里提它?** +本文分享的 StreamJsonRpc 集成方案,正是我们在开发 HagiCode 过程中实践总结出来的。如果你觉得这套工程化方案有价值,说明我们的技术品味还不错——那么 HagiCode 本身也值得关注一下。 + +**想了解更多?** +- GitHub: [github.com/HagiCode-org/site](https://github.com/HagiCode-org/site)(求 Star) +- 官网: [hagicode.com](https://hagicode.com) +- 视频演示: [www.bilibili.com/video/BV1pirZBuEzq/](https://www.bilibili.com/video/BV1pirZBuEzq/)(30 分钟实战演示) +- 安装指南: [hagicode.com/installation/docker-compose](https://hagicode.com/installation/docker-compose) +- 公测已开始:现在安装即可参与公测 + +## 分析 + +当前项目处于 ACP 协议集成的关键阶段,面临着以下几个技术痛点和架构挑战: + +### 1. 自定义实现的局限 +原有的 JSON-RPC 实现位于 `src/HagiCode.ClaudeHelper/AcpImp/`,包含 `JsonRpcEndpoint` 和 `ClientSideConnection` 等组件。维护这套自定义代码成本高,且缺乏成熟库的高级功能(如进度报告、取消支持)。 + +### 2. StreamJsonRpc 集成障碍 +在尝试将现有的 `CallbackProxyTarget` 模式迁移到 StreamJsonRpc 时,发现 `_rpc.AddLocalRpcTarget(target)` 方法无法识别通过代理模式创建的目标。具体表现为,StreamJsonRpc 无法自动将泛型类型 `T` 的属性拆分为 RPC 方法参数,导致服务器端无法正确处理客户端发起的方法调用。 + +### 3. 架构分层混乱 +现有的 `ClientSideConnection` 混合了传输层(WebSocket/Stdio)、协议层(JSON-RPC)和业务层(ACP Agent 接口),导致职责不清,且存在 `AcpAgentCallbackRpcAdapter` 方法绑定缺失的问题。 + +### 4. 日志缺失 +WebSocket 传输层缺少对原始 JSON 内容的日志输出,导致在调试 RPC 通信问题时难以定位是序列化问题还是网络问题。 + +## 解决 + +针对上述问题,我们采用了以下系统化的解决方案,从架构重构、库集成和调试增强三个维度进行优化: + +### 1. 全面迁移至 StreamJsonRpc + +#### 移除旧代码 +删除 `JsonRpcEndpoint.cs`、`AgentSideConnection.cs` 及相关的自定义序列化转换器(`JsonRpcMessageJsonConverter` 等)。 + +#### 集成官方库 +引入 `StreamJsonRpc` NuGet 包,利用其 `JsonRpc` 类处理核心通信逻辑。 + +#### 抽象传输层 +定义 `IAcpTransport` 接口,统一处理 `WebSocket` 和 `Stdio` 两种传输模式,确保协议层与传输层解耦。 + +```csharp +// IAcpTransport 接口定义 +public interface IAcpTransport +{ + Task SendAsync(string message, CancellationToken cancellationToken = default); + Task ReceiveAsync(CancellationToken cancellationToken = default); + Task CloseAsync(CancellationToken cancellationToken = default); +} + +// WebSocket 传输实现 +public class WebSocketTransport : IAcpTransport +{ + private readonly WebSocket _webSocket; + + public WebSocketTransport(WebSocket webSocket) + { + _webSocket = webSocket; + } + + // 实现发送和接收方法 + // ... +} + +// Stdio 传输实现 +public class StdioTransport : IAcpTransport +{ + private readonly StreamReader _reader; + private readonly StreamWriter _writer; + + public StdioTransport(StreamReader reader, StreamWriter writer) + { + _reader = reader; + _writer = writer; + } + + // 实现发送和接收方法 + // ... +} +``` + +### 2. 修复代理目标识别问题 + +#### 分析 `CallbackProxyTarget` +检查现有的动态代理生成逻辑,确定 StreamJsonRpc 无法识别的根本原因(通常是因为代理对象没有公开实际的方法签名,或者使用了 StreamJsonRpc 不支持的参数类型)。 + +#### 重构参数传递 +将泛型属性拆分为明确的 RPC 方法参数。不再依赖动态属性,而是定义具体的 Request/Response DTO(数据传输对象),确保 StreamJsonRpc 能通过反射正确识别方法签名。 + +```csharp +// 原有的泛型属性方式 +public class CallbackProxyTarget +{ + public Func Callback { get; set; } +} + +// 重构后的具体方法方式 +public class ReadTextFileRequest +{ + public string FilePath { get; set; } +} + +public class ReadTextFileResponse +{ + public string Content { get; set; } +} + +public interface IAcpAgentCallback +{ + Task ReadTextFileAsync(ReadTextFileRequest request); + // 其他方法... +} +``` + +#### 使用 `Attach` 替代 `AddLocalRpcTarget` +在某些复杂场景下,手动代理 `JsonRpc` 对象并处理 `RpcConnection` 可能比直接添加目标更灵活。 + +### 3. 实现方法绑定与日志增强 + +#### 实现 `AcpAgentCallbackRpcAdapter` +确保该组件显式实现 StreamJsonRpc 的代理接口,将 ACP 协议定义的方法(如 `ReadTextFileAsync`)映射到 StreamJsonRpc 的回调处理器上。 + +#### 集成日志记录 +在 WebSocket 或 Stdio 的消息处理管道中,拦截并记录 JSON-RPC 请求和响应的原始文本。利用 `ILogger` 在解析前和序列化后输出原始 payload,以便排查格式错误。 + +```csharp +// 日志增强的传输包装器 +public class LoggingAcpTransport : IAcpTransport +{ + private readonly IAcpTransport _innerTransport; + private readonly ILogger _logger; + + public LoggingAcpTransport(IAcpTransport innerTransport, ILogger logger) + { + _innerTransport = innerTransport; + _logger = logger; + } + + public async Task SendAsync(string message, CancellationToken cancellationToken = default) + { + _logger.LogTrace("Sending message: {Message}", message); + await _innerTransport.SendAsync(message, cancellationToken); + } + + public async Task ReceiveAsync(CancellationToken cancellationToken = default) + { + var message = await _innerTransport.ReceiveAsync(cancellationToken); + _logger.LogTrace("Received message: {Message}", message); + return message; + } + + public async Task CloseAsync(CancellationToken cancellationToken = default) + { + _logger.LogDebug("Closing connection"); + await _innerTransport.CloseAsync(cancellationToken); + } +} +``` + +### 4. 架构分层重构 + +#### 传输层 (`AcpRpcClient`) +封装 StreamJsonRpc 连接,负责 `InvokeAsync` 和连接生命周期管理。 + +```csharp +public class AcpRpcClient : IDisposable +{ + private readonly JsonRpc _rpc; + private readonly IAcpTransport _transport; + + public AcpRpcClient(IAcpTransport transport) + { + _transport = transport; + _rpc = new JsonRpc(new StreamRpcTransport(transport)); + _rpc.StartListening(); + } + + public async Task InvokeAsync(string methodName, object parameters) + { + return await _rpc.InvokeAsync(methodName, parameters); + } + + public void Dispose() + { + _rpc.Dispose(); + _transport.Dispose(); + } + + // StreamRpcTransport 是对 IAcpTransport 的 StreamJsonRpc 适配器 + private class StreamRpcTransport : IDuplexPipe + { + // 实现 IDuplexPipe 接口 + // ... + } +} +``` + +#### 协议层 (`IAcpAgentClient` / `IAcpAgentCallback`) +定义清晰的 client-to-agent 和 agent-to-client 接口,移除 `Func` 这种循环依赖的工厂模式,改用依赖注入或直接注册回调。 + +## 实践 + +基于 StreamJsonRpc 的最佳实践和项目经验,以下是实施过程中的关键建议: + +### 1. 强类型 DTO 优于动态对象 +StreamJsonRpc 的核心优势在于强类型。不要使用 `dynamic` 或 `JObject` 传递参数。应为每个 RPC 方法定义明确的 C# POCO 类作为参数。这不仅解决了代理目标识别问题,还能在编译时发现类型错误。 + +示例:将 `CallbackProxyTarget` 中的泛型属性替换为 `ReadTextFileRequest` 和 `WriteTextFileRequest` 等具体类。 + +### 2. 显式声明 Method Name +使用 `[JsonRpcMethod]` 特性显式指定 RPC 方法名称,不要依赖默认的方法名映射。这可以防止因命名风格差异(如 PascalCase vs camelCase)导致的调用失败。 + +```csharp +public interface IAcpAgentCallback +{ + [JsonRpcMethod("readTextFile")] + Task ReadTextFileAsync(ReadTextFileRequest request); + + [JsonRpcMethod("writeTextFile")] + Task WriteTextFileAsync(WriteTextFileRequest request); +} +``` + +### 3. 利用连接状态回调 +StreamJsonRpc 提供了 `JsonRpc.ConnectionLost` 事件。务必监听此事件以处理进程意外退出或网络断开的情况,这比单纯依赖 Orleans 的 Grain 失效检测更及时。 + +```csharp +_rpc.ConnectionLost += (sender, e) => +{ + _logger.LogError("RPC connection lost: {Reason}", e.ToString()); + // 处理重连逻辑或通知用户 +}; +``` + +### 4. 日志分层记录 +- **Trace 级别**:记录完整的 JSON Request/Response 原文。 +- **Debug 级别**:记录方法调用栈和参数摘要。 +- **注意**:确保日志中不包含敏感的 Authorization Token 或大文件内容的 Base64 编码。 + +### 5. 处理流式传输的特殊性 +StreamJsonRpc 原生支持 `IAsyncEnumerable`。在实现 ACP 的流式 Prompt 响应时,应直接使用 `IAsyncEnumerable` 而不是自定义的分页逻辑。这能极大简化流式处理的代码量。 + +```csharp +public interface IAcpAgentCallback +{ + [JsonRpcMethod("streamText")] + IAsyncEnumerable StreamTextAsync(StreamTextRequest request); +} +``` + +### 6. 适配器模式 (Adapter Pattern) +保持 `ACPSession` 和 `ClientSideConnection` 的分离。`ACPSession` 应专注于 Orleans 的状态管理和业务逻辑(如消息入队),通过组合而非继承的方式使用 StreamJsonRpc 连接对象。 + +## 总结 + +通过全面集成 StreamJsonRpc,HagiCode 项目成功解决了原自定义实现的维护成本高、功能局限性和架构分层混乱等问题。关键改进包括: + +1. 采用强类型 DTO 替代动态属性,提高了代码的可维护性和可靠性 +2. 实现了传输层抽象和协议层分离,提升了架构的清晰性 +3. 增强了日志记录功能,便于排查通信问题 +4. 引入了流式传输支持,简化了流式处理的实现 + +这些改进为 HagiCode 提供了更稳定、更高效的通信基础,使其能够更好地与外部 AI 工具进行交互,并为未来的功能扩展奠定了坚实的基础。 + +## 参考资料 + +- StreamJsonRpc 官方文档:[https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.threading.streamjsonrpc](https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.threading.streamjsonrpc) +- ACP (Agent Communication Protocol) 规范:[https://github.com/microsoft/agentcommunicationprotocol](https://github.com/microsoft/agentcommunicationprotocol) +- HagiCode 项目:[https://github.com/HagiCode-org/site](https://github.com/HagiCode-org/site) +- Orleans 官方文档:[https://learn.microsoft.com/en-us/dotnet/orleans](https://learn.microsoft.com/en-us/dotnet/orleans) + +--- + +如果本文对你有帮助: +- 点个赞让更多人看到 +- 来 GitHub 给个 Star:[github.com/HagiCode-org/site](https://github.com/HagiCode-org/site) +- 访问官网了解更多:[hagicode.com](https://hagicode.com) +- 观看 30 分钟实战演示:[www.bilibili.com/video/BV1pirZBuEzq/](https://www.bilibili.com/video/BV1pirZBuEzq/) +- 一键安装体验:[hagicode.com/installation/docker-compose](https://hagicode.com/installation/docker-compose) +- 公测已开始,欢迎安装体验 + + + +--- + +感谢您的阅读,如果您觉得本文有用,快点击下方点赞按钮👍,让更多的人看到本文。 + +本内容采用人工智能辅助协作,经本人审核,符合本人观点与立场。 + +- **本文作者:** [newbe36524](https://www.newbe.pro) +- **本文链接:** [https://hagicode.com/blog/2026/01/28/streamjsonrpc-integration-in-hagicode](https://hagicode.com/blog/2026/01/28/streamjsonrpc-integration-in-hagicode) +- **版权声明:** 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处! \ No newline at end of file diff --git "a/src/content/docs/blog/2026-01-28-\345\210\251\347\224\250-worker-threads-\344\274\230\345\214\226-vite-\346\236\204\345\273\272\346\200\247\350\203\275\347\232\204\345\256\236\346\210\230.mdx" "b/src/content/docs/blog/2026-01-28-\345\210\251\347\224\250-worker-threads-\344\274\230\345\214\226-vite-\346\236\204\345\273\272\346\200\247\350\203\275\347\232\204\345\256\236\346\210\230.mdx" new file mode 100644 index 0000000..7bafd34 --- /dev/null +++ "b/src/content/docs/blog/2026-01-28-\345\210\251\347\224\250-worker-threads-\344\274\230\345\214\226-vite-\346\236\204\345\273\272\346\200\247\350\203\275\347\232\204\345\256\236\346\210\230.mdx" @@ -0,0 +1,351 @@ +--- +title: "利用 Worker Threads 优化 Vite 构建性能的实战" +date: 2026-01-28 +truncate: true +--- + +# 120秒到45秒:利用 Worker Threads 优化 Vite 构建性能的实战 + +> 在处理大型前端项目时,生产环境的代码构建往往让人望眼欲穿。本文分享如何通过 Node.js Worker Threads 将 Vite 构建中的代码混淆环节耗时从 120 秒降低至 45 秒,并详细介绍 HagiCode 项目中的实施细节与踩坑经验。 + +## 背景 + +在我们的前端工程化实践中,随着项目规模的扩大,构建效率问题逐渐凸显。特别是在生产环境构建流程中,为了保护源码逻辑,我们通常会引入 JavaScript 混淆工具(如 `javascript-obfuscator`)。这一步虽然必要,但计算量巨大,极其消耗 CPU 资源。 + +在**HagiCode**项目的早期开发阶段,我们遇到了一个非常棘手的性能瓶颈:生产构建时间随着代码量的增加迅速恶化。 + +**具体痛点如下**: +- 单线程串行执行混淆任务,CPU 单核跑满,其他核心闲置 +- 构建时间从最初的 30 秒飙升至 110-120 秒 +- 每次修改代码后的构建验证流程极其漫长,严重拖慢了开发迭代效率 +- CI/CD 流水线中,构建环节成为最耗时的部分 + +**为什么 HagiCode 会有这个需求?** +HagiCode 是一款 AI 驱动的代码智能助手,其前端架构包含复杂的业务逻辑和 AI 交互模块。为了确保核心代码的安全性,我们在生产发布时强制开启了高强度混淆。面对长达两分钟的构建等待,我们决定对构建系统进行一次深度的性能优化。 + +## 关于 HagiCode + +> 既然提到了这个项目,不妨多介绍两句。 + +如果你在开发中遇到过这些烦恼: +- 多项目、多技术栈,构建脚本维护成本高 +- CI/CD 流水线配置繁琐,每次改都要查文档 +- 跨平台兼容性问题层出不穷 +- 想让 AI 帮忙写代码,但现有工具不够智能 + +那么我们正在做的 **HagiCode** 可能你会感兴趣。 + +**HagiCode 是什么?** +- 一款 AI 驱动的代码智能助手 +- 支持多语言、跨平台的代码生成与优化 +- 内置游戏化机制,让编码不再枯燥 + +**为什么在这里提它?** +本文分享的 **JavaScript 并行混淆方案**,正是我们在开发 HagiCode 过程中实践总结出来的。如果你觉得这套工程化方案有价值,说明我们的技术品味还不错——那么 HagiCode 本身也值得关注一下。 + +**想了解更多?** +- GitHub: [github.com/HagiCode-org/site](https://github.com/HagiCode-org/site)(求 Star) +- 官网: [hagicode.com](https://hagicode.com) +- 视频演示: [www.bilibili.com/video/BV1pirZBuEzq/](https://www.bilibili.com/video/BV1pirZBuEzq/)(30 分钟实战演示) +- 安装指南: [hagicode.com/installation/docker-compose](https://hagicode.com/installation/docker-compose) +- 公测已开始:现在安装即可参与公测 + +--- + +## 分析:寻找性能瓶颈的突破口 + +在着手解决性能问题之前,我们需要先理清思路,确定最优的技术方案。 + +### 核心决策:为什么选择 Worker Threads? + +Node.js 环境下实现并行计算主要有三种方案: +1. **child_process**:创建独立的子进程 +2. **Web Workers**:主要用于浏览器端 +3. **worker_threads**:Node.js 原生多线程支持 + +经过对比分析,HagiCode 最终选择了 **Worker Threads**,原因如下: +- **零序列化开销**:Worker Threads 位于同一进程,可以通过 `SharedArrayBuffer` 或转移控制权的方式共享内存,避免了进程间通信的大额序列化成本。 +- **原生支持**:Node.js 12+ 版本内置支持,无需引入额外的重依赖。 +- **上下文统一**:调试和日志记录比子进程更方便。 + +### 任务粒度:如何拆分混淆任务? + +混淆一个巨大的 JS Bundle 文件很难并行(因为代码有依赖关系),但 Vite 的构建产物是由多个 **Chunk** 组成的。这给了我们一个天然的并行边界: + +- **独立性**:Vite 打包后的不同 Chunk 之间依赖关系已解耦,可以安全地并行处理。 +- **粒度适中**:通常项目会有 10-30 个 Chunk,这个数量级非常适合并行调度。 +- **易于集成**:Vite 插件的 `generateBundle` 钩子允许我们在文件生成前拦截并处理这些 Chunk。 + +### 架构设计 + +我们设计了一个包含四个核心组件的并行处理系统: + +1. **Task Splitter**:遍历 Vite 的 bundle 对象,过滤不需要混淆的文件(如 vendor),生成任务队列。 +2. **Worker Pool Manager**:管理 Worker 的生命周期,负责任务的分发、回收和错误重试。 +3. **Progress Reporter**:实时输出构建进度,消除用户的等待焦虑。 +4. **ObfuscationWorker**:实际执行混淆逻辑的工作线程。 + +## 解决:实战编码与实施 + +基于上述分析,我们开始动手实现这套并行混淆系统。 + +### 1. 配置 Vite 插件 + +首先,我们在 `vite.config.ts` 中集成并行混淆插件。配置非常直观,只需指定 Worker 数量和混淆规则。 + +```typescript +import { defineConfig } from 'vite' +import { parallelJavascriptObfuscator } from './buildTools/plugin' + +export default defineConfig(({ mode }) => { + const isProduction = mode === 'production' + + return { + build: { + rollupOptions: { + ...(isProduction + ? { + plugins: [ + parallelJavascriptObfuscator({ + enabled: true, + // 根据 CPU 核心数自动调整,建议留出一个核心给主线程 + workerCount: 4, + retryAttempts: 3, + fallbackToMainThread: true, // 出错时自动降级为单线程 + // 过滤掉 vendor chunk,通常不需要混淆第三方库 + isVendorChunk: (fileName: string) => fileName.includes('vendor-'), + obfuscationConfig: { + compact: true, + controlFlowFlattening: true, + deadCodeInjection: true, + disableConsoleOutput: true, + // ... 更多混淆选项 + }, + }), + ], + } + : {}), + }, + }, + } +}) +``` + +### 2. 实现 Worker 逻辑 + +Worker 是执行任务的单元。我们需要定义好输入和输出的数据结构。 + +**注意**:这里的代码虽然简单,但有几个坑点需要注意。比如 `parentPort` 的空值检查,以及错误处理。在 HagiCode 的实践中,我们发现有些特殊的 ES6 语法可能会导致混淆器崩溃,所以加上了 `try-catch` 保护。 + +```typescript +import { parentPort } from 'worker_threads' +import javascriptObfuscator from 'javascript-obfuscator' + +export interface ObfuscationTask { + chunkId: string + code: string + config: any +} + +export interface ObfuscationResult { + chunkId: string + obfuscatedCode: string + error?: string +} + +// 监听主线程发来的任务 +if (parentPort) { + parentPort.on('message', async (task: ObfuscationTask) => { + try { + // 执行混淆 + const obfuscated = javascriptObfuscator.obfuscate(task.code, task.config) + const result: ObfuscationResult = { + chunkId: task.chunkId, + obfuscatedCode: obfuscated.getObfuscatedCode(), + } + // 将结果发回主线程 + parentPort?.postMessage(result) + } catch (error) { + // 处理异常,确保单个 Worker 崩溃不会阻塞整个构建 + const result: ObfuscationResult = { + chunkId: task.chunkId, + obfuscatedCode: '', + error: error instanceof Error ? error.message : 'Unknown error', + } + parentPort?.postMessage(result) + } + }) +} +``` + +### 3. Worker 池管理器 + +这是整个方案的核心。我们需要维护一个固定大小的 Worker 池,采用 **FIFO(先进先出)** 策略调度任务。 + +```typescript +import { Worker } from 'worker_threads' +import os from 'os' + +export class WorkerPool { + private workers: Worker[] = [] + private taskQueue: Array<{ + task: ObfuscationTask + resolve: (result: ObfuscationResult) => void + reject: (error: Error) => void + }> = [] + + constructor(options: WorkerPoolOptions = {}) { + // 默认为核心数 - 1,给主线程留一点喘息的空间 + const workerCount = options.workerCount ?? Math.max(1, (os.cpus().length || 4) - 1) + + for (let i = 0; i < workerCount; i++) { + this.createWorker() + } + } + + private createWorker() { + const worker = new Worker('./worker.ts') + + worker.on('message', (result) => { + // 任务完成后,从队列中取出下一个任务 + const nextTask = this.taskQueue.shift() + if (nextTask) { + this.dispatchTask(worker, nextTask) + } else { + // 如果没有待处理任务,标记 Worker 为空闲 + this.activeWorkers.delete(worker) + } + }) + + this.workers.push(worker) + } + + // 提交任务到池中 + public runTask(task: ObfuscationTask): Promise { + return new Promise((resolve, reject) => { + const job = { task, resolve, reject } + const idleWorker = this.workers.find(w => !this.activeWorkers.has(w)) + + if (idleWorker) { + this.dispatchTask(idleWorker, job) + } else { + this.taskQueue.push(job) + } + }) + } + + private dispatchTask(worker: Worker, job: any) { + this.activeWorkers.set(worker, job.task) + worker.postMessage(job.task) + } +} +``` + +### 4. 进度报告 + +等待是痛苦的,尤其是不知道还要等多久。我们增加了一个简单的进度报告器,实时反馈当前状态。 + +```typescript +export class ProgressReporter { + private completed = 0 + private readonly total: number + private readonly startTime: number + + constructor(total: number) { + this.total = total + this.startTime = Date.now() + } + + increment(): void { + this.completed++ + this.report() + } + + private report(): void { + const now = Date.now() + const elapsed = now - this.startTime + const percentage = (this.completed / this.total) * 100 + + // 简单的 ETA 估算 + const avgTimePerChunk = elapsed / this.completed + const remaining = (this.total - this.completed) * avgTimePerChunk + + console.log( + `[Parallel Obfuscation] ${this.completed}/${this.total} chunks completed (${percentage.toFixed(1)}%) | ETA: ${(remaining / 1000).toFixed(1)}s` + ) + } +} +``` + +## 实践:效果与踩坑 + +部署这套方案后,HagiCode 项目的构建性能有了立竿见影的提升。 + +### 性能基准数据 + +我们在以下环境进行了测试: +- CPU:Intel Core i7-12700K (12 cores / 20 threads) +- RAM:32GB DDR4 +- Node.js:v18.17.0 +- OS:Ubuntu 22.04 + +**结果对比**: +- **单线程(优化前)**:118 秒 +- **4 Workers**:55 秒(提升 **53%**) +- **8 Workers**:48 秒(提升 **60%**) +- **12 Workers**:45 秒(提升 **62%**) + +可以看出,收益并不是线性的。当 Worker 数量超过 8 个后,提升幅度变小。这主要受限于任务分配的均匀度和内存带宽瓶颈。 + +### 常见问题与解决方案 + +在 HagiCode 的实际使用中,我们也遇到了一些坑,这里分享给大家: + +**Q1: 构建时间没有明显减少,反而变慢了?** +- **原因**:Worker 创建本身有开销,或者 Worker 数量设置过多导致上下文切换频繁。 +- **解决**:建议 Worker 数量设置为 `CPU 核心数 - 1`。同时检查是否有单个 Chunk 特别大(例如 > 5MB),这种"巨无霸"文件会成为短板,可以考虑优化代码分割策略。 + +**Q2: 偶尔出现 Worker 崩溃,构建失败?** +- **原因**:某些特殊的代码语法可能导致混淆器内部报错。 +- **解决**:我们实现了 **自动降级机制**。当 Worker 连续失败次数达到阈值时,插件会自动回退到单线程模式,确保构建不中断。同时记录下错误的文件名,方便后续针对性修复。 + +**Q3: 内存占用过高(OOM)?** +- **原因**:每个 Worker 都需要独立内存空间来加载混淆器和解析 AST。 +- **解决**: + - 减少 Worker 数量。 + - 增加 Node.js 的内存限制:`NODE_OPTIONS="--max-old-space-size=4096" npm run build`。 + - 确保不在 Worker 内部持有不必要的大对象引用。 + +## 总结 + +通过引入 Node.js Worker Threads,我们成功将 HagiCode 项目的生产构建时间从 120 秒降低到了 45 秒左右,极大提升了开发体验和 CI/CD 效率。 + +这套方案的核心在于: +1. **合理拆分任务**:利用 Vite 的 Chunk 作为并行单元。 +2. **资源控制**:使用 Worker 池避免资源耗尽。 +3. **容错设计**:自动降级机制确保构建稳定性。 + +如果你也在为前端构建效率发愁,或者你的项目也在做重度代码处理,不妨试试这套方案。当然,更推荐你直接关注我们的 HagiCode 项目,这些工程化的细节都已经集成在里面了。 + +如果本文对你有帮助,欢迎来 GitHub 给个 Star,或者参与公测体验一下~ + +## 参考资料 + +- Node.js Worker Threads 官方文档: [nodejs.org/api/worker_threads.html](https://nodejs.org/api/worker_threads.html) +- javascript-obfuscator 文档: [github.com/javascript-obfuscator/javascript-obfuscator](https://github.com/javascript-obfuscator/javascript-obfuscator) +- Vite 插件开发指南: [vitejs.dev/guide/api-plugin.html](https://vitejs.dev/guide/api-plugin.html) +- **HagiCode GitHub**: [github.com/HagiCode-org/site](https://github.com/HagiCode-org/site) +- **HagiCode 官网**: [hagicode.com](https://hagicode.com) +- **安装指南**: [hagicode.com/installation/docker-compose](https://hagicode.com/installation/docker-compose) + + + +--- + +感谢您的阅读,如果您觉得本文有用,快点击下方点赞按钮👍,让更多的人看到本文。 + +本内容采用人工智能辅助协作,经本人审核,符合本人观点与立场。 + +- **本文作者:** [newbe36524](https://www.newbe.pro) +- **本文链接:** [https://hagicode.com/blog/2026/01/27/optimizing-vite-build-with-worker-threads](https://hagicode.com/blog/2026/01/27/optimizing-vite-build-with-worker-threads) +- **版权声明:** 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处! \ No newline at end of file diff --git a/src/content/docs/blog/2026-01-31-migrate-docusaurus-to-astro-with-islands-architecture.mdx b/src/content/docs/blog/2026-01-31-migrate-docusaurus-to-astro-with-islands-architecture.mdx new file mode 100644 index 0000000..f16b533 --- /dev/null +++ b/src/content/docs/blog/2026-01-31-migrate-docusaurus-to-astro-with-islands-architecture.mdx @@ -0,0 +1,224 @@ +--- +title: "Docusaurus 3.x 到 Astro 5.x 迁移实战:利用 Islands 架构实现性能与构建速度双重提升" +englishSlug: "migrate-docusaurus-to-astro-with-islands-architecture" +date: 2026-01-31 +--- + +# 从 Docusaurus 3.x 到 Astro 5.x:HagiCode 站点迁移实战复盘 + +> 本文复盘了我们将 HagiCode 官方网站从 Docusaurus 3.x 迁移至 Astro 5.x 的全过程。我们将深入探讨如何通过 Astro 的 Islands 架构解决性能瓶颈,同时保留现有的 React 组件资产,实现构建速度与加载性能的双重提升。 + + +## 背景 + +2026 年 1 月,我们对 HagiCode 的官方站点进行了一次"心脏移植手术"——将核心框架从 Docusaurus 3.x 全面迁移至 Astro 5.x。这不是一次冲动的大重构,而是经过深思熟虑的技术抉择。 + +在迁移前,我们的站点虽然功能完善,但逐渐显露出一些"富贵病":构建产物体积臃肿、JavaScript 负载过高,且页面加载速度在复杂文档页面下不够理想。作为一个 AI 代码助手项目,HagiCode 需要频繁更新文档和功能介绍,构建效率直接影响发布速度。同时,我们希望站点对搜索引擎(SEO)更加友好,以便让更多开发者发现这个项目。 + +为了解决这些痛点,我们做了一个大胆的决定:整个构建系统推倒重来,迁移到 Astro。这个决定带来的变化,可能比你想象的还要大——稍后我会具体说。 + +## 关于 HagiCode + +本文分享的站点迁移方案,来自我们在 [HagiCode](https://github.com/HagiCode-org/site) 项目中的实践经验。 + +HagiCode 是一款致力于提升开发效率的 AI 代码助手,我们不仅关注核心功能的迭代,同样重视开发者体验。这次站点的重构,也是为了让用户在浏览文档和官网时能获得极致的加载速度。 + +## 为什么要放弃成熟的 Docusaurus? + +在 React 生态中,Docusaurus 一直是文档站点的"标准答案"。它开箱即用,插件丰富,社区活跃。但是,随着 HagiCode 功能的增加,我们也感受到了它的局限性: + +1. **性能瓶颈**:Docusaurus 本质上是一个 React SPA(单页应用)。哪怕你是写纯静态页面,客户端也需要加载 React 运行时并进行水合,这对于简单的文档页面来说太重了。 +2. **资源体积**:即便页面内容很少,打包后的 JS 体积也相对固定,这对移动端用户和网络较差的环境不够友好。 +3. **灵活性不足**:虽然也能扩展,但在构建流程的定制上,我们渴望拥有更底层的控制权。 + +Astro 的出现正好解决了这些问题。它提供了一个全新的"岛屿架构"(Islands Architecture):默认情况下,Astro 生成零 JavaScript 的静态 HTML,只有需要交互的组件才会"激活"并加载 JS。这意味着我们的站点大部分内容都是纯 HTML,速度极快。 + +## 迁移核心策略:架构平滑过渡 + +迁移不是简单的复制粘贴,而是思维模式的转变。我们从 Docusaurus 的"全 React 模式"切换到了 Astro 的"Core + Islands"模式。 + +### 1. 配置系统的重构 + +首先,我们需要从 `docusaurus.config.ts` 转向 `astro.config.mjs`。这不仅是文件名的变化,更是路由和构建逻辑的重写。 + +在 Docusaurus 中,一切皆插件;而在 Astro 中,一切皆集成。我们需要重新定义站点的基础路径、构建输出模式(静态 vs SSR)以及资源压缩策略。 + +**迁移前:** +```typescript +// docusaurus.config.ts +export default { + title: 'HagiCode', + url: 'https://hagicode.com', + baseUrl: '/', + // ... 更多配置 +}; +``` + +**迁移后:** +```javascript +// astro.config.mjs +import { defineConfig } from 'astro/config'; +import react from '@astrojs/react'; + +export default defineConfig({ + integrations: [react()], + site: 'https://hagicode.com', + base: '/', + // 针对静态资源的优化配置 + build: { + inlineStylesheets: 'auto', + }, +}); +``` + +### 2. React 组件的去留与改造 + +这是迁移中最头疼的部分。我们现有的站点有很多 React 组件(比如 Tabs 组件、代码高亮、反馈按钮等)。直接扔掉太可惜,全都保留又会导致 JS 负载过重。 + +HagiCode 采用了**渐进式水合**策略: +* **纯静态组件**:对于展示型内容(如页眉、页脚、纯文本文档),重写为 Astro 组件(`.astro` 文件),在构建时直接渲染为 HTML。 +* **交互式岛屿**:对于必须保留交互的组件(如主题切换器、Tabs 切换、代码块复制按钮),保留 React 实现,并添加 `client:load` 或 `client:visible` 指令。 + +例如,我们的文档中常用的 Tabs 组件: + +```jsx +// src/components/Tabs.jsx +import { useState } from 'react'; +import './Tabs.css'; // 引入样式 + +export default function Tabs({ items }) { + const [activeIndex, setActiveIndex] = useState(0); + // ... 状态逻辑 + return ( + + {/* 渲染逻辑 */} + + ); +} +``` + +在 Markdown 中使用时,我们明确告诉 Astro:"这个组件需要 JS": + +```markdown +// src/content/docs/example.mdx +import Tabs from '../../components/Tabs.jsx'; + + + +``` + +这样,非视口内的交互组件不会抢占带宽,极大地优化了首屏加载速度。 + +### 3. 样式系统的适配:CSS Modules 到 Scoped + +Docusaurus 默认支持 CSS Modules,而 Astro 推崇使用 Scoped CSS(通过 ` +``` + +同时,我们统一了全局 CSS 变量系统,利用 Astro 的环境感知能力,确保暗色模式在不同页面间的切换无缝衔接。 + +## 实践中的坑与解决方案 + +在 HagiCode 的实际迁移过程中,我们遇到了不少坑,这里挑几个最典型的分享一下。 + +### 1. 路径与环境变量的痛点 + +HagiCode 支持子路径部署(比如部署到 GitHub Pages 的子目录)。在 Docusaurus 中,它自动处理 `baseUrl`。但在 Astro 中,处理图片链接和 API 请求时,我们需要更小心。 + +我们引入了环境变量机制来统一管理: + +```javascript +// 在构建脚本中处理路径 +const getBasePath = () => import.meta.env.VITE_SITE_BASE || '/'; +``` + +切记,不要在代码中硬编码 `/` 开头的路径。在开发环境和生产环境,或者配置了 `base` 路径后,这会导致资源 404。 + +### 2. CommonJS 脚本的兼容 + +我们的旧站点有一些 Node.js 脚本(用于自动抓取 Metrics 数据、更新 sitemap 等),它们是用 CommonJS (`require`) 写的。Astro 和现代构建工具全面拥抱 ES Modules (`import`/`export`)。 + +如果你也有类似的脚本,记得把它们全部重构为 ES Modules。这是大势所趋,早点改了早点省心。 + +```javascript +// 旧方式 +const fs = require('fs'); + +// 新方式 +import fs from 'fs'; +``` + +### 3. 别忘了 SEO 与重定向 + +搜索引擎已经收录了 HagiCode 旧的 Docusaurus 页面。如果直接切到 Astro,URL 结构发生变化,会导致大量 404,权重大跌。 + +我们在 Astro 中配置了重定向规则: + +```javascript +// astro.config.mjs +export default defineConfig({ + redirects: { + '/docs/old-path': '/docs/new-path', + // 批量映射旧链接到新链接 + } +}); +``` +或者在服务器配置层面处理。确保旧链接能 301 重定向到新地址,这对 SEO 至关重要。 + +## 总结 + +从 Docusaurus 迁移到 Astro,对 HagiCode 来说,不仅仅是一次框架升级,更是一次对"性能优先"理念的实践。 + +**我们的收获:** +* **极致的 Lighthouse 分数**:迁移后,HagiCode 站点的性能评分轻松接近满分。 +* **更快的构建速度**:Astro 的增量构建让我们文档更新的发布时间缩短了一半。 +* **保留了灵活性**:通过 Islands 架构,我们没有牺牲任何交互功能,依然可以在需要的地方使用 React。 + +如果你也在维护文档型站点,并且深受打包体积或加载速度的困扰,不妨试试 Astro。虽然迁移过程需要动动手术(比如把 PCode 的名字改成 HagiCode,把组件一个个挖过来),但换来的是如丝般顺滑的用户体验,绝对值得。 + +本文分享的构建系统,正是我们在开发 HagiCode 过程中实际踩坑、实际优化出来的方案。如果你觉得这套方案有价值,说明我们的工程实力还不错——那么 HagiCode 本身也值得关注一下。 + +## 参考资料 + +- [Astro 官方文档](https://docs.astro.build) +- [从 Docusaurus 迁移指南](https://docs.astro.build/en/guides/migrate-to-astro/migrate-from-docusaurus/) +- [Islands 架构详解](https://docs.astro.build/en/core-concepts/islands/) +- **HagiCode 项目地址**:[github.com/HagiCode-org/site](https://github.com/HagiCode-org/site) +- **HagiCode 官网**:[hagicode-org.github.io/site](https://hagicode-org.github.io/site) +- **一键安装体验**:[hagicode-org.github.io/site/docs/installation/docker-compose](https://hagicode-org.github.io/site/docs/installation/docker-compose) + +如果本文对你有帮助,欢迎来 GitHub 给个 Star,公测已经开始啦! + + + +--- + +感谢您的阅读,如果您觉得本文有用,快点击下方点赞按钮👍,让更多的人看到本文。 + +本内容采用人工智能辅助协作,经本人审核,符合本人观点与立场。 + +- **本文作者:** [newbe36524](https://www.newbe.pro) +- **本文链接:** [https://hagicode-org.github.io/site/blog/2026-01-31-migrate-docusaurus-to-astro-with-islands-architecture/](https://hagicode-org.github.io/site/blog/2026-01-31-migrate-docusaurus-to-astro-with-islands-architecture/) +- **版权声明:** 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处! \ No newline at end of file diff --git "a/src/content/docs/blog/2026-02-01-net-core-\345\217\214\346\225\260\346\215\256\345\272\223\345\256\236\346\210\230\344\274\230\351\233\205\350\236\215\345\220\210-postgresql-\344\270\216-sqlite-\347\232\204\346\234\200\344\275\263\345\256\236\350\267\265.mdx" "b/src/content/docs/blog/2026-02-01-net-core-\345\217\214\346\225\260\346\215\256\345\272\223\345\256\236\346\210\230\344\274\230\351\233\205\350\236\215\345\220\210-postgresql-\344\270\216-sqlite-\347\232\204\346\234\200\344\275\263\345\256\236\350\267\265.mdx" new file mode 100644 index 0000000..19d0fef --- /dev/null +++ "b/src/content/docs/blog/2026-02-01-net-core-\345\217\214\346\225\260\346\215\256\345\272\223\345\256\236\346\210\230\344\274\230\351\233\205\350\236\215\345\220\210-postgresql-\344\270\216-sqlite-\347\232\204\346\234\200\344\275\263\345\256\236\350\267\265.mdx" @@ -0,0 +1,225 @@ +--- +title: ".NET Core 双数据库实战:优雅融合 PostgreSQL 与 SQLite 的最佳实践" +date: 2026-02-01 +--- + +# .NET Core 双数据库实战:让 PostgreSQL 与 SQLite 和平共处 + +> 在构建现代化应用时,我们经常面临这样的抉择:开发环境渴望轻量便捷,而生产环境则需要高并发与高可用。本文将分享如何在 .NET Core 项目中优雅地同时支持 PostgreSQL 和 SQLite,实现“开发用 SQLite,生产用 PG”的最佳实践。 + + +## 背景 + +在软件开发中,环境差异化一直是困扰开发团队的难题之一。以我们正在构建的 **HagiCode** 平台为例,这是一个基于 ASP.NET Core 10 和 React 的 AI 辅助开发系统,内部集成了 Orleans 进行分布式状态管理,技术栈相当现代且复杂。 + +在项目初期,我们遇到了一个典型的工程痛点:开发人员希望本地环境能够“开箱即用”,不希望安装和配置繁重的 PostgreSQL 数据库;但在生产环境中,我们需要处理高并发写入和复杂的 JSON 查询,这时轻量级的 SQLite 又显得力不从心。 + +如何在保持代码库统一的前提下,让应用既能像客户端软件一样利用 SQLite 的便携性,又能像企业级服务一样发挥 PostgreSQL 的强悍性能?这就是本文要探讨的核心问题。 + +## 关于 HagiCode + +本文分享的双数据库适配方案,直接来源于我们在 **HagiCode** 项目中的实战经验。HagiCode 是一个集成了 AI 提示词管理和 OpenSpec 工作流的下一代开发平台。正是为了兼顾开发者的体验和生产环境的稳定性,我们探索出了这套行之有效的架构模式。 + +欢迎访问我们的 GitHub 仓库了解项目全貌:[HagiCode-org/site](https://github.com/HagiCode-org/site)。 + +## 核心内容一:架构设计与统一抽象 + +要在 .NET Core 中实现双数据库支持,核心思想是“依赖抽象而非具体实现”。我们需要把数据库的选择权从业务代码中剥离出来,交给配置层决定。 + +### 设计思路 + +1. **统一接口**:所有的业务逻辑都应依赖于 `DbContext` 基类或自定义的接口,而不是具体的 `PostgreSqlDbContext`。 +2. **配置驱动**:通过 `appsettings.json` 中的配置项,在应用启动时动态决定加载哪个数据库提供程序。 +3. **特性隔离**:针对 PostgreSQL 特有的功能(如 JSONB)进行适配处理,确保在 SQLite 中也能降级运行。 + +### 代码实现:动态上下文配置 + +在 ASP.NET Core 的 `Program.cs` 中,我们不应硬编码 `UseNpgsql` 或 `UseSqlite`。相反,我们应该读取配置来动态决定。 + +首先,定义配置类: + +```csharp +public class DatabaseSettings +{ + public const string SectionName = "Database"; + + // 数据库类型:PostgreSQL 或 SQLite + public string DbType { get; set; } = "PostgreSQL"; + + // 连接字符串 + public string ConnectionString { get; set; } = string.Empty; +} +``` + +然后,在 `Program.cs` 中根据配置注册服务: + +```csharp +// 读取配置 +var databaseSettings = builder.Configuration.GetSection(DatabaseSettings.SectionName).Get(); + +// 注册 DbContext +builder.Services.AddDbContext(options => +{ + if (databaseSettings?.DbType?.ToLower() == "sqlite") + { + // SQLite 配置 + options.UseSqlite(databaseSettings.ConnectionString); + + // SQLite 的并发写入限制处理 + // 注意:在生产环境中建议开启 WAL 模式以提高并发性能 + } + else + { + // PostgreSQL 配置(默认) + options.UseNpgsql(databaseSettings.ConnectionString, npgsqlOptions => + { + // 开启 JSONB 支持,这在处理 AI 对话记录时非常有用 + npgsqlOptions.UseJsonNet(); + }); + + // 配置连接池重连策略 + options.EnableRetryOnFailure(3); + } +}); +``` + +## 核心内容二:处理差异性与迁移策略 + +PostgreSQL 和 SQLite 虽然都支持 SQL 标准,但在具体特性和行为上存在显著差异。如果不处理好这些差异,很可能会出现“本地跑得通,上线就报错”的尴尬情况。 + +### 1. JSON 类型的处理 + +在 HagiCode 中,我们需要存储大量的提示词和 AI 元数据,这通常涉及 JSON 列。 +- **PostgreSQL**:拥有原生的 `JSONB` 类型,查询性能极佳。 +- **SQLite**:没有原生的 JSON 类型(新版本有 JSON1 扩展,但对象映射上仍有差异),通常存储为 TEXT。 + +**解决方案**: +在 EF Core 的实体映射中,我们将其配置为可转换的类型。 + +```csharp +protected override void OnModelCreating(ModelBuilder modelBuilder) +{ + base.OnModelCreating(modelBuilder); + + // 配置实体 + modelBuilder.Entity(entity => + { + entity.Property(e => e.Metadata) + .HasColumnType("jsonb") // PG 使用 jsonb + .HasConversion( + v => JsonSerializer.Serialize(v, (JsonSerializerOptions)null), + v => JsonSerializer.Deserialize>(v, (JsonSerializerOptions)null) + ); + }); +} +``` + +当使用 SQLite 时,虽然 `HasColumnType("jsonb")` 会被忽略或产生警告,但由于配置了 `HasConversion`,数据会被正确地序列化和反序列化为字符串存入 TEXT 字段,从而保证了兼容性。 + +### 2. 迁移策略的分离 + +绝对不要试图让同一套 Migration 脚本同时适配 PG 和 SQLite。由于主键生成策略、索引语法等的不同,这必然会导致失败。 + +**推荐实践**: +维护两个迁移分支或项目。在 HagiCode 的开发流中,我们是这样处理的: + +1. **开发阶段**:主要在 SQLite 下工作。使用 `Add-Migration Init_Sqlite -OutputDir Migrations/Sqlite`。 +2. **适配阶段**:开发完一段功能后,切换连接字符串指向 PostgreSQL,执行 `Add-Migration Init_Postgres -OutputDir Migrations/Postgres`。 +3. **自动化脚本**:编写一个简单的 PowerShell 或 Bash 脚本,根据当前环境变量自动应用对应的迁移。 + +```bash +# 简单的部署逻辑伪代码 +if [ "$DATABASE_PROVIDER" = "PostgreSQL" ]; then + dotnet ef database update --project Migrations.Postgres +else + dotnet ef database update --project Migrations.Sqlite +fi +``` + +## 核心内容三:HagiCode 的实战经验总结 + +在将 **HagiCode** 从单一数据库重构为双数据库支持的过程中,我们踩过一些坑,也总结了一些关键的经验,希望能给大家避坑。 + +### 1. 并发与事务的区别 + +PostgreSQL 是服务端-客户端架构,支持高并发写入,事务隔离级别非常强大。而 SQLite 是文件锁机制,写入操作会锁定整个数据库文件(除非开启 WAL 模式)。 + +**建议**: +在编写涉及频繁写入的业务逻辑时(例如实时保存用户的编辑状态),一定要考虑到 SQLite 的锁机制。在设计 **HagiCode** 的 OpenSpec 协作模块时,我们引入了“写前合并”机制,减少数据库的直接写入频率,从而在两种数据库下都能保持高性能。 + +### 2. 连接字符串的生命周期管理 + +PostgreSQL 的连接建立成本较高,依赖连接池。而 SQLite 连接非常轻量,但如果不及时释放,文件锁可能会导致后续操作超时。 + +在 `Program.cs` 中,我们可以针对不同数据库做精细化调整: + +```csharp +if (databaseSettings?.DbType?.ToLower() == "sqlite") +{ + // SQLite:保持连接开启能提升性能,但要注意文件锁 + options.UseSqlite(connectionString, sqliteOptions => + { + // 设置命令超时时间 + sqliteOptions.CommandTimeout(30); + }); +} +else +{ + // PG:利用连接池 + options.UseNpgsql(connectionString, npgsqlOptions => + { + npgsqlOptions.MaxBatchSize(100); + npgsqlOptions.CommandTimeout(30); + }); +} +``` + +### 3. 测试覆盖的重要性 + +很多开发者(包括我们团队早期的成员)容易犯一个错误:只在开发环境(通常是 SQLite)跑单元测试。 + +我们在 HagiCode 的 CI/CD 流水线中强制加入了 GitHub Action 步骤,确保每次 Pull Request 都要跑过 PostgreSQL 的集成测试。 + +```yaml +# .github/workflows/test.yml 示例片段 +- name: Run Integration Tests (PostgreSQL) + run: | + docker-compose up -d db_postgres + dotnet test --filter "Category=Integration" +``` + +这帮我们拦截了无数次关于 SQL 语法差异、大小写敏感性的 Bug。 + +## 总结 + +通过引入抽象层和配置驱动的依赖注入,我们在 **HagiCode** 项目中成功实现了 PostgreSQL 和 SQLite 的“双轨制”运行。这不仅极大降低了新开发者的上手门槛(不需要装 PG),也为生产环境提供了坚实的性能保障。 + +回顾一下关键点: +1. **抽象至上**:业务代码不依赖具体数据库实现。 +2. **配置分离**:开发和生产使用不同的 `appsettings.json`。 +3. **迁移分离**:不要尝试一套 Migration 走天下。 +4. **特性降级**:在 SQLite 中以兼容性优先,在 PostgreSQL 中以性能优先。 + +这种架构模式不仅适用于 HagiCode,也适用于任何需要在轻量级开发和重量级生产之间寻找平衡的 .NET 项目。 + +--- + +如果本文对你有帮助,欢迎来 GitHub 给个 Star,或者直接体验 **HagiCode** 带来的高效开发流程: +- 来 GitHub 给个 Star:[github.com/HagiCode-org/site](https://github.com/HagiCode-org/site) +- 访问官网了解更多:[hagicode.com](https://hagicode.com) +- 观看 30 分钟实战演示:[www.bilibili.com/video/BV1pirZBuEzq/](https://www.bilibili.com/video/BV1pirZBuEzq/) +- 一键安装体验:[hagicode.com/installation/docker-compose](https://hagicode.com/installation/docker-compose) + +公测已开始,欢迎安装体验! + + + +--- + +感谢您的阅读,如果您觉得本文有用,快点击下方点赞按钮👍,让更多的人看到本文。 + +本内容采用人工智能辅助协作,经本人审核,符合本人观点与立场。 + +- **本文作者:** [newbe36524](https://www.newbe.pro) +- **本文链接:** [https://hagicode.com/blog/2026-02-01-dotnet-core-dual-database-postgresql-sqlite/](https://hagicode.com/blog/2026-02-01-dotnet-core-dual-database-postgresql-sqlite/) +- **版权声明:** 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处! \ No newline at end of file diff --git a/src/content/docs/blog/2026-02-03-hagicode-react-19-hydration-splash-screen.mdx b/src/content/docs/blog/2026-02-03-hagicode-react-19-hydration-splash-screen.mdx new file mode 100644 index 0000000..ddf25b1 --- /dev/null +++ b/src/content/docs/blog/2026-02-03-hagicode-react-19-hydration-splash-screen.mdx @@ -0,0 +1,215 @@ +--- +title: "HagiCode 启动页设计:React 19 应用中填补 Hydration 空白期的极致体验" +date: 2026-02-03 +--- + +# 为 HagiCode 设计 12 种极致的启动体验:从极简到赛博朋克 + +> 在 React 19 应用下载和 Hydration 的短暂间隙,是留给用户感知品牌个性的黄金窗口。本文分享了我们在 HagiCode 项目中,基于 HTML/CSS/JS 构建的一套完整的启动风格系统。 + + +## 背景 + +HagiCode 作为一个基于 ASP.NET Core 10 和 React 19 (Vite) 的现代化应用,采用了前后端分离部署的架构。前端产物被打包放置于后端的 `wwwroot/` 目录下由 ASP.NET Core 托管。 + +然而,这种架构带来了一个经典的用户体验痛点:当用户访问网页时,浏览器需要先加载 HTML,再下载巨大的 JS Bundle,最后由 React 执行 Hydration(注水)。在这几百毫秒到数秒的"真空期"里,用户面对的是一片空白,或者是一个毫无生气的静态页面。 + +为了填补这段间隙,并注入 HagiCode 的品牌个性,我们需要设计一套完全基于 `index.html` 内联代码的启动风格系统。 + +## 关于 HagiCode + +本文分享的启动页设计方案来自我们在 [HagiCode](https://github.com/HagiCode-org/site) 项目中的实践经验。作为一个 AI 代码助手,HagiCode 不仅关注代码生成的效率,也同样重视开发者的视觉体验。这套启动系统正是我们在追求极致前端性能过程中的产物。 + +## 核心挑战与架构设计 + +在动手设计之前,我们必须先明确技术约束。既然要在 `index.html` 中内联实现,意味着我们不能加载任何外部 CSS 或 JS 文件(除了 React 本身的 Bundle)。 + +### 技术约束分析 + +1. **零依赖原则**:所有样式必须写在 ` + + + 正在跳转到产品概述,如果没有自动跳转,请点击这里。 + + +
正在跳转到产品概述,如果没有自动跳转,请点击这里。