From 5aa3c094a5fc5b250a2ee41b54594a0deb8e82b0 Mon Sep 17 00:00:00 2001 From: Adam Matthiesen Date: Sun, 5 Jul 2026 13:14:02 -0700 Subject: [PATCH 01/40] start of Astro setup --- .dockerignore | 3 - .github/renovate.json | 24 - .github/workflows/ci.yml | 35 - .github/workflows/quality.yml | 38 - .gitignore | 38 +- .oxfmtrc.json | 26 - .oxlintrc.json | 18 - .prototools | 1 + .vscode/extensions.json | 4 + .vscode/launch.json | 11 + AGENTS.md | 22 + CLAUDE.md | 1 + Dockerfile | 28 - README.md | 49 + astro.config.ts | 107 + bun.lock | 980 ---- bunfig.toml | 4 - content/docs/java/configuration.mdx | 77 - content/docs/java/custom-metrics.mdx | 147 - content/docs/java/error-tracking.mdx | 177 - content/docs/java/feature-flags.mdx | 109 - content/docs/java/index.mdx | 164 - content/docs/java/meta.json | 19 - content/docs/java/migration.mdx | 237 - content/docs/java/obfuscation-mappings.mdx | 154 - content/docs/java/platform/bukkit.mdx | 39 - content/docs/java/platform/bungeecord.mdx | 39 - content/docs/java/platform/fabric.mdx | 41 - content/docs/java/platform/hytale.mdx | 45 - content/docs/java/platform/minestom.mdx | 34 - content/docs/java/platform/neoforge.mdx | 37 - content/docs/java/platform/nukkit.mdx | 42 - content/docs/java/platform/sponge.mdx | 49 - content/docs/java/platform/velocity.mdx | 50 - content/docs/java/system-properties.mdx | 54 - content/docs/meta.json | 4 - .../docs/platform/chart-editor/flow-nodes.mdx | 416 -- content/docs/platform/chart-editor/index.mdx | 38 - content/docs/platform/chart-editor/meta.json | 3 - .../platform/chart-editor/output-nodes.mdx | 75 - .../docs/platform/error-tracking/meta.json | 3 - content/docs/platform/guide/meta.json | 3 - content/docs/platform/meta.json | 16 - content/docs/web-analytics/configuration.mdx | 118 - content/docs/web-analytics/consent.mdx | 119 - content/docs/web-analytics/error-tracking.mdx | 143 - content/docs/web-analytics/events.mdx | 88 - content/docs/web-analytics/feature-flags.mdx | 95 - content/docs/web-analytics/identify.mdx | 86 - content/docs/web-analytics/index.mdx | 37 - content/docs/web-analytics/javascript.mdx | 91 - content/docs/web-analytics/meta.json | 23 - content/docs/web-analytics/nuxt.mdx | 94 - content/docs/web-analytics/react.mdx | 150 - content/docs/web-analytics/session-replay.mdx | 97 - content/docs/web-analytics/sourcemaps.mdx | 241 - content/docs/web-analytics/web-vitals.mdx | 72 - ec.config.mjs | 14 + next.config.mjs | 84 - package.json | 63 +- pnpm-lock.yaml | 4406 +++++++++++++++++ pnpm-workspace.yaml | 3 + postcss.config.mjs | 7 - source.config.ts | 23 - src/app/(docs)/(main)/[[...slug]]/page.tsx | 72 - src/app/(docs)/(main)/layout.tsx | 27 - src/app/(docs)/not-found.tsx | 10 - src/app/docs-search/route.ts | 6 - src/app/global.css | 182 - src/app/layout.tsx | 31 - src/app/llms-full.txt/route.ts | 10 - src/app/llms.mdx/docs/[[...slug]]/route.ts | 23 - src/app/llms.txt/route.ts | 13 - src/app/not-found.tsx | 10 - src/app/og/docs/[...slug]/route.tsx | 34 - src/app/tokens.css | 142 - src/assets/houston.webp | Bin 0 -> 98506 bytes src/assets/icon-dark.svg | 4 + src/assets/icon-light.svg | 4 + src/components/LinkCard.astro | 0 src/components/ReadMore.astro | 24 + src/components/ai/page-actions.tsx | 58 - src/components/api-page.tsx | 5 - src/components/docs/docs-not-found.tsx | 45 - src/components/docs/docs-sidebar.tsx | 75 - src/components/docs/node-preview.tsx | 433 -- src/components/og/faststats-icon.tsx | 10 - src/components/og/og-template.tsx | 188 - src/components/site-brand.tsx | 16 - src/components/starlight/ContentPanel.astro | 38 + src/components/starlight/Sidebar.astro | 23 + src/components/starlight/topics/Topics.astro | 134 + .../starlight/topics/TopicsSelector.astro | 8 + src/content.config.ts | 30 + {content => src/content}/docs/api/index.mdx | 10 +- src/content/docs/index.mdx | 41 + .../content/docs/platform/error-tracking.mdx | 0 .../content}/docs/platform/guide/badges.mdx | 0 .../content}/docs/platform/guide/embed.mdx | 0 .../content}/docs/platform/hotkeys.mdx | 6 +- .../content}/docs/platform/index.mdx | 20 +- .../content/docs/platform/retention.mdx | 0 src/integrations/dev-file-watcher.ts | 35 + src/lib/docs-tabs.tsx | 73 - src/lib/docs/repository.ts | 19 - src/lib/layout.shared.tsx | 47 - src/lib/openapi.ts | 20 - src/lib/source.ts | 56 - src/mdx-components.tsx | 13 - src/styles/starlight.css | 117 + tsconfig.json | 49 +- 111 files changed, 5152 insertions(+), 6524 deletions(-) delete mode 100644 .dockerignore delete mode 100644 .github/renovate.json delete mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/quality.yml delete mode 100644 .oxfmtrc.json delete mode 100644 .oxlintrc.json create mode 100644 .prototools create mode 100644 .vscode/extensions.json create mode 100644 .vscode/launch.json create mode 100644 AGENTS.md create mode 120000 CLAUDE.md delete mode 100644 Dockerfile create mode 100644 README.md create mode 100644 astro.config.ts delete mode 100644 bun.lock delete mode 100644 bunfig.toml delete mode 100644 content/docs/java/configuration.mdx delete mode 100644 content/docs/java/custom-metrics.mdx delete mode 100644 content/docs/java/error-tracking.mdx delete mode 100644 content/docs/java/feature-flags.mdx delete mode 100644 content/docs/java/index.mdx delete mode 100644 content/docs/java/meta.json delete mode 100644 content/docs/java/migration.mdx delete mode 100644 content/docs/java/obfuscation-mappings.mdx delete mode 100644 content/docs/java/platform/bukkit.mdx delete mode 100644 content/docs/java/platform/bungeecord.mdx delete mode 100644 content/docs/java/platform/fabric.mdx delete mode 100644 content/docs/java/platform/hytale.mdx delete mode 100644 content/docs/java/platform/minestom.mdx delete mode 100644 content/docs/java/platform/neoforge.mdx delete mode 100644 content/docs/java/platform/nukkit.mdx delete mode 100644 content/docs/java/platform/sponge.mdx delete mode 100644 content/docs/java/platform/velocity.mdx delete mode 100644 content/docs/java/system-properties.mdx delete mode 100644 content/docs/meta.json delete mode 100644 content/docs/platform/chart-editor/flow-nodes.mdx delete mode 100644 content/docs/platform/chart-editor/index.mdx delete mode 100644 content/docs/platform/chart-editor/meta.json delete mode 100644 content/docs/platform/chart-editor/output-nodes.mdx delete mode 100644 content/docs/platform/error-tracking/meta.json delete mode 100644 content/docs/platform/guide/meta.json delete mode 100644 content/docs/platform/meta.json delete mode 100644 content/docs/web-analytics/configuration.mdx delete mode 100644 content/docs/web-analytics/consent.mdx delete mode 100644 content/docs/web-analytics/error-tracking.mdx delete mode 100644 content/docs/web-analytics/events.mdx delete mode 100644 content/docs/web-analytics/feature-flags.mdx delete mode 100644 content/docs/web-analytics/identify.mdx delete mode 100644 content/docs/web-analytics/index.mdx delete mode 100644 content/docs/web-analytics/javascript.mdx delete mode 100644 content/docs/web-analytics/meta.json delete mode 100644 content/docs/web-analytics/nuxt.mdx delete mode 100644 content/docs/web-analytics/react.mdx delete mode 100644 content/docs/web-analytics/session-replay.mdx delete mode 100644 content/docs/web-analytics/sourcemaps.mdx delete mode 100644 content/docs/web-analytics/web-vitals.mdx create mode 100644 ec.config.mjs delete mode 100644 next.config.mjs create mode 100644 pnpm-lock.yaml create mode 100644 pnpm-workspace.yaml delete mode 100644 postcss.config.mjs delete mode 100644 source.config.ts delete mode 100644 src/app/(docs)/(main)/[[...slug]]/page.tsx delete mode 100644 src/app/(docs)/(main)/layout.tsx delete mode 100644 src/app/(docs)/not-found.tsx delete mode 100644 src/app/docs-search/route.ts delete mode 100644 src/app/global.css delete mode 100644 src/app/layout.tsx delete mode 100644 src/app/llms-full.txt/route.ts delete mode 100644 src/app/llms.mdx/docs/[[...slug]]/route.ts delete mode 100644 src/app/llms.txt/route.ts delete mode 100644 src/app/not-found.tsx delete mode 100644 src/app/og/docs/[...slug]/route.tsx delete mode 100644 src/app/tokens.css create mode 100644 src/assets/houston.webp create mode 100644 src/assets/icon-dark.svg create mode 100644 src/assets/icon-light.svg create mode 100644 src/components/LinkCard.astro create mode 100644 src/components/ReadMore.astro delete mode 100644 src/components/ai/page-actions.tsx delete mode 100644 src/components/api-page.tsx delete mode 100644 src/components/docs/docs-not-found.tsx delete mode 100644 src/components/docs/docs-sidebar.tsx delete mode 100644 src/components/docs/node-preview.tsx delete mode 100644 src/components/og/faststats-icon.tsx delete mode 100644 src/components/og/og-template.tsx delete mode 100644 src/components/site-brand.tsx create mode 100644 src/components/starlight/ContentPanel.astro create mode 100644 src/components/starlight/Sidebar.astro create mode 100644 src/components/starlight/topics/Topics.astro create mode 100644 src/components/starlight/topics/TopicsSelector.astro create mode 100644 src/content.config.ts rename {content => src/content}/docs/api/index.mdx (81%) create mode 100644 src/content/docs/index.mdx rename content/docs/platform/error-tracking/index.mdx => src/content/docs/platform/error-tracking.mdx (100%) rename {content => src/content}/docs/platform/guide/badges.mdx (100%) rename {content => src/content}/docs/platform/guide/embed.mdx (100%) rename {content => src/content}/docs/platform/hotkeys.mdx (95%) rename {content => src/content}/docs/platform/index.mdx (80%) rename content/docs/platform/retention/index.mdx => src/content/docs/platform/retention.mdx (100%) create mode 100644 src/integrations/dev-file-watcher.ts delete mode 100644 src/lib/docs-tabs.tsx delete mode 100644 src/lib/docs/repository.ts delete mode 100644 src/lib/layout.shared.tsx delete mode 100644 src/lib/openapi.ts delete mode 100644 src/lib/source.ts delete mode 100644 src/mdx-components.tsx create mode 100644 src/styles/starlight.css diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 8b88447..0000000 --- a/.dockerignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules -.next -.git diff --git a/.github/renovate.json b/.github/renovate.json deleted file mode 100644 index fef230b..0000000 --- a/.github/renovate.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:recommended", - "security:minimumReleaseAgeNpm", - ":disableDependencyDashboard" - ], - "minimumReleaseAge": "1 day", - "packageRules": [ - { - "groupName": "fumadocs", - "matchPackageNames": [ - "fumadocs-core", - "fumadocs-mdx", - "fumadocs-openapi", - "fumadocs-ui" - ] - }, - { - "groupName": "takumi", - "matchPackageNames": ["@takumi-rs/core", "@takumi-rs/image-response"] - } - ] -} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 461a455..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: CI - -on: - push: - branches: - - main - pull_request: - -permissions: - contents: read - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - check: - name: Typecheck and build - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v7 - - - name: Setup Bun - uses: oven-sh/setup-bun@v2 - - - name: Install dependencies - run: bun install --frozen-lockfile - - - name: Typecheck - run: bun run typecheck - - - name: Build - run: bun run build diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml deleted file mode 100644 index 2d36348..0000000 --- a/.github/workflows/quality.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Code Quality - -on: - push: - branches: - - main - pull_request: - -permissions: - contents: read - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - quality: - name: Format and lint - runs-on: ubuntu-latest - timeout-minutes: 10 - - steps: - - name: Checkout - uses: actions/checkout@v7 - - - name: Setup Bun - uses: oven-sh/setup-bun@v2 - with: - bun-version: 1.3.14 - - - name: Install dependencies - run: bun install --frozen-lockfile - - - name: Check formatting - run: bun run format:check - - - name: Lint - run: bun run lint diff --git a/.gitignore b/.gitignore index 9e429e4..120dcb7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,26 +1,24 @@ -# deps -/node_modules +# build output +dist/ +# generated types +.astro/ -# generated content -.source +# dependencies +node_modules/ -# test & build -/coverage -/.next/ -/out/ -/build -*.tsbuildinfo - -# misc -.DS_Store -*.pem -/.pnp -.pnp.js +# logs npm-debug.log* yarn-debug.log* yarn-error.log* +pnpm-debug.log* + + +# environment variables +.env +.env.production + +# macOS-specific files +.DS_Store + -# others -.env*.local -.vercel -next-env.d.ts \ No newline at end of file +.fumadocs/ \ No newline at end of file diff --git a/.oxfmtrc.json b/.oxfmtrc.json deleted file mode 100644 index 5b70d3a..0000000 --- a/.oxfmtrc.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "$schema": "./node_modules/oxfmt/configuration_schema.json", - "useTabs": true, - "tabWidth": 2, - "printWidth": 80, - "endOfLine": "lf", - "singleQuote": false, - "jsxSingleQuote": false, - "quoteProps": "as-needed", - "trailingComma": "all", - "semi": true, - "arrowParens": "always", - "bracketSameLine": false, - "bracketSpacing": true, - "sortImports": { - "newlinesBetween": false - }, - "sortTailwindcss": true, - "ignorePatterns": [ - "apps/downloads-poller/*", - "apps/feature-flags-service/*", - "apps/blog/src/data/countries-110m.json", - "apps/tanstack/src/lib/embed/assets/countries-110m.json", - "apps/tanstack/src/routeTree.gen.ts" - ] -} diff --git a/.oxlintrc.json b/.oxlintrc.json deleted file mode 100644 index 7150748..0000000 --- a/.oxlintrc.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "$schema": "./node_modules/oxlint/configuration_schema.json", - "plugins": [ - "typescript", - "unicorn", - "oxc", - "react", - "react-perf", - "jsx-a11y" - ], - "categories": { - "correctness": "error" - }, - "rules": {}, - "env": { - "builtin": true - } -} diff --git a/.prototools b/.prototools new file mode 100644 index 0000000..a574098 --- /dev/null +++ b/.prototools @@ -0,0 +1 @@ +node = "22.20.0" diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..22a1505 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,4 @@ +{ + "recommendations": ["astro-build.astro-vscode"], + "unwantedRecommendations": [] +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..d642209 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "command": "./node_modules/.bin/astro dev", + "name": "Development server", + "request": "launch", + "type": "node-terminal" + } + ] +} diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..c5ff429 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,22 @@ +## Development + +When starting the dev server, use background mode: + +``` +astro dev --background +``` + +Manage the background server with `astro dev stop`, `astro dev status`, and `astro dev logs`. + +## Documentation + +Full documentation: https://docs.astro.build + +Consult these guides before working on related tasks: + +- [Adding pages, dynamic routes, or middleware](https://docs.astro.build/en/guides/routing/) +- [Working with Astro components](https://docs.astro.build/en/basics/astro-components/) +- [Using React, Vue, Svelte, or other framework components](https://docs.astro.build/en/guides/framework-components/) +- [Adding or managing content](https://docs.astro.build/en/guides/content-collections/) +- [Adding styles or using Tailwind](https://docs.astro.build/en/guides/styling/) +- [Supporting multiple languages](https://docs.astro.build/en/guides/internationalization/) diff --git a/CLAUDE.md b/CLAUDE.md new file mode 120000 index 0000000..47dc3e3 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index f758add..0000000 --- a/Dockerfile +++ /dev/null @@ -1,28 +0,0 @@ -FROM node:26-slim AS builder -COPY --from=oven/bun:1.3.14-slim /usr/local/bin/bun /usr/local/bin/bun -WORKDIR /app - -COPY package.json bun.lock ./ -RUN bun install --frozen-lockfile --ignore-scripts -COPY . . - -ENV CI=true -RUN bun run fumadocs-mdx -RUN bun run build - -FROM node:26-slim AS runner -WORKDIR /app -ENV NODE_ENV=production -ENV HOSTNAME=0.0.0.0 - -RUN groupadd --system --gid 1001 nodejs && \ - useradd --system --uid 1001 --gid nodejs --shell /bin/false appuser - -COPY --from=builder --chown=appuser:nodejs /app/.next/standalone ./ -COPY --from=builder --chown=appuser:nodejs /app/.next/static ./.next/static -COPY --from=builder --chown=appuser:nodejs /app/public ./public - -USER appuser -EXPOSE ${PORT} - -CMD ["node", "server.js"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..909d737 --- /dev/null +++ b/README.md @@ -0,0 +1,49 @@ +# Starlight Starter Kit: Basics + +[![Built with Starlight](https://astro.badg.es/v2/built-with-starlight/tiny.svg)](https://starlight.astro.build) + +``` +pnpm create astro@latest -- --template starlight +``` + +> πŸ§‘β€πŸš€ **Seasoned astronaut?** Delete this file. Have fun! + +## πŸš€ Project Structure + +Inside of your Astro + Starlight project, you'll see the following folders and files: + +``` +. +β”œβ”€β”€ public/ +β”œβ”€β”€ src/ +β”‚ β”œβ”€β”€ assets/ +β”‚ β”œβ”€β”€ content/ +β”‚ β”‚ └── docs/ +β”‚ └── content.config.ts +β”œβ”€β”€ astro.config.mjs +β”œβ”€β”€ package.json +└── tsconfig.json +``` + +Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name. + +Images can be added to `src/assets/` and embedded in Markdown with a relative link. + +Static assets, like favicons, can be placed in the `public/` directory. + +## 🧞 Commands + +All commands are run from the root of the project, from a terminal: + +| Command | Action | +| :------------------------ | :----------------------------------------------- | +| `pnpm install` | Installs dependencies | +| `pnpm dev` | Starts local dev server at `localhost:4321` | +| `pnpm build` | Build your production site to `./dist/` | +| `pnpm preview` | Preview your build locally, before deploying | +| `pnpm astro ...` | Run CLI commands like `astro add`, `astro check` | +| `pnpm astro -- --help` | Get help using the Astro CLI | + +## πŸ‘€ Want to learn more? + +Check out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat). diff --git a/astro.config.ts b/astro.config.ts new file mode 100644 index 0000000..e6f83bf --- /dev/null +++ b/astro.config.ts @@ -0,0 +1,107 @@ +// @ts-check +import { defineConfig } from 'astro/config'; +import starlight from '@astrojs/starlight'; +import starlightSidebarTopicsPlugin from 'starlight-sidebar-topics'; +import { devServerFileWatcher } from './src/integrations/dev-file-watcher'; + +// https://astro.build/config +export default defineConfig({ + site: "https://docs.faststats.dev", + + integrations: [ + devServerFileWatcher([ + './src/integrations/*.ts', + ]), + starlight({ + title: 'FastStats Docs', + description: 'Error tracking, session replays, web vitals, funnels, and retention in one platform β€” stop stitching five tools together. Free during closed beta.', + tagline: 'Product Analytics That Makes Sense', + + favicon: '/icon-dark.svg', + logo: { + dark: './src/assets/icon-dark.svg', + light: './src/assets/icon-light.svg', + }, + + head: [ + { + tag: 'link', + attrs: { + rel: 'icon', + href: '/icon-light.svg', + media: '(prefers-color-scheme: light)', + }, + }, + { + tag: 'link', + attrs: { + rel: 'icon', + href: '/icon-dark.svg', + media: '(prefers-color-scheme: dark)', + }, + } + ], + + social: [ + { icon: 'github', label: 'GitHub', href: 'https://github.com/faststats-dev' }, + { icon: 'discord', label: 'Discord', href: 'https://discord.com/invite/SKnDU5VwMS' }, + ], + + components: { + Sidebar: './src/components/starlight/Sidebar.astro', + }, + + customCss: [ + './src/styles/starlight.css', + ], + + editLink: { + baseUrl: 'https://github.com/faststats-dev/docs/tree/main', + }, + + plugins: [ + starlightSidebarTopicsPlugin([ + { + label: 'Platform', + id: 'platform', + link: '/platform/', + icon: 'puzzle', + items: [ + 'platform', + 'platform/hotkeys', + 'platform/guide/embed', + 'platform/guide/badges', + 'platform/error-tracking', + 'platform/retention' + ], + }, + { + label: 'Java', + id: 'java', + link: '/java/', + icon: 'seti:java', + items: [{ autogenerate: { directory: 'java' } }], + }, + { + label: 'Rest API', + id: 'api', + link: '/api/', + icon: 'open-book', + items: [{ autogenerate: { directory: 'api' } }], + }, + { + label: 'Web Analytics', + id: 'web-analytics', + link: '/web-analytics/', + icon: 'analytics', + items: [{ autogenerate: { directory: 'web-analytics' } }], + badge: { + text: "Coming Soon", + variant: 'tip' + } + } + ]) + ] + }), + ], +}); diff --git a/bun.lock b/bun.lock deleted file mode 100644 index 23f8050..0000000 --- a/bun.lock +++ /dev/null @@ -1,980 +0,0 @@ -{ - "lockfileVersion": 1, - "configVersion": 1, - "workspaces": { - "": { - "name": "docs", - "dependencies": { - "@faststats/react": "0.5.0", - "@fontsource-variable/geist": "^5.2.8", - "@fontsource-variable/geist-mono": "^5.2.7", - "@takumi-rs/image-response": "^1.1.2", - "cnfast": "0.0.8", - "fumadocs-core": "16.10.7", - "fumadocs-mdx": "15.0.13", - "fumadocs-openapi": "11.0.6", - "fumadocs-ui": "16.10.7", - "lucide-react": "1.23.0", - "next": "16.2.10", - "react": "19.2.7", - "react-dom": "19.2.7", - }, - "devDependencies": { - "@tailwindcss/postcss": "4.3.2", - "@types/mdx": "^2.0.13", - "@types/node": "^26.0.0", - "@types/react": "^19.2.17", - "@types/react-dom": "^19.2.3", - "@typescript/native-preview": "^7.0.0-dev.20260627.2", - "oxfmt": "0.57.0", - "oxlint": "1.72.0", - "postcss": "^8.5.13", - "tailwindcss": "^4.3.0", - "typescript": "rc", - }, - }, - }, - "packages": { - "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], - - "@emnapi/runtime": ["@emnapi/runtime@1.11.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA=="], - - "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.28.1", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ=="], - - "@esbuild/android-arm": ["@esbuild/android-arm@0.28.1", "", { "os": "android", "cpu": "arm" }, "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ=="], - - "@esbuild/android-arm64": ["@esbuild/android-arm64@0.28.1", "", { "os": "android", "cpu": "arm64" }, "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg=="], - - "@esbuild/android-x64": ["@esbuild/android-x64@0.28.1", "", { "os": "android", "cpu": "x64" }, "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng=="], - - "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.28.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q=="], - - "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.28.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ=="], - - "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.28.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw=="], - - "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.28.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ=="], - - "@esbuild/linux-arm": ["@esbuild/linux-arm@0.28.1", "", { "os": "linux", "cpu": "arm" }, "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ=="], - - "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.28.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g=="], - - "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.28.1", "", { "os": "linux", "cpu": "ia32" }, "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w=="], - - "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg=="], - - "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ=="], - - "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.28.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ=="], - - "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ=="], - - "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.28.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag=="], - - "@esbuild/linux-x64": ["@esbuild/linux-x64@0.28.1", "", { "os": "linux", "cpu": "x64" }, "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA=="], - - "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.28.1", "", { "os": "none", "cpu": "arm64" }, "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw=="], - - "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.28.1", "", { "os": "none", "cpu": "x64" }, "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg=="], - - "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.28.1", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q=="], - - "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.28.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw=="], - - "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.28.1", "", { "os": "none", "cpu": "arm64" }, "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg=="], - - "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.28.1", "", { "os": "sunos", "cpu": "x64" }, "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ=="], - - "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.28.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA=="], - - "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.28.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg=="], - - "@esbuild/win32-x64": ["@esbuild/win32-x64@0.28.1", "", { "os": "win32", "cpu": "x64" }, "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A=="], - - "@faststats/react": ["@faststats/react@0.5.0", "", { "dependencies": { "@faststats/web": "^0.5.0" }, "peerDependencies": { "react": ">=18" } }, "sha512-utETA4H+RAw2TaB/4chcrj2j2Ptw0pNt2QyxocrfnryNHaJKia+HkRTNnNN7+v5IEnC30PcxL/LBtUILcQwq6A=="], - - "@faststats/web": ["@faststats/web@0.5.0", "", { "dependencies": { "@rrweb/record": "^2.1.0", "@rrweb/rrweb-plugin-console-record": "^2.1.0", "@rrweb/rrweb-plugin-sequential-id-record": "^2.1.0", "web-vitals": "^5.3.0" } }, "sha512-p9+JqCMJAHyElC9mR3VnQwSYwzMYmtZZjg/3r5NdG9CRr2R8Fmvdt7fJR+MdacxYkVPrrRIbeNZlRJxALy+rWg=="], - - "@floating-ui/core": ["@floating-ui/core@1.7.5", "", { "dependencies": { "@floating-ui/utils": "^0.2.11" } }, "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ=="], - - "@floating-ui/dom": ["@floating-ui/dom@1.7.6", "", { "dependencies": { "@floating-ui/core": "^1.7.5", "@floating-ui/utils": "^0.2.11" } }, "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ=="], - - "@floating-ui/react-dom": ["@floating-ui/react-dom@2.1.8", "", { "dependencies": { "@floating-ui/dom": "^1.7.6" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A=="], - - "@floating-ui/utils": ["@floating-ui/utils@0.2.11", "", {}, "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg=="], - - "@fontsource-variable/geist": ["@fontsource-variable/geist@5.2.9", "", {}, "sha512-TP+QSBG3wxKGPE33CbMy/L0Nu3qvJ6Fy81Yc4LnQ95xH+i+cfEp8fyU8/kfV14YwszxIFPhnoMTbjL71waVpyQ=="], - - "@fontsource-variable/geist-mono": ["@fontsource-variable/geist-mono@5.2.8", "", {}, "sha512-KI5bj+hkkRiHttYHmccotUZ80ZuZyai+RwI1d7UId0clkx/jXxlo8qYK8j54WzmpBjtMoEMPyllV7faDcj+6RA=="], - - "@fuma-translate/react": ["@fuma-translate/react@1.0.2", "", { "peerDependencies": { "@types/react": "*", "react": "^19.2.0", "react-dom": "^19.2.0" }, "optionalPeers": ["@types/react"] }, "sha512-uOiOtBx3nRXR8Nu1GzBf1tApgF1FErDBTHxRIAQeyQdyOoZbrNRN6H4kDCWObY4qyGeGbHydG0DHzgeUgFDMIw=="], - - "@fumadocs/api-docs": ["@fumadocs/api-docs@0.0.4", "", { "dependencies": { "@fuma-translate/react": "^1.0.2", "@fumari/stf": "1.0.5", "@radix-ui/react-accordion": "^1.2.14", "@radix-ui/react-dialog": "^1.1.17", "@radix-ui/react-select": "^2.3.1", "class-variance-authority": "^0.7.1", "cnfast": "^0.0.8", "github-slugger": "^2.0.0", "js-yaml": "^5.1.0", "lucide-react": "^1.21.0" }, "peerDependencies": { "@types/react": "*", "fumadocs-core": "^16.9.0", "fumadocs-ui": "^16.9.0", "json-schema-typed": "*", "react": "^19.2.0", "react-dom": "^19.2.0" }, "optionalPeers": ["@types/react", "json-schema-typed"] }, "sha512-zgYDe1bgRvHRfeqTQEjE505QgSQkC3XcAUEtX4TLJKckX6aMpPJIEWz6pWIoOMKqIFFGrhy+hr3FvI+JFbKgkw=="], - - "@fumadocs/tailwind": ["@fumadocs/tailwind@0.0.5", "", { "peerDependencies": { "@tailwindcss/oxide": "^4.0.0", "tailwindcss": "^4.0.0" }, "optionalPeers": ["@tailwindcss/oxide", "tailwindcss"] }, "sha512-ENKPWUDRmriccsrUDE4bDBq3FNr/ms3BP2rWlsAEMV1yP23pcCaan+ceGfeBUsAQjw7sj9Q3R4Kl3g/TCStPzQ=="], - - "@fumari/json-schema-ts": ["@fumari/json-schema-ts@0.0.2", "", { "dependencies": { "esrap": "^2.2.3" }, "peerDependencies": { "json-schema-typed": "^8.0.2" }, "optionalPeers": ["json-schema-typed"] }, "sha512-A2x8nj45r8Kc3Gqa+HpWRF9uzIMc9dySB6L2R2kiyjLHXWBsZUX99Atj5+Yup/iRQXQ9s8AX+uAPwPze7Xn05A=="], - - "@fumari/stf": ["@fumari/stf@1.0.5", "", { "peerDependencies": { "@types/react": "*", "react": "^19.2.0", "react-dom": "^19.2.0" }, "optionalPeers": ["@types/react"] }, "sha512-O9UQIbV15ePV5vUgceCcaMDuBRYfrSuogDEY5E//CmrbIiWJ1Ji5VgGHHH0L0HQuRr5riUJuAEr9lYIvJl9OyQ=="], - - "@img/colour": ["@img/colour@1.1.0", "", {}, "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ=="], - - "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="], - - "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="], - - "@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="], - - "@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="], - - "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="], - - "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="], - - "@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="], - - "@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.2.4", "", { "os": "linux", "cpu": "none" }, "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA=="], - - "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="], - - "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="], - - "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="], - - "@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="], - - "@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="], - - "@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="], - - "@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA=="], - - "@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.2.4" }, "os": "linux", "cpu": "none" }, "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw=="], - - "@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="], - - "@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="], - - "@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="], - - "@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="], - - "@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="], - - "@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="], - - "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="], - - "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="], - - "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], - - "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], - - "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], - - "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], - - "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], - - "@mdx-js/mdx": ["@mdx-js/mdx@3.1.1", "", { "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" } }, "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ=="], - - "@next/env": ["@next/env@16.2.10", "", {}, "sha512-zLPxg9M0MEHmygpj5OuxjQ+vHMiy/K7cSp74G8ecYolmgUWw0RwN02tF56npup/+qaI8JB97hQgS/r2Hb6QwVA=="], - - "@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.2.10", "", { "os": "darwin", "cpu": "arm64" }, "sha512-v9IdJCa0H0mbo+8z5zwUpOk1Vj7RjkcI5uNYf5Ws1y6szf/p3Mzl9hLaST8SCt6L9h8NGnruZcd2+o0NTNwDhA=="], - - "@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.2.10", "", { "os": "darwin", "cpu": "x64" }, "sha512-17IS0jJRViROGmA9uGdNR8VPJpfbnaVG7E9qhso5jDLkmyd0lSDORWxbcKINzcFqzZqGwGtMSnrFRxBpuUYjLQ=="], - - "@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.2.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-GRQRsRtuciNJvB54AvvuQTiq0oZtFwa1owQqtZD8wwnGpM2L39MV22kpI72YSXLKIyY40LC66EiLFv4PiicXxg=="], - - "@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.2.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-zkN9MQYS7UQBro+FnISUq1itaQjXI9xqISzuQ+2bc921NcJ1x4yPCqrn77tVN6/dOOXaaWVX3k6/bR07pPwK+A=="], - - "@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.2.10", "", { "os": "linux", "cpu": "x64" }, "sha512-iCVJnwvrPYECvA6WM/7+oo+OiTvedIKLxtCLAZP4xZR3nXa1zmzZyLPbYCmWvpd4CvMYF1EMTafd0ii3DygLvA=="], - - "@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.2.10", "", { "os": "linux", "cpu": "x64" }, "sha512-ov2g4H0dHY9bPoOU83m91hWT7Iq5qy13bUnyyshLU3HGR1Ownn0X9QpmDPc5iIUaahTp7f7LeGAhV4DSFtackw=="], - - "@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.2.10", "", { "os": "win32", "cpu": "arm64" }, "sha512-DwAnhLX76HQiFFQNgWlcK+JzlnD1rZ+UK/WY0ZMI/deXpvgnesjNYrqcfo1JzBuz4Kf7o3brIBL0glI1junatA=="], - - "@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.2.10", "", { "os": "win32", "cpu": "x64" }, "sha512-0JXq3b85Jk9Jg4ntLUbXSPvoDw3gpZou7twuKdoFG2jOw635v7+IiXfTaa0TxVMyx78pUjnrVYwLgjKfX4e6/A=="], - - "@orama/orama": ["@orama/orama@3.1.18", "", {}, "sha512-a61ljmRVVyG5MC/698C8/FfFDw5a8LOIvyOLW5fztgUXqUpc1jOfQzOitSCbge657OgXXThmY3Tk8fpiDb4UcA=="], - - "@oxfmt/binding-android-arm-eabi": ["@oxfmt/binding-android-arm-eabi@0.57.0", "", { "os": "android", "cpu": "arm" }, "sha512-qVBsEO+KugOsCmUHcO8iqNnqc65p7PCKpCs8M66mPZ+Ri+CWbcpoQOEJBg2OTu03+0qu++NK1jj6IzvQVs0Sig=="], - - "@oxfmt/binding-android-arm64": ["@oxfmt/binding-android-arm64@0.57.0", "", { "os": "android", "cpu": "arm64" }, "sha512-mp6PibWbao3aizijcheOeHQaYEhcUAt8pwLniYbtLfHxL/psFF0BykAwCj+s3c6qIpa8yN8keZICWrqtZ70w8g=="], - - "@oxfmt/binding-darwin-arm64": ["@oxfmt/binding-darwin-arm64@0.57.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-T+0stuCBqmUVY+aMIvrgXhzGhHO3sD5tNiiEcYqgSdPsnukskQqn2u5qOVD0sv1l7RLdFS5Z/f5Wi9Ktyjr3Eg=="], - - "@oxfmt/binding-darwin-x64": ["@oxfmt/binding-darwin-x64@0.57.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-O+3JbqWs/mCI2oi4xfhRO2IVPFJNDDEBV8Odo+ZpmsUOeKJfjXoNH7nDmBEQcDgK7NfjDIyE7kRgYSZcTLDO0A=="], - - "@oxfmt/binding-freebsd-x64": ["@oxfmt/binding-freebsd-x64@0.57.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-pxwhxVC+JkLX9twOQ/8C/vbuOQcMZyKIDmiRDZfO7yITuVcIdZCiLRqqf4QOxb2+8FWrRXzQpm+1DBKcMpHSSQ=="], - - "@oxfmt/binding-linux-arm-gnueabihf": ["@oxfmt/binding-linux-arm-gnueabihf@0.57.0", "", { "os": "linux", "cpu": "arm" }, "sha512-pxBU4zH2imB/MDBfth2rOMeVxXUMjRQLCazagwLARIFH3hVlxZJBlM4nSnHXaIHJK4/qezoFCIORN6AY8Mra4A=="], - - "@oxfmt/binding-linux-arm-musleabihf": ["@oxfmt/binding-linux-arm-musleabihf@0.57.0", "", { "os": "linux", "cpu": "arm" }, "sha512-JAprOzt8tycYou36ZgEw14DlRHTiN8qdtKANdV3VZIRIvTI/lh/cX13c9pJ/EnDk2GT3FASH7KvCgQ2AufAifQ=="], - - "@oxfmt/binding-linux-arm64-gnu": ["@oxfmt/binding-linux-arm64-gnu@0.57.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-ajtjaxSaj9xl4BW7REt+Cef/ttzbAq00Bq4z7JUDZEfgFXdwSjH8K9bF+IcIJzZB9lKqMfQ4eHuSFOvvlvtqOg=="], - - "@oxfmt/binding-linux-arm64-musl": ["@oxfmt/binding-linux-arm64-musl@0.57.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-p4Y/+RYk9Bk5WO+zHSUXAClRmZ2fbJCejMuCAsU2HhyME4jqf6Ftt/mJYEwIah1wGCBDYOB7wEGV1x5bCEZ6hA=="], - - "@oxfmt/binding-linux-ppc64-gnu": ["@oxfmt/binding-linux-ppc64-gnu@0.57.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-By6tRALAZsno0F4zedmtG+wdMvJiJmJoXM4d3+A9zHE4HRXLqXITwRH8mgrlcXc5yJM2g2W3riRPwTYdgemZLQ=="], - - "@oxfmt/binding-linux-riscv64-gnu": ["@oxfmt/binding-linux-riscv64-gnu@0.57.0", "", { "os": "linux", "cpu": "none" }, "sha512-skYeG+RgvyzspqVEBsEprL90OYYZfoVNqB3HcCNR6QDJyXKOzfDRT3zncnHmUaFluIlBHuY23mU1b5WGgR98hA=="], - - "@oxfmt/binding-linux-riscv64-musl": ["@oxfmt/binding-linux-riscv64-musl@0.57.0", "", { "os": "linux", "cpu": "none" }, "sha512-FFgACrZOXAXUh5KQh2mt1CDOVOZmn+QzHP71wM9QobNwyQvoFfyAeefVUltW83g3sm7LTiH3yfFqLLVUpA5ZFQ=="], - - "@oxfmt/binding-linux-s390x-gnu": ["@oxfmt/binding-linux-s390x-gnu@0.57.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-Nm/BAOfQeFiiKd502mZn/GAVKJwtd0RdCg17G3Wz/WSOIQmDi3+7/SZH4BHn1Ye5KvTVH3ua8WvfwLLycNIuvA=="], - - "@oxfmt/binding-linux-x64-gnu": ["@oxfmt/binding-linux-x64-gnu@0.57.0", "", { "os": "linux", "cpu": "x64" }, "sha512-BiSy5Ku3mQqyxS6YIqAJgd403wEUWvI7kerfzPxc2l/txZVmZM0pSj7oDM+4bGBExowxOi7o73jEam1W0EDTZg=="], - - "@oxfmt/binding-linux-x64-musl": ["@oxfmt/binding-linux-x64-musl@0.57.0", "", { "os": "linux", "cpu": "x64" }, "sha512-BCRkJiotz5s9afLYD2LuMvzAoDYx9H17E/YbDyu4xK7l4zHDPeny9ErSXL//i/nJyaOwRk08x4b8cgJC00+JDg=="], - - "@oxfmt/binding-openharmony-arm64": ["@oxfmt/binding-openharmony-arm64@0.57.0", "", { "os": "none", "cpu": "arm64" }, "sha512-4Oaxe1qrGgXfpCJ1C/ERJ2iCtV2rN1R79ga9fsfyVHfSQRu/hVW780u2KDqZWFZ/iGTHODJji0JemxqFZ63eIQ=="], - - "@oxfmt/binding-win32-arm64-msvc": ["@oxfmt/binding-win32-arm64-msvc@0.57.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-MYLAsDnhdNsSGheLYhWgbk0vfIrlS84iQYun/y21fX6u0jj8iBtYtbpZMdiqYeuf8U12eVPUjVY2xE2NrCfJ0g=="], - - "@oxfmt/binding-win32-ia32-msvc": ["@oxfmt/binding-win32-ia32-msvc@0.57.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-PBwdzZALJY/jcCx2E6is0yu+cuVXeySTDmwuseD+9j0mHqlRNxwlKgsyRTBed/woPeqfVfuXfWjoq4Cx2Zt3Eg=="], - - "@oxfmt/binding-win32-x64-msvc": ["@oxfmt/binding-win32-x64-msvc@0.57.0", "", { "os": "win32", "cpu": "x64" }, "sha512-bQJdH9i4RRfw55jm7+8/xS7GzHLLTbHx4huhrrDxQJaJtbSDbsyOnODvP1ftT7EG0KFKAYO2S+q6AcioXODx8w=="], - - "@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.72.0", "", { "os": "android", "cpu": "arm" }, "sha512-zhCmvn+1Mj3UchAc/90i99S0t7jJUsHmFVSPg4UWrjO8b8eaSGwscgO6QAUtvHBstkjQwBttQNswEnAF1mIQdA=="], - - "@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.72.0", "", { "os": "android", "cpu": "arm64" }, "sha512-mtH+aY/ozv1eZoCUC2owjFAtyNBKHpJHygKeEu9zXXnQGW1Q2/qOpvx+I+Lf23+TvTz66F4iiXUbl2cGvoLPCQ=="], - - "@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.72.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-EvnajNPDtfknB3ZieeOOyDTwJn9QXDiwfnF4ZDQqART6RG6hjY4WigQcZdGoK2dkB3e1vrmEzN9aYbQCUkh/gQ=="], - - "@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.72.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZkCdEa/G80A7vEHfeCDz/+L3m33DE73v32mDKhgOIgz8Uwf0DFcK7+uu6qC+7LEhmz5fpOe1osWKyjSNMydFIQ=="], - - "@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.72.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-NroXv2vh+sxVY1uya/rM5pjhx1hm8BzlYpx9q67QP0Xhw5MH2bf5GJylpvLEC+781p1Xli/317EoV9AlGwViag=="], - - "@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.72.0", "", { "os": "linux", "cpu": "arm" }, "sha512-0NDywYgfj279Ou/BcQuCYSj7NJwBfmWn5qc5uGO/Ny7fUWmXyIpvawqX/8acQlWG6IXelJsJhj+JAy6sjsKj0A=="], - - "@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.72.0", "", { "os": "linux", "cpu": "arm" }, "sha512-4vpXB06h65Ezsy4hRyrGjGrfa1SkVPii09yaajiYhmVpgsFiLD+KNxIx/BNAY+XiO+i1yqp9HHdwqM8VTqa5XQ=="], - - "@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.72.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-immaN4g2ZGFiOkKrvRX9LvzZdd2GkQM5wR+UyzYyUuyhUTXGQ4HKUJH18xp4G8OfhCVaVAJfKZxwE1r8+4hhaQ=="], - - "@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.72.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-JGHS9Mnr7iWyyLDxgCv1MhzVpAckgptg00F2gnxt/GD7lQ2SW1BRcxHqhSTaSdDpjWRrBkBxMMh4+Hn3aVtExg=="], - - "@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.72.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-AOYgBZqxNshrg83P9v0RYv+m8s10Cqkj4/PxXFDhcS3k7FqsIG5+CxErshZCIN7G8iy4Y+VGfAsuEdar8AcbBg=="], - - "@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.72.0", "", { "os": "linux", "cpu": "none" }, "sha512-QMybPS5ij3/vrKG67mqzHwW++91sYxK/PPUVi6SBtNCEzW4niS52fVBdXbQ6nou0wWbUPEpx8Sl/ZjtgE3clXA=="], - - "@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.72.0", "", { "os": "linux", "cpu": "none" }, "sha512-gOc3W7JV0PXRpIL7stUlLe3Wa9Gp0Kdlup87IT3gHDvPKck2xNgMIl/Gs2lldYY2lyXZDC4rWi3hmoLUobkgbQ=="], - - "@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.72.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-rpGxph+FjjHcYI5q6uxB3Az+tnfmEnDbSA8+PK9ZE/VzyUAkvBOMeuY7ZQMhu5mpZH7YQDsTdW6Cx4kV/msc6w=="], - - "@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.72.0", "", { "os": "linux", "cpu": "x64" }, "sha512-WND+uhf/Ko13SLqQMWQUgsZuLvYYEvL0ZKgg0tgGYfLqxG7l8Ju123fHDMJyYSDl5E3bUbpFUuii/OvMreFQzw=="], - - "@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.72.0", "", { "os": "linux", "cpu": "x64" }, "sha512-SrpbrUL70nG9vh6zP4/oKHWgLuHquwsr7MW9XOn0olBVgh10Uqr8qscKhQoBGEn6olK/IUpn5GSKcdQ5AjUhGA=="], - - "@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.72.0", "", { "os": "none", "cpu": "arm64" }, "sha512-qkrsEn6NmgFKr7U/QnezQMb+q/vzAy0Dd9Y95gQGQTyjzDLN+HRZMuM5u70iyH4nBLCfKBzhjMsYCehKay2jyg=="], - - "@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.72.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-LWR6ZlFZph+KPjXv8opgZsXRDCdrdQe8VL8Cg9zxCoBS73h6znzZpydVgmdnwj8mB9AuSM5jxEgDJDpQkjboeg=="], - - "@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.72.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-yt6HEh7IsHvtjRWtmeZRX134eaXKHq5Gnqlf1xBJdJl1JtdoRUEJw3nAxpZoUDS860cX/foKbztO441anVBtVQ=="], - - "@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.72.0", "", { "os": "win32", "cpu": "x64" }, "sha512-b2eKFD2hX7tIwmo/cyH6TDq8vzWRZ2qNHrzoGntUTmq0h3zQh/uX3eTSHCwI8OB/ADQfJCRelLItK8BsxuucDA=="], - - "@radix-ui/number": ["@radix-ui/number@1.1.2", "", {}, "sha512-ceTwaxc4I5IOi97DgCotl3pqiyRGvffcc0oOsE2dQYaJOFIDsDt4VWG6xEbg1QePv9QWausCEIppud/tJ1wNig=="], - - "@radix-ui/primitive": ["@radix-ui/primitive@1.1.4", "", {}, "sha512-7AdCK9PQyiljKoBDbN8OuctCbd/esdwZPQ8RtOE3SsyQtUpiPb+ND75q0jEhC1m1ecBI0MFNeLJvwIh9iKHRcQ=="], - - "@radix-ui/react-accordion": ["@radix-ui/react-accordion@1.2.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collapsible": "1.1.15", "@radix-ui/react-collection": "1.1.11", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-24Zz/0SYx8F2bSVThBnQrdJs2VbKelyuJordcFRRdA0fRAhrq/wSegGCqaQz34VQoiWqSMGYCYXEhynLSlyQlg=="], - - "@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.11", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Kdil9BB1rIFC/khmf4hC35bn8701AJcizTU7G7cUbEbk5XqqbjDuHW60uUfKqO5WojjZcbAW51Q7P0hRmMLw8A=="], - - "@radix-ui/react-collapsible": ["@radix-ui/react-collapsible@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-8A1zibu5skAQ+UVbaeNH5hVMibiFCRJzgMuM14LTWGttnTZKQL9jwYnhAbHRuxrtCqPXa4JvvnVUq1pTNgyZYw=="], - - "@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.11", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-djW9+zeg137KQdlPtmE8xnaD+K2rcXXMWFrSg0hsmYZ6HRbdTA7tDHFgpaW9+huWVEu0RCabL+985T4TA0BE7g=="], - - "@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-rYOP8OMnuuPMQF1uhPVlGNcCDlkokKqGFE3JcxFViIkAXP7EvFWUliJAstrapypaBLJNHbZL6jGhbVDGTwmVhA=="], - - "@radix-ui/react-context": ["@radix-ui/react-context@1.1.4", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-QwH4PO5urrbO+FaGd5Aglg+YJgWTyyuZ3g/6mKvsqraLkglDdckw9JafgL5McL5VEJ6EPNduPaT3ZE9BttDAqg=="], - - "@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.18", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.14", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.11", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-portal": "1.1.13", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-use-controllable-state": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-apa28mldjMgORmE6g/w3sCcA0Y9UAVeeDVoozN4i7kOw12mLl9RBchfzK3Nn6qxOWjrZhK1Lfy7f07kyzxtnBw=="], - - "@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-C3vFhbyi4SW3PmbAi6Awpu4OzJtd0MxGurvSsYtr7p7nM8RNB3VAF3CUmnp2j50knpkrRcB7+ycVXzgLgF6yNA=="], - - "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-effect-event": "0.0.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-4lUhWTWAjbDIqFrAPWJ3WqBOpO5YchVZ88X3nh6H9Lu5AFi5nCUeTPj3D8FSDmabmFeRe9ME0BDA4MwKTha5GQ=="], - - "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.4", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-cot/aB/mOm0IYVYTTmQcEEK1M48lZWi8FlYe5nDPQQ8NYZUlXEFgncJ9p2Kzer3RKSrY7cTTpEMLZKNo9QoP5Q=="], - - "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.11", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Mn88Vg2whaRocGJNOH+DKFqYm6ySFPQaiwHNxZPyjn99B52KAEJWWY9NP83+nWdk2HM3rdov+STu9AG471Rt9w=="], - - "@radix-ui/react-id": ["@radix-ui/react-id@1.1.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-orBC88futVpqCmhX1p4cvquNHsELQ+w+vBJnuj3ftETI5bJb0bZn3Tqu3SWN2IOcPycTnMGnhwoermvISt72sA=="], - - "@radix-ui/react-navigation-menu": ["@radix-ui/react-navigation-menu@1.2.17", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.11", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.14", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-visually-hidden": "1.2.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-fYeYQvbeNn5AQk2RBbpO7koLm2YbS00UYxC/IL2sgLlninEH5UNIv+X3E0KJ1Vy4WIo+dhN9w8GNqSHhbHWCIg=="], - - "@radix-ui/react-popover": ["@radix-ui/react-popover@1.1.18", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.14", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.11", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-popper": "1.3.2", "@radix-ui/react-portal": "1.1.13", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-use-controllable-state": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-qdXDes+eHlnMUGlBAAAe5EG7oOQvqsXuq4mq585diMudg80iB+jHbsSeG3+Q4eWNsogNyhqU2p/3i+Y0iEepqg=="], - - "@radix-ui/react-popper": ["@radix-ui/react-popper@1.3.2", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.11", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-rect": "1.1.2", "@radix-ui/react-use-size": "1.1.2", "@radix-ui/rect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-3QXNeMkdshed1MR3LNoiCirBywRFPkD8ETJa/HlPuLwSajaQixf2ro+isoDNJlGABg9ug41XuZpINZJIle4XWg=="], - - "@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.13", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-z3oXfmaHLJTF1wktbjgD6cn9jiEbq3WSondB10LIuIt2m2Ym4iJlrW04/euMwENDdWDdE7z+OuY7Qyp1YpRSwA=="], - - "@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.6", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-zdTk4PlUO0E18HnZ3wYbW0KkJJxWCdiNYp6g6X1PtONFhxVkg01vliTJAmwIszU6mHiyBOoW9P0rAugl5/hULQ=="], - - "@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.7", "", { "dependencies": { "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bC3NiwsprbxKjuon9l7X6BUTw7FPVzEYaL92MPEY5SCd/9hUTPXVFtVwRix7778wtRsVao+zE062gL79FZleeQ=="], - - "@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.11", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-8Qcnx9447tx/aCBgw6Jenfqg4Skq+vqab9mCBmuGNipIS5YXvL275wbKEu7+ICYHIlAPgCduUMJH1XOYewKF6Q=="], - - "@radix-ui/react-scroll-area": ["@radix-ui/react-scroll-area@1.2.13", "", { "dependencies": { "@radix-ui/number": "1.1.2", "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7tncSubo2G0UY1e8rk+72qe3XRzrGnOLtZQ1PL1KoBfRUNX0NrJT5akb+0kfwSCc3gVR4wdHqyhAQBDpDNOwDw=="], - - "@radix-ui/react-select": ["@radix-ui/react-select@2.3.2", "", { "dependencies": { "@radix-ui/number": "1.1.2", "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.11", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.14", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.11", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-popper": "1.3.2", "@radix-ui/react-portal": "1.1.13", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-visually-hidden": "1.2.7", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-brXD6C/V0fVK0DDbscLVw6LsXrjQ+ay8jdOBaN+tLb4vsHsAMm6Gt6eT77wHX1Eq8GPtD5rJ+RxFtfDozsb4+Q=="], - - "@radix-ui/react-slot": ["@radix-ui/react-slot@1.3.0", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-MojKku4U/miO8Av4Dkb+ctMAQx7JmY96LmtDQlAarCRtd7rN52QCSzBF+XAvr5S6coSVj9HEPBgHAHKEJVk/WA=="], - - "@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-roving-focus": "1.1.14", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-v3Ab2l7z6U7tRB4xA0IyKdq0OsqaO1o9ZjsIEoKKnSZ/l96mZz8aCTX0NCXw+YVHJXr8Km4d+Mn6/Q8YjXa+gw=="], - - "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-xCso9j1/u8sEgP1RNHjFrXJLApL8LiqOkI1R4ywuN00rxWdYg4oQXuwKLS3i0j5NWLromUD27/4nlxj2UFVvIw=="], - - "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.3", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.3", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-PLzC90MS+ReootmjC597dvopoelpZ8Q61HJkDXZSExitIq7PL55vHNnesAHwguHK0aPfBnpdNzQtv1uliaqQrA=="], - - "@radix-ui/react-use-effect-event": ["@radix-ui/react-use-effect-event@0.0.3", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-6c8ZqvPTWILEKnyVkP53EGRCcpnJiKTC21sS/6R1GF5xKyHJJWQEPfkqlcgUkdRQivd6tb23abUwe4ngWmY0JA=="], - - "@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jrBWOxZITuGcnjRCM2t2U5ZPkCLxD+Ym6DjfssS5haTj2iiak/DOb64JeN6OdLfLgptb6/e2kKR+ZuTrGoZTPA=="], - - "@radix-ui/react-use-previous": ["@radix-ui/react-use-previous@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-IGBQPtRFdhN6MQ8dbegVmBq1LVZluya3F1jWY+puIcQC3MHctRwTDSBWCkL/3ZcnMJLTMJ++Z+ktmvg0F89iCw=="], - - "@radix-ui/react-use-rect": ["@radix-ui/react-use-rect@1.1.2", "", { "dependencies": { "@radix-ui/rect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-d8a+bBY/FxikNPlgJJoaBHZX+zKVbWHYJGTLnLvveQgFSTntkGdEKv3JDtHrMS0DNYpllz2nRsTLGLKYttbpmw=="], - - "@radix-ui/react-use-size": ["@radix-ui/react-use-size@1.1.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-giWQp+4mxjBPt4KZ0MmyuykFNWfbDxKt4x+fPkRYmgRFJSbCZFzUglvMb/Kjn38tm10YP4ufiQZDx3zna4LU6w=="], - - "@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.2.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-1wNZBggTDK3GRuuQ6nP4k2yi7a6l7I5qbMPbZcRsrGsGVead/f/d5FhEzUvqFs0bcrDLx7n1zKQ3JvLR6whaaw=="], - - "@radix-ui/rect": ["@radix-ui/rect@1.1.2", "", {}, "sha512-xnXE7wG13PI+cxieVssYXlQJuYVRhH9NBoxt3KNwzghDIA69GMm7d4wXRouHIYjE+KvS6U/MsMO73NdS2MH9ZA=="], - - "@rrweb/record": ["@rrweb/record@2.1.0", "", { "dependencies": { "@rrweb/types": "^2.1.0", "@rrweb/utils": "^2.1.0", "rrweb": "^2.1.0" } }, "sha512-jnbpYQED6QdKn1MuEoqJyILkYhuWDhb3kzA/l1i+Di5sfP7apf3HvrlVIMoyZgATMlk2if65BUUrc5R+vabCjQ=="], - - "@rrweb/rrweb-plugin-console-record": ["@rrweb/rrweb-plugin-console-record@2.1.0", "", { "peerDependencies": { "@rrweb/utils": "^2.0.1", "rrweb": "^2.0.1" } }, "sha512-pwzkwkE++pyg7TqSdkBkV7g+Rhi2IkVflNCzOagCguUyyz0KhRRjJyjJ1gZe313tNh42I8wVEMsOaU9lcQdAvA=="], - - "@rrweb/rrweb-plugin-sequential-id-record": ["@rrweb/rrweb-plugin-sequential-id-record@2.1.0", "", { "peerDependencies": { "rrweb": "^2.0.1" } }, "sha512-TTsqWzfOxqKFAXEZBGvAhfJ7uBv7OJkjij7BedI9/Xo8spOJJ8Wy22FseuqMXD6PBH87mLwGeTEhnSPetrxsjg=="], - - "@rrweb/types": ["@rrweb/types@2.1.0", "", {}, "sha512-svOHkcuukP6rIjz2umwVsS7uYct+2h0N97+bg+8IJYKIUj5+YjwIvqx5y9NILFKPIu3yk+Mb+KDFfJ8RV+4JlA=="], - - "@rrweb/utils": ["@rrweb/utils@2.1.0", "", {}, "sha512-hU7MT3TSdD+Do7FmMoHrBfPevFCheN5vo2mn97Y4vbXuwemopAmo8dqo5KJeMaA6oQQt7FinHJ0Xqb7k68Ci6Q=="], - - "@shikijs/core": ["@shikijs/core@4.3.1", "", { "dependencies": { "@shikijs/primitive": "4.3.1", "@shikijs/types": "4.3.1", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-ANMDxuaPsNMdDC1m4vfvhlDmJweMwkE5XitTwrq2rWHx5jM+dlm4MmHt2PP6t0uejfR77SuhrhJ0zEijIF/uhA=="], - - "@shikijs/engine-javascript": ["@shikijs/engine-javascript@4.3.1", "", { "dependencies": { "@shikijs/types": "4.3.1", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.6" } }, "sha512-JBItcnPuYq7jVJdZo/vMj94r+szT7XEjHFX+mvFDGSEIbVAXAGyHAHzhbWzpGOwYidCZrErJLLgn2PVeiokHnQ=="], - - "@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@4.3.1", "", { "dependencies": { "@shikijs/types": "4.3.1", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-OXyNMzg0pews+msMj4cHeqT4xiYKKvbnn6VbdAXxfoFl3SSx4fJTc8FadECuc5/H9p3BzhNAoAUXKwAu9rWYhg=="], - - "@shikijs/langs": ["@shikijs/langs@4.3.1", "", { "dependencies": { "@shikijs/types": "4.3.1" } }, "sha512-m0l9nsDqgBHvbZbk7A0/kXz/impK3uB/c6rAn6Gpg/uPtdZRQ+alsN/17MU5thb68XTj/4DxkZAotrM0GGSpDQ=="], - - "@shikijs/primitive": ["@shikijs/primitive@4.3.1", "", { "dependencies": { "@shikijs/types": "4.3.1", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-CXQRQOYy1leqQ8ceTeJdmXv/bsUY++6QyLpXJ94LZAAYj5X2SKRdc5ipguv4NPyGVKItB2PPwUpRNe0Sjh5S1A=="], - - "@shikijs/themes": ["@shikijs/themes@4.3.1", "", { "dependencies": { "@shikijs/types": "4.3.1" } }, "sha512-dgpoJ4WqNi2yTmizQHBJ5zcX6j2lE6icN/0yt4l1kkf16jrY/pwPLoTb1ETsWMz0OBLf9ZNvwmxft+cH+N9qSA=="], - - "@shikijs/types": ["@shikijs/types@4.3.1", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-CHFxE0jztBIZRHH6gxXE7DXUCFXjReEGxZ/j0rfSLGKZuwp2xBYycEP14875DSa9KLL/6700oxIq6oO6ef9K2g=="], - - "@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="], - - "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - - "@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="], - - "@tailwindcss/node": ["@tailwindcss/node@4.3.2", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "5.21.6", "jiti": "^2.7.0", "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.3.2" } }, "sha512-yWP/sqEcBLaD8JuA6zNwxoYKr75qxTioYwlRwekj5Jr/I5GXnoJfjetH/psLUIv74cYTH2lBUEzBkinthoYcBg=="], - - "@tailwindcss/oxide": ["@tailwindcss/oxide@4.3.2", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.3.2", "@tailwindcss/oxide-darwin-arm64": "4.3.2", "@tailwindcss/oxide-darwin-x64": "4.3.2", "@tailwindcss/oxide-freebsd-x64": "4.3.2", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.2", "@tailwindcss/oxide-linux-arm64-gnu": "4.3.2", "@tailwindcss/oxide-linux-arm64-musl": "4.3.2", "@tailwindcss/oxide-linux-x64-gnu": "4.3.2", "@tailwindcss/oxide-linux-x64-musl": "4.3.2", "@tailwindcss/oxide-wasm32-wasi": "4.3.2", "@tailwindcss/oxide-win32-arm64-msvc": "4.3.2", "@tailwindcss/oxide-win32-x64-msvc": "4.3.2" } }, "sha512-z8ZgnzX8gdNoWLBLqBPoh/sjnxkwvf9ZuWjnO0l0yIzbLa5/9S+eC5QxGZKRobVHIC3/1BoMWjHblqWjcgFgag=="], - - "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.3.2", "", { "os": "android", "cpu": "arm64" }, "sha512-WHxqIuHpvZ5VtdX6GTl1Ik/Vp2YuN42Et+0CdeaVd/frQ9jAvGmvR8vLT+jk3e8/Q3x8kECB9+R17pgpp2BulA=="], - - "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.3.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-GZypeUY/IDJW3877KeM+O67vbXr3MBnbtEL4aYhNErv/JWZhye2vGSWWG9tB6iiqR2MqRNkY8IOUy4NdSZV26w=="], - - "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.3.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-UIIzmefR6KO1sDU7MzRqAxC8iBpft/VhkGjTjnhoS6k7Z3rQ9wEgA1ODSiyH/tcSYssulNm4Ci3hOeK1jH7ccQ=="], - - "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.3.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-GN+uAmcI6DNspnCDwtOAZrTz6oukJnp337qZvxqCGLd3BHBzJpO0ZbTLRvJNdztOeAmTzewewGIMPb0tk2R4WA=="], - - "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.3.2", "", { "os": "linux", "cpu": "arm" }, "sha512-4ABn7qSbdHRwTiDiuWNegCyb5+2FJ4vKIKc3DmKrvAFw7MU1Lm11dIkTPwUaFdTzc7IsOpDbqBrlh0x6y36U/w=="], - - "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.3.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-wDgEIGwoM8w8pufh9LVt1PahDgNdKXrLC2qfAnV3vAmococ9RWbxeAw4pxPttd/TsJfwjyLf90Dg1y9y8I6Emw=="], - - "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.3.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-J5Nuk0uZQIiMTJj3LEx4sAA9tMFUoXQZFv1J6An+QGYe53HKRJuFDi0rpq/tuouCZeAbOBY3kQ6g8qeD4TUjtA=="], - - "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.3.2", "", { "os": "linux", "cpu": "x64" }, "sha512-kqCZpSKOBEJO4mz7OqWoofBZeXTAwaVGPj0ErAj7CojmhKpWVWVOnrt9dE8odoIraZq4oj3ausM37kXi+Tow8w=="], - - "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.3.2", "", { "os": "linux", "cpu": "x64" }, "sha512-cixpqbh2toJDmkuCRI68nXA8ZxNmdK9Y+9v5h3MC3ZQKy/0BO8AWzlkWyRM7JAFSGBlfig4YVTPsK6MVgqz1uw=="], - - "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.3.2", "", { "dependencies": { "@emnapi/core": "^1.11.1", "@emnapi/runtime": "^1.11.1", "@emnapi/wasi-threads": "^1.2.2", "@napi-rs/wasm-runtime": "^1.1.4", "@tybys/wasm-util": "^0.10.2", "tslib": "^2.8.1" }, "cpu": "none" }, "sha512-4ec2Z/LOmRsAgU23CS4xeJfcJlmRg94A/XrbGRCF1gyU/zdDfRLYDVsS+ynSZCmGNxQ1jQriQOKMQeQxBA3Isw=="], - - "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.3.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-Zyr/M0+XcYZu3bZrUytc7TXvrk0ftWfl8gN2MwekNDzhqhKRUucMPSeOzM0o0wH5AWOU49BsKRrfKxI2atCPMQ=="], - - "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.3.2", "", { "os": "win32", "cpu": "x64" }, "sha512-QI9BO7KlNZsp2GuO0jwAAj5jCDABOKXRkCk2XuKTSaNEFSdfzqswYVTtCHBNKHLsqyjFyFkqlDiwkNbTYSssMQ=="], - - "@tailwindcss/postcss": ["@tailwindcss/postcss@4.3.2", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.3.2", "@tailwindcss/oxide": "4.3.2", "postcss": "^8.5.15", "tailwindcss": "4.3.2" } }, "sha512-rjVWYCa7Ngbi5AarT6k8TkxUG3Wl1QKzHdIZVsjZSzf36Jmo2IKZt/NHRAwly8oDkbBOH0YTu+CHuf9jPxMc+g=="], - - "@takumi-rs/core": ["@takumi-rs/core@1.8.7", "", { "dependencies": { "@takumi-rs/helpers": "1.8.7" }, "optionalDependencies": { "@takumi-rs/core-darwin-arm64": "1.8.7", "@takumi-rs/core-darwin-x64": "1.8.7", "@takumi-rs/core-linux-arm64-gnu": "1.8.7", "@takumi-rs/core-linux-arm64-musl": "1.8.7", "@takumi-rs/core-linux-x64-gnu": "1.8.7", "@takumi-rs/core-linux-x64-musl": "1.8.7", "@takumi-rs/core-win32-arm64-msvc": "1.8.7", "@takumi-rs/core-win32-x64-msvc": "1.8.7" } }, "sha512-Ia8I3vg0VAQPnzHiYRrd18UgZbIj3X0zMwWMjuTm3yb2TBH1988lPwnnlf+eAfYMwZrutNiXLLtgEnkzsm2gMw=="], - - "@takumi-rs/core-darwin-arm64": ["@takumi-rs/core-darwin-arm64@1.8.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-an8vc2B/Qf9vo3uwDmJ6WKazpMBpDruRy/kXr+x98GfIkzMHDEUy+9EgNfUYxprtZo49cJruXrVwzxsqqW+1tA=="], - - "@takumi-rs/core-darwin-x64": ["@takumi-rs/core-darwin-x64@1.8.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-q0xQxmb4y4EwYK3ILMBvWvqLGX8gxsqcEas0zOwNbPnxBLTQFF8KVH4jXaKXLUFwj020lu8nsf1BNvLIkJMo3Q=="], - - "@takumi-rs/core-linux-arm64-gnu": ["@takumi-rs/core-linux-arm64-gnu@1.8.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-uZ6l792M4Mc06XG+m+8RarTgdR5o1ZLjncULKUEPAw3nBKhRbJ50Re3aLM4n4+p25iOj1oL9QwEZRcaJn8u/Ag=="], - - "@takumi-rs/core-linux-arm64-musl": ["@takumi-rs/core-linux-arm64-musl@1.8.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-akVy80ztI2as/b0n0EVCfHNKhibp+Od4ioP49PtX2rQMi6KDtqv3aoCIjaBls8oxzv+4x77/2U9fsWIO2XZQjg=="], - - "@takumi-rs/core-linux-x64-gnu": ["@takumi-rs/core-linux-x64-gnu@1.8.7", "", { "os": "linux", "cpu": "x64" }, "sha512-SV1YesGs/HfC1CMpSF5SqS6KbL4hDLvD2m54JcfB+X/0xatmo/CS2XleqoIXhSmR+95X8Of5g2vg1a4TAdpcug=="], - - "@takumi-rs/core-linux-x64-musl": ["@takumi-rs/core-linux-x64-musl@1.8.7", "", { "os": "linux", "cpu": "x64" }, "sha512-zprYQ/ivPDmYX4tFaONiAzoDJNTANA3kqfIe7SMHZ2YhkfEhYnr3PE3XtBytgB4W/VlTc9WQLyD77SKwPnPuFw=="], - - "@takumi-rs/core-win32-arm64-msvc": ["@takumi-rs/core-win32-arm64-msvc@1.8.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-2S5YcgIj/c0E3sLzWDcxzlXoPvEjR2xC1v7yODe0CvimlRx95Df6rJ9idTS6E1KNUjDaTfqxTr8Ud4gWqYrrPg=="], - - "@takumi-rs/core-win32-x64-msvc": ["@takumi-rs/core-win32-x64-msvc@1.8.7", "", { "os": "win32", "cpu": "x64" }, "sha512-sooiM6fL0JN597ciNAFVp9F7YxCW+8hXpwu/7wRMRo0TGQ/KMi1Y94tf1FUu2csCHN0pgy9a3y09y8+qnw3FTw=="], - - "@takumi-rs/helpers": ["@takumi-rs/helpers@1.8.7", "", { "peerDependencies": { "react": "^19.2.5", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["react", "react-dom"] }, "sha512-5dSR9W8msQ7Asp4TCvUUB9Bt8yLgIc2ASjWtEG4Jn9xSuAVJLWFZ21Xl8HShW5GE6SV5aCCM9BL0NA9YuBWIJw=="], - - "@takumi-rs/image-response": ["@takumi-rs/image-response@1.8.7", "", { "dependencies": { "takumi-js": "1.8.7" } }, "sha512-OL7kvQ9o8CBf9v47j6NZOyMAXsqu6WCHS2F8nOUffwGxGn1pFaFGKoTn8P3u1NUWQ97mJJVk7dnXZpBCnC492Q=="], - - "@takumi-rs/wasm": ["@takumi-rs/wasm@1.8.7", "", { "dependencies": { "@takumi-rs/helpers": "1.8.7" } }, "sha512-LVBBMcYdvA0a+w1DRCwjYhFPTFVWd+oYW7kY8jMeBYEX+l0HF8PHbjWCOMDbW8iA80489UGx4fG2frLE+MKcMg=="], - - "@types/css-font-loading-module": ["@types/css-font-loading-module@0.0.7", "", {}, "sha512-nl09VhutdjINdWyXxHWN/w9zlNCfr60JUqJbd24YXUuCwgeL0TpFSdElCwb6cxfB6ybE19Gjj4g0jsgkXxKv1Q=="], - - "@types/debug": ["@types/debug@4.1.13", "", { "dependencies": { "@types/ms": "*" } }, "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw=="], - - "@types/estree": ["@types/estree@1.0.9", "", {}, "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg=="], - - "@types/estree-jsx": ["@types/estree-jsx@1.0.5", "", { "dependencies": { "@types/estree": "*" } }, "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg=="], - - "@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="], - - "@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="], - - "@types/mdx": ["@types/mdx@2.0.14", "", {}, "sha512-T48PeuJtvLosNTPVhfnIp3i/n3a4g4Bad7YCq5k64D4u7NwDrAotikQ+5+sjtUvBmxCMlbo3dVL+C2dP0rWHzg=="], - - "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], - - "@types/node": ["@types/node@26.1.0", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-O0A1G3xPGy4w7AgQdAQYUlQ+BKk2Oovw8eRpofyp5KdBZULnbe+WqaOVNrm705SHphCiG4XHsACrSmPu1f+Kgw=="], - - "@types/react": ["@types/react@19.2.17", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw=="], - - "@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="], - - "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], - - "@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20260704.1", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260704.1", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260704.1", "@typescript/native-preview-linux-arm": "7.0.0-dev.20260704.1", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260704.1", "@typescript/native-preview-linux-x64": "7.0.0-dev.20260704.1", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260704.1", "@typescript/native-preview-win32-x64": "7.0.0-dev.20260704.1" }, "bin": { "tsgo": "bin/tsgo" } }, "sha512-B8CxdI0CumQVV9/9COcanWCWJmu8Jm1kMuYvse3iGm5ay9QrKTD+qyb11x8SPKUMtiUqnhNxt0n4ESNt+LQMuQ=="], - - "@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20260704.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-WHNMx8HTka+2w9ZifYbfkHHyQBzO+MCbOLQzNJE3K7A7mYJ1aq6ZEvBhRcNqixjKAIIO4U34KQvaQ6PXlwezkQ=="], - - "@typescript/native-preview-darwin-x64": ["@typescript/native-preview-darwin-x64@7.0.0-dev.20260704.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-IZJib4da/+3gRVSQFoQU1uFzsiSXnI02xBZljipDoPwahRcOdjH9gJ7DMBFbZ53pUtN5lvqbpES4oXiJZTneDA=="], - - "@typescript/native-preview-linux-arm": ["@typescript/native-preview-linux-arm@7.0.0-dev.20260704.1", "", { "os": "linux", "cpu": "arm" }, "sha512-Dkz8oqvg4nEIu2Acz/d+iBDhIIOqjaAJ6mo6a2diRrDI+K5NAHljTzvkclCxgz6WIa5JnUY3kWzy8jE5AtaCQg=="], - - "@typescript/native-preview-linux-arm64": ["@typescript/native-preview-linux-arm64@7.0.0-dev.20260704.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-rjyHYAmDQ68NZIpU5i46D50hgQ63UJGGN/LJv3DAPWC8KraNonS5j4fN2bH/V+acQV9l/sS3+US1daV8VkQaFQ=="], - - "@typescript/native-preview-linux-x64": ["@typescript/native-preview-linux-x64@7.0.0-dev.20260704.1", "", { "os": "linux", "cpu": "x64" }, "sha512-y2L2eNwCgrTgXKMol9n/bSPeyNHwJbrUDAv6/J7/087yhPNCt61l3KbpiGAYs0KYcCt3V2lNSDtS3geHQfSWJQ=="], - - "@typescript/native-preview-win32-arm64": ["@typescript/native-preview-win32-arm64@7.0.0-dev.20260704.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-PzBVRs8UNSAqtoCp9BtT1jsG4SSOfuDT1yo8Z3gGevmNtKEFZjb92BTSnBZaMPPQkM22fq83zgrAEVOEENIicw=="], - - "@typescript/native-preview-win32-x64": ["@typescript/native-preview-win32-x64@7.0.0-dev.20260704.1", "", { "os": "win32", "cpu": "x64" }, "sha512-wb/C+fqWpXAoJZd8KQZdpjOq67v/cmLsApjL9oHjC1X6zqz7AzyOQ486uxWT6LvYzKkar4A+iq8h5h+PNgN38w=="], - - "@typescript/typescript-aix-ppc64": ["@typescript/typescript-aix-ppc64@7.0.1-rc", "", { "os": "aix", "cpu": "ppc64" }, "sha512-oqq2ZfEJ7BQuufcC3QBQndZLPNyamYNHLao8lKRBeeSkZKypBqxPSgkzrcFZtbYcIaBvpiyUnQP9MT7DEYHWbw=="], - - "@typescript/typescript-darwin-arm64": ["@typescript/typescript-darwin-arm64@7.0.1-rc", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Slc0yTftT2F/uGDmtPst8ijydneL6uZaLEyr2UjahxZpbhTjHFBJ5agXtVz/TL4A+ldxzjzj+E8QtLZlh/5mXw=="], - - "@typescript/typescript-darwin-x64": ["@typescript/typescript-darwin-x64@7.0.1-rc", "", { "os": "darwin", "cpu": "x64" }, "sha512-h68iFW/LbA1/BsGgSRGFw981/3s1f/rY27YrmeZNuN+ly7dI+fiDduwT9ZT9866x2onoKNRq7PTyxSKyKDzfAQ=="], - - "@typescript/typescript-freebsd-arm64": ["@typescript/typescript-freebsd-arm64@7.0.1-rc", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-DE+ppd8Ix2c6OMuRkKY4PJ4hngMGJ9M95OQUP17p9xL/1IKXof7npIeuusMN/bgL5o5JzMfSGh+N+5scTYRg0Q=="], - - "@typescript/typescript-freebsd-x64": ["@typescript/typescript-freebsd-x64@7.0.1-rc", "", { "os": "freebsd", "cpu": "x64" }, "sha512-ST1ozHMw0u+CLOnWkcTyWDMV4Qn9osZ6fd1V1lnKDM1t0hZIp81mdGpdHxyHJjd7jdGrb6Gb/QXcZ1uqZ0t5zw=="], - - "@typescript/typescript-linux-arm": ["@typescript/typescript-linux-arm@7.0.1-rc", "", { "os": "linux", "cpu": "arm" }, "sha512-gHmHwT5Naq5CKM8g9bbaGeEpnwQEvWCLn3fwP4K2m61VQdDKkPk0Dhab/OoZ4LV2SrMddmclYXTzpyg23YGt5g=="], - - "@typescript/typescript-linux-arm64": ["@typescript/typescript-linux-arm64@7.0.1-rc", "", { "os": "linux", "cpu": "arm64" }, "sha512-N46pRihK3t5zD5MUtTQcdmQUqr1WI4U2nxno1gLwOtRSsB4krFkRjPHcQNG7h2DtRkX64rQiReX6WKwg2wprMA=="], - - "@typescript/typescript-linux-loong64": ["@typescript/typescript-linux-loong64@7.0.1-rc", "", { "os": "linux", "cpu": "none" }, "sha512-G17Sao312rgiPBTh2F4nOpLpa3CcnBSaNhqNghZk2LNhnsp1RaMO5HMq2me21gqu9xLpc6CIgHtOzU6JBgNlfg=="], - - "@typescript/typescript-linux-mips64el": ["@typescript/typescript-linux-mips64el@7.0.1-rc", "", { "os": "linux", "cpu": "none" }, "sha512-0FQspOb5UsQ4tQKvWgUO3pS9OIWkP7/8dPRWq+CRazJUeQZ4LBjtYK52jg5iIOrvItrVl2CwvRtrU3/9OihwJg=="], - - "@typescript/typescript-linux-ppc64": ["@typescript/typescript-linux-ppc64@7.0.1-rc", "", { "os": "linux", "cpu": "ppc64" }, "sha512-SUmwfVBEv6A2Ld0eWfcvW0FqrgemfQL8jFGOmV1qYxsDqumjE5DekHXqbstgmbE4SHr4rrjHjvmuGCY+kTH/vw=="], - - "@typescript/typescript-linux-riscv64": ["@typescript/typescript-linux-riscv64@7.0.1-rc", "", { "os": "linux", "cpu": "none" }, "sha512-rxeqnNnGiYzv/LlPHi/3+4p0ooR1cNJLjRIHXKovtiVmxXGJq6gtw8VSpbHuWPekyFMXgIAoLCZN0SQ51rAALQ=="], - - "@typescript/typescript-linux-s390x": ["@typescript/typescript-linux-s390x@7.0.1-rc", "", { "os": "linux", "cpu": "s390x" }, "sha512-RYWCHCiPypxajdRHM2CNK/eM22e4Ex5TTjV2pXf7PTtBowGr0xX8i8kIMknyZS0LX2QfleYHouaoMVsFDSle3g=="], - - "@typescript/typescript-linux-x64": ["@typescript/typescript-linux-x64@7.0.1-rc", "", { "os": "linux", "cpu": "x64" }, "sha512-PfLJSu0JzroDkqw2m4nqflPEcn8yev0m/vHFQlY9EzHorzjR6QG0wL8AJHvnD1e6h1s76AZngJ5u+z1K/D/HKw=="], - - "@typescript/typescript-netbsd-arm64": ["@typescript/typescript-netbsd-arm64@7.0.1-rc", "", { "os": "none", "cpu": "arm64" }, "sha512-FfbPxH3dTfp8yVIaNM7bdWTixXuyxpzoemluqcqMROSIz+ImpCG3Q9HO9Ptzp9/giv+P9YYEnCMSXh61migj2w=="], - - "@typescript/typescript-netbsd-x64": ["@typescript/typescript-netbsd-x64@7.0.1-rc", "", { "os": "none", "cpu": "x64" }, "sha512-FzdTfSzhRYb6hlav6K3cI5RVgcvCTvNAu/vc+t7B6AmZkThQ+t/1ntnvT5fnHmY1Az2RIBw7/b+qtCEG61HJTQ=="], - - "@typescript/typescript-openbsd-arm64": ["@typescript/typescript-openbsd-arm64@7.0.1-rc", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-PQGhlxfNig+0YQ9Wwzd0USPBkt6w/ZqkBQWsU7G/0JkTzunJel+jSWwhKw4947pak/m7hGSeYiI04xReDLGZww=="], - - "@typescript/typescript-openbsd-x64": ["@typescript/typescript-openbsd-x64@7.0.1-rc", "", { "os": "openbsd", "cpu": "x64" }, "sha512-WJ7NYgO2mHmLUkI/tZ+hl8lFd26QPJqO8ONOHNuYbdsybLvSB6B6sep222JIVrOfPRDGvFinbGGB+l3m1FWRWA=="], - - "@typescript/typescript-sunos-x64": ["@typescript/typescript-sunos-x64@7.0.1-rc", "", { "os": "sunos", "cpu": "x64" }, "sha512-UYjDeUxd765V9qcwlUPk4pEXyL0i3G76CJm9baK4i99u1pGO1psf3nXDw4MMmElVOPvGbZag99ZR/O59E2OX6w=="], - - "@typescript/typescript-win32-arm64": ["@typescript/typescript-win32-arm64@7.0.1-rc", "", { "os": "win32", "cpu": "arm64" }, "sha512-KzXzFSXZOm7zvEt2Aw0MsB2LbTL88znAiVqTDNAOHdlEb7brgmUQh/X2wM/8Be+N0fjEqWKl65cBKNwpWEbJiw=="], - - "@typescript/typescript-win32-x64": ["@typescript/typescript-win32-x64@7.0.1-rc", "", { "os": "win32", "cpu": "x64" }, "sha512-98R3+OqDr/r0/PLWEoXu88AE0lGVLNd335Ew8ONgzK1JWkNs4ou/5BGt3Or1ij4iXjH+c7PRL+jFjCbtWze+EA=="], - - "@ungap/structured-clone": ["@ungap/structured-clone@1.3.2", "", {}, "sha512-5jsZFwgR5rTdKwidH9Qmat75RKwqfpKlWWB1frDkljN127mwqBu8K0PYo7/hFpF03IEJpfVPpCQDY/eDx3iHvA=="], - - "@xstate/fsm": ["@xstate/fsm@1.6.5", "", {}, "sha512-b5o1I6aLNeYlU/3CPlj/Z91ybk1gUsKT+5NAJI+2W4UjvS5KLG28K9v5UvNoFVjHV8PajVZ00RH3vnjyQO7ZAw=="], - - "acorn": ["acorn@8.17.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg=="], - - "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], - - "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], - - "aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="], - - "astring": ["astring@1.9.0", "", { "bin": { "astring": "bin/astring" } }, "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg=="], - - "bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="], - - "base64-arraybuffer": ["base64-arraybuffer@1.0.2", "", {}, "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ=="], - - "baseline-browser-mapping": ["baseline-browser-mapping@2.10.41", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-WwS7MHhqGHHlaVsqRZnhvCEMS0owDX+SxRlve7JkuH7My1Ara3ZriTmCQupPfYjxMZ8I/tgxtJYr2t7taHaH4A=="], - - "caniuse-lite": ["caniuse-lite@1.0.30001800", "", {}, "sha512-MMHtuAz9Ys840zAY5F4k6fV5GaivZ9sPk+nz0mY+GYVzRBnYkN0mpqkSR92oWRQ19yQWo4HvBV/FnC16AJX8MA=="], - - "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], - - "character-entities": ["character-entities@2.0.2", "", {}, "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="], - - "character-entities-html4": ["character-entities-html4@2.1.0", "", {}, "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="], - - "character-entities-legacy": ["character-entities-legacy@3.0.0", "", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="], - - "character-reference-invalid": ["character-reference-invalid@2.0.1", "", {}, "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw=="], - - "chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], - - "class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="], - - "client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="], - - "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], - - "cnfast": ["cnfast@0.0.8", "", { "bin": { "cnfast": "bin/cli.js" } }, "sha512-EjXKMfGfdwtV4AcNSQ6AwQaVzpC1B7IxeiwA3FlhTXz+YFlMKVi4c1JX9tgD2QOlahQXjB8KUXrBaYG+3v871Q=="], - - "collapse-white-space": ["collapse-white-space@2.1.0", "", {}, "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw=="], - - "comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="], - - "compute-scroll-into-view": ["compute-scroll-into-view@3.1.1", "", {}, "sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw=="], - - "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], - - "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" }, "peerDependencies": { "supports-color": "*" }, "optionalPeers": ["supports-color"] }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], - - "decode-named-character-reference": ["decode-named-character-reference@1.3.0", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q=="], - - "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], - - "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], - - "detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="], - - "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], - - "enhanced-resolve": ["enhanced-resolve@5.21.6", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.3" } }, "sha512-aNnGCvbJ/RIyWo1IuhNdVjnNF+EjH9wpzpNHt+ci/m9He9LJvUN8wrCcXjp9cWsGNAuvSpVFTx/vraAFQ8qGjQ=="], - - "entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], - - "esast-util-from-estree": ["esast-util-from-estree@2.0.0", "", { "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" } }, "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ=="], - - "esast-util-from-js": ["esast-util-from-js@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "acorn": "^8.0.0", "esast-util-from-estree": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw=="], - - "esbuild": ["esbuild@0.28.1", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.28.1", "@esbuild/android-arm": "0.28.1", "@esbuild/android-arm64": "0.28.1", "@esbuild/android-x64": "0.28.1", "@esbuild/darwin-arm64": "0.28.1", "@esbuild/darwin-x64": "0.28.1", "@esbuild/freebsd-arm64": "0.28.1", "@esbuild/freebsd-x64": "0.28.1", "@esbuild/linux-arm": "0.28.1", "@esbuild/linux-arm64": "0.28.1", "@esbuild/linux-ia32": "0.28.1", "@esbuild/linux-loong64": "0.28.1", "@esbuild/linux-mips64el": "0.28.1", "@esbuild/linux-ppc64": "0.28.1", "@esbuild/linux-riscv64": "0.28.1", "@esbuild/linux-s390x": "0.28.1", "@esbuild/linux-x64": "0.28.1", "@esbuild/netbsd-arm64": "0.28.1", "@esbuild/netbsd-x64": "0.28.1", "@esbuild/openbsd-arm64": "0.28.1", "@esbuild/openbsd-x64": "0.28.1", "@esbuild/openharmony-arm64": "0.28.1", "@esbuild/sunos-x64": "0.28.1", "@esbuild/win32-arm64": "0.28.1", "@esbuild/win32-ia32": "0.28.1", "@esbuild/win32-x64": "0.28.1" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw=="], - - "escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], - - "esrap": ["esrap@2.2.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" }, "peerDependencies": { "@typescript-eslint/types": "^8.2.0" }, "optionalPeers": ["@typescript-eslint/types"] }, "sha512-m8jH5hZgJE2RRUK/jjkGPcJEDAV+dYnZYFkosQaPTcE+Yw4xynXHOo6FUdwaWBtdR3b1MMa7wEDTSHeR2VWsGA=="], - - "estree-util-attach-comments": ["estree-util-attach-comments@3.0.0", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw=="], - - "estree-util-build-jsx": ["estree-util-build-jsx@3.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "estree-walker": "^3.0.0" } }, "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ=="], - - "estree-util-is-identifier-name": ["estree-util-is-identifier-name@3.0.0", "", {}, "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg=="], - - "estree-util-scope": ["estree-util-scope@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0" } }, "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ=="], - - "estree-util-to-js": ["estree-util-to-js@2.0.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "astring": "^1.8.0", "source-map": "^0.7.0" } }, "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg=="], - - "estree-util-value-to-estree": ["estree-util-value-to-estree@3.5.0", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-aMV56R27Gv3QmfmF1MY12GWkGzzeAezAX+UplqHVASfjc9wNzI/X6hC0S9oxq61WT4aQesLGslWP9tKk6ghRZQ=="], - - "estree-util-visit": ["estree-util-visit@2.0.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/unist": "^3.0.0" } }, "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww=="], - - "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], - - "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], - - "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], - - "framer-motion": ["framer-motion@12.42.2", "", { "dependencies": { "motion-dom": "^12.42.2", "motion-utils": "^12.39.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-5XY9luDiu0oHfHBjpDthFMh0ES+122w6p/papSJBweMkO8Sn+PW2QaEgRblQBpWFnuvZS5qvarpt/hO2pjGmnw=="], - - "fumadocs-core": ["fumadocs-core@16.10.7", "", { "dependencies": { "@orama/orama": "^3.1.18", "estree-util-value-to-estree": "^3.5.0", "github-slugger": "^2.0.0", "hast-util-to-estree": "^3.1.3", "hast-util-to-jsx-runtime": "^2.3.6", "js-yaml": "^5.1.0", "mdast-util-mdx": "^3.0.0", "mdast-util-to-markdown": "^2.1.2", "remark": "^15.0.1", "remark-gfm": "^4.0.1", "remark-rehype": "^11.1.2", "scroll-into-view-if-needed": "^3.1.0", "shiki": "^4.2.0", "tinyglobby": "^0.2.17", "unified": "^11.0.5", "unist-util-visit": "^5.1.0", "vfile": "^6.0.3" }, "peerDependencies": { "@mdx-js/mdx": "*", "@mixedbread/sdk": "0.x.x", "@orama/core": "1.x.x", "@oramacloud/client": "2.x.x", "@tanstack/react-router": "1.x.x", "@types/estree-jsx": "*", "@types/hast": "*", "@types/mdast": "*", "@types/react": "*", "algoliasearch": "5.x.x", "flexsearch": "*", "lucide-react": "*", "next": "16.x.x", "react": "^19.2.0", "react-dom": "^19.2.0", "react-router": "7.x.x || 8.x.x", "waku": "*", "zod": "4.x.x" }, "optionalPeers": ["@mdx-js/mdx", "@mixedbread/sdk", "@orama/core", "@oramacloud/client", "@tanstack/react-router", "@types/estree-jsx", "@types/hast", "@types/mdast", "@types/react", "algoliasearch", "flexsearch", "lucide-react", "next", "react", "react-dom", "react-router", "waku", "zod"] }, "sha512-lR1hDOtJ8ubsLKYH2VMkp+iVZTDdOiMh4StFaWtuTvy8Wfnngz0YSHeFijmm2K+4lg2DLXLMuCEHQ6my54g2Eg=="], - - "fumadocs-mdx": ["fumadocs-mdx@15.0.13", "", { "dependencies": { "@mdx-js/mdx": "^3.1.1", "@standard-schema/spec": "^1.1.0", "chokidar": "^5.0.0", "esbuild": "^0.28.1", "estree-util-value-to-estree": "^3.5.0", "js-yaml": "^5.1.0", "mdast-util-mdx": "^3.0.0", "picocolors": "^1.1.1", "picomatch": "^4.0.4", "tinyexec": "^1.2.4", "tinyglobby": "^0.2.17", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.1.0", "vfile": "^6.0.3", "zod": "^4.4.3" }, "peerDependencies": { "@types/mdast": "*", "@types/mdx": "*", "@types/react": "*", "fumadocs-core": "^16.7.0", "mdast-util-directive": "*", "next": "^15.3.0 || ^16.0.0", "react": "^19.2.0", "rolldown": "*", "vite": "7.x.x || 8.x.x" }, "optionalPeers": ["@types/mdast", "@types/mdx", "@types/react", "mdast-util-directive", "next", "react", "rolldown", "vite"], "bin": { "fumadocs-mdx": "./bin.js" } }, "sha512-VsGhCiLriXXMzm3WbgrVP7t6LvOthwh1BC+IGSI1ZW63UcSo1jE4aAiuUrTIF0jv1EGQkJG8cPsy0cOnf4sejA=="], - - "fumadocs-openapi": ["fumadocs-openapi@11.0.6", "", { "dependencies": { "@fuma-translate/react": "^1.0.2", "@fumadocs/api-docs": "0.0.4", "@fumari/json-schema-ts": "^0.0.2", "@fumari/stf": "1.0.5", "chokidar": "^5.0.0", "class-variance-authority": "^0.7.1", "cnfast": "^0.0.8", "github-slugger": "^2.0.0", "hast-util-to-jsx-runtime": "^2.3.6", "js-yaml": "^5.1.0", "lucide-react": "^1.21.0", "remark": "^15.0.1", "remark-rehype": "^11.1.2", "shiki": "^4.2.0" }, "peerDependencies": { "@scalar/api-client-react": "^2.0.20", "@types/react": "*", "fumadocs-core": "^16.10.0", "fumadocs-ui": "^16.10.0", "json-schema-typed": "*", "react": "^19.2.0", "react-dom": "^19.2.0" }, "optionalPeers": ["@scalar/api-client-react", "@types/react", "json-schema-typed"] }, "sha512-aqLvr5WwFerT5V8B3iQUV7Qsk17dmf88Oc9jbsbKbkp3hMvOZW7mrfSf7WXBpqqppp1y1DDJOlOuPz6tppE0Cg=="], - - "fumadocs-ui": ["fumadocs-ui@16.10.7", "", { "dependencies": { "@fuma-translate/react": "^1.0.2", "@fumadocs/tailwind": "0.0.5", "@radix-ui/react-accordion": "^1.2.14", "@radix-ui/react-collapsible": "^1.1.14", "@radix-ui/react-dialog": "^1.1.17", "@radix-ui/react-direction": "^1.1.2", "@radix-ui/react-navigation-menu": "^1.2.16", "@radix-ui/react-popover": "^1.1.17", "@radix-ui/react-presence": "^1.1.6", "@radix-ui/react-scroll-area": "^1.2.12", "@radix-ui/react-slot": "^1.3.0", "@radix-ui/react-tabs": "^1.1.15", "class-variance-authority": "^0.7.1", "cnfast": "^0.0.8", "lucide-react": "^1.21.0", "motion": "^12.41.0", "next-themes": "^0.4.6", "react-remove-scroll": "^2.7.2", "rehype-raw": "^7.0.0", "scroll-into-view-if-needed": "^3.1.0", "shiki": "^4.2.0", "unist-util-visit": "^5.1.0" }, "peerDependencies": { "@takumi-rs/image-response": "*", "@types/mdx": "*", "@types/react": "*", "fumadocs-core": "16.10.7", "next": "16.x.x", "react": "^19.2.0", "react-dom": "^19.2.0" }, "optionalPeers": ["@takumi-rs/image-response", "@types/mdx", "@types/react", "next"] }, "sha512-zE93/DKW5bhedXRKHYg3rhE/juYi+kXx1xl3ey1dArWbCiPx6lq6/4RLswYXS0lQp1W1f8NsbY1TeA8wSQuEvw=="], - - "get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="], - - "github-slugger": ["github-slugger@2.0.0", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="], - - "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], - - "hast-util-from-parse5": ["hast-util-from-parse5@8.0.3", "", { "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" } }, "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg=="], - - "hast-util-parse-selector": ["hast-util-parse-selector@4.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A=="], - - "hast-util-raw": ["hast-util-raw@9.1.0", "", { "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" } }, "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw=="], - - "hast-util-to-estree": ["hast-util-to-estree@3.1.3", "", { "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" } }, "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w=="], - - "hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "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" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="], - - "hast-util-to-jsx-runtime": ["hast-util-to-jsx-runtime@2.3.6", "", { "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" } }, "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg=="], - - "hast-util-to-parse5": ["hast-util-to-parse5@8.0.1", "", { "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" } }, "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA=="], - - "hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="], - - "hastscript": ["hastscript@9.0.1", "", { "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" } }, "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w=="], - - "html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="], - - "inline-style-parser": ["inline-style-parser@0.2.7", "", {}, "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA=="], - - "is-alphabetical": ["is-alphabetical@2.0.1", "", {}, "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ=="], - - "is-alphanumerical": ["is-alphanumerical@2.0.1", "", { "dependencies": { "is-alphabetical": "^2.0.0", "is-decimal": "^2.0.0" } }, "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw=="], - - "is-decimal": ["is-decimal@2.0.1", "", {}, "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A=="], - - "is-hexadecimal": ["is-hexadecimal@2.0.1", "", {}, "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg=="], - - "is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="], - - "jiti": ["jiti@2.7.0", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ=="], - - "js-yaml": ["js-yaml@5.2.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.mjs" } }, "sha512-zfLtNfQqxVqq3uaTqSkh4x4hZw3KHobGUA0fJUj4wawW8bsQLTVqpHdXSIzidh7o+4lEW36tANuAGdaFx6Zgnw=="], - - "lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="], - - "lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="], - - "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="], - - "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.32.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w=="], - - "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.32.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig=="], - - "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.32.0", "", { "os": "linux", "cpu": "arm" }, "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw=="], - - "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ=="], - - "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg=="], - - "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA=="], - - "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg=="], - - "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.32.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="], - - "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="], - - "longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="], - - "lucide-react": ["lucide-react@1.23.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-38BpJcD0JhFosxHApP/BYsBetLpQFRoTRzEzstM/XCc3jsAG7wqaY1lgVwxiUe3xqYE+lNxo2PkCmYwXWrwwIw=="], - - "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], - - "markdown-extensions": ["markdown-extensions@2.0.0", "", {}, "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q=="], - - "markdown-table": ["markdown-table@3.0.4", "", {}, "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw=="], - - "mdast-util-find-and-replace": ["mdast-util-find-and-replace@3.0.2", "", { "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" } }, "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg=="], - - "mdast-util-from-markdown": ["mdast-util-from-markdown@2.0.3", "", { "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" } }, "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q=="], - - "mdast-util-gfm": ["mdast-util-gfm@3.1.0", "", { "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" } }, "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ=="], - - "mdast-util-gfm-autolink-literal": ["mdast-util-gfm-autolink-literal@2.0.1", "", { "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" } }, "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ=="], - - "mdast-util-gfm-footnote": ["mdast-util-gfm-footnote@2.1.0", "", { "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" } }, "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ=="], - - "mdast-util-gfm-strikethrough": ["mdast-util-gfm-strikethrough@2.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg=="], - - "mdast-util-gfm-table": ["mdast-util-gfm-table@2.0.0", "", { "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" } }, "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg=="], - - "mdast-util-gfm-task-list-item": ["mdast-util-gfm-task-list-item@2.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ=="], - - "mdast-util-mdx": ["mdast-util-mdx@3.0.0", "", { "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" } }, "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w=="], - - "mdast-util-mdx-expression": ["mdast-util-mdx-expression@2.0.1", "", { "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" } }, "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ=="], - - "mdast-util-mdx-jsx": ["mdast-util-mdx-jsx@3.2.0", "", { "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" } }, "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q=="], - - "mdast-util-mdxjs-esm": ["mdast-util-mdxjs-esm@2.0.1", "", { "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" } }, "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg=="], - - "mdast-util-phrasing": ["mdast-util-phrasing@4.1.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "unist-util-is": "^6.0.0" } }, "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w=="], - - "mdast-util-to-hast": ["mdast-util-to-hast@13.2.1", "", { "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" } }, "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA=="], - - "mdast-util-to-markdown": ["mdast-util-to-markdown@2.1.2", "", { "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" } }, "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA=="], - - "mdast-util-to-string": ["mdast-util-to-string@4.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0" } }, "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg=="], - - "micromark": ["micromark@4.0.2", "", { "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" } }, "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA=="], - - "micromark-core-commonmark": ["micromark-core-commonmark@2.0.3", "", { "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" } }, "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg=="], - - "micromark-extension-gfm": ["micromark-extension-gfm@3.0.0", "", { "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" } }, "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w=="], - - "micromark-extension-gfm-autolink-literal": ["micromark-extension-gfm-autolink-literal@2.1.0", "", { "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" } }, "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw=="], - - "micromark-extension-gfm-footnote": ["micromark-extension-gfm-footnote@2.1.0", "", { "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" } }, "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw=="], - - "micromark-extension-gfm-strikethrough": ["micromark-extension-gfm-strikethrough@2.1.0", "", { "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" } }, "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw=="], - - "micromark-extension-gfm-table": ["micromark-extension-gfm-table@2.1.1", "", { "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" } }, "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg=="], - - "micromark-extension-gfm-tagfilter": ["micromark-extension-gfm-tagfilter@2.0.0", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg=="], - - "micromark-extension-gfm-task-list-item": ["micromark-extension-gfm-task-list-item@2.1.0", "", { "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" } }, "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw=="], - - "micromark-extension-mdx-expression": ["micromark-extension-mdx-expression@3.0.1", "", { "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" } }, "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q=="], - - "micromark-extension-mdx-jsx": ["micromark-extension-mdx-jsx@3.0.2", "", { "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" } }, "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ=="], - - "micromark-extension-mdx-md": ["micromark-extension-mdx-md@2.0.0", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ=="], - - "micromark-extension-mdxjs": ["micromark-extension-mdxjs@3.0.0", "", { "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" } }, "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ=="], - - "micromark-extension-mdxjs-esm": ["micromark-extension-mdxjs-esm@3.0.0", "", { "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" } }, "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A=="], - - "micromark-factory-destination": ["micromark-factory-destination@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA=="], - - "micromark-factory-label": ["micromark-factory-label@2.0.1", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg=="], - - "micromark-factory-mdx-expression": ["micromark-factory-mdx-expression@2.0.3", "", { "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" } }, "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ=="], - - "micromark-factory-space": ["micromark-factory-space@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg=="], - - "micromark-factory-title": ["micromark-factory-title@2.0.1", "", { "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" } }, "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw=="], - - "micromark-factory-whitespace": ["micromark-factory-whitespace@2.0.1", "", { "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" } }, "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ=="], - - "micromark-util-character": ["micromark-util-character@2.1.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q=="], - - "micromark-util-chunked": ["micromark-util-chunked@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA=="], - - "micromark-util-classify-character": ["micromark-util-classify-character@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q=="], - - "micromark-util-combine-extensions": ["micromark-util-combine-extensions@2.0.1", "", { "dependencies": { "micromark-util-chunked": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg=="], - - "micromark-util-decode-numeric-character-reference": ["micromark-util-decode-numeric-character-reference@2.0.2", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw=="], - - "micromark-util-decode-string": ["micromark-util-decode-string@2.0.1", "", { "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" } }, "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ=="], - - "micromark-util-encode": ["micromark-util-encode@2.0.1", "", {}, "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="], - - "micromark-util-events-to-acorn": ["micromark-util-events-to-acorn@2.0.3", "", { "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" } }, "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg=="], - - "micromark-util-html-tag-name": ["micromark-util-html-tag-name@2.0.1", "", {}, "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA=="], - - "micromark-util-normalize-identifier": ["micromark-util-normalize-identifier@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q=="], - - "micromark-util-resolve-all": ["micromark-util-resolve-all@2.0.1", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg=="], - - "micromark-util-sanitize-uri": ["micromark-util-sanitize-uri@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ=="], - - "micromark-util-subtokenize": ["micromark-util-subtokenize@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA=="], - - "micromark-util-symbol": ["micromark-util-symbol@2.0.1", "", {}, "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="], - - "micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="], - - "mitt": ["mitt@3.0.1", "", {}, "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="], - - "motion": ["motion@12.42.2", "", { "dependencies": { "framer-motion": "^12.42.2", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-Atvv11yUKIid41cVrRBDVX5m8tF8kNpExRSlbpt6APClhDjtwQssgFHhQzejxw7/7YYbjHSPKBVbHo05BuJT5Q=="], - - "motion-dom": ["motion-dom@12.42.2", "", { "dependencies": { "motion-utils": "^12.39.0" } }, "sha512-5gIMWLp/PycBtJRJWRgjxke5n8dlvkSn2DrYW+tr3XcqAZY1xZh6BJyooJXCM8wdfM7wfMjkBJNLge1CKPUIRA=="], - - "motion-utils": ["motion-utils@12.39.0", "", {}, "sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ=="], - - "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], - - "nanoid": ["nanoid@3.3.15", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA=="], - - "next": ["next@16.2.10", "", { "dependencies": { "@next/env": "16.2.10", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.9.19", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.2.10", "@next/swc-darwin-x64": "16.2.10", "@next/swc-linux-arm64-gnu": "16.2.10", "@next/swc-linux-arm64-musl": "16.2.10", "@next/swc-linux-x64-gnu": "16.2.10", "@next/swc-linux-x64-musl": "16.2.10", "@next/swc-win32-arm64-msvc": "16.2.10", "@next/swc-win32-x64-msvc": "16.2.10", "sharp": "^0.34.5" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-2som5AVXb3kE6Yjine3/mNbBayYF58eguBWIVVUdr1y/L426xyVEgYxgBG+1QC34P2x5E+tcDup6XkuOAX3dCA=="], - - "next-themes": ["next-themes@0.4.6", "", { "peerDependencies": { "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA=="], - - "oniguruma-parser": ["oniguruma-parser@0.12.2", "", {}, "sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw=="], - - "oniguruma-to-es": ["oniguruma-to-es@4.3.6", "", { "dependencies": { "oniguruma-parser": "^0.12.2", "regex": "^6.1.0", "regex-recursion": "^6.0.2" } }, "sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA=="], - - "oxfmt": ["oxfmt@0.57.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.57.0", "@oxfmt/binding-android-arm64": "0.57.0", "@oxfmt/binding-darwin-arm64": "0.57.0", "@oxfmt/binding-darwin-x64": "0.57.0", "@oxfmt/binding-freebsd-x64": "0.57.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.57.0", "@oxfmt/binding-linux-arm-musleabihf": "0.57.0", "@oxfmt/binding-linux-arm64-gnu": "0.57.0", "@oxfmt/binding-linux-arm64-musl": "0.57.0", "@oxfmt/binding-linux-ppc64-gnu": "0.57.0", "@oxfmt/binding-linux-riscv64-gnu": "0.57.0", "@oxfmt/binding-linux-riscv64-musl": "0.57.0", "@oxfmt/binding-linux-s390x-gnu": "0.57.0", "@oxfmt/binding-linux-x64-gnu": "0.57.0", "@oxfmt/binding-linux-x64-musl": "0.57.0", "@oxfmt/binding-openharmony-arm64": "0.57.0", "@oxfmt/binding-win32-arm64-msvc": "0.57.0", "@oxfmt/binding-win32-ia32-msvc": "0.57.0", "@oxfmt/binding-win32-x64-msvc": "0.57.0" }, "peerDependencies": { "svelte": "^5.0.0", "vite-plus": "*" }, "optionalPeers": ["svelte", "vite-plus"], "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-ZB7Bi+rGDSqmVIo9jwcLyFgjxXvQhDdU+jx+ZrVy6VRiVXK2+CHc4hO3J4dUQjHe7V0ymHB+MDuv5z+NhK07HA=="], - - "oxlint": ["oxlint@1.72.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.72.0", "@oxlint/binding-android-arm64": "1.72.0", "@oxlint/binding-darwin-arm64": "1.72.0", "@oxlint/binding-darwin-x64": "1.72.0", "@oxlint/binding-freebsd-x64": "1.72.0", "@oxlint/binding-linux-arm-gnueabihf": "1.72.0", "@oxlint/binding-linux-arm-musleabihf": "1.72.0", "@oxlint/binding-linux-arm64-gnu": "1.72.0", "@oxlint/binding-linux-arm64-musl": "1.72.0", "@oxlint/binding-linux-ppc64-gnu": "1.72.0", "@oxlint/binding-linux-riscv64-gnu": "1.72.0", "@oxlint/binding-linux-riscv64-musl": "1.72.0", "@oxlint/binding-linux-s390x-gnu": "1.72.0", "@oxlint/binding-linux-x64-gnu": "1.72.0", "@oxlint/binding-linux-x64-musl": "1.72.0", "@oxlint/binding-openharmony-arm64": "1.72.0", "@oxlint/binding-win32-arm64-msvc": "1.72.0", "@oxlint/binding-win32-ia32-msvc": "1.72.0", "@oxlint/binding-win32-x64-msvc": "1.72.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.22.1", "vite-plus": "*" }, "optionalPeers": ["oxlint-tsgolint", "vite-plus"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-1rhdZIP/EvoI91ABIwNU5Q8+bWf8mjrS5UzIOZld4d4bXxJvtlUhlQvaoTogIGin/qdErMOrwaIJvCSIAKTLhA=="], - - "parse-entities": ["parse-entities@4.0.2", "", { "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" } }, "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw=="], - - "parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="], - - "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], - - "picomatch": ["picomatch@4.0.5", "", {}, "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A=="], - - "postcss": ["postcss@8.5.16", "", { "dependencies": { "nanoid": "^3.3.12", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg=="], - - "property-information": ["property-information@7.2.0", "", {}, "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg=="], - - "react": ["react@19.2.7", "", {}, "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ=="], - - "react-dom": ["react-dom@19.2.7", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.7" } }, "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ=="], - - "react-remove-scroll": ["react-remove-scroll@2.7.2", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q=="], - - "react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="], - - "react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="], - - "readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], - - "recma-build-jsx": ["recma-build-jsx@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-util-build-jsx": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew=="], - - "recma-jsx": ["recma-jsx@1.0.1", "", { "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" }, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w=="], - - "recma-parse": ["recma-parse@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "esast-util-from-js": "^2.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ=="], - - "recma-stringify": ["recma-stringify@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-util-to-js": "^2.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g=="], - - "regex": ["regex@6.1.0", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg=="], - - "regex-recursion": ["regex-recursion@6.0.2", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg=="], - - "regex-utilities": ["regex-utilities@2.3.0", "", {}, "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng=="], - - "rehype-raw": ["rehype-raw@7.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-raw": "^9.0.0", "vfile": "^6.0.0" } }, "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww=="], - - "rehype-recma": ["rehype-recma@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", "hast-util-to-estree": "^3.0.0" } }, "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw=="], - - "remark": ["remark@15.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.0" } }, "sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A=="], - - "remark-gfm": ["remark-gfm@4.0.1", "", { "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" } }, "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg=="], - - "remark-mdx": ["remark-mdx@3.1.1", "", { "dependencies": { "mdast-util-mdx": "^3.0.0", "micromark-extension-mdxjs": "^3.0.0" } }, "sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg=="], - - "remark-parse": ["remark-parse@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", "micromark-util-types": "^2.0.0", "unified": "^11.0.0" } }, "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA=="], - - "remark-rehype": ["remark-rehype@11.1.2", "", { "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" } }, "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw=="], - - "remark-stringify": ["remark-stringify@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-to-markdown": "^2.0.0", "unified": "^11.0.0" } }, "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw=="], - - "rrdom": ["rrdom@2.1.0", "", { "dependencies": { "rrweb-snapshot": "^2.1.0" } }, "sha512-d7oaIHzwffxI74UJMZDGq/f97/Yfm3QX4CcTIlQelt2HsLavItLjp8x8nQ0g9Pet5+5wG1RGr9yvsxb1gJlo8A=="], - - "rrweb": ["rrweb@2.1.0", "", { "dependencies": { "@rrweb/types": "^2.1.0", "@rrweb/utils": "^2.1.0", "@types/css-font-loading-module": "0.0.7", "@xstate/fsm": "^1.4.0", "base64-arraybuffer": "^1.0.1", "mitt": "^3.0.0", "rrdom": "^2.1.0", "rrweb-snapshot": "^2.1.0" } }, "sha512-gGGvd1eXWnOuJpQumH7+gPmBwTXzNrjmQyedWVePcEx0S5fe3VkQW4vw5f5ItY+vuigaaktte9cZKOg0OEvv+w=="], - - "rrweb-snapshot": ["rrweb-snapshot@2.1.0", "", { "dependencies": { "postcss": "^8.4.38" } }, "sha512-CFjUKWlO+Dl72gk8qwcDcNE/Pj9yr6IvGRAiRAx12pmJaSWaOKFoFgpQQ1j/mW0WKwEZXbHnMJL8M92gIsdwUQ=="], - - "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], - - "scroll-into-view-if-needed": ["scroll-into-view-if-needed@3.1.0", "", { "dependencies": { "compute-scroll-into-view": "^3.0.2" } }, "sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ=="], - - "semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], - - "sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "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" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="], - - "shiki": ["shiki@4.3.1", "", { "dependencies": { "@shikijs/core": "4.3.1", "@shikijs/engine-javascript": "4.3.1", "@shikijs/engine-oniguruma": "4.3.1", "@shikijs/langs": "4.3.1", "@shikijs/themes": "4.3.1", "@shikijs/types": "4.3.1", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-oR+qDVi2OjX1tmDpyv+3KviX01KzO6Af+0NNnKnsp9491UEGz2YpxTuJboS/6VhYpTdqzmuJBuiTlrAWWJAssw=="], - - "source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="], - - "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], - - "space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="], - - "stringify-entities": ["stringify-entities@4.0.4", "", { "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" } }, "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="], - - "style-to-js": ["style-to-js@1.1.21", "", { "dependencies": { "style-to-object": "1.0.14" } }, "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ=="], - - "style-to-object": ["style-to-object@1.0.14", "", { "dependencies": { "inline-style-parser": "0.2.7" } }, "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw=="], - - "styled-jsx": ["styled-jsx@5.1.6", "", { "dependencies": { "client-only": "0.0.1" }, "peerDependencies": { "@babel/core": "*", "babel-plugin-macros": "*", "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" }, "optionalPeers": ["@babel/core", "babel-plugin-macros"] }, "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA=="], - - "tailwindcss": ["tailwindcss@4.3.2", "", {}, "sha512-WtctNNSH8A9jlMIqxzuYumOHU5uGZyRv0Q5svQl+oEPy5w84YpBxdb7MdqyiSPQge5jTJ6zFQLq0PFygdccSBA=="], - - "takumi-js": ["takumi-js@1.8.7", "", { "dependencies": { "@takumi-rs/core": "1.8.7", "@takumi-rs/helpers": "1.8.7", "@takumi-rs/wasm": "1.8.7" } }, "sha512-vJ4znkQvSecOkiAwge2P7lkwF6GFEbQIPD1C1EebyQq3x2xcE2+Wu9HkUVlMOuh3Un9p/GBHePr0jNpUCwHQOQ=="], - - "tapable": ["tapable@2.3.3", "", {}, "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A=="], - - "tinyexec": ["tinyexec@1.2.4", "", {}, "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg=="], - - "tinyglobby": ["tinyglobby@0.2.17", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g=="], - - "tinypool": ["tinypool@2.1.0", "", {}, "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw=="], - - "trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="], - - "trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="], - - "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "typescript": ["typescript@7.0.1-rc", "", { "optionalDependencies": { "@typescript/typescript-aix-ppc64": "7.0.1-rc", "@typescript/typescript-darwin-arm64": "7.0.1-rc", "@typescript/typescript-darwin-x64": "7.0.1-rc", "@typescript/typescript-freebsd-arm64": "7.0.1-rc", "@typescript/typescript-freebsd-x64": "7.0.1-rc", "@typescript/typescript-linux-arm": "7.0.1-rc", "@typescript/typescript-linux-arm64": "7.0.1-rc", "@typescript/typescript-linux-loong64": "7.0.1-rc", "@typescript/typescript-linux-mips64el": "7.0.1-rc", "@typescript/typescript-linux-ppc64": "7.0.1-rc", "@typescript/typescript-linux-riscv64": "7.0.1-rc", "@typescript/typescript-linux-s390x": "7.0.1-rc", "@typescript/typescript-linux-x64": "7.0.1-rc", "@typescript/typescript-netbsd-arm64": "7.0.1-rc", "@typescript/typescript-netbsd-x64": "7.0.1-rc", "@typescript/typescript-openbsd-arm64": "7.0.1-rc", "@typescript/typescript-openbsd-x64": "7.0.1-rc", "@typescript/typescript-sunos-x64": "7.0.1-rc", "@typescript/typescript-win32-arm64": "7.0.1-rc", "@typescript/typescript-win32-x64": "7.0.1-rc" }, "bin": { "tsc": "bin/tsc" } }, "sha512-drEP77wK7CCDlPfXZH4e008UUQOsw1DFmHmZOZjuNA+yoDLLnSNMZRXi90NbV/1LVo7SbNLq1bs3jjvk49TEqQ=="], - - "undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="], - - "unified": ["unified@11.0.5", "", { "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" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="], - - "unist-util-is": ["unist-util-is@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g=="], - - "unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="], - - "unist-util-position-from-estree": ["unist-util-position-from-estree@2.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ=="], - - "unist-util-remove-position": ["unist-util-remove-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q=="], - - "unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="], - - "unist-util-visit": ["unist-util-visit@5.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="], - - "unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="], - - "use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="], - - "use-sidecar": ["use-sidecar@1.1.3", "", { "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ=="], - - "vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="], - - "vfile-location": ["vfile-location@5.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg=="], - - "vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], - - "web-namespaces": ["web-namespaces@2.0.1", "", {}, "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ=="], - - "web-vitals": ["web-vitals@5.3.0", "", {}, "sha512-q6LWsLatGYZp5VGBIOvbTj6JBV2nOmC8KvWztXBmwJcfFAzhwKwbOxhUH306XY3CcaZDUlSmSuNPBsCn0bFu+g=="], - - "zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="], - - "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], - - "@fumadocs/api-docs/lucide-react": ["lucide-react@1.22.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-c9o3l0PiNcgOQDW4F31BEYHudE7kgxVt3o30qMl36ZPwTxXlGB4QnLilhERvVM4uh/pl5MDyY1/gzZSYcHDtBg=="], - - "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.11.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" }, "bundled": true }, "sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA=="], - - "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.11.2", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA=="], - - "@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.2", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA=="], - - "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.6", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" }, "bundled": true }, "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg=="], - - "@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.3", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="], - - "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "fumadocs-openapi/lucide-react": ["lucide-react@1.22.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-c9o3l0PiNcgOQDW4F31BEYHudE7kgxVt3o30qMl36ZPwTxXlGB4QnLilhERvVM4uh/pl5MDyY1/gzZSYcHDtBg=="], - - "fumadocs-ui/lucide-react": ["lucide-react@1.22.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-c9o3l0PiNcgOQDW4F31BEYHudE7kgxVt3o30qMl36ZPwTxXlGB4QnLilhERvVM4uh/pl5MDyY1/gzZSYcHDtBg=="], - - "next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="], - - "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], - } -} diff --git a/bunfig.toml b/bunfig.toml deleted file mode 100644 index fae775c..0000000 --- a/bunfig.toml +++ /dev/null @@ -1,4 +0,0 @@ -[install] -# Only install package versions published at least 1 day ago. -minimumReleaseAge = 86400 # seconds -minimumReleaseAgeExcludes = ["@faststats/react"] diff --git a/content/docs/java/configuration.mdx b/content/docs/java/configuration.mdx deleted file mode 100644 index 446773a..0000000 --- a/content/docs/java/configuration.mdx +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: Configuration -description: Advanced configuration options for FastStats Java SDK -icon: Settings ---- - -Configure FastStats by creating a platform context and attaching the services -your project uses. - -## Basic Configuration - -The minimal metrics configuration requires only a token: - -```java -import dev.faststats.Metrics; -import dev.faststats.bukkit.BukkitContext; - -private final BukkitContext context = new BukkitContext.Factory(plugin, "YOUR_TOKEN") - .metrics(Metrics.Factory::create) - .create(); - -public void onEnable() { - context.ready(); -} -``` - -## Complete Configuration Example - -Here's a configured Bukkit context with error tracking, custom metrics, and a -flush callback: - -```java -import dev.faststats.ErrorTracker; -import dev.faststats.bukkit.BukkitContext; -import dev.faststats.data.Metric; -import org.bukkit.plugin.java.JavaPlugin; - -import java.util.concurrent.atomic.AtomicInteger; - -public final class MyBukkitPlugin extends JavaPlugin { - public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); - private final AtomicInteger arenaMatches = new AtomicInteger(); - - private final BukkitContext context = new BukkitContext.Factory(this, "YOUR_TOKEN") - .errorTrackerService(ERROR_TRACKER) - .metrics(factory -> factory - .addMetric(Metric.number("arena_matches", arenaMatches::get)) - .addMetric(Metric.string("active_ruleset", () -> "ranked_duels")) - .addMetric(Metric.bool("ranked_mode", () -> true)) - .addMetric(Metric.stringArray("used_hooks", () -> new String[]{"Vault", "PlaceholderAPI"})) - .onFlush(() -> arenaMatches.set(0)) - .create()) - .create(); - - @Override - public void onEnable() { - context.ready(); - } - - @Override - public void onDisable() { - context.shutdown(); - } -} -``` - -Metrics submission and error tracking start after `context.ready()` is called. -Call `context.ready()` from the platform startup hook, and call -`context.shutdown()` during shutdown. - -For error tracking configuration, see [Error Tracking](/java/error-tracking). For platform-specific setup, see the platform pages in the sidebar. - -## Best Practices - -- Keep metric suppliers lightweight -- Cache expensive calculations and values that never change -- Metric suppliers must be thread-safe and pure diff --git a/content/docs/java/custom-metrics.mdx b/content/docs/java/custom-metrics.mdx deleted file mode 100644 index 1ecbfc2..0000000 --- a/content/docs/java/custom-metrics.mdx +++ /dev/null @@ -1,147 +0,0 @@ ---- -title: Custom Metrics -description: Send custom values from your Java project -icon: Database ---- - -Custom metrics let you submit project-specific values alongside the built-in -platform metrics. Each custom metric must match a data source configured in your -FastStats project settings. - -## Add Metrics - -Attach custom metrics when you create the platform context: - -```java -import dev.faststats.bukkit.BukkitContext; -import dev.faststats.data.Metric; - -import java.util.concurrent.atomic.AtomicInteger; - -private final AtomicInteger arenaMatches = new AtomicInteger(); - -private final BukkitContext context = new BukkitContext.Factory(this, "YOUR_TOKEN") - .metrics(factory -> factory - .addMetric(Metric.number("arena_matches", arenaMatches::get)) - .addMetric(Metric.stringArray("used_hooks", () -> new String[]{"Vault", "PlaceholderAPI"})) - .onFlush(() -> arenaMatches.set(0)) - .create()) - .create(); - -public void onEnable() { - context.ready(); -} -``` - -Metrics submission starts after `context.ready()` is called. Call -`context.shutdown()` during your platform's shutdown hook. - -## Data Source IDs - -The first argument passed to `Metric.*` is the source ID. It must match the data -source ID in your FastStats project. - -```java -Metric.number("arena_matches", arenaMatches::get); -``` - -Source IDs must use lowercase letters and underscores only, for example -`arena_matches`, `used_hooks`, or `active_ruleset`. - -## Supported Types - -Use the factory method that matches the data source type: - -| Method | Value type | -| ----------------------------------- | ------------------------------- | -| `Metric.number(id, supplier)` | `Number` | -| `Metric.string(id, supplier)` | `String` | -| `Metric.bool(id, supplier)` | `Boolean` | -| `Metric.numberArray(id, supplier)` | `Number[]` | -| `Metric.stringArray(id, supplier)` | `String[]` | -| `Metric.booleanArray(id, supplier)` | `Boolean[]` | -| `Metric.numberMap(id, supplier)` | `Map` | -| `Metric.stringMap(id, supplier)` | `Map` | -| `Metric.booleanMap(id, supplier)` | `Map` | - -```java -Metric.number("active_arenas", () -> 4); -Metric.string("active_ruleset", () -> "ranked_duels"); -Metric.bool("ranked_mode", () -> true); - -Metric.stringArray("used_hooks", () -> new String[]{"Vault", "PlaceholderAPI"}); -Metric.numberArray("match_durations", () -> new Number[]{310, 428, 275}); -Metric.booleanArray("enabled_features", () -> new Boolean[]{true, false}); -``` - -Map metrics are useful when the set of keys is dynamic: - -```java -Metric.numberMap("hook_usage", () -> Map.of( - "vault", 12, - "placeholderapi", 4, - "luckperms", 9 -)); -``` - -## Supplier Behavior - -Metric suppliers are called by the SDK during submission. Keep them: - -- lightweight -- thread-safe -- side-effect free -- resilient to missing or temporarily unavailable platform state - -Return `null` from a supplier when a value should be skipped for that -submission. - -```java -Metric.string("active_event", () -> currentEvent != null ? currentEvent.id() : null); -``` - -If a value is expensive to compute, update a cached value from your own platform -events and read the cached value from the metric supplier. - -```java -private volatile int cachedQueueDepth = 0; - -public void updateQueueDepth() { - cachedQueueDepth = matchmakingQueue.size(); -} - -Metric.number("queue_depth", () -> cachedQueueDepth); -``` - -## Flush Callback - -Use `onFlush` to clear counters after FastStats accepts a metrics submission. - -```java -private final AtomicInteger arenaMatches = new AtomicInteger(); - -.metrics(factory -> factory - .addMetric(Metric.number("arena_matches", arenaMatches::get)) - .onFlush(() -> arenaMatches.set(0)) - .create()) -``` - -Do not reset counters inside the metric supplier itself. Suppliers may be called -without a successful submission. - -## Built-In Metrics Only - -If you do not need custom metrics, create the metrics service without adding any -metrics: - -```java -import dev.faststats.Metrics; - -private final BukkitContext context = new BukkitContext.Factory(this, "YOUR_TOKEN") - .metrics(Metrics.Factory::create) - .create(); - -public void onEnable() { - context.ready(); -} -``` diff --git a/content/docs/java/error-tracking.mdx b/content/docs/java/error-tracking.mdx deleted file mode 100644 index 4447df6..0000000 --- a/content/docs/java/error-tracking.mdx +++ /dev/null @@ -1,177 +0,0 @@ ---- -title: Error Tracking -description: Monitor and report errors from your Minecraft server plugin -icon: Bug ---- - -FastStats can automatically track errors in your project. - - - Error tracking must be enabled in the project settings. Otherwise, all - reported errors will be ignored. - - - - The error tracker does not replace proper error handling. It should only be - used as a way to report errors for monitoring purposes. - - -## Context-Aware Error Tracker - -The context-aware error tracker automatically tracks uncaught errors from the -same class loader: - -```java -import dev.faststats.ErrorTracker; -import dev.faststats.bukkit.BukkitContext; -import org.bukkit.plugin.java.JavaPlugin; - -public final class MyBukkitPlugin extends JavaPlugin { - public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); - - private final BukkitContext context = new BukkitContext.Factory(this, "YOUR_TOKEN") - .errorTrackerService(ERROR_TRACKER) - .create(); - - @Override - public void onEnable() { - context.ready(); - } - - @Override - public void onDisable() { - context.shutdown(); - } - - public void doSomethingWrong() { - try { - throw new RuntimeException("Something went wrong!"); - } catch (Exception e) { - // This exception will be reported as handled. - ERROR_TRACKER.trackError(e); - } - } -} -``` - - - The automatic tracking only covers errors that would otherwise be swallowed by - the JVM. Use manual tracking in addition to passive tracking. - - -## Context-Unaware Error Tracker - -The context-unaware error tracker only tracks errors passed to `trackError()`: - -```java -import dev.faststats.ErrorTracker; -import dev.faststats.bukkit.BukkitContext; -import org.bukkit.plugin.java.JavaPlugin; - -public final class MyBukkitPlugin extends JavaPlugin { - public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextUnaware(); - - private final BukkitContext context = new BukkitContext.Factory(this, "YOUR_TOKEN") - .errorTrackerService(ERROR_TRACKER) - .create(); - - @Override - public void onEnable() { - context.ready(); - } - - public void doSomethingWrong() { - try { - throw new RuntimeException("Something went wrong!"); - } catch (Exception e) { - ERROR_TRACKER.trackError(e); - } - } -} -``` - -## Ignoring and Anonymizing Errors - -You can ignore specific error types or messages, and anonymize sensitive data in error messages: - -```java -public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware() - .ignoreError(InvocationTargetException.class, "Expected .* but got .*") - .ignoreError(AccessDeniedException.class); - -public static final ErrorTracker MANUAL_ERROR_TRACKER = ErrorTracker.contextUnaware() - .anonymize("^[\\w-.]+@([\\w-]+\\.)+[\\w-]{2,4}$", "[email hidden]") - .anonymize("Bearer [A-Za-z0-9._~+/=-]+", "Bearer [token hidden]") - .anonymize("AKIA[0-9A-Z]{16}", "[aws-key hidden]") - .anonymize("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}", "[uuid hidden]") - .anonymize("([?&](?:api_?key|token|secret)=)[^&\\s]+", "$1[redacted]"); - -private final BukkitContext context = new BukkitContext.Factory(plugin, "YOUR_TOKEN") - .errorTrackerService(ERROR_TRACKER) - .create(); - -{ - context.errorTrackerService().orElseThrow().registerErrorTracker(MANUAL_ERROR_TRACKER); -} -``` - -## Tracker Attributes - -Attributes stored on an error tracker are attached to reports submitted through -that tracker. Use them for stable context such as environment or component. - -All enabled metrics are already added to the error context by default. This -includes the standard runtime and platform details FastStats collects, such as -Java version and plugin version. Add tracker attributes only for extra context -that FastStats cannot infer automatically. - -```java -public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); -public static final ErrorTracker MANUAL_ERROR_TRACKER = ErrorTracker.contextUnaware(); - -{ - ERROR_TRACKER.getAttributes() - .put("environment", "production") - .put("component", "global-error-handler"); - - MANUAL_ERROR_TRACKER.getAttributes() - .put("component", "manual-error-handler"); -} -``` - -Attributes on the global/internal tracker are used for every error report, -including reports submitted through additional registered trackers. Additional -trackers can override global attributes with the same key. - -Attribute precedence is: - -1. Global tracker attributes -2. Per-tracker attributes -3. Per-error attributes - -## Per-Error Attributes and Options - -`trackError(...)` returns a tracked error, so you can add context that only -applies to that specific report. Per-error attributes are useful for operation -names, severity, retry state, player or request context, and other values that -change per failure. They override both global and per-tracker attributes with -the same key. - -```java -import dev.faststats.Attributes; - -try { - throw new RuntimeException("Something went wrong!"); -} catch (Exception e) { - MANUAL_ERROR_TRACKER.trackError(e) - .attributes(Attributes.empty() - .put("operation", "manualTracking") - .put("severity", "warning") - .put("retryable", false)) - .handled(false); -} -``` - -Use `.handled(false)` when the error was not recovered from properly and should -be treated as unhandled. Errors tracked manually are handled by default unless -you override that option. diff --git a/content/docs/java/feature-flags.mdx b/content/docs/java/feature-flags.mdx deleted file mode 100644 index 1628b5e..0000000 --- a/content/docs/java/feature-flags.mdx +++ /dev/null @@ -1,109 +0,0 @@ ---- -title: Feature Flags -description: Evaluate FastStats feature flags from Java projects -icon: Flag ---- - - - Feature Flags are still in **Private Preview** please contact staff if you - would like to try them out. - - -Feature flags are configured on a FastStats context. A context may enable -metrics, error tracking, feature flags, or any combination of those services. - -## Configure a Service - -```java -import dev.faststats.Attributes; -import dev.faststats.FastStatsContext; -import dev.faststats.FeatureFlagService; -import dev.faststats.bukkit.BukkitContext; - -import java.time.Duration; - -BukkitContext context = new BukkitContext.Factory(plugin, "YOUR_TOKEN") - .featureFlagService(factory -> factory - .attributes(Attributes.empty() - .put("version", "1.2.3") - .put("java_version", System.getProperty("java.version"))) - .ttl(Duration.ofMinutes(10)) - .create()) - .create(); - -FeatureFlagService flags = context.featureFlagService().orElseThrow(); -``` - -Use `.featureFlagService(FeatureFlagService.Factory::create)` when you want the -default settings. - -## Define Flags - -Define flags with a key and a local default value. The default is used before a -server value is available or when evaluation fails. - -```java -var newCommands = flags.define("new_commands", false); -var compression = flags.define("compression", "zstd"); -var maxPlayers = flags.define("max_players", 100); -``` - -Supported value types are boolean, string, and number. - -## Read Values - -```java -newCommands.whenReady().thenAccept(enabled -> { - if (enabled) { - // Register the new commands. - } -}); - -compression.getCached().ifPresent(value -> { - // Use the cached value without starting a request. -}); - -if (compression.isExpired()) { - compression.fetch().thenAccept(value -> { - // React to the refreshed value. - }); -} -``` - -`whenReady()` returns the cached value when it is still valid. Otherwise it -fetches the latest value. `fetch()` always requests a fresh value from the -server. - -## Per-Flag Attributes - -Global attributes configured on the service are sent with every evaluation. You -can add per-flag attributes when a specific flag needs more targeting context. - -```java -var betaUi = flags.define( - "beta_ui", - false, - Attributes.empty().put("world", "lobby") -); -``` - -Per-flag attributes override global attributes with the same key. - -## Opt In and Opt Out - -Flags that allow specific opt-in can be changed from the SDK: - -```java -newCommands.optIn().thenAccept(enabled -> { - if (enabled) { - // The server accepted the opt-in and returned the current value. - } -}); - -newCommands.optOut(); -``` - -Opt-in and opt-out invalidate the local value and fetch the current server value -again. - -For platform concepts and dashboard setup, see [Feature Flags](/platform/feature-flags). diff --git a/content/docs/java/index.mdx b/content/docs/java/index.mdx deleted file mode 100644 index bca83b1..0000000 --- a/content/docs/java/index.mdx +++ /dev/null @@ -1,164 +0,0 @@ ---- -title: Installation -description: Add FastStats to your Minecraft server project -icon: Download ---- - -import { DynamicCodeBlock } from "fumadocs-ui/components/dynamic-codeblock"; -import { latestVersion } from "@/lib/docs/repository"; -export const version = await latestVersion("core"); - -Add the FastStats SDK to your project using Maven or Gradle. - - - - ```xml - - faststats-releases - FastStats - https://repo.faststats.dev/releases - - ``` - - - ```kts - maven { - name = "faststatsReleases" - url = uri("https://repo.faststats.dev/releases") - } - ``` - - - ```groovy - maven { - name "faststatsReleases" - url "https://repo.faststats.dev/releases" - } - ``` - - - ```scala - resolvers += - "faststats-releases" - at "https://repo.faststats.dev/releases" - ``` - - - -## Platform-Specific Artifacts - -Choose the artifact for your platform: - -| Platform | Artifact ID | Java Versions | -| -------------------------- | ----------------------------------------- | ------------- | -| Bukkit/Spigot/Paper/Folia… | [`bukkit`](/java/platform/bukkit) | 17+ | -| BungeeCord | [`bungeecord`](/java/platform/bungeecord) | 17+ | -| Fabric | [`fabric`](/java/platform/fabric) | 25+ | -| Hytale | [`hytale`](/java/platform/hytale) | 25+ | -| Minestom | [`minestom`](/java/platform/minestom) | 25+ | -| NeoForge | [`neoforge`](/java/platform/neoforge) | 25+ | -| Nukkit | [`nukkit`](/java/platform/nukkit) | 17+ | -| Sponge | [`sponge`](/java/platform/sponge) | 17+ | -| Velocity | [`velocity`](/java/platform/velocity) | 21+ | - - - - - dev.faststats.metrics - bukkit - ${version} -`} - /> - - - - - - - - - - - - -## Shading - -To include FastStats directly in your plugin JAR, you can use the Maven Shade or Gradle Shadow Plugin. - - - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.5.0 - - - package - - shade - - - - - dev.faststats - your.plugin.libs.faststats - - - - - - - -`} - /> - - - - - - - - - - diff --git a/content/docs/java/meta.json b/content/docs/java/meta.json deleted file mode 100644 index 8615aab..0000000 --- a/content/docs/java/meta.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "root": true, - "title": "Java", - "icon": "Coffee", - "pages": [ - "---Configuration---", - "index", - "migration", - "configuration", - "custom-metrics", - "error-tracking", - "feature-flags", - "---Platforms---", - "...platform", - "---Advanced---", - "obfuscation-mappings", - "system-properties" - ] -} diff --git a/content/docs/java/migration.mdx b/content/docs/java/migration.mdx deleted file mode 100644 index 6eef4a4..0000000 --- a/content/docs/java/migration.mdx +++ /dev/null @@ -1,237 +0,0 @@ ---- -title: Migration Guide -description: Upgrade FastStats Java SDK from 0.23.0 to 0.24.0 -icon: ArrowRightLeft ---- - -This guide covers the breaking Java SDK changes between `0.23.0` and `0.24.0`. - -Version `0.24.0` moves FastStats from standalone metrics instances to a shared -platform context. The context owns the token, config, metrics, error tracking, -feature flags, and lifecycle. - -## Imports - -All core classes moved out of `dev.faststats.core`. - -```java -// 0.23.0 -import dev.faststats.core.ErrorTracker; -import dev.faststats.core.Metrics; -import dev.faststats.core.data.Metric; - -// 0.24.0 -import dev.faststats.ErrorTracker; -import dev.faststats.Metrics; -import dev.faststats.data.Metric; -``` - -## Metrics Setup - -Platform metrics factories such as `BukkitMetrics.factory()` were replaced by -platform context factories such as `BukkitContext.Factory`. - -**Old Code** - -```java -// 0.23.0 -private final BukkitMetrics metrics = BukkitMetrics.factory() - .addMetric(Metric.number("arena_matches", arenaMatches::get)) - .onFlush(() -> arenaMatches.set(0)) - .token("YOUR_TOKEN") - .create(this); - -@Override -public void onEnable() { - metrics.ready(); -} - -@Override -public void onDisable() { - metrics.shutdown(); -} -``` - -**Updated Code** - -```java -// 0.24.0 -private final BukkitContext context = new BukkitContext.Factory(this, "YOUR_TOKEN") - .metrics(factory -> factory - .addMetric(Metric.number("arena_matches", arenaMatches::get)) - .onFlush(() -> arenaMatches.set(0)) - .create()) - .create(); - -@Override -public void onEnable() { - context.ready(); -} - -@Override -public void onDisable() { - context.shutdown(); -} -``` - -Use `.metrics(Metrics.Factory::create)` if you only need the built-in metrics -without custom metrics. - -## Token, URL, and Debug - -The token is now passed to the context factory constructor or builder. Per-metrics -`.token(...)`, `.url(...)`, and `.debug(...)` calls were removed. - -```java -// 0.23.0 -BukkitMetrics.factory() - .url(URI.create("https://metrics.example.com/v1/collect")) - .debug(true) - .token("YOUR_TOKEN") - .create(this); -``` - -```java -// 0.24.0 -new BukkitContext.Factory(this, "YOUR_TOKEN") - .metrics(Metrics.Factory::create) - .create(); -``` - -Call `context.ready()` from your platform startup hook before metrics are used. -For runtime configuration, use the FastStats config and system properties. For -example, use `-Dfaststats.debug=true` to enable debug logging. - -## Error Tracking - -Error trackers are now attached to the context with `.errorTrackerService(...)`. -They are no longer configured on the metrics factory. - -```java -// 0.23.0 -public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); - -private final BukkitMetrics metrics = BukkitMetrics.factory() - .errorTracker(ERROR_TRACKER) - .token("YOUR_TOKEN") - .create(this); -``` - -```java -// 0.24.0 -public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); - -private final BukkitContext context = new BukkitContext.Factory(this, "YOUR_TOKEN") - .errorTrackerService(ERROR_TRACKER) - .metrics(Metrics.Factory::create) - .create(); - -public void onEnable() { - context.ready(); -} -``` - -Context-unaware trackers still exist, but additional trackers must be registered -with the context error tracker service. - -```java -public static final ErrorTracker MANUAL_TRACKER = ErrorTracker.contextUnaware(); - -{ - context.errorTrackerService().orElseThrow().registerErrorTracker(MANUAL_TRACKER); -} -``` - -`trackError(...)` now returns a `TrackedError`, so callers may attach additional -data to the tracked error after creating it. - -```java -MANUAL_TRACKER.trackError(error) - .handled(false) - .attributes(Attributes.empty() - .put("version", "1.0.0")); -``` - -## Platform Factories - -Use the new platform context factory for your platform: - -| Platform | 0.23.0 | 0.24.0 | -| ---------- | ------------------------------------------ | --------------------------------------------------- | -| Bukkit | `BukkitMetrics.factory().create(plugin)` | `new BukkitContext.Factory(plugin, token).create()` | -| BungeeCord | `BungeeMetrics.factory().create(plugin)` | `new BungeeContext.Factory(plugin, token).create()` | -| Fabric | `FabricMetrics.factory().create(modId)` | `new FabricContext.Factory(modId, token).create()` | -| Hytale | `HytaleMetrics.factory().create(plugin)` | `new HytaleContext.Factory(plugin, token).create()` | -| Minestom | `MinestomMetrics.factory().create(server)` | `new MinestomContext.Factory(token).create()` | -| Nukkit | `NukkitMetrics.factory().create(plugin)` | `new NukkitContext.Factory(plugin, token).create()` | -| Sponge | injected `SpongeMetrics.Factory` | injected `SpongeContext.Builder` | -| Velocity | injected `VelocityMetrics.Factory` | injected `VelocityContext.Builder` | - -Sponge and Velocity builders receive the platform objects from dependency -injection, so configure the token on the injected builder: - -```java -// Sponge -private @Inject SpongeContext.Builder contextBuilder; - -@Listener -public void onServerStart(final StartedEngineEvent event) { - this.context = contextBuilder - .token("YOUR_TOKEN") - .metrics(Metrics.Factory::create) - .create(); - context.ready(); -} -``` - -```java -// Velocity -@Inject -public ExamplePlugin(final VelocityContext.Builder contextBuilder) { - this.context = contextBuilder - .token("YOUR_TOKEN") - .metrics(Metrics.Factory::create) - .create(); -} - -@Subscribe -public void onProxyInitialize(final ProxyInitializeEvent event) { - context.ready(); -} -``` - -## Configuration Access - -Metrics no longer expose token and config directly. Read them from the context: - -```java -// 0.23.0 -metrics.getToken(); -metrics.getConfig(); - -// 0.24.0 -context.getToken(); -context.getConfig(); -``` - -The config API also separates global enablement from metrics submission: - -```java -context.getConfig().enabled(); -context.getConfig().submitMetrics(); -context.getConfig().errorTracking(); -context.getConfig().additionalMetrics(); -context.getConfig().debug(); -``` - -## Checklist - -- Replace `dev.faststats.core.*` imports with `dev.faststats.*`. -- Replace `dev.faststats.core.data.*` imports with `dev.faststats.data.*`. -- Replace platform **metrics** factories with platform **context** factories. -- Move `.token(...)` to the context factory constructor or injected builder. -- Move `.errorTracker(...)` to `.errorTrackerService(...)`. -- Move custom metrics into `.metrics(factory -> factory ... .create())`. -- Replace `metrics.ready()` and `metrics.shutdown()` with `context.ready()` and `context.shutdown()`. -- Call `context.ready()` when using metrics or error tracking. -- Use context accessors for token, config, metrics, error tracker service, and feature flag service. diff --git a/content/docs/java/obfuscation-mappings.mdx b/content/docs/java/obfuscation-mappings.mdx deleted file mode 100644 index 755131c..0000000 --- a/content/docs/java/obfuscation-mappings.mdx +++ /dev/null @@ -1,154 +0,0 @@ ---- -title: Obfuscation Mappings -description: Upload ProGuard/R8 obfuscation mapping files for stack traces deobfuscation. -icon: FileKey ---- - -import { Callout } from "fumadocs-ui/components/callout"; - -FastStats resolves obfuscated Java stack traces using uploaded ProGuard/R8 mapping files. -The recommended workflow is the `dev.faststats.proguard-mappings-upload` Gradle plugin. - -## Installation - - - - - ```kotlin - plugins { - id("dev.faststats.proguard-mappings-upload") version "0.1.0" - } - ``` - - - - - ```groovy - plugins { - id 'dev.faststats.proguard-mappings-upload' version '0.1.0' - } - ``` - - - - - -## Configuration - -### Android Projects - -The plugin automatically detects Android R8/ProGuard mapping file outputs when the Android Gradle Plugin is present. -No additional configuration is needed beyond the auth token: - -```kotlin -mappingsUpload { - authToken.set("your-auth-token") -} -``` - -### Custom ProGuard Task - -If you're using a standalone ProGuard task, point the plugin to your mapping file and task: - -```kotlin -mappingsUpload { - authToken.set("your-auth-token") - proguardTask.set(tasks.getByName("proguard")) - mappingFiles.from(layout.buildDirectory.file("proguard/mapping.txt")) -} -``` - -Setting `proguardTask` ensures the upload task runs after ProGuard finishes. `mappingFiles` must match the location -configured in your `printmapping` setting. - - - When `proguardTask` is set, running `./gradlew uploadProguardMappings` is - sufficient: the ProGuard task will run automatically as a dependency. Running - `./gradlew proguard uploadProguardMappings` would execute ProGuard twice. - - -## Upload Authentication - -Generate an API key in your FastStats project settings. The plugin accepts it via the `authToken` option -or the `FASTSTATS_AUTH_TOKEN` environment variable. - - - The upload auth token is a **secret** and must never be committed to version - control or exposed publicly. Always use environment variables or a secrets - manager to provide it, especially in CI pipelines. - - -## All Options - -| Option | Description | -| -------------- | ------------------------------------------------------------------------------------ | -| `authToken` | Bearer token for upload authentication. Falls back to `FASTSTATS_AUTH_TOKEN` env var | -| `endpoint` | Upload API URL (default: `https://sourcemaps.faststats.dev/api/sourcemaps`) | -| `buildId` | Explicit build ID (default: `project.version`) | -| `proguardTask` | Task that produces the mapping file (adds a `dependsOn`) | -| `mappingFiles` | Mapping files to upload | - -## Usage - -Run the upload task directly: - -```bash -./gradlew uploadProguardMappings -``` - -Or chain it after your obfuscation task: - -```bash -./gradlew proguard uploadProguardMappings -``` - -## CI Configuration - -### GitHub Actions - -```yaml -name: Build & Upload Mappings - -on: - push: - branches: [main] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-java@v4 - with: - distribution: temurin - java-version: 17 - - - name: Build & Upload - run: ./gradlew proguard uploadProguardMappings - env: - FASTSTATS_AUTH_TOKEN: ${{ secrets.FASTSTATS_AUTH_TOKEN }} -``` - -### GitLab CI - -```yaml -build: - stage: build - script: - - ./gradlew proguard uploadProguardMappings - variables: - FASTSTATS_AUTH_TOKEN: $FASTSTATS_AUTH_TOKEN -``` - -## How It Works - -1. The plugin collects mapping files added via `mappingFiles.from(...)`, or auto-detected Android build outputs. -2. If `proguardTask` is set, the upload task automatically depends on it. -3. `project.version` is used as the `buildId` by default. -4. Each mapping file is split by class sections and uploaded in batches of up to 50 MB, ensuring no class mapping is split across batches. - -## Requirements - -- Gradle 7.0+ -- JDK 11+ diff --git a/content/docs/java/platform/bukkit.mdx b/content/docs/java/platform/bukkit.mdx deleted file mode 100644 index 2739eea..0000000 --- a/content/docs/java/platform/bukkit.mdx +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Bukkit -description: Integrate FastStats with any Bukkit-based plugins -icon: Box ---- - -Use `dev.faststats.bukkit.BukkitContext` for Bukkit-based server plugins. Requires Java 17+. - -**Artifact:** `dev.faststats.metrics:bukkit` - -```java -import dev.faststats.ErrorTracker; -import dev.faststats.Metrics; -import dev.faststats.bukkit.BukkitContext; -import org.bukkit.plugin.java.JavaPlugin; - -public final class ExamplePlugin extends JavaPlugin { - public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); - - private final BukkitContext context = new BukkitContext.Factory(this, "YOUR_TOKEN") - .errorTrackerService(ERROR_TRACKER) - .metrics(Metrics.Factory::create) - .create(); - - @Override - public void onEnable() { - context.ready(); - } - - @Override - public void onDisable() { - context.shutdown(); - } -} -``` - -Call `context.ready()` in `onEnable()` before using metrics or error tracking. On Paper-based servers, this also registers additional exception handlers. See [Error Tracking](/java/error-tracking) for configuring error reporting. - -[View full example on GitHub](https://github.com/faststats-dev/faststats-java/blob/main/bukkit/example-plugin/src/main/java/com/example/ExamplePlugin.java) diff --git a/content/docs/java/platform/bungeecord.mdx b/content/docs/java/platform/bungeecord.mdx deleted file mode 100644 index d5c5f8e..0000000 --- a/content/docs/java/platform/bungeecord.mdx +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: BungeeCord -description: Integrate FastStats with BungeeCord proxy plugins -icon: Network ---- - -Use `dev.faststats.bungee.BungeeContext` for BungeeCord proxy plugins. Requires Java 17+. - -**Artifact:** `dev.faststats.metrics:bungeecord` - -```java -import dev.faststats.ErrorTracker; -import dev.faststats.Metrics; -import dev.faststats.bungee.BungeeContext; -import net.md_5.bungee.api.plugin.Plugin; - -public class ExamplePlugin extends Plugin { - public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); - - private final BungeeContext context = new BungeeContext.Factory(this, "YOUR_TOKEN") - .errorTrackerService(ERROR_TRACKER) - .metrics(Metrics.Factory::create) - .create(); - - @Override - public void onEnable() { - context.ready(); - } - - @Override - public void onDisable() { - context.shutdown(); - } -} -``` - -See [Error Tracking](/java/error-tracking) for configuring error reporting. - -[View full example on GitHub](https://github.com/faststats-dev/faststats-java/blob/main/bungeecord/example-plugin/src/main/java/com/example/ExamplePlugin.java) diff --git a/content/docs/java/platform/fabric.mdx b/content/docs/java/platform/fabric.mdx deleted file mode 100644 index cb2938b..0000000 --- a/content/docs/java/platform/fabric.mdx +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: Fabric -description: Integrate FastStats with Fabric mods -icon: Layers ---- - -Use `dev.faststats.fabric.FabricContext` for Fabric mods. Requires Java 25+. - - - The Fabric SDK currently only supports Minecraft version 26.1.2. Multi-version - support will be added soon. - - -**Artifact:** `dev.faststats.metrics:fabric` - -```java -import dev.faststats.ErrorTracker; -import dev.faststats.Metrics; -import dev.faststats.fabric.FabricContext; -import net.fabricmc.api.ModInitializer; - -public class ExampleMod implements ModInitializer { - public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); - - private final FabricContext context = new FabricContext.Factory("example-mod", "YOUR_TOKEN") - .errorTrackerService(ERROR_TRACKER) - .metrics(Metrics.Factory::create) - .create(); - - @Override - public void onInitialize() { - // your actual logic - } -} -``` - -Pass your mod ID, as defined in `fabric.mod.json`, to `FabricContext.Factory`. - -See [Error Tracking](/java/error-tracking) for configuring error reporting. - -[View full example on GitHub](https://github.com/faststats-dev/faststats-java/blob/main/fabric/example-mod/src/main/java/com/example/ExampleMod.java) diff --git a/content/docs/java/platform/hytale.mdx b/content/docs/java/platform/hytale.mdx deleted file mode 100644 index 5634ffc..0000000 --- a/content/docs/java/platform/hytale.mdx +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: Hytale -description: Integrate FastStats with Hytale server plugins -icon: Gamepad2 ---- - -Use `dev.faststats.hytale.HytaleContext` for Hytale server plugins. Requires Java 25+. - -**Artifact:** `dev.faststats.metrics:hytale` - -```java -import com.hypixel.hytale.server.core.plugin.JavaPlugin; -import com.hypixel.hytale.server.core.plugin.JavaPluginInit; -import dev.faststats.ErrorTracker; -import dev.faststats.Metrics; -import dev.faststats.hytale.HytaleContext; - -public class ExamplePlugin extends JavaPlugin { - public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); - - private final HytaleContext context = new HytaleContext.Factory(this, "YOUR_TOKEN") - .errorTrackerService(ERROR_TRACKER) - .metrics(Metrics.Factory::create) - .create(); - - public ExamplePlugin(final JavaPluginInit init) { - super(init); - context.ready(); - } - - @Override - protected void setup() { - context.ready(); - } - - @Override - protected void shutdown() { - context.shutdown(); - } -} -``` - -See [Error Tracking](/java/error-tracking) for configuring error reporting. - -[View full example on GitHub](https://github.com/faststats-dev/faststats-java/blob/main/hytale/example-plugin/src/main/java/com/example/ExamplePlugin.java) diff --git a/content/docs/java/platform/minestom.mdx b/content/docs/java/platform/minestom.mdx deleted file mode 100644 index 0f1ea08..0000000 --- a/content/docs/java/platform/minestom.mdx +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: Minestom -description: Integrate FastStats with Minestom servers -icon: Server ---- - -Use `dev.faststats.minestom.MinestomContext` for Minestom servers. Requires Java 25+. - -**Artifact:** `dev.faststats.metrics:minestom` - -```java -import dev.faststats.ErrorTracker; -import dev.faststats.Metrics; -import dev.faststats.minestom.MinestomContext; -import net.minestom.server.MinecraftServer; - -public final class ExampleServer { - public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); - - public static void main(String[] args) { - MinecraftServer server = MinecraftServer.init(); - - MinestomContext context = new MinestomContext.Factory("YOUR_TOKEN") - .errorTrackerService(ERROR_TRACKER) - .metrics(Metrics.Factory::create) - .create(); - - server.start("0.0.0.0", 25565); - context.ready(); - } -} -``` - -Call `context.ready()` after `MinecraftServer.init()` before using metrics or error tracking. This also registers exception handlers. See [Error Tracking](/java/error-tracking) for configuring error reporting. diff --git a/content/docs/java/platform/neoforge.mdx b/content/docs/java/platform/neoforge.mdx deleted file mode 100644 index 94927e8..0000000 --- a/content/docs/java/platform/neoforge.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: NeoForge -description: Integrate FastStats with NeoForge mods -icon: Hammer ---- - -Use `dev.faststats.neoforge.NeoForgeContext` for NeoForge mods. Requires Java 25+. - - - The NeoForge SDK currently only supports Minecraft version 26.1.2. - Multi-version support will be added soon. - - -**Artifact:** `dev.faststats.metrics:neoforge` - -```java -import dev.faststats.ErrorTracker; -import dev.faststats.Metrics; -import dev.faststats.neoforge.NeoForgeContext; -import net.neoforged.fml.common.Mod; - -@Mod("example_mod") -public class ExampleMod { - public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); - - private final NeoForgeContext context = new NeoForgeContext.Factory("example_mod", "YOUR_TOKEN") - .errorTrackerService(ERROR_TRACKER) - .metrics(Metrics.Factory::create) - .create(); -} -``` - -Pass your mod ID, as defined in `neoforge.mods.toml`, to `NeoForgeContext.Factory`. - -See [Error Tracking](/java/error-tracking) for configuring error reporting. - -[View full example on GitHub](https://github.com/faststats-dev/faststats-java/blob/main/neoforge/example-mod/src/main/java/com/example/ExampleMod.java) diff --git a/content/docs/java/platform/nukkit.mdx b/content/docs/java/platform/nukkit.mdx deleted file mode 100644 index a4400e6..0000000 --- a/content/docs/java/platform/nukkit.mdx +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: Nukkit -description: Integrate FastStats with Nukkit plugins -icon: Plug ---- - -Use `dev.faststats.nukkit.NukkitContext` for Nukkit plugins. Requires Java 17+. - -**Artifact:** `dev.faststats.metrics:nukkit` - -```java -import cn.nukkit.plugin.PluginBase; -import dev.faststats.ErrorTracker; -import dev.faststats.Metrics; -import dev.faststats.nukkit.NukkitContext; - -public final class ExamplePlugin extends PluginBase { - public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); - - private NukkitContext context; - - @Override - public void onLoad() { - context = new NukkitContext.Factory(this, "YOUR_TOKEN") - .errorTrackerService(ERROR_TRACKER) - .metrics(Metrics.Factory::create) - .create(); - } - - @Override - public void onEnable() { - context.ready(); - } - - @Override - public void onDisable() { - context.shutdown(); - } -} -``` - -See [Error Tracking](/java/error-tracking) for configuring error reporting. diff --git a/content/docs/java/platform/sponge.mdx b/content/docs/java/platform/sponge.mdx deleted file mode 100644 index 5b1994f..0000000 --- a/content/docs/java/platform/sponge.mdx +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: Sponge -description: Integrate FastStats with Sponge plugins -icon: Circle ---- - -Use `dev.faststats.sponge.SpongeContext` for Sponge plugins. Requires Java 17+. - -**Artifact:** `dev.faststats.metrics:sponge` - -```java -import com.google.inject.Inject; -import dev.faststats.ErrorTracker; -import dev.faststats.Metrics; -import dev.faststats.sponge.SpongeContext; -import org.jspecify.annotations.Nullable; -import org.spongepowered.api.Server; -import org.spongepowered.api.event.Listener; -import org.spongepowered.api.event.lifecycle.StartedEngineEvent; -import org.spongepowered.api.event.lifecycle.StoppingEngineEvent; -import org.spongepowered.plugin.builtin.jvm.Plugin; - -@Plugin("example") -public class ExamplePlugin { - public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); - private @Inject SpongeContext.Builder contextBuilder; - - private @Nullable SpongeContext context = null; - - @Listener - public void onServerStart(final StartedEngineEvent event) { - this.context = contextBuilder - .token("YOUR_TOKEN") - .errorTrackerService(ERROR_TRACKER) - .metrics(Metrics.Factory::create) - .create(); - context.ready(); - } - - @Listener - public void onServerStop(final StoppingEngineEvent event) { - if (context != null) context.shutdown(); - } -} -``` - -See [Error Tracking](/java/error-tracking) for configuring error reporting. - -[View full example on GitHub](https://github.com/faststats-dev/faststats-java/blob/main/sponge/example-plugin/src/main/java/com/example/ExamplePlugin.java) diff --git a/content/docs/java/platform/velocity.mdx b/content/docs/java/platform/velocity.mdx deleted file mode 100644 index 2d111cd..0000000 --- a/content/docs/java/platform/velocity.mdx +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: Velocity -description: Integrate FastStats with Velocity proxy plugins -icon: Zap ---- - -Use `dev.faststats.velocity.VelocityContext` for Velocity proxy plugins. Requires Java 21+. - -**Artifact:** `dev.faststats.metrics:velocity` - -```java -import com.google.inject.Inject; -import com.velocitypowered.api.event.Subscribe; -import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; -import com.velocitypowered.api.event.proxy.ProxyShutdownEvent; -import com.velocitypowered.api.plugin.Plugin; -import dev.faststats.ErrorTracker; -import dev.faststats.Metrics; -import dev.faststats.velocity.VelocityContext; - -@Plugin(id = "example", name = "Example Plugin", version = "1.0.0") -public class ExamplePlugin { - public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); - - private final VelocityContext context; - - @Inject - public ExamplePlugin(final VelocityContext.Builder contextBuilder) { - this.context = contextBuilder - .token("YOUR_TOKEN") - .errorTrackerService(ERROR_TRACKER) - .metrics(Metrics.Factory::create) - .create(); - } - - @Subscribe - public void onProxyInitialize(final ProxyInitializeEvent event) { - context.ready(); - } - - @Subscribe - public void onProxyStop(final ProxyShutdownEvent event) { - context.shutdown(); - } -} -``` - -See [Error Tracking](/java/error-tracking) for configuring error reporting. - -[View full example on GitHub](https://github.com/faststats-dev/faststats-java/blob/main/velocity/example-plugin/src/main/java/com/example/ExamplePlugin.java) diff --git a/content/docs/java/system-properties.mdx b/content/docs/java/system-properties.mdx deleted file mode 100644 index 7cf4ccc..0000000 --- a/content/docs/java/system-properties.mdx +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: System Properties -description: Configure FastStats using system properties -icon: TableProperties ---- - -System properties provide runtime control over FastStats behavior. -These flags only affect the current running server session/instance and are not persisted. - -## `faststats.debug` - -Enable debug logging for all FastStats projects. - -**Usage:** - -```bash -java -Dfaststats.debug=true -jar server.jar -``` - -**Values:** - -- `true` - Enable debug logging -- `false` - Disable debug logging - -## `faststats.enabled` - -Enable or disable FastStats data transmission globally. - -**Usage:** - -```bash -java -Dfaststats.enabled=false -jar server.jar -``` - -**Values:** - -- `true` - Enable data transmission -- `false` - Disable data transmission - -## `faststats.initial-delay` - -Configure the initial delay before FastStats starts collecting metrics. - -_This flag is meant to be used during development to delay or speed up the start of metric collection._ - -**Usage:** - -```bash -java -Dfaststats.initial-delay=5 -jar server.jar -``` - -**Values:** - -- Time in seconds (default: `30`) diff --git a/content/docs/meta.json b/content/docs/meta.json deleted file mode 100644 index 64c7aed..0000000 --- a/content/docs/meta.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "Documentation", - "pages": ["platform", "java", "api", "web-analytics"] -} diff --git a/content/docs/platform/chart-editor/flow-nodes.mdx b/content/docs/platform/chart-editor/flow-nodes.mdx deleted file mode 100644 index ceb4250..0000000 --- a/content/docs/platform/chart-editor/flow-nodes.mdx +++ /dev/null @@ -1,416 +0,0 @@ ---- -title: Flow Nodes -description: All available nodes for building data pipelines in the flow editor -icon: Workflow ---- - -import { - DatasourceNodePreview, - FilterNodePreview, - AggregateNodePreview, - GroupNodePreview, - TimeGroupNodePreview, - TextTransformNodePreview, - FormulaNodePreview, - LimitNodePreview, - MaxAgeNodePreview, - MinAgeNodePreview, - ResultNodePreview, -} from "@/components/docs/node-preview"; - -The Flow Editor lets you build chart queries by connecting nodes in a pipeline. Drag nodes onto the canvas, configure them, and wire them together. Data flows from top to bottom, starting at a **Data Source**, passing through transformations, and ending at an **Output**. - -## Getting started - -1. Add a **Data Source** node to choose which adapter and field to read from -2. Connect transformation nodes like **Filter**, **Group By**, or **Aggregate** to shape the data -3. Finish with an **Output** node to produce the chart result - -Each node has handles on its top and/or bottom edge. Connect the bottom handle of one node to the top handle of the next to build the pipeline. The colored badge on each node shows its category. Sources, filters, aggregates, groupings, transforms, time operations, and outputs each have their own color. - -## Nodes - -### Data Source - -
-
-

- The starting point of every pipeline. Choose which dataset to read from - and which field to pull out of it. -

-
    -
  • - Adapter: the data provider or dataset (for example, - Events or Sessions). This determines which fields you can pick below. -
  • -
  • - Field: the metric or property to read from the selected - adapter. -
  • -
  • - Dedupe: when checked, counts only the latest row per - identity (where the data source supports it). Useful for unique-visitor - style queries. -
  • -
-
-
- -
-
- ---- - -### Filter - -
-
-

- Keeps rows that match a condition and drops the rest. Pick a field, an - operator, and a comparison value. Only matching rows continue down the - pipeline. -

-
    -
  • - Field: which upstream field to compare. -
  • -
  • - Operator: how to compare. Available options:{" "} - equals, not equals, contains,{" "} - matches regex, does not match regex,{" "} - greater than, less than,{" "} - greater or equal, less or equal. -
  • -
  • - Value: what to compare against. Becomes a true/false - dropdown when filtering a boolean field. -
  • -
  • - Map target: only shown for map fields. Choose whether - to filter on the map's keys or its values. -
  • -
-
-
- -
-
- ---- - -### Aggregate - -
-
-

- Reduces multiple rows into one computed value per group. Usually placed - after a Group By or Time Group node. -

-
    -
  • - Function: how values inside each group are combined: -
      -
    • - count: number of rows in the group -
    • -
    • - sum: adds numeric values -
    • -
    • - avg: average of numeric values -
    • -
    • - min: smallest numeric value -
    • -
    • - max: largest numeric value -
    • -
    • - distinct: count of unique values -
    • -
    -
  • -
-
-
- -
-
- ---- - -### Group By - -
-
-

- Groups rows by one or more categorical fields. Usually paired with an{" "} - Aggregate node to compute per-group metrics (for example, - page views grouped by browser). -

-
    -
  • - Fields: the grouping dimensions. Rows that share the - same values across these fields end up in the same group. Add as many as - you need. -
  • -
  • - Multi-field mode: only shown when more than one field - is selected. -
      -
    • - combined: joins field values into a single composite - key (for example, Chrome / Germany as one group). -
    • -
    • - flat: keeps each field as its own dimension so the - chart can break down by either axis. -
    • -
    -
  • -
-
-
- -
-
- ---- - -### Time Group - -
-
-

- Groups rows into time-based buckets. This is the foundation of every - time-series chart. -

-
    -
  • - Bucket size: the interval each row rolls into:{" "} - Auto, Minute, Hour,{" "} - Day, Week, Month.{" "} - Auto picks a sensible size based on the chart's time range. -
  • -
  • - Missing buckets: what to do when a time period has no - data: -
      -
    • - Zero: insert a zero value so the line stays continuous. -
    • -
    • - None: leave the gap empty and the series breaks. -
    • -
    -
  • -
  • - Cumulative: carry each bucket's value into every later - bucket. Use this for running totals, such as total users or downloads so - far. -
  • -
-
-
- -
-
- ---- - -### Text Transform - -
-
-

- Rewrites string values before they are grouped, filtered, or displayed. - Useful for normalizing inconsistent text (for example, casing) or - extracting derived labels. -

-
    -
  • - Operation: which transformation to apply: -
      -
    • - lowercase / uppercase /{" "} - title case: change casing -
    • -
    • - trim: strip leading and trailing whitespace -
    • -
    • - append: add a fixed string to the end of each value -
    • -
    • - replace text: find an exact string and replace it -
    • -
    • - replace regex: match a regular expression and - substitute (use \1, \2, and so on for - capture groups) -
    • -
    • - length: replace each value with its character count -
    • -
    -
  • -
  • - Text to append: only for append. The - string added to every value. -
  • -
  • - Find / Pattern and Replace with: only - for replace text and replace regex. Leave the - replacement empty to delete matches. -
  • -
-
-
- -
-
- ---- - -### Formula - -
-
-

- Computes a derived numeric value from a custom expression. Each input - connection to the Formula node gets a letter (A,{" "} - B, C, and so on) in the order it was connected. - Use those letters as variables in the expression. -

-
    -
  • - Expression: the formula to evaluate, for example{" "} - A + B, A / B * 100, or{" "} - (A + B) / C. -
  • -
  • - Output name: name of the resulting field. Downstream - nodes and the chart legend use this label. -
  • -
  • - Precision: number of decimal places to round the result - to. Leave empty to keep full precision. -
  • -
-
-
- -
-
- ---- - -### Limit - -
-
-

- Caps the number of rows that flow through. Most useful after a{" "} - Group By when you only want the top N groups in a chart. -

-
    -
  • - Max rows: the maximum number of rows to keep. -
  • -
  • - Group rows over limit as Other: instead of dropping - rows beyond the limit, fold them into a single Other bucket - so totals still match. -
  • -
-
-
- -
-
- ---- - -### Max Age - -
-
-

- Limits the pipeline to events within a rolling window relative to now. - Combine with Min Age to look at a slice between two - points in the past. -

-
    -
  • - Look back at most: the size of the window. Pick a - number and a unit: ms, seconds,{" "} - minutes, hours, days. -
  • -
-
-
- -
-
- ---- - -### Min Age - -
-
-

- Drops events that are too recent. Useful for excluding the live tail of - data that has not fully settled yet, or for comparing past periods. -

-
    -
  • - Exclude newer than: events within this window before - the current time are removed. Uses the same units as{" "} - Max Age. -
  • -
-
-
- -
-
- ---- - -### Output - -
-
-

- The final node in every pipeline. This is what produces the chart result. - See{" "} - Output & Multi-Series{" "} - for how multiple Output nodes combine into tabs, multi-line charts, or - stacked bars. -

-
    -
  • - Output name (or Tab name on list - charts): label shown in the chart legend or as the tab header. -
  • -
  • - Icon set: only on list charts. Optional icons shown - next to each row. -
  • -
  • - Nest by: only on list and pie charts. Splits each row - into a nested hierarchy, either by another data field or by a custom - delimiter. -
  • -
  • - Delimiter: only when nesting by a custom pattern. The - character or string used to split values (for example, / to - split a URL path). -
  • -
-
-
- -
-
diff --git a/content/docs/platform/chart-editor/index.mdx b/content/docs/platform/chart-editor/index.mdx deleted file mode 100644 index 027b39e..0000000 --- a/content/docs/platform/chart-editor/index.mdx +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: Chart Editor -description: Build and configure charts using the visual flow editor -icon: ChartArea ---- - -import { Cards, Card } from "fumadocs-ui/components/card"; - -The Chart Editor is where you build charts in fastStats. Connect nodes on a canvas to choose your data, transform it, and decide how it shows up in the chart. - - - - Every node in the editor: Data Source, Filter, Aggregate, Group By, Time - Group, Formula, and more. - - - How tabs, multi-line charts, and stacked bars work when you add more than - one Output node. - - - -## How it works - -Every chart is a pipeline of nodes. Drag nodes onto the canvas and connect them from top to bottom: - -1. **Pick your data** with a Data Source node -2. **Shape it** using Filter, Group By, Aggregate, or other transformation nodes -3. **Display it** with one or more Output nodes - -How many Output nodes you use changes what the chart shows: - -| Output nodes | Result | -| ------------ | -------------------------------------------------------- | -| 1 | One series: a single line, bar group, or widget value | -| 2+ | Multiple series: extra lines, stacked bars, or list tabs | diff --git a/content/docs/platform/chart-editor/meta.json b/content/docs/platform/chart-editor/meta.json deleted file mode 100644 index b4a3f18..0000000 --- a/content/docs/platform/chart-editor/meta.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "title": "Chart Editor" -} diff --git a/content/docs/platform/chart-editor/output-nodes.mdx b/content/docs/platform/chart-editor/output-nodes.mdx deleted file mode 100644 index a8e45b8..0000000 --- a/content/docs/platform/chart-editor/output-nodes.mdx +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: Output & Multi-Series -description: How to create tabs, multi-line charts, and stacked bars using multiple Output nodes -icon: GitFork ---- - -import { ResultNodePreview } from "@/components/docs/node-preview"; -import { Callout } from "fumadocs-ui/components/callout"; - -The Output node is the last step in every pipeline. One Output gives you a simple chart. Add more Output nodes to build multi-line charts, stacked bars, or tabbed lists. - -
- -
- -## Output settings - -| Setting | Description | -| ----------- | ---------------------------------------------------------------------------------- | -| Output name | Label for this series in the legend (or tab name on list charts) | -| Icon set | Optional icons next to each row (list charts only) | -| Nest by | Split rows into nested sections by field or custom delimiter (list and pie charts) | -| Delimiter | Character or string used to split values when nesting by a custom pattern | - -The **output name** matters most. It shows up in the chart legend or as a tab title on list charts. Leave it blank on a single-output chart and it defaults to "Output". With multiple outputs, unnamed series are numbered automatically ("Output 1", "Output 2", and so on). - -## Multiple outputs - -When a flow has more than one Output node, each one runs as its own pipeline. The results are merged so the chart can show several series at once. - -### Ordering - -Output nodes are ordered by where they sit on the canvas. The leftmost Output becomes the first series, the next one becomes the second, and so on. - - - Place Output nodes left to right on the canvas to control series order. - - -## Multi-line charts - -To compare two metrics over time (for example, page views and unique visitors): - -1. Create two pipelines, each starting with a **Data Source** node -2. Add a **Time Group** node to each (use the same interval) -3. Add an **Aggregate** node to each (for example, `count` on one and `distinct` on the other) -4. End each pipeline with its own **Output** node -5. Give each one a name (for example, "Page Views" and "Unique Visitors") - -Both pipelines run together. Each time bucket gets both values as separate lines on the chart. - -## Stacked bar charts - -Stacked bars work like multi-line charts: use multiple Output nodes and set the chart type to **Bar**. The chart type decides whether series render as lines or stacked bars. - -1. Build two or more pipelines with **Group By** and **Aggregate** -2. End each with a named **Output** node -3. Set the chart type to **Bar** - -Series stack in the same order as your Output nodes on the canvas. - -## Tabbed lists - -On list charts, multiple Output nodes become **tabs** instead of overlapping series. Each Output is its own tab. - -1. Build a separate pipeline for each tab -2. Name each Output node with the tab label (for example, "Browsers" or "Countries") -3. Set the chart type to **List** - -Each output name becomes a tab header. Pipelines run independently, and each tab shows its own result set. - -## Tips - -- **Disconnected outputs are ignored.** If an Output node is not wired to anything, it will not appear in the chart. -- **Pipelines can be shared.** Multiple Output nodes can connect to the same upstream nodes, so you do not always need to duplicate the whole flow. -- **Widget charts use one pipeline only.** Extra Output nodes are ignored for widget chart types. diff --git a/content/docs/platform/error-tracking/meta.json b/content/docs/platform/error-tracking/meta.json deleted file mode 100644 index 3dd6010..0000000 --- a/content/docs/platform/error-tracking/meta.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "title": "Error Tracking" -} diff --git a/content/docs/platform/guide/meta.json b/content/docs/platform/guide/meta.json deleted file mode 100644 index 82f3195..0000000 --- a/content/docs/platform/guide/meta.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "title": "Guides" -} diff --git a/content/docs/platform/meta.json b/content/docs/platform/meta.json deleted file mode 100644 index 9d8a7b3..0000000 --- a/content/docs/platform/meta.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "root": true, - "title": "Platform", - "icon": "LayoutDashboard", - "pages": [ - "index", - "hotkeys", - "guide/embed", - "guide/badges", - "chart-editor", - "error-tracking", - "feature-flags", - "retention/index", - "web-vitals/index" - ] -} diff --git a/content/docs/web-analytics/configuration.mdx b/content/docs/web-analytics/configuration.mdx deleted file mode 100644 index 8695de9..0000000 --- a/content/docs/web-analytics/configuration.mdx +++ /dev/null @@ -1,118 +0,0 @@ ---- -title: Configuration -description: Every option you can pass to FastStats Web Analytics -icon: Settings ---- - -All packages share the same set of options. In React you pass them as props on -the `Analytics` component, in Nuxt you set them under the `faststats` key, and in -plain JavaScript you pass them to the `WebAnalytics` constructor. - -## Core Options - -| Option | Type | Default | Description | -| --------------------- | --------- | ------------------------------- | -------------------------------------------------------------- | -| `siteKey` | `string` | required | The project key that ties events to your FastStats project | -| `baseUrl` | `string` | `https://metrics.faststats.dev` | Where events, identify calls, vitals and replays are sent | -| `featureFlagsBaseUrl` | `string` | `https://flags.faststats.dev` | Where feature flag checks are sent | -| `debug` | `boolean` | `false` | Logs every action to the console | -| `autoTrack` | `boolean` | `true` | Starts tracking automatically. Set to `false` to start by hand | -| `trackHash` | `boolean` | `false` | Treats hash changes as page views for hash based routers | -| `cookieless` | `boolean` | `false` | Forces cookieless mode with no stored identifiers | - -## Error Tracking - -```ts -errorTracking: { - enabled: true, -} -``` - -| Field | Type | Default | Description | -| --------- | --------- | ------- | -------------------- | -| `enabled` | `boolean` | `false` | Turns the tracker on | - -Read more in [Error Tracking](/web-analytics/error-tracking). - -### Web Vitals - -```ts -webVitals: { - enabled: true, - attribution: false, -} -``` - -| Field | Type | Default | Description | -| ------------- | --------- | ------- | ------------------------------------------ | -| `enabled` | `boolean` | `false` | Turns the tracker on | -| `attribution` | `boolean` | `false` | Adds debug attribution data to each metric | - -Read more in [Web Vitals](/web-analytics/web-vitals). - -### Session Replays - -```ts -sessionReplays: { - enabled: true, -}, -replayOptions: { - flushInterval: 5_000, - maxEvents: 1000, - maxBatchSizeBytes: 512 * 1024, -} -``` - -| Field | Type | Default | Description | -| --------------------------------- | --------- | -------- | -------------------------------------------------------- | -| `enabled` | `boolean` | `false` | Turns the recorder on | -| `replayOptions.flushInterval` | `number` | `5000` | Flush interval in milliseconds | -| `replayOptions.maxEvents` | `number` | `1000` | Flush after this many buffered rrweb events | -| `replayOptions.maxBatchSizeBytes` | `number` | `524288` | Flush after the buffered event payload reaches this size | - -For masking and recording details see -[Session Replay](/web-analytics/session-replay). - -### Consent - -```ts -consent: { - mode: "granted", - pendingBehavior: "anonymous", -} -``` - -| Field | Type | Default | Description | -| ----------------- | ------------------------------------ | ------------- | ------------------------------------------------------------------- | -| `mode` | `"pending" \| "granted" \| "denied"` | `"granted"` | The current consent state | -| `pendingBehavior` | `"anonymous" \| "disabled"` | `"anonymous"` | Cookieless tracking while consent is pending, or no tracking at all | - -Read more in [Consent and Cookieless](/web-analytics/consent). - -## Manual Start - -When `autoTrack` is `false` the SDK does not begin until you call `start`. This -lets you wait for a cookie banner or any other gate. - -```ts -import { WebAnalytics } from "@faststats/web"; - -const analytics = new WebAnalytics({ - siteKey: "your_site_key", - autoTrack: false, -}); - -// once you are ready -analytics.start(); -``` - -## Disable Tracking on a Device - -The SDK checks `localStorage` for a flag before it sends anything. Set it to opt -a single browser out, which is useful for your own devices. - -```ts -localStorage.setItem("disable-faststats", "true"); -``` - -Remove the key to turn tracking back on. diff --git a/content/docs/web-analytics/consent.mdx b/content/docs/web-analytics/consent.mdx deleted file mode 100644 index 879fa02..0000000 --- a/content/docs/web-analytics/consent.mdx +++ /dev/null @@ -1,119 +0,0 @@ ---- -title: Consent and Cookieless -description: Run analytics with or without stored identifiers -icon: ShieldCheck ---- - - - This is no legal advice. Consult a lawyer for your specific use case. - - -The SDK supports cookieless mode and three consent states: `pending`, `granted`, -and `denied`. Switch modes at runtime with `setConsentMode`, `optIn`, or -`optOut`. - -## How Identifiers Work - -In the normal mode the SDK keeps an anonymous id in `localStorage` and a session -in storage so returning visits and sessions can be measured. In cookieless mode -no anonymous id is stored and events are sent without a user id, which means -visitors cannot be recognized across reloads. - -## Cookieless Mode - -Set `cookieless` to `true` to never store an identifier. - - - - -```tsx - -``` - - - - -```ts title="nuxt.config.ts" -faststats: { - siteKey: "your_site_key", - cookieless: true, -} -``` - - - - -```ts -new WebAnalytics({ siteKey: "your_site_key", cookieless: true }); -``` - - - - - -## Consent Modes - -When you use a consent banner, start in `pending` and update the mode once the -user decides. There are three modes. - -| Mode | Meaning | -| --------- | --------------------------------------------- | -| `pending` | The user has not chosen yet | -| `granted` | The user accepted, the SDK stores identifiers | -| `denied` | The user declined, the SDK runs cookieless | - -While the mode is `pending` the SDK runs cookieless by default, so you can still -count page views without storing anything. Set `pendingBehavior` to `"disabled"` -if you prefer to send nothing at all until consent. - -```ts -new WebAnalytics({ - siteKey: "your_site_key", - consent: { mode: "pending", pendingBehavior: "anonymous" }, -}); -``` - -## Update Consent at Runtime - -Call `optIn` or `optOut` from your banner buttons, or call `setConsentMode` for -full control. The SDK switches storage behavior right away and tells the replay -and other trackers about the change. - - - - -```tsx -import { optIn, optOut } from "@faststats/react"; - - - -``` - - - - -```ts -import { optIn, optOut, setConsentMode } from "@faststats/web"; - -optIn(); // same as setConsentMode("granted") -optOut(); // same as setConsentMode("denied") -setConsentMode("pending"); -``` - - - - - - - You can call `setConsentMode`, `optIn` or `optOut` before the instance has - started. The chosen mode is remembered and applied as soon as tracking begins. - - -## React Consent Prop - -In React you can also drive the mode through the `consent.mode` prop. When the -prop changes the component updates the running instance for you. - -```tsx - -``` diff --git a/content/docs/web-analytics/error-tracking.mdx b/content/docs/web-analytics/error-tracking.mdx deleted file mode 100644 index 0e9c413..0000000 --- a/content/docs/web-analytics/error-tracking.mdx +++ /dev/null @@ -1,143 +0,0 @@ ---- -title: Error Tracking -description: Capture client and server errors -icon: Bug ---- - -Browser errors are reported by the web SDK. Server errors in Nitro routes are -reported by `@faststats/nitro`. - -## Browser Errors - -Turn on `errorTracking.enabled` to capture uncaught errors and unhandled promise -rejections. The tracker batches them and drops noise from browser extensions -automatically. - - - - -```tsx - -``` - - - - -```ts title="nuxt.config.ts" -faststats: { - siteKey: "your_site_key", - errorTracking: { enabled: true }, -} -``` - - - - -```ts -new WebAnalytics({ - siteKey: "your_site_key", - errorTracking: { enabled: true }, -}); -``` - - - - - -Errors are grouped by their type and message so the same error from many -visitors does not flood your dashboard. Identical errors within a batch are -counted instead of repeated. - -## Report Errors by Hand - -When you catch an error yourself you can still send it with `reportError`. This -only works when `errorTracking.enabled` is `true`. - -```ts -import { reportError } from "@faststats/web"; - -try { - doRiskyThing(); -} catch (error) { - reportError(error as Error); -} -``` - -In Nuxt the module already hooks into the Vue error handler, so component errors -are reported without extra code. - -## Server Errors with Nitro - -If you run Nitro, either standalone or through Nuxt, you can report errors thrown -in server routes with `@faststats/nitro`. The package ships a plugin for Nitro -v2 and one for Nitro v3. - -`npm npm install @faststats/nitro ` - - - - -```ts title="nuxt.config.ts" -import { createRequire } from "node:module"; - -const require = createRequire(import.meta.url); -const errorTrackingPlugin = require.resolve("@faststats/nitro/v2"); - -export default defineNuxtConfig({ - nitro: { - plugins: [errorTrackingPlugin], - }, -}); -``` - - - - -```ts title="nitro.config.ts" -export default defineNitroConfig({ - plugins: ["@faststats/nitro/v2"], -}); -``` - - - - - -Use the `/v3` import instead when you are on Nitro v3. - -### Server Configuration - -The server plugin reads its settings from environment variables. The token is a -project token, not the browser site key, so keep it on the server only. - -| Variable | Default | Description | -| -------------------------- | ---------------------------------------- | ---------------------------------------- | -| `FASTSTATS_TOKEN` | required | Project token used to authorize reports | -| `FASTSTATS_ERROR_ENDPOINT` | `https://metrics.faststats.dev/v1/error` | Where server errors are sent | -| `FASTSTATS_BUILD_ID` | none | Tags errors with a build for source maps | -| `FASTSTATS_DEBUG` | `0` | Set to `1` to log reporter activity | - -```bash title=".env" -FASTSTATS_TOKEN=your_project_token -``` - -If `FASTSTATS_TOKEN` is not set the plugin stays silent and skips reporting, so -it is safe to leave installed in environments without a token. - -### Custom Configuration - -You can also create a plugin with explicit options instead of environment -variables. This lets you attach extra context to every error. - -```ts title="server/plugins/faststats.ts" -import { createFaststatsNitroPluginV2 } from "@faststats/nitro/v2"; - -export default createFaststatsNitroPluginV2({ - token: process.env.FASTSTATS_TOKEN, - getContext: ({ path }) => ({ route: path }), -}); -``` - -The reporter batches errors, retries failed sends and opens a short circuit -breaker after repeated failures so a broken endpoint never slows your server -down. diff --git a/content/docs/web-analytics/events.mdx b/content/docs/web-analytics/events.mdx deleted file mode 100644 index 576d70d..0000000 --- a/content/docs/web-analytics/events.mdx +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: Events -description: Automatic tracking and custom events -icon: MousePointerClick ---- - -The SDK sends `pageview`, `page_leave`, and `outbound_link` events -automatically. Use `trackEvent` for custom events. - -## Automatic Tracking - -Once the SDK starts it records these without any extra code. - -| Event | When it fires | -| --------------- | ------------------------------------------------------- | -| `pageview` | On the first load and on every client side route change | -| `page_leave` | When the page is hidden or the user navigates away | -| `outbound_link` | When a user clicks a link that points to another host | - -Each page view carries the path, full URL, referrer, page title and any UTM -parameters from the query string. The `page_leave` event also includes the time -spent on the page, the deepest scroll depth in percent and the session duration. - -Single page navigation is detected through the History API, so `pushState`, -`replaceState` and the back and forward buttons all create new page views. Hash -based routers need `trackHash` turned on. See -[Configuration](/web-analytics/configuration). - -## Custom Events - -Call `trackEvent` with a name and an optional object of properties. Use clear, -lower case names so they read well in your dashboard. - - - - -```tsx -import { trackEvent } from "@faststats/react"; - -trackEvent("signup", { plan: "pro", source: "hero" }); -``` - - - - -```ts -import { trackEvent } from "@faststats/web"; - -trackEvent("signup", { plan: "pro", source: "hero" }); -``` - - - - - -The event name is trimmed and empty names are ignored, so a stray space never -creates a broken event. - -## Properties and Dimensions - -You can attach any JSON friendly values as properties. A few keys are treated as -known dimensions and are stored as first class fields instead of free form -properties. These are `browser`, `browser_version`, `device`, `os`, -`os_version`, `referrer`, `utm_source`, `utm_medium`, `utm_campaign`, -`utm_term`, `utm_content`, `title`, `page` and `url`. - -Everything else you pass lands in the properties bag. - -```ts -trackEvent("video_play", { - // stored as a dimension - page: "/courses/intro", - // stored as custom properties - video_id: "abc123", - position_seconds: 12, -}); -``` - -## Good Practices - -Keep a small, stable set of event names and put varying details in properties. -Use one event name with a `step` property instead of separate names per step. - -```ts -trackEvent("checkout", { step: "cart" }); -trackEvent("checkout", { step: "shipping" }); -trackEvent("checkout", { step: "payment" }); -``` diff --git a/content/docs/web-analytics/feature-flags.mdx b/content/docs/web-analytics/feature-flags.mdx deleted file mode 100644 index 3ce6549..0000000 --- a/content/docs/web-analytics/feature-flags.mdx +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: Feature Flags -description: Evaluate FastStats feature flags in the browser -icon: Flag ---- - - - Feature Flags are still in **Private Preview**. Please contact staff if you - would like to try them out. - - -Evaluate a flag for the current visitor with `useFlag` in React or -`checkFeatureFlag` on the SDK instance. The response includes the value and, -for multivariate flags, the chosen variant. - -## React Hook - -The `useFlag` hook is the simplest way to read a flag in React. It returns the -value together with loading and error state, and a `refetch` helper. - -```tsx -"use client"; - -import { useFlag } from "@faststats/react"; - -export function NewDashboard() { - const { value, isLoading } = useFlag("new_dashboard"); - - if (isLoading) return ; - if (value === "true") return ; - return ; -} -``` - -The hook needs an active `Analytics` component on the page. It uses the current -visitor identity to evaluate the flag. - -### Hook Options - -```tsx -const { value, error, refetch } = useFlag("pricing_test", { - attributes: { country: "DE", plan: "pro" }, - externalId: "user_123", - skip: false, -}); -``` - -| Option | Type | Description | -| ------------ | ------------------------- | --------------------------------------------------- | -| `attributes` | `Record` | Extra context used by the targeting rules | -| `externalId` | `string` | Evaluate for a specific user instead of the visitor | -| `skip` | `boolean` | Skip the request, for example until you are ready | - -### Result Shape - -| Field | Type | Description | -| -------------- | --------------- | ---------------------------------------------- | -| `value` | `string` | The flag value, defaults to `"false"` | -| `variantKey` | `string` | The chosen variant key when the flag is a test | -| `variantValue` | `string` | The value attached to that variant | -| `isLoading` | `boolean` | True while the request is in flight | -| `error` | `Error \| null` | Set when the evaluation failed | -| `refetch` | `() => void` | Run the evaluation again | - -## Outside React - -When you do not use React, evaluate a flag through the instance. - -```ts -import { getInstance } from "@faststats/web"; - -const result = await getInstance()?.checkFeatureFlag("new_dashboard", { - country: "DE", -}); - -if (result?.value === "true") { - // turn the feature on -} -``` - -## Values are Strings - -Flag values come back as strings, so a boolean flag returns `"true"` or -`"false"`. Compare against the string form rather than a real boolean. - -```ts -if (value === "true") { - // correct -} -``` - -## Custom Flags Endpoint - -Flag checks go to `https://flags.faststats.dev` by default. To send them through -your own domain, set `featureFlagsBaseUrl`. diff --git a/content/docs/web-analytics/identify.mdx b/content/docs/web-analytics/identify.mdx deleted file mode 100644 index a0a2d92..0000000 --- a/content/docs/web-analytics/identify.mdx +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: Identify Users -description: Attach a known identity to a visitor -icon: UserCheck ---- - -Call `identify` after sign-in to link the anonymous visitor id to an external -user id and profile fields. - -## Identify a User - -Pass a stable external id and an email. The external id should be the same value -your own system uses for that user, such as a database id. - - - - -```tsx -import { identify } from "@faststats/react"; - -await identify("user_123", "ada@example.com", { - name: "Ada Lovelace", - traits: { plan: "pro" }, -}); -``` - - - - -```ts -import { identify } from "@faststats/web"; - -await identify("user_123", "ada@example.com", { - name: "Ada Lovelace", - traits: { plan: "pro" }, -}); -``` - - - - - -The third argument is optional and accepts a few profile fields. - -| Field | Type | Description | -| ----------- | ------------------------- | -------------------------------------------- | -| `name` | `string` | The display name of the user | -| `phone` | `string` | A phone number | -| `avatarUrl` | `string` | A link to an avatar image | -| `traits` | `Record` | Any extra attributes you want on the profile | - -## What identify Returns - -`identify` returns a promise that resolves to a boolean. It is `false` when the -call was skipped, for example when the external id or email is empty or when the -visitor is in cookieless mode, and `true` once the call is on its way. - -```ts -const ok = await identify("user_123", "ada@example.com"); -if (!ok) { - // the visitor is cookieless or the input was empty -} -``` - - - Identify is disabled in cookieless mode because there is no stored identifier - to link a profile to. See [Consent and Cookieless](/web-analytics/consent). - - -## Log Out - -When a user signs out, call `logout` to start a fresh anonymous session so their -next activity is not tied to the old profile. - -```ts -import { logout } from "@faststats/web"; - -logout(); -``` - -By default this also resets the anonymous identifier. Pass `false` if you want -to keep the same anonymous id and only rotate the session. - -```ts -logout(false); -``` diff --git a/content/docs/web-analytics/index.mdx b/content/docs/web-analytics/index.mdx deleted file mode 100644 index 0490de6..0000000 --- a/content/docs/web-analytics/index.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Installation -description: Add FastStats Web Analytics to your website or web app -icon: Download ---- - -Web Analytics is not yet publicly available - -Install one of the packages below and pass your site key. - -## Choose a Package - -| Package | Use it when | Guide | -| ------------------ | ----------------------------------------------- | --------------------------------------- | -| `@faststats/react` | You build with React or Next.js | [React](/web-analytics/react) | -| `@faststats/nuxt` | You build with Nuxt | [Nuxt](/web-analytics/nuxt) | -| `@faststats/web` | You use plain JavaScript or any other framework | [JavaScript](/web-analytics/javascript) | - -## Install - - - `npm npm install @faststats/react` - `npm npm install @faststats/nuxt` - `npm npm install @faststats/web` - - -## Get Your Site Key - -Every request is tied to a site key. You can find it in your FastStats project -settings. The key is safe to ship in the browser because it only allows writing -events for that one project. - -## Next Steps - -- [Configuration](/web-analytics/configuration): all SDK options -- [Events](/web-analytics/events): automatic and custom tracking -- [Consent and Cookieless](/web-analytics/consent): cookieless mode and consent states diff --git a/content/docs/web-analytics/javascript.mdx b/content/docs/web-analytics/javascript.mdx deleted file mode 100644 index 7fdc584..0000000 --- a/content/docs/web-analytics/javascript.mdx +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: JavaScript -description: Add FastStats Web Analytics with the plain browser SDK -icon: Braces ---- - -The `@faststats/web` package is the core browser SDK. The React and Nuxt -packages are built on top of it. Use it directly when you work with plain -JavaScript, with a framework that has no dedicated package yet, or when you want -full control over the lifecycle. - -## Install - -```npm - npm install @faststats/web -``` - -## Create an Instance - -Create one `WebAnalytics` instance as early as possible. It starts tracking -automatically once the page is ready. - -```ts title="analytics.ts" -import { WebAnalytics } from "@faststats/web"; - -new WebAnalytics({ - siteKey: "your_site_key", -}); -``` - -That single line already records page views, page leaves, sessions, outbound -link clicks and scroll depth. To enable more features pass extra options. - -```ts -new WebAnalytics({ - siteKey: "your_site_key", - errorTracking: { enabled: true }, - webVitals: { enabled: true }, - sessionReplays: { enabled: true }, -}); -``` - -## Track Custom Events - -The package exports functions that talk to the active instance. You can call -them from any module without holding a reference yourself. - -```ts -import { trackEvent } from "@faststats/web"; - -document.querySelector("#buy")?.addEventListener("click", () => { - trackEvent("purchase", { plan: "pro", price: 29 }); -}); -``` - -## Single Page Apps - -The SDK patches `pushState` and `replaceState` and listens for `popstate`, so -client side route changes are tracked as new page views with no extra work. If -your router uses the hash for routing, turn on `trackHash`. - -```ts -new WebAnalytics({ - siteKey: "your_site_key", - trackHash: true, -}); -``` - -## Reach the Instance Later - -`getInstance` returns the active instance once it has started. This is handy for -debugging in the console or for advanced calls such as feature flag checks. - -```ts -import { getInstance } from "@faststats/web"; - -const analytics = getInstance(); -analytics?.getSessionId(); -``` - -## Clean Up - -If you manage the lifecycle yourself, call `destroy` to remove all listeners and -stop the child trackers. This is mostly useful in tests or in micro frontends -that mount and unmount whole apps. - -```ts -const analytics = new WebAnalytics({ siteKey: "your_site_key" }); -// later -analytics.destroy(); -``` diff --git a/content/docs/web-analytics/meta.json b/content/docs/web-analytics/meta.json deleted file mode 100644 index 27b8929..0000000 --- a/content/docs/web-analytics/meta.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "root": true, - "title": "Web Analytics", - "icon": "Globe", - "pages": [ - "---Getting Started---", - "index", - "react", - "nuxt", - "javascript", - "---Usage---", - "configuration", - "events", - "identify", - "consent", - "---Features---", - "error-tracking", - "sourcemaps", - "web-vitals", - "session-replay", - "feature-flags" - ] -} diff --git a/content/docs/web-analytics/nuxt.mdx b/content/docs/web-analytics/nuxt.mdx deleted file mode 100644 index 1cc7ca6..0000000 --- a/content/docs/web-analytics/nuxt.mdx +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: Nuxt -description: Add FastStats Web Analytics to a Nuxt app -icon: Mountain ---- - -The `@faststats/nuxt` module sets up the browser SDK for you. It reads its -configuration from your `nuxt.config`, starts tracking on the client and wires -the SDK into the Vue error handler so unhandled component errors are reported. - -## Install - -```npm - npm install @faststats/nuxt -``` - -## Register the Module - -Add the module and your settings under the `faststats` key. - -```ts title="nuxt.config.ts" -export default defineNuxtConfig({ - modules: ["@faststats/nuxt"], - faststats: { - siteKey: "your_site_key", - errorTracking: { enabled: true }, - webVitals: { enabled: true }, - sessionReplays: { enabled: true }, - }, -}); -``` - -The module accepts every option from the SDK. See -[Configuration](/web-analytics/configuration) for the full list. - -## Use Environment Variables - -Anything under `faststats` lives in the public runtime config, so you can set it -through environment variables. The site key maps to -`NUXT_PUBLIC_FASTSTATS_SITE_KEY`. - -```bash title=".env" -NUXT_PUBLIC_FASTSTATS_SITE_KEY=your_site_key -``` - -If the site key is missing the module logs a warning during build so you notice -early. - -## Track Custom Events - -Import the functions from `@faststats/web` anywhere on the client. - -```vue title="pages/pricing.vue" - - - -``` - -## Track Server Errors - -Nuxt runs on Nitro, so you can report errors thrown in server routes with the -`@faststats/nitro` plugin. Install it and register the plugin that matches your -Nitro version. - -`npm npm install @faststats/nitro ` - -```ts title="nuxt.config.ts" -import { createRequire } from "node:module"; - -const require = createRequire(import.meta.url); -const errorTrackingPlugin = require.resolve("@faststats/nitro/v2"); - -export default defineNuxtConfig({ - modules: ["@faststats/nuxt"], - faststats: { - siteKey: "your_site_key", - }, - nitro: { - plugins: [errorTrackingPlugin], - }, -}); -``` - -The server plugin needs its own project token through `FASTSTATS_TOKEN`. Read -the server section in [Error Tracking](/web-analytics/error-tracking) for the -details. diff --git a/content/docs/web-analytics/react.mdx b/content/docs/web-analytics/react.mdx deleted file mode 100644 index 33bb14f..0000000 --- a/content/docs/web-analytics/react.mdx +++ /dev/null @@ -1,150 +0,0 @@ ---- -title: React and Next.js -description: Add FastStats Web Analytics to a React or Next.js app -icon: Atom ---- - -The `@faststats/react` package wraps the browser SDK in a single component and a -set of hooks. It works with any React app and with the Next.js App Router. - -## Install - -```npm - npm install @faststats/react -``` - -## Add the Analytics Component - -Render the `Analytics` component once, near the root of your app. It starts -tracking when it mounts and cleans up when it unmounts. You never have to create -an instance by hand. - - - - -```tsx title="app/layout.tsx" -import { Analytics } from "@faststats/react"; - -export default function RootLayout({ - children, -}: { - children: React.ReactNode; -}) { - return ( - - - - {children} - - - ); -} -``` - - - - -```tsx title="src/main.tsx" -import { Analytics } from "@faststats/react"; -import { StrictMode } from "react"; -import { createRoot } from "react-dom/client"; -import App from "./App"; - -createRoot(document.getElementById("root")!).render( - - - - , -); -``` - - - - - -The component accepts every option from the SDK. Here is a fuller example that -turns on a few extra features. - -```tsx title="app/layout.tsx" - -``` - -See [Configuration](/web-analytics/configuration) for the full list. - -## Track Custom Events - -You can call the plain functions from anywhere, or use the hooks inside -components. Both reach the same active instance. - -```tsx title="components/buy-button.tsx" -"use client"; - -import { trackEvent } from "@faststats/react"; - -export function BuyButton() { - return ( - - ); -} -``` - -The same call through a hook looks like this. - -```tsx -"use client"; - -import { useTrack } from "@faststats/react"; - -export function BuyButton() { - const track = useTrack(); - return ( - - ); -} -``` - -`useEvent` builds a stable handler when the name and properties do not change. - -```tsx -const onSignup = useEvent("signup", { source: "hero" }); -return ( - -); -``` - -## Available Hooks - -| Hook | Returns | -| ---------------- | ------------------------------------------------- | -| `useTrack` | The `trackEvent` function | -| `useEvent` | A memoized handler for one named event | -| `useIdentify` | The `identify` function | -| `useLogout` | The `logout` function | -| `useConsentMode` | The `setConsentMode` function | -| `useOptIn` | The `optIn` function | -| `useOptOut` | The `optOut` function | -| `useFlag` | A feature flag value with loading and error state | - -Read more in [Events](/web-analytics/events), -[Identify](/web-analytics/identify) and -[Feature Flags](/web-analytics/feature-flags). - -## Server Side Routes - -The React package only runs in the browser. If you also want to capture errors -thrown in Next.js route handlers or server functions, read the server section in -[Error Tracking](/web-analytics/error-tracking). diff --git a/content/docs/web-analytics/session-replay.mdx b/content/docs/web-analytics/session-replay.mdx deleted file mode 100644 index 615ccda..0000000 --- a/content/docs/web-analytics/session-replay.mdx +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: Session Replay -description: Record DOM sessions with rrweb -icon: Video ---- - -Session replay records DOM mutations and user interactions using -[rrweb](https://www.rrweb.io/). Recordings are serialized events, not video. - -## Enable Replay - -Turn it on with the object form. - - - - -```tsx - -``` - - - - -```ts title="nuxt.config.ts" -faststats: { - siteKey: "your_site_key", - sessionReplays: { enabled: true }, -} -``` - - - - -```ts -new WebAnalytics({ - siteKey: "your_site_key", - sessionReplays: { enabled: true }, -}); -``` - - - - - -## Batching - -Replay events are buffered in the browser and uploaded in chunks. The defaults -prefer fewer, larger chunks so a normal one-minute replay should usually create -single-digit storage objects instead of dozens. - -```ts -sessionReplays: { enabled: true }, -replayOptions: { - flushInterval: 5_000, - maxEvents: 1000, - maxBatchSizeBytes: 512 * 1024, -} -``` - -The collector coalesces these small reliable browser flushes into fewer storage -objects. The recorder still flushes early on page hide, session rotation, -periodic full snapshots, and when a batch reaches the byte limit. - -## Privacy and Masking - -The recorder masks inputs by default and lets you hide elements with -`replayOptions`. - -```ts -new WebAnalytics({ - siteKey: "your_site_key", - sessionReplays: { enabled: true }, - replayOptions: { - maskAllInputs: true, - maskTextSelector: ".sensitive", - blockSelector: ".no-record", - }, -}); -``` - -| Option | Type | Description | -| ------------------ | --------- | ------------------------------------------------- | -| `maskAllInputs` | `boolean` | Masks the value of every input field | -| `maskTextSelector` | `string` | Masks text inside elements matching this selector | -| `maskTextClass` | `string` | Masks text inside elements with this class | -| `blockSelector` | `string` | Skips recording elements matching this selector | -| `blockClass` | `string` | Skips recording elements with this class | -| `recordConsole` | `boolean` | Records console output during the session | - -Any element you mark with the block selector is replaced with a placeholder, so -its content never leaves the browser. - -## Cookieless Behavior - -Replay follows your consent setup. In cookieless or denied mode the recorder -stops and clears any buffered events, so nothing is recorded until consent is -granted. See [Consent and Cookieless](/web-analytics/consent). diff --git a/content/docs/web-analytics/sourcemaps.mdx b/content/docs/web-analytics/sourcemaps.mdx deleted file mode 100644 index 12f2371..0000000 --- a/content/docs/web-analytics/sourcemaps.mdx +++ /dev/null @@ -1,241 +0,0 @@ ---- -title: Sourcemaps -description: Upload JavaScript sourcemaps so FastStats can show readable stack traces. -icon: FileBracesCorner ---- - -FastStats can turn minified browser stack traces back into the original file, -line and column when you upload the sourcemaps from the same build. - -The easiest way to do this is with `@faststats/sourcemap-uploader-plugin`. The -plugin runs during your production build, uploads every `.map` file it finds and -adds the build ID to your JavaScript bundle. The FastStats web SDK reads that -build ID when it reports an error, so FastStats can choose the matching -sourcemap. - -## Install the plugin - -Install the package in the app that builds your frontend. - -```npm -npm install --save-dev @faststats/sourcemap-uploader-plugin -``` - -You also need a sourcemap upload key from your FastStats project settings. Store -it as a secret in CI and pass it to the plugin with `authToken`. - -```bash title=".env" -FASTSTATS_SOURCEMAP_KEY=your_sourcemap_upload_key -``` - -## Add it to your bundler - -Turn on sourcemap output in your bundler, then add the FastStats plugin. The -default upload endpoint is `https://sourcemaps.faststats.dev/v0/upload`, so most -projects only need to pass `authToken`. - - - - -```ts title="vite.config.ts" -import { defineConfig } from "vite"; -import sourcemapsPlugin from "@faststats/sourcemap-uploader-plugin/vite"; - -export default defineConfig({ - build: { - sourcemap: true, - }, - plugins: [ - sourcemapsPlugin({ - authToken: process.env.FASTSTATS_SOURCEMAP_KEY, - }), - ], -}); -``` - - - - -```ts title="rollup.config.ts" -import sourcemapsPlugin from "@faststats/sourcemap-uploader-plugin/rollup"; - -export default { - input: "src/index.ts", - output: { - dir: "dist", - format: "es", - sourcemap: true, - }, - plugins: [ - sourcemapsPlugin({ - authToken: process.env.FASTSTATS_SOURCEMAP_KEY, - }), - ], -}; -``` - - - - -```ts title="webpack.config.ts" -import sourcemapsPlugin from "@faststats/sourcemap-uploader-plugin/webpack"; - -export default { - devtool: "source-map", - plugins: [ - sourcemapsPlugin({ - authToken: process.env.FASTSTATS_SOURCEMAP_KEY, - }), - ], -}; -``` - - - - -```ts title="rspack.config.ts" -import sourcemapsPlugin from "@faststats/sourcemap-uploader-plugin/rspack"; - -export default { - devtool: "source-map", - plugins: [ - sourcemapsPlugin({ - authToken: process.env.FASTSTATS_SOURCEMAP_KEY, - }), - ], -}; -``` - - - - -```ts title="build.ts" -import { build } from "esbuild"; -import sourcemapsPlugin from "@faststats/sourcemap-uploader-plugin/esbuild"; - -await build({ - entryPoints: ["src/index.ts"], - bundle: true, - sourcemap: true, - outfile: "dist/app.js", - plugins: [ - sourcemapsPlugin({ - authToken: process.env.FASTSTATS_SOURCEMAP_KEY, - }), - ], -}); -``` - - - - -The package also exports `rolldown`, `farm`, `bun` and `unloader` adapters. Use -the adapter that matches your bundler and keep sourcemap output enabled. - -## Recommended production setup - -Run the upload as part of the same CI job that builds and deploys your frontend. -Keep the upload key in your CI secrets. - -```yaml title="GitHub Actions" -name: Build - -on: - push: - branches: - - main - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-node@v4 - with: - node-version: 22 - - - run: npm ci - - run: npm run build - env: - FASTSTATS_SOURCEMAP_KEY: ${{ secrets.FASTSTATS_SOURCEMAP_KEY }} -``` - -If your public site does not need to serve sourcemaps, set -`deleteAfterUpload: true`. The plugin deletes local `.map` files only after a -successful upload. - -```ts -sourcemapsPlugin({ - authToken: process.env.FASTSTATS_SOURCEMAP_KEY, - deleteAfterUpload: true, -}); -``` - -## Build IDs - -Every upload has a `buildId`. The browser error reporter sends the same build ID -with each error, which is how FastStats finds the right sourcemap. - -By default the plugin uses the current git commit hash. If git is not available, -it creates a random ID for that build. You can also set the ID yourself. - -```ts -sourcemapsPlugin({ - authToken: process.env.FASTSTATS_SOURCEMAP_KEY, - buildId: process.env.GITHUB_SHA, -}); -``` - -## Options - -`authToken` is the bearer token used to upload sourcemaps. You should almost -always set it from an environment variable. - -`endpoint` changes where sourcemaps are uploaded. Use this only if you are using -a self hosted sourcemap service. - -`buildId` sets the build ID manually. If you leave it empty, the plugin uses the -current git commit hash when it can. - -`deleteAfterUpload` removes `.map` files after a successful upload. - -`failOnError` controls whether a failed upload fails the build. It is `true` by -default. - -`enabled` can turn the plugin on or off. It accepts a boolean or a function that -receives the bundler name. - -`maxUploadBodyBytes` controls the largest upload request body. The default is 50 -MB. Larger sourcemap sets are split into multiple upload requests. - -`globalKey` changes the runtime global used for build metadata. The default is -`__SOURCEMAPS_BUILD__`. - -`onUploadSuccess` and `onUploadError` let you run custom code after an upload -succeeds or fails. - -## What the plugin uploads - -The plugin sends JSON to `/v0/upload` with the mapping type, build ID, upload -time and sourcemap files. - -```json -{ - "type": "javascript", - "buildId": "build-123", - "uploadedAt": "2026-04-01T12:00:00.000Z", - "files": [ - { - "fileName": "assets/app.js.map", - "content": "{...}" - } - ] -} -``` - -The request uses bearer auth with your sourcemap upload key. - -```txt -Authorization: Bearer -``` diff --git a/content/docs/web-analytics/web-vitals.mdx b/content/docs/web-analytics/web-vitals.mdx deleted file mode 100644 index c771de5..0000000 --- a/content/docs/web-analytics/web-vitals.mdx +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: Web Vitals -description: Report Core Web Vitals from the browser SDK -icon: Gauge ---- - -Set `webVitals.enabled` to report LCP, CLS, INP, FCP, and TTFB from visitor -sessions. - -## Enable Web Vitals - -Turn the feature on with the object form so you can also set attribution. - - - - -```tsx - -``` - - - - -```ts title="nuxt.config.ts" -faststats: { - siteKey: "your_site_key", - webVitals: { enabled: true }, -} -``` - - - - -```ts -new WebAnalytics({ - siteKey: "your_site_key", - webVitals: { enabled: true }, -}); -``` - - - - - -## Collected Metrics - -The tracker reports the standard set of Core Web Vitals. - -| Metric | Name | -| ------ | ------------------------- | -| `LCP` | Largest Contentful Paint | -| `CLS` | Cumulative Layout Shift | -| `INP` | Interaction to Next Paint | -| `FCP` | First Contentful Paint | -| `TTFB` | Time to First Byte | - -Each metric is sent with its value, an id, a rating and the navigation type. -Metrics are flushed when the page is hidden and when the route changes in a -single page app. - -## Attribution - -Turn on `attribution` to include extra debugging data that points to the element -or event responsible for a metric. This payload is larger, so leave it off -unless you are chasing a specific issue. - -```ts -webVitals: { - enabled: true, - attribution: true, -} -``` diff --git a/ec.config.mjs b/ec.config.mjs new file mode 100644 index 0000000..6a6e8d8 --- /dev/null +++ b/ec.config.mjs @@ -0,0 +1,14 @@ +import { defineEcConfig } from '@astrojs/starlight/expressive-code'; +import { transformerColorizedBrackets } from '@shikijs/colorized-brackets'; + +export default defineEcConfig({ + shiki: { + transformers: [transformerColorizedBrackets()], + }, + themes: ['dark-plus', 'light-plus'], + styleOverrides: { + frames: { + editorActiveTabIndicatorBottomColor: 'var(--sl-color-accent)', + } + }, +}); diff --git a/next.config.mjs b/next.config.mjs deleted file mode 100644 index aeb8ad5..0000000 --- a/next.config.mjs +++ /dev/null @@ -1,84 +0,0 @@ -import path from "node:path"; -import { fileURLToPath } from "node:url"; -import { createMDX } from "fumadocs-mdx/next"; - -const withMDX = createMDX(); -const __dirname = path.dirname(fileURLToPath(import.meta.url)); - -/** @type {import('next').NextConfig} */ -const config = { - output: "standalone", - serverExternalPackages: ["@takumi-rs/core"], - reactStrictMode: true, - webpack(config) { - config.resolve.alias = { - ...config.resolve.alias, - "@": path.join(__dirname, "src"), - }; - return config; - }, - async rewrites() { - return [ - { - source: "/:path*.md", - destination: "/llms.mdx/docs/:path*", - }, - ]; - }, - async redirects() { - return [ - { - source: "/", - destination: "/platform", - permanent: false, - }, - { - source: "/guide/:path*", - destination: "/platform/guide/:path*", - permanent: true, - }, - { - source: "/chart-editor/:path*", - destination: "/platform/chart-editor/:path*", - permanent: true, - }, - { - source: "/error-tracking/:path*", - destination: "/platform/error-tracking/:path*", - permanent: true, - }, - { - source: "/retention", - destination: "/platform/retention", - permanent: true, - }, - { - source: "/web-vitals", - destination: "/platform/web-vitals", - permanent: true, - }, - { - source: "/web", - destination: "/web-analytics", - permanent: true, - }, - { - source: "/api/search", - destination: "/docs-search", - permanent: true, - }, - { - source: "/openapi", - destination: "/api", - permanent: true, - }, - { - source: "/openapi/:path*", - destination: "/api/:path*", - permanent: true, - }, - ]; - }, -}; - -export default withMDX(config); diff --git a/package.json b/package.json index 0cc0341..f6a528c 100644 --- a/package.json +++ b/package.json @@ -1,44 +1,21 @@ { - "name": "docs", - "version": "0.0.0", - "private": true, - "scripts": { - "build": "next build", - "dev": "next dev -p 3001", - "format": "oxfmt && oxlint --fix", - "format:check": "oxfmt --check", - "lint": "oxlint", - "start": "next start", - "typecheck": "fumadocs-mdx && next typegen && tsgo --noEmit", - "postinstall": "fumadocs-mdx" - }, - "dependencies": { - "@faststats/react": "0.5.0", - "@fontsource-variable/geist": "^5.2.8", - "@fontsource-variable/geist-mono": "^5.2.7", - "@takumi-rs/image-response": "^1.1.2", - "cnfast": "0.0.8", - "fumadocs-core": "16.10.7", - "fumadocs-mdx": "15.0.13", - "fumadocs-openapi": "11.0.6", - "fumadocs-ui": "16.10.7", - "lucide-react": "1.23.0", - "next": "16.2.10", - "react": "19.2.7", - "react-dom": "19.2.7" - }, - "devDependencies": { - "@tailwindcss/postcss": "4.3.2", - "@types/mdx": "^2.0.13", - "@types/node": "^26.0.0", - "@types/react": "^19.2.17", - "@types/react-dom": "^19.2.3", - "@typescript/native-preview": "^7.0.0-dev.20260627.2", - "oxfmt": "0.57.0", - "oxlint": "1.72.0", - "postcss": "^8.5.13", - "tailwindcss": "^4.3.0", - "typescript": "rc" - }, - "packageManager": "bun@1.3.14" -} + "name": "docs", + "type": "module", + "version": "0.0.1", + "scripts": { + "dev": "astro dev", + "start": "astro dev", + "build": "astro build", + "preview": "astro preview", + "astro": "astro" + }, + "dependencies": { + "@astrojs/starlight": "^0.41.3", + "@shikijs/colorized-brackets": "^4.3.1", + "@types/node": "^26.1.0", + "astro": "^7.0.2", + "sharp": "^0.34.5", + "starlight-sidebar-topics": "^0.8.0", + "typescript": "^6.0.3" + } +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..4198528 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,4406 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@astrojs/starlight': + specifier: ^0.41.3 + version: 0.41.3(@astrojs/markdown-remark@7.2.1)(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0))(typescript@6.0.3) + '@shikijs/colorized-brackets': + specifier: ^4.3.1 + version: 4.3.1 + '@types/node': + specifier: ^26.1.0 + version: 26.1.0 + astro: + specifier: ^7.0.2 + version: 7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0) + sharp: + specifier: ^0.34.5 + version: 0.34.5 + starlight-sidebar-topics: + specifier: ^0.8.0 + version: 0.8.0(@astrojs/starlight@0.41.3(@astrojs/markdown-remark@7.2.1)(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0))(typescript@6.0.3)) + typescript: + specifier: ^6.0.3 + version: 6.0.3 + +packages: + + '@astrojs/compiler-binding-darwin-arm64@0.3.0': + resolution: {integrity: sha512-3n0uu+uJpnCq8b4JFi3uGDsIisAvHctxSmH+cIO9Gbei1H1Y1QXaYboXyiWJugUmprr3OEYP7+LdodzpVFzLMQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@astrojs/compiler-binding-darwin-x64@0.3.0': + resolution: {integrity: sha512-scxNGKjOBydMo1QR4LtK0FMgh7ubQomJDv953nz2msQFkPKke/0FpPv/cQM0T/kuZdReZQFU8Oz3iOrP/6WHEg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@astrojs/compiler-binding-linux-arm64-gnu@0.3.0': + resolution: {integrity: sha512-NZrWLolVUANmrnl0zrFK/Sx5Sock1gEUT49ALfMTTCA5Ya2ec/BoJXMIg4KgE+wZcrdXJ8e+WyEhM7YLk/FJkA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@astrojs/compiler-binding-linux-arm64-musl@0.3.0': + resolution: {integrity: sha512-PjwRmKgMFDsFhg82g0poXlIY8Qn3fMA3hXjaR0coJWJzTJsRH9ATU0j2ocigjtU1h3vL/yR7yLUxGj/lTCq73g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@astrojs/compiler-binding-linux-x64-gnu@0.3.0': + resolution: {integrity: sha512-Dr69VJYlnSfyL8gzELW6S4mE41P7TDPn1IKjwMnjdZ7+dxgJI50oMLFSk1LVe26bHmWB3ktuh8fDVK1THI9e9A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@astrojs/compiler-binding-linux-x64-musl@0.3.0': + resolution: {integrity: sha512-AEt+bRw8PfImCcyRH1lpXVB8CdmQ1K/wPo5u99iec4/U/XdNvQZ715YVuNzIJpbJXelgQeZ5H2+Ea7XwRyWY5g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@astrojs/compiler-binding-wasm32-wasi@0.3.0': + resolution: {integrity: sha512-U80tA1j8V6LjhiTZzVCtG4E8hrNVVNXDGV5fCgJ94q8FU9CPH+XwdDDhLzBybfWhKfyItXmQiZNRPTiPCYTpVg==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@astrojs/compiler-binding-win32-arm64-msvc@0.3.0': + resolution: {integrity: sha512-CpY1RII2r1XMpOUVD1VR/F2wtuRsiOCkFULS10Khyj8/DFZMtxVuUCAWGw+CW2Ka0h6eP3Xc1CA+glFlvXMPxA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@astrojs/compiler-binding-win32-x64-msvc@0.3.0': + resolution: {integrity: sha512-qmFbs769oeeGrRebAnCW7aBk8m71vf85W/dX/jddfx5Z06/w0wf7TZCfJPOX1Fld2t+4N+iXzfGEJG+zJQ+bzg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@astrojs/compiler-binding@0.3.0': + resolution: {integrity: sha512-zlsOT5COD9hRwplJCgQhS21unxON5AKirf0vgt1ijXwuseYIaZdm2ZOpF8fsz+DY9EyXx+I/ukxtg7uoBep68A==} + engines: {node: ^20.19.0 || >=22.12.0} + + '@astrojs/compiler-rs@0.3.0': + resolution: {integrity: sha512-J2qEVHtIDjEM9TxwmwuebOGmZNwhKu/dR7P7qBpnJKGmBBX0vdweQ/4cEXhj8fBbWVUB5V12xWChri3CgKNULQ==} + engines: {node: '>=22.12.0'} + + '@astrojs/internal-helpers@0.10.1': + resolution: {integrity: sha512-5phcroT/vmOOrYuuAxtkbPixy5hePtlz9i8K4OeDv3dNK6/UQRuXPOSRTxIOBbUY5Sonw2UaxjbuVc43Mcir6Q==} + + '@astrojs/markdown-remark@7.2.1': + resolution: {integrity: sha512-jPVNIqTvk+yKviikszv/Y1U4jGUSKpp/Nw48QZV4qjWgp70j4Lkq3lhSDRbWwCfgKvEyO9GHuVbV1dM2WYXy1w==} + + '@astrojs/markdown-satteri@0.3.3': + resolution: {integrity: sha512-Lje33Ittd8UQGgbIIWQvhPkj5X5c4b1sZnZWX3JQV/AWpfbuQGxVi2ONt6+ScydcwfR4egilslEWyczMclrJ1g==} + + '@astrojs/mdx@7.0.2': + resolution: {integrity: sha512-l+sJY5U1KkGZUdr+bIL4Y6BefeS549qoSHVSkUSs6A9INwdCND+/0+vN0NroPBXwl5Vcg5u78t7VQRsJjePxbw==} + engines: {node: '>=22.12.0'} + peerDependencies: + '@astrojs/markdown-satteri': ^0.3.1 + astro: ^7.0.0 + peerDependenciesMeta: + '@astrojs/markdown-satteri': + optional: true + + '@astrojs/prism@4.0.2': + resolution: {integrity: sha512-KTivpmnz6lDsC6o9H4+DNm2SrE/GHzw8cNAvEJwAvUT+eoaEnn/4NtbDNfRRaxaJHdp15gf+tfHAWiXR4wB3BA==} + engines: {node: '>=22.12.0'} + + '@astrojs/sitemap@3.7.3': + resolution: {integrity: sha512-f8euLVsyeAmAkSm/1M2Kb8sL8byQmfgbvBNaHFItCheTj/IpiJYSEWVcqDHZ/yEHxiS7+w87mQkzwZaPHmk5GA==} + + '@astrojs/starlight@0.41.3': + resolution: {integrity: sha512-8xsG6UpK581TJmtOc7/pnxHKEbP16rV06VLWaVa7FOyE/VEwnaHOsLtL+miifCEfuiuv0Wn+j8u3JSluRQesMQ==} + peerDependencies: + '@astrojs/markdown-remark': ^7.2.0 + astro: ^7.0.2 + peerDependenciesMeta: + '@astrojs/markdown-remark': + optional: true + + '@astrojs/telemetry@3.3.2': + resolution: {integrity: sha512-j8DNruA8ors99Al39RYZPJK4DC1bKkoNm93mAMuBhY9TCNC4R8n1q7ovFnJ5qhGh5Lsh7pa1gpQVpYpsJPeTHQ==} + engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} + + '@babel/helper-string-parser@7.29.7': + resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.7': + resolution: {integrity: sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.29.7': + resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==} + engines: {node: '>=6.9.0'} + + '@bruits/satteri-darwin-arm64@0.9.4': + resolution: {integrity: sha512-W3MSUkr2mZRR8Stoe+lqNAyzQzRuFMU8WffV9IvFSxTok0LGWR0ZZQPLELU4QTRiUbhL2Y4VUP9vV7pj8rHjgg==} + cpu: [arm64] + os: [darwin] + + '@bruits/satteri-darwin-x64@0.9.4': + resolution: {integrity: sha512-DXOuuaE1lsv7mpk2mOvGrzqoEWEvOIZEO/fXVa7zfM23Iob+CBjBkRAMwpHA4pmZ3j6Gj7WJzPKw0kQ7w741AQ==} + cpu: [x64] + os: [darwin] + + '@bruits/satteri-linux-arm64-gnu@0.9.4': + resolution: {integrity: sha512-gJxU9rGGoqIznSEgEzpjxkry24jeHuMpoo1tCIAhHYh7WaD3j5F8zt3jmHxEaN1Uwa+K5+wFgIR2uIGOnMzEmw==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@bruits/satteri-linux-arm64-musl@0.9.4': + resolution: {integrity: sha512-Wjzu9hmmAbfmDkBfPI1VdZygJtYz9uYZQnkEyrXi6S2JFi+2pXQ1A5irj38bqm0IZmWcTbk0cVG4NZnPdtVNJA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@bruits/satteri-linux-x64-gnu@0.9.4': + resolution: {integrity: sha512-MR1Q+wMx65FQlbSV7cRqWW87Knp0zkoaIV55Dt+xZl028wJABXEPEEmG3670SLq7lVZvcGIDwCgSg2kCYxvRwA==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@bruits/satteri-linux-x64-musl@0.9.4': + resolution: {integrity: sha512-T4gxhXve3zyNAZesrXAd/rDZOGRkbfFIUFld4TGsw6BsjoIteCcDji6IMqeXyaWEVSykY2X8Eid2hr6aXGYAaw==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@bruits/satteri-wasm32-wasi@0.9.4': + resolution: {integrity: sha512-/CEG8LUlpaBEnhFnYVn0UnlHFLs51UhrkJBUPDUXLzkadzAcnR88iRA/nOl7Zwhjb4WhfBV4p3P5qeOJMtH0iA==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@bruits/satteri-win32-arm64-msvc@0.9.4': + resolution: {integrity: sha512-E1ZPQbgCtFKiU7pFYVndynvY7ne4coeVDUgnVThErSFlJ2ceQCBZrfRTD1lzrIDy63Bbqo+g/cZY9duw+JYjIw==} + cpu: [arm64] + os: [win32] + + '@bruits/satteri-win32-x64-msvc@0.9.4': + resolution: {integrity: sha512-5I7SiarsNdAUuhJb50CXJPTwr/ECVrBoU+fymoLjChK5fW//+srhY4lstcNTzgFRtQSYfVtm4OQZz16CVMeTeA==} + cpu: [x64] + os: [win32] + + '@capsizecss/unpack@4.0.1': + resolution: {integrity: sha512-CuNiSqg7+e1cO/GjffyMOm5Tt2jUF9CWHHnvQ/UkqvtkGfHdgwEC0wpmq7fkN3gxwpRnrAN0WzO3vREKmNolMQ==} + engines: {node: '>=18'} + + '@clack/core@1.4.3': + resolution: {integrity: sha512-/kr3UWNtdJfxZtPgDqUOmG2pvwlmcLGheex5yiZKdwbzZJxhV+HMNR9QNmyY5cGwTNV6LrR7Jtp+KjhUAP1qBQ==} + engines: {node: '>= 20.12.0'} + + '@clack/prompts@1.7.0': + resolution: {integrity: sha512-y7/yvZ2TPAnR9+jnc00klvNNLkJiXFFrQA/hlLCcxA9a2A4zQIOimyFQ9XfwYKiGD1fb5GY8vbKIIgO8d5Tb2A==} + engines: {node: '>= 20.12.0'} + + '@ctrl/tinycolor@4.2.0': + resolution: {integrity: sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==} + engines: {node: '>=14'} + + '@emnapi/core@1.11.1': + resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==} + + '@emnapi/runtime@1.11.1': + resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} + + '@emnapi/runtime@1.11.2': + resolution: {integrity: sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==} + + '@emnapi/wasi-threads@1.2.2': + resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} + + '@esbuild/aix-ppc64@0.28.1': + resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.28.1': + resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.28.1': + resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.28.1': + resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.28.1': + resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.28.1': + resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.28.1': + resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.28.1': + resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.28.1': + resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.28.1': + resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.28.1': + resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.28.1': + resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.28.1': + resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.28.1': + resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.28.1': + resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.28.1': + resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.28.1': + resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.28.1': + resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.28.1': + resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.28.1': + resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.28.1': + resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.28.1': + resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.28.1': + resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.28.1': + resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.28.1': + resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.28.1': + resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@expressive-code/core@0.44.0': + resolution: {integrity: sha512-xgiF2P6tYUbrhi3+x0S8xHZWT1t3Bvb3U91tAtRbLb9HLejLvYc5GZUqKICKLaUN4iSGhhNJu2fM/aH8e5yCMg==} + + '@expressive-code/plugin-frames@0.44.0': + resolution: {integrity: sha512-V6M6+zVc1GzqCvXkQHc2m5rcFOIVzJgMq5gnfrMnVf2gwtj/sg4H93c1f/mGeqHycubwkHFUDyParAOiGeDZeA==} + + '@expressive-code/plugin-shiki@0.44.0': + resolution: {integrity: sha512-RZsdaqlbGqyAQKuoX4myQXxjmiE2l5KBpJ/gKPh62tCdIdpWyjbzVqSo8+5XsezZxkfi8AJ/J6EUaBTPROFX/Q==} + + '@expressive-code/plugin-text-markers@0.44.0': + resolution: {integrity: sha512-0/m3A5b+lz2upyNq+wzZ1S69HRoJmyFs5LsR42lVZ9pmGRlBiSBYQpvqlji4DBj1+Riamxc0AvcCr5kuzOQeWA==} + + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.34.5': + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.34.5': + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.2.4': + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-linux-arm64@0.34.5': + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-arm@0.34.5': + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-ppc64@0.34.5': + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-riscv64@0.34.5': + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-s390x@0.34.5': + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-x64@0.34.5': + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-linuxmusl-arm64@0.34.5': + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-linuxmusl-x64@0.34.5': + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-wasm32@0.34.5': + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.34.5': + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.5': + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@mdx-js/mdx@3.1.1': + resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} + + '@napi-rs/wasm-runtime@1.1.6': + resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + + '@oslojs/encoding@1.1.0': + resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} + + '@oxc-project/types@0.138.0': + resolution: {integrity: sha512-1a7ZKmrRTCoN1XMZ4L0PyyqrMnrNlLyPuOkdSX2MZg7IiIGRUyurNhAm73ptDOraoBcIordsIGKNPKUzy3ZmfA==} + + '@pagefind/darwin-arm64@1.5.2': + resolution: {integrity: sha512-MXpI+7HsAdPkvJ0gk9xj9g541BCqBZOBbdwj9g6lB5LCj6kSV6nqDSjzcAJwvOsfu0fjwvC8hQU+ecfhp+MpiQ==} + cpu: [arm64] + os: [darwin] + + '@pagefind/darwin-x64@1.5.2': + resolution: {integrity: sha512-IojxFWMEJe0RQ7PQ3KXQsPIImNsbpPYpoZ+QUDrL8fAl/O27IX+LVLs74/UzEZy5uA2LD8Nz1AiwKr72vrkZQw==} + cpu: [x64] + os: [darwin] + + '@pagefind/default-ui@1.5.2': + resolution: {integrity: sha512-pm1LMnQg8N2B3n2TnjKlhaFihpz6zTiA4HiGQ6/slKO/+8K9CAU5kcjdSSPgpuk1PMuuN4hxLipUIifnrkl3Sg==} + + '@pagefind/freebsd-x64@1.5.2': + resolution: {integrity: sha512-7EVzo9+0w+2cbe671BtMj10UlNo83I+HrLVLfRxO731svHRJKUfJ/mo05gU14pe9PCfpKNQT8FS3Xc/oDN6pOA==} + cpu: [x64] + os: [freebsd] + + '@pagefind/linux-arm64@1.5.2': + resolution: {integrity: sha512-Ovt9+K35sqzn8H3ZMXGwls4TD/wMJuvRtShHIsmUQREmaxjrDEX7gHckRCrwYJ4XE1H1p6HkLz3wukrAnsfXQw==} + cpu: [arm64] + os: [linux] + + '@pagefind/linux-x64@1.5.2': + resolution: {integrity: sha512-V+tFqHKXhQKq/WqPBD67AFy7scn1/aZID00ws4fSDd+1daSi5UHR9VVlRrOUYKxn3VuFQYRD7lYXdZK1WED1YA==} + cpu: [x64] + os: [linux] + + '@pagefind/windows-arm64@1.5.2': + resolution: {integrity: sha512-hN9Nh90fNW61nNRCW9ZyQrAj/mD0eRvmJ8NlTUzkbuW8kIzGJUi3cxjFkEcMZ5h/8FsKWD/VcouZl4yo1F7B6g==} + cpu: [arm64] + os: [win32] + + '@pagefind/windows-x64@1.5.2': + resolution: {integrity: sha512-Fa2Iyw7kaDRzGMfNYNUXNW2zbL5FQVDgSOcbDHdzBrDEdpqOqg8TcZ68F22ol6NJ9IGzvUdmeyZypLW5dyhqsg==} + cpu: [x64] + os: [win32] + + '@rolldown/binding-android-arm64@1.1.4': + resolution: {integrity: sha512-EZLpf/8y7GXkkra90ML47kzik/GMP3EMcE9bPyHmRfxLC6z9+aW5A8poCsoxjrT5GfEcNAAvWwUHjvP1pUQkfw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.1.4': + resolution: {integrity: sha512-aUi+HBvmYb7j8krl1+qJgkG8C17fO79gk3c+jPw4S8glRFc1DTija9S3EyaTSQUm5GJXYKDAsugBEhFHH2vYiQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.1.4': + resolution: {integrity: sha512-F7hHC3gwY11+vByKPRWqwGbeXWVgKmL+pTGCinaEhdihzBV2aQ0fvZOch9cXYUOKuKKq429HeYXOqQLc7wFCEg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.1.4': + resolution: {integrity: sha512-sI5yw+7s92SK6odiEhD5lKCBlWcpjHS5qyqpVQbZAJ0fIzEUXrmbl3DH2ybR3PZogulNJF+COLtmA8hUfvkCCQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.1.4': + resolution: {integrity: sha512-mCi0OKgEieFircrtVYmQAFGszRtMnZ6fpZAXrxanXAu7lqZcsK1E1RAaZNG0uKAnxox3B1f4EyQNnoyMfN1vAA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.1.4': + resolution: {integrity: sha512-B9Ial3Kv5sh0SHnB1g/QWcUQCEvCF6QKGAl4zXypYj65mVI+B4AhFBwPtSN7pDrJeIx8Z7zdy4ntx+wQABom7w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.1.4': + resolution: {integrity: sha512-lZVym0PuHE1KZ22gmFTC15lAkrg9iTszR617oYRB/iPY1A56ywoJzVKOJBKaot5RiikCObmur6pogpse3gRcng==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.1.4': + resolution: {integrity: sha512-t2DNiLJWNTbnEHyUzTumldML6ET4/g16467LZoDDJ3tSxGvguL5/NyC2lCsNKuyRycg9XeDQF5SSv+TNOhQEXg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.1.4': + resolution: {integrity: sha512-0WIRnL1Uw4BvTZRLQt+PVgo6ZKTJadlC2btP+/EOXv2f/DWbY0rEgl+y834mIVwP1FkTlWVTrGGJXf12lru7EQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.1.4': + resolution: {integrity: sha512-JWtGshGfX+oENAKonoNkqEJX+7hC8yfhi9GUyPX1VX4mdh1y5r+ZiJLR5XzAB0aoP6s/PcILsGjKq8O0mm24bw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.1.4': + resolution: {integrity: sha512-rT6yQcxUuXs4CnbofqwHRRV0iem349rLMYpTjkgQGLjrY4ado/eDzwPZPTCgTOlF6Nkp8NEv70yLMTn6qkWxsQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.1.4': + resolution: {integrity: sha512-KXMGoboq5cyaCQjDA4GLuRiOwBQ0EyFnJoVViLeZ45/3rFItRODEr+NdsBcVpll40hhNArlm/speWGRvj08LzA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.1.4': + resolution: {integrity: sha512-5K83rb36oJiY7BCyE9zLZtGcPV4g5wvq+xwdO0XPIwDVZI8cyB/AUjkNXGb92/rnmezEkjMOpgY61rtwjQtFwg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.1.4': + resolution: {integrity: sha512-PnWBtw3TV5KOg69HQQDR0mnQuyCmSGR2pAB4DC1rPF808fgKeTUMj2EOEyKATpgiuxuR5APQmiDO7PDgEjTFSA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.1.4': + resolution: {integrity: sha512-M1lpniBePobTfsa7Ks9a199e1akxsXn+GYBUKsEzv3YFzOm1HJAMNwKI3qr0Zq+mxwx9gOZoTdP1yXRYsZUocQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + + '@rollup/pluginutils@5.4.0': + resolution: {integrity: sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@shikijs/colorized-brackets@4.3.1': + resolution: {integrity: sha512-hyp9iRV7iEnU/sT1DL3eLevY0wOwIeFMp6ss8U8FfWdwT5LLhv4sO5Xt6r0dD3eteeswDngBiuEv6nQzQEwv2w==} + engines: {node: '>=20'} + + '@shikijs/core@4.3.1': + resolution: {integrity: sha512-ANMDxuaPsNMdDC1m4vfvhlDmJweMwkE5XitTwrq2rWHx5jM+dlm4MmHt2PP6t0uejfR77SuhrhJ0zEijIF/uhA==} + engines: {node: '>=20'} + + '@shikijs/engine-javascript@4.3.1': + resolution: {integrity: sha512-JBItcnPuYq7jVJdZo/vMj94r+szT7XEjHFX+mvFDGSEIbVAXAGyHAHzhbWzpGOwYidCZrErJLLgn2PVeiokHnQ==} + engines: {node: '>=20'} + + '@shikijs/engine-oniguruma@4.3.1': + resolution: {integrity: sha512-OXyNMzg0pews+msMj4cHeqT4xiYKKvbnn6VbdAXxfoFl3SSx4fJTc8FadECuc5/H9p3BzhNAoAUXKwAu9rWYhg==} + engines: {node: '>=20'} + + '@shikijs/langs@4.3.1': + resolution: {integrity: sha512-m0l9nsDqgBHvbZbk7A0/kXz/impK3uB/c6rAn6Gpg/uPtdZRQ+alsN/17MU5thb68XTj/4DxkZAotrM0GGSpDQ==} + engines: {node: '>=20'} + + '@shikijs/primitive@4.3.1': + resolution: {integrity: sha512-CXQRQOYy1leqQ8ceTeJdmXv/bsUY++6QyLpXJ94LZAAYj5X2SKRdc5ipguv4NPyGVKItB2PPwUpRNe0Sjh5S1A==} + engines: {node: '>=20'} + + '@shikijs/themes@4.3.1': + resolution: {integrity: sha512-dgpoJ4WqNi2yTmizQHBJ5zcX6j2lE6icN/0yt4l1kkf16jrY/pwPLoTb1ETsWMz0OBLf9ZNvwmxft+cH+N9qSA==} + engines: {node: '>=20'} + + '@shikijs/types@4.3.1': + resolution: {integrity: sha512-CHFxE0jztBIZRHH6gxXE7DXUCFXjReEGxZ/j0rfSLGKZuwp2xBYycEP14875DSa9KLL/6700oxIq6oO6ef9K2g==} + engines: {node: '>=20'} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + + '@tybys/wasm-util@0.10.3': + resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} + + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/js-yaml@4.0.9': + resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mdx@2.0.14': + resolution: {integrity: sha512-T48PeuJtvLosNTPVhfnIp3i/n3a4g4Bad7YCq5k64D4u7NwDrAotikQ+5+sjtUvBmxCMlbo3dVL+C2dP0rWHzg==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/nlcst@2.0.3': + resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==} + + '@types/node@24.13.2': + resolution: {integrity: sha512-fRa09kZTgu8o71KFcDjUFuc7F+dEbZYZmkI0mg5YBTRs0yMKjYHsq/c0urDKeDb+D5qVgXOdFcuu+DZPKOITwA==} + + '@types/node@26.1.0': + resolution: {integrity: sha512-O0A1G3xPGy4w7AgQdAQYUlQ+BKk2Oovw8eRpofyp5KdBZULnbe+WqaOVNrm705SHphCiG4XHsACrSmPu1f+Kgw==} + + '@types/sax@1.2.7': + resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@ungap/structured-clone@1.3.2': + resolution: {integrity: sha512-5jsZFwgR5rTdKwidH9Qmat75RKwqfpKlWWB1frDkljN127mwqBu8K0PYo7/hFpF03IEJpfVPpCQDY/eDx3iHvA==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.17.0: + resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} + engines: {node: '>=0.4.0'} + hasBin: true + + am-i-vibing@0.4.0: + resolution: {integrity: sha512-MxT4XZL7pzLHpuvhDKdMaQHMGGkJDLluKBLsbstn+8wv9sWcFT6h+0ve9qkml95amVTZtZV83gQe2hY+ojgHLg==} + hasBin: true + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + array-iterate@2.0.1: + resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==} + + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + hasBin: true + + astro-expressive-code@0.44.0: + resolution: {integrity: sha512-b1wN/ZvbJprzxlGKIpIes2kQrCY5KRLwys2tWbZAZyjGZcW5ZtgneZnBwzNRiBna9/48d4mQl19KLjcRuhO1hw==} + peerDependencies: + astro: ^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta || ^7.0.0 + + astro@7.0.6: + resolution: {integrity: sha512-Myw0sFia+zs/Y0yqfZEsUYXfDPh3ELcLf1f0Q/qQzVXBh/af1qO62WNT+P89DCcfGVV51nMoQhEfkBYqJmoUOQ==} + engines: {node: '>=22.12.0', npm: '>=9.6.5', pnpm: '>=7.1.0'} + hasBin: true + peerDependencies: + '@astrojs/markdown-remark': 7.2.1 + peerDependenciesMeta: + '@astrojs/markdown-remark': + optional: true + + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + + bcp-47-match@2.0.3: + resolution: {integrity: sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==} + + bcp-47@2.1.1: + resolution: {integrity: sha512-KLw+H/gd2p4zly1X7Yh/qziuyae5/w/QFnvTng9eZL5fvszL7Whl3MBoWF8yxL7ksUjBfOD+OxkytiqbBpG+Fw==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + + ci-info@4.4.0: + resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} + engines: {node: '>=8'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + + common-ancestor-path@2.0.0: + resolution: {integrity: sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng==} + engines: {node: '>= 18'} + + cookie-es@1.2.3: + resolution: {integrity: sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw==} + + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} + engines: {node: '>=18'} + + crossws@0.3.5: + resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} + + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + + css-selector-parser@3.3.0: + resolution: {integrity: sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g==} + + css-tree@2.2.1: + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + css-tree@3.2.1: + resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + csso@5.0.5: + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + + defu@6.1.7: + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + devalue@5.8.1: + resolution: {integrity: sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw==} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + diff@8.0.4: + resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} + engines: {node: '>=0.3.1'} + + direction@2.0.1: + resolution: {integrity: sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==} + hasBin: true + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + dset@3.1.4: + resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} + engines: {node: '>=4'} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + + es-module-lexer@2.3.0: + resolution: {integrity: sha512-KLdwQm2NvGLDkQDCGvmiQrhkd0JbMzXthwQAUgWjQuQdBLFa3eiBP5arXZyA+f8x+x7OXgud6bq2rxjGtHV2tw==} + + esast-util-from-estree@2.0.0: + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} + + esast-util-from-js@2.0.1: + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + + esbuild@0.28.1: + resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} + engines: {node: '>=18'} + hasBin: true + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + estree-util-attach-comments@3.0.0: + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} + + estree-util-build-jsx@3.0.1: + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} + + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + + estree-util-scope@1.0.0: + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} + + estree-util-to-js@2.0.0: + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} + + estree-util-visit@2.0.0: + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + eventemitter3@5.0.4: + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + + expressive-code@0.44.0: + resolution: {integrity: sha512-JXVWVNCKlLuZLMQH8cOiDUSosT0Bb+elwE/dbAkpwFwDFmyFyWlECoWZIohh2FkIF1iI67TQJ+Ts9k7oNDh2qA==} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fast-string-truncated-width@3.0.3: + resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} + + fast-string-width@3.0.2: + resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} + + fast-wrap-ansi@0.2.2: + resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + flattie@1.1.1: + resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==} + engines: {node: '>=8'} + + fontace@0.4.1: + resolution: {integrity: sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw==} + + fontkitten@1.0.3: + resolution: {integrity: sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw==} + engines: {node: '>=20'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + get-tsconfig@5.0.0-beta.4: + resolution: {integrity: sha512-7nF7C9fIPFEMHgEMEfgIlO9wDdZ8CyHw27rWciFZfHvHDReIiPhsYuzPRXsfvBCqFy1l8RRyyWV7QLM+ZhUJsQ==} + engines: {node: '>=20.20.0'} + + github-slugger@2.0.0: + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} + + h3@1.15.11: + resolution: {integrity: sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==} + + hast-util-embedded@3.0.0: + resolution: {integrity: sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==} + + hast-util-format@1.1.0: + resolution: {integrity: sha512-yY1UDz6bC9rDvCWHpx12aIBGRG7krurX0p0Fm6pT547LwDIZZiNr8a+IHDogorAdreULSEzP82Nlv5SZkHZcjA==} + + hast-util-from-html@2.0.3: + resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} + + hast-util-from-parse5@8.0.3: + resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} + + hast-util-has-property@3.0.0: + resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==} + + hast-util-is-body-ok-link@3.0.1: + resolution: {integrity: sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==} + + hast-util-is-element@3.0.0: + resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} + + hast-util-minify-whitespace@1.0.1: + resolution: {integrity: sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==} + + hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + + hast-util-phrasing@3.0.1: + resolution: {integrity: sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==} + + hast-util-raw@9.1.0: + resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} + + hast-util-select@6.0.4: + resolution: {integrity: sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw==} + + hast-util-to-estree@3.1.3: + resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} + + hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + + hast-util-to-parse5@8.0.1: + resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==} + + hast-util-to-string@3.0.1: + resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==} + + hast-util-to-text@4.0.2: + resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hastscript@9.0.1: + resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + + html-escaper@3.0.3: + resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + html-whitespace-sensitive-tag-names@3.0.1: + resolution: {integrity: sha512-q+310vW8zmymYHALr1da4HyXUQ0zgiIwIicEfotYPWGN0OJVEN/58IJ3A4GBYcEq3LGAZqKb+ugvP0GNB9CEAA==} + + http-cache-semantics@4.2.0: + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + + i18next@26.3.4: + resolution: {integrity: sha512-pa7m0d7pBDqGHZxljT+WPFeyFgQ7P7SciPPo1tTqYuO0z4sqADYhwnBESmmGp/wEof1inwdls/k8ZgTg8rxFHA==} + peerDependencies: + typescript: ^5 || ^6 + peerDependenciesMeta: + typescript: + optional: true + + inline-style-parser@0.2.7: + resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + + iron-webcrypto@1.2.1: + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-docker@4.0.0: + resolution: {integrity: sha512-LHE+wROyG/Y/0ZnbktRCoTix2c1RhgWaZraMZ8o1Q7zCh0VSrICJQO5oqIIISrcSBtrXv0o233w1IYwsWCjTzA==} + engines: {node: '>=20'} + hasBin: true + + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-wsl@3.1.1: + resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} + engines: {node: '>=16'} + + js-yaml@4.3.0: + resolution: {integrity: sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==} + hasBin: true + + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + + klona@2.0.6: + resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} + engines: {node: '>= 8'} + + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + lru-cache@11.5.1: + resolution: {integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==} + engines: {node: 20 || >=22} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + magicast@0.5.3: + resolution: {integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==} + + markdown-extensions@2.0.0: + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} + engines: {node: '>=16'} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + mdast-util-definitions@6.0.0: + resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==} + + mdast-util-directive@3.1.0: + resolution: {integrity: sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==} + + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + + mdast-util-from-markdown@2.0.3: + resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdx@3.0.0: + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + mdn-data@2.0.28: + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + + mdn-data@2.27.1: + resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-directive@4.0.0: + resolution: {integrity: sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-extension-mdx-expression@3.0.1: + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} + + micromark-extension-mdx-jsx@3.0.2: + resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} + + micromark-extension-mdx-md@2.0.0: + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} + + micromark-extension-mdxjs-esm@3.0.0: + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} + + micromark-extension-mdxjs@3.0.0: + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-mdx-expression@2.0.3: + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-events-to-acorn@2.0.3: + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.15: + resolution: {integrity: sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + neotraverse@0.6.18: + resolution: {integrity: sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==} + engines: {node: '>= 10'} + + nlcst-to-string@4.0.0: + resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==} + + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + + node-mock-http@1.0.4: + resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + obug@2.1.3: + resolution: {integrity: sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==} + engines: {node: '>=12.20.0'} + + ofetch@1.5.1: + resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} + + ohash@2.0.11: + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} + + oniguruma-parser@0.12.2: + resolution: {integrity: sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==} + + oniguruma-to-es@4.3.6: + resolution: {integrity: sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==} + + p-limit@7.3.0: + resolution: {integrity: sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==} + engines: {node: '>=20'} + + p-queue@9.3.1: + resolution: {integrity: sha512-POWdiIPmsUPGwb4FeQ4OBg46aqmcInSWe45CKDsGHiOBiVQM9chqfQTuqhuTzcg2Vz9faTI65at0KkVyVEiCHw==} + engines: {node: '>=20'} + + p-timeout@7.0.1: + resolution: {integrity: sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==} + engines: {node: '>=20'} + + package-manager-detector@1.7.0: + resolution: {integrity: sha512-xg1eHpwYL/D/HEdWw2goFZP6vV0FH7W+PZ5rFkGjdIDLtxq7EkzBUeT3m+lndYCt8wKbmofUu1MUdMCXkCk9ZQ==} + + pagefind@1.5.2: + resolution: {integrity: sha512-XTUaK0hXMCu2jszWE584JGQT7y284TmMV9l/HX3rnG5uo3rHI/uHU56XTyyyPFjeWEBxECbAi0CaFDJOONtG0Q==} + hasBin: true + + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + + parse-latin@7.0.0: + resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + + piccolore@0.1.3: + resolution: {integrity: sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + engines: {node: '>=8.6'} + + picomatch@4.0.5: + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} + engines: {node: '>=12'} + + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + + postcss-selector-parser@6.1.4: + resolution: {integrity: sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ==} + engines: {node: '>=4'} + + postcss@8.5.16: + resolution: {integrity: sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==} + engines: {node: ^10 || ^12 || >=14} + + prismjs@1.30.0: + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} + engines: {node: '>=6'} + + process-ancestry@0.1.0: + resolution: {integrity: sha512-tGqJW/UnclpYASFcM6Xh8D8l/BMtaQ9+CSG0vlJSJTcdMM4lDRv4c6H0Pdcsfted+bVczdYSfk2fdukg2gQkZg==} + engines: {node: '>=18.0.0'} + + property-information@7.2.0: + resolution: {integrity: sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==} + + radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + + readdirp@5.0.0: + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} + engines: {node: '>= 20.19.0'} + + recma-build-jsx@1.0.0: + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} + + recma-jsx@1.0.1: + resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + recma-parse@1.0.0: + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} + + recma-stringify@1.0.0: + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + + regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@6.1.0: + resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} + + rehype-expressive-code@0.44.0: + resolution: {integrity: sha512-5r74C5F2sMR3X+QJH8OKWgZBO/cqRw5W1fLT6GVlSfLqepk+4j8tGFkyPqZYWjwntsBHzKPDH2zI68sZ7ScLfA==} + + rehype-format@5.0.1: + resolution: {integrity: sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ==} + + rehype-parse@9.0.1: + resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==} + + rehype-raw@7.0.0: + resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + + rehype-recma@1.0.0: + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + + rehype-stringify@10.0.1: + resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==} + + rehype@13.0.2: + resolution: {integrity: sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==} + + remark-directive@4.0.0: + resolution: {integrity: sha512-7sxn4RfF1o3izevPV1DheyGDD6X4c9hrGpfdUpm7uC++dqrnJxIZVkk7CoKqcLm0VUMAuOol7Mno3m6g8cfMuA==} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-mdx@3.1.1: + resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + + remark-smartypants@3.0.2: + resolution: {integrity: sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==} + engines: {node: '>=16.0.0'} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + retext-latin@4.0.0: + resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==} + + retext-smartypants@6.2.0: + resolution: {integrity: sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==} + + retext-stringify@4.0.0: + resolution: {integrity: sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==} + + retext@9.0.0: + resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==} + + rolldown@1.1.4: + resolution: {integrity: sha512-IjZYiLxZwpnhwhdBH2ugdTGVSdhCQUmLxLoqyjiL0JxYjyRst+5a0P3xfrTxJ5F638j4Mvvw5FAX5XE6eHpXbA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + satteri@0.9.4: + resolution: {integrity: sha512-BKob126Tay84diOZsnVNH/Q/c+3njPJTCad3w5zLKa6j8bVjxskPNHDtxrMwYK4bN/RlqUSdMnPwKY4k65EMOQ==} + + sax@1.6.0: + resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} + engines: {node: '>=11.0.0'} + + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + engines: {node: '>=10'} + hasBin: true + + sharp@0.34.5: + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + shiki@4.3.1: + resolution: {integrity: sha512-oR+qDVi2OjX1tmDpyv+3KviX01KzO6Af+0NNnKnsp9491UEGz2YpxTuJboS/6VhYpTdqzmuJBuiTlrAWWJAssw==} + engines: {node: '>=20'} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + sitemap@9.0.1: + resolution: {integrity: sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ==} + engines: {node: '>=20.19.5', npm: '>=10.8.2'} + hasBin: true + + smol-toml@1.7.0: + resolution: {integrity: sha512-aqVvWoyO21L23mb+drl4RmMXbf6N7FdHjAhTRA9ZBL7apWBgfWC16KjrASI+1p9GAroljyMHj6fK67i0UiTNvQ==} + engines: {node: '>= 18'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + starlight-sidebar-topics@0.8.0: + resolution: {integrity: sha512-hE8+w2vNL13h6cq3UJGl05milJQ3+1BSlhaV5V4a993YzYczU6uLAj6jfUDKQ2mmgkdVWp8/UNDF4Je/rQXNQw==} + engines: {node: '>=22.12.0'} + peerDependencies: + '@astrojs/starlight': '>=0.38.0' + + stream-replace-string@2.0.0: + resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + style-to-js@1.1.21: + resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} + + style-to-object@1.0.14: + resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + + svgo@4.0.1: + resolution: {integrity: sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==} + engines: {node: '>=16'} + hasBin: true + + tiny-inflate@1.0.3: + resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} + + tinyclip@0.1.15: + resolution: {integrity: sha512-uo33abH+Ays0xYaDysoBt494Hb3hsEczMpcC0MwFl773pazORx4fmvKhclhR1wonUbB6vvpRsvVMwnhfqeMc+A==} + engines: {node: ^16.14.0 || >= 17.3.0} + + tinyexec@1.2.4: + resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} + engines: {node: '>=18'} + + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.6.4: + resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} + + ultrahtml@1.6.0: + resolution: {integrity: sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==} + + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + + undici-types@7.18.2: + resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} + + undici-types@8.3.0: + resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==} + + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unifont@0.7.4: + resolution: {integrity: sha512-oHeis4/xl42HUIeHuNZRGEvxj5AaIKR+bHPNegRq5LV1gdc3jundpONbjglKpihmJf+dswygdMJn3eftGIMemg==} + + unist-util-find-after@5.0.0: + resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-modify-children@4.0.0: + resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==} + + unist-util-position-from-estree@2.0.0: + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-remove-position@5.0.0: + resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-children@3.0.0: + resolution: {integrity: sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + + unstorage@1.17.5: + resolution: {integrity: sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg==} + 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 + + url-extras@0.1.0: + resolution: {integrity: sha512-8tzwTeXFPuX/5PHuCDQE5Dd9Ts4rwoq2t9aIT+HS4iAVpmj5l4Ao7Q+BuuFjvWRqrLswBhQDk8O96ZicgCqQqw==} + engines: {node: '>=20'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vfile-location@5.0.3: + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vite@8.1.3: + resolution: {integrity: sha512-Ds+gBRbj0lwRO2Y5hwnUBdxSwlAve9LeRyU4sNnAr0ewW0gWF0n5bgXgUzbgZ49MV9BVUAQUFYVcDUcilUExMA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.3.0 + esbuild: ^0.27.0 || ^0.28.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitefu@1.1.3: + resolution: {integrity: sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + vite: + optional: true + + web-namespaces@2.0.1: + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + + which-pm-runs@1.1.0: + resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==} + engines: {node: '>=4'} + + xxhash-wasm@1.1.0: + resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==} + + yargs-parser@22.0.0: + resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + + yocto-queue@1.2.2: + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} + engines: {node: '>=12.20'} + + zod@4.4.3: + resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@astrojs/compiler-binding-darwin-arm64@0.3.0': + optional: true + + '@astrojs/compiler-binding-darwin-x64@0.3.0': + optional: true + + '@astrojs/compiler-binding-linux-arm64-gnu@0.3.0': + optional: true + + '@astrojs/compiler-binding-linux-arm64-musl@0.3.0': + optional: true + + '@astrojs/compiler-binding-linux-x64-gnu@0.3.0': + optional: true + + '@astrojs/compiler-binding-linux-x64-musl@0.3.0': + optional: true + + '@astrojs/compiler-binding-wasm32-wasi@0.3.0(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)': + dependencies: + '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2) + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + optional: true + + '@astrojs/compiler-binding-win32-arm64-msvc@0.3.0': + optional: true + + '@astrojs/compiler-binding-win32-x64-msvc@0.3.0': + optional: true + + '@astrojs/compiler-binding@0.3.0(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)': + optionalDependencies: + '@astrojs/compiler-binding-darwin-arm64': 0.3.0 + '@astrojs/compiler-binding-darwin-x64': 0.3.0 + '@astrojs/compiler-binding-linux-arm64-gnu': 0.3.0 + '@astrojs/compiler-binding-linux-arm64-musl': 0.3.0 + '@astrojs/compiler-binding-linux-x64-gnu': 0.3.0 + '@astrojs/compiler-binding-linux-x64-musl': 0.3.0 + '@astrojs/compiler-binding-wasm32-wasi': 0.3.0(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2) + '@astrojs/compiler-binding-win32-arm64-msvc': 0.3.0 + '@astrojs/compiler-binding-win32-x64-msvc': 0.3.0 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + + '@astrojs/compiler-rs@0.3.0(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)': + dependencies: + '@astrojs/compiler-binding': 0.3.0(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2) + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + + '@astrojs/internal-helpers@0.10.1': + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + js-yaml: 4.3.0 + picomatch: 4.0.5 + retext-smartypants: 6.2.0 + shiki: 4.3.1 + smol-toml: 1.7.0 + unified: 11.0.5 + + '@astrojs/markdown-remark@7.2.1': + dependencies: + '@astrojs/internal-helpers': 0.10.1 + '@astrojs/prism': 4.0.2 + github-slugger: 2.0.0 + hast-util-from-html: 2.0.3 + hast-util-to-text: 4.0.2 + 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 + unified: 11.0.5 + unist-util-remove-position: 5.0.0 + unist-util-visit: 5.1.0 + unist-util-visit-parents: 6.0.2 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@astrojs/markdown-satteri@0.3.3': + dependencies: + '@astrojs/internal-helpers': 0.10.1 + '@astrojs/prism': 4.0.2 + github-slugger: 2.0.0 + satteri: 0.9.4 + + '@astrojs/mdx@7.0.2(@astrojs/markdown-satteri@0.3.3)(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0))': + dependencies: + '@astrojs/internal-helpers': 0.10.1 + '@astrojs/markdown-remark': 7.2.1 + '@mdx-js/mdx': 3.1.1 + acorn: 8.17.0 + astro: 7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0) + es-module-lexer: 2.3.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.1.0 + vfile: 6.0.3 + optionalDependencies: + '@astrojs/markdown-satteri': 0.3.3 + transitivePeerDependencies: + - supports-color + + '@astrojs/prism@4.0.2': + dependencies: + prismjs: 1.30.0 + + '@astrojs/sitemap@3.7.3': + dependencies: + sitemap: 9.0.1 + stream-replace-string: 2.0.0 + zod: 4.4.3 + + '@astrojs/starlight@0.41.3(@astrojs/markdown-remark@7.2.1)(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0))(typescript@6.0.3)': + dependencies: + '@astrojs/markdown-satteri': 0.3.3 + '@astrojs/mdx': 7.0.2(@astrojs/markdown-satteri@0.3.3)(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0)) + '@astrojs/sitemap': 3.7.3 + '@pagefind/default-ui': 1.5.2 + '@types/hast': 3.0.4 + '@types/js-yaml': 4.0.9 + '@types/mdast': 4.0.4 + astro: 7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0) + astro-expressive-code: 0.44.0(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0)) + bcp-47: 2.1.1 + hast-util-from-html: 2.0.3 + hast-util-select: 6.0.4 + hast-util-to-string: 3.0.1 + hastscript: 9.0.1 + i18next: 26.3.4(typescript@6.0.3) + js-yaml: 4.3.0 + klona: 2.0.6 + magic-string: 0.30.21 + mdast-util-directive: 3.1.0 + mdast-util-to-markdown: 2.1.2 + mdast-util-to-string: 4.0.0 + pagefind: 1.5.2 + rehype: 13.0.2 + rehype-format: 5.0.1 + remark-directive: 4.0.0 + satteri: 0.9.4 + ultrahtml: 1.6.0 + unified: 11.0.5 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + optionalDependencies: + '@astrojs/markdown-remark': 7.2.1 + transitivePeerDependencies: + - supports-color + - typescript + + '@astrojs/telemetry@3.3.2': + dependencies: + ci-info: 4.4.0 + dset: 3.1.4 + is-docker: 4.0.0 + is-wsl: 3.1.1 + which-pm-runs: 1.1.0 + + '@babel/helper-string-parser@7.29.7': {} + + '@babel/helper-validator-identifier@7.29.7': {} + + '@babel/parser@7.29.7': + dependencies: + '@babel/types': 7.29.7 + + '@babel/types@7.29.7': + dependencies: + '@babel/helper-string-parser': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + + '@bruits/satteri-darwin-arm64@0.9.4': + optional: true + + '@bruits/satteri-darwin-x64@0.9.4': + optional: true + + '@bruits/satteri-linux-arm64-gnu@0.9.4': + optional: true + + '@bruits/satteri-linux-arm64-musl@0.9.4': + optional: true + + '@bruits/satteri-linux-x64-gnu@0.9.4': + optional: true + + '@bruits/satteri-linux-x64-musl@0.9.4': + optional: true + + '@bruits/satteri-wasm32-wasi@0.9.4': + dependencies: + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) + optional: true + + '@bruits/satteri-win32-arm64-msvc@0.9.4': + optional: true + + '@bruits/satteri-win32-x64-msvc@0.9.4': + optional: true + + '@capsizecss/unpack@4.0.1': + dependencies: + fontkitten: 1.0.3 + + '@clack/core@1.4.3': + dependencies: + fast-wrap-ansi: 0.2.2 + sisteransi: 1.0.5 + + '@clack/prompts@1.7.0': + dependencies: + '@clack/core': 1.4.3 + fast-string-width: 3.0.2 + fast-wrap-ansi: 0.2.2 + sisteransi: 1.0.5 + + '@ctrl/tinycolor@4.2.0': {} + + '@emnapi/core@1.11.1': + dependencies: + '@emnapi/wasi-threads': 1.2.2 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.11.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.11.2': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.2': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild/aix-ppc64@0.28.1': + optional: true + + '@esbuild/android-arm64@0.28.1': + optional: true + + '@esbuild/android-arm@0.28.1': + optional: true + + '@esbuild/android-x64@0.28.1': + optional: true + + '@esbuild/darwin-arm64@0.28.1': + optional: true + + '@esbuild/darwin-x64@0.28.1': + optional: true + + '@esbuild/freebsd-arm64@0.28.1': + optional: true + + '@esbuild/freebsd-x64@0.28.1': + optional: true + + '@esbuild/linux-arm64@0.28.1': + optional: true + + '@esbuild/linux-arm@0.28.1': + optional: true + + '@esbuild/linux-ia32@0.28.1': + optional: true + + '@esbuild/linux-loong64@0.28.1': + optional: true + + '@esbuild/linux-mips64el@0.28.1': + optional: true + + '@esbuild/linux-ppc64@0.28.1': + optional: true + + '@esbuild/linux-riscv64@0.28.1': + optional: true + + '@esbuild/linux-s390x@0.28.1': + optional: true + + '@esbuild/linux-x64@0.28.1': + optional: true + + '@esbuild/netbsd-arm64@0.28.1': + optional: true + + '@esbuild/netbsd-x64@0.28.1': + optional: true + + '@esbuild/openbsd-arm64@0.28.1': + optional: true + + '@esbuild/openbsd-x64@0.28.1': + optional: true + + '@esbuild/openharmony-arm64@0.28.1': + optional: true + + '@esbuild/sunos-x64@0.28.1': + optional: true + + '@esbuild/win32-arm64@0.28.1': + optional: true + + '@esbuild/win32-ia32@0.28.1': + optional: true + + '@esbuild/win32-x64@0.28.1': + optional: true + + '@expressive-code/core@0.44.0': + dependencies: + '@ctrl/tinycolor': 4.2.0 + hast-util-select: 6.0.4 + hast-util-to-html: 9.0.5 + hast-util-to-text: 4.0.2 + hastscript: 9.0.1 + postcss: 8.5.16 + postcss-nested: 6.2.0(postcss@8.5.16) + unist-util-visit: 5.1.0 + unist-util-visit-parents: 6.0.2 + + '@expressive-code/plugin-frames@0.44.0': + dependencies: + '@expressive-code/core': 0.44.0 + + '@expressive-code/plugin-shiki@0.44.0': + dependencies: + '@expressive-code/core': 0.44.0 + shiki: 4.3.1 + + '@expressive-code/plugin-text-markers@0.44.0': + dependencies: + '@expressive-code/core': 0.44.0 + + '@img/colour@1.1.0': {} + + '@img/sharp-darwin-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.2.4 + optional: true + + '@img/sharp-darwin-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.2.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.2.4': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-s390x@1.2.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + optional: true + + '@img/sharp-linux-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.4 + optional: true + + '@img/sharp-linux-arm@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.2.4 + optional: true + + '@img/sharp-linux-ppc64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.2.4 + optional: true + + '@img/sharp-linux-riscv64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.2.4 + optional: true + + '@img/sharp-linux-s390x@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.2.4 + optional: true + + '@img/sharp-linux-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + optional: true + + '@img/sharp-wasm32@0.34.5': + dependencies: + '@emnapi/runtime': 1.11.2 + optional: true + + '@img/sharp-win32-arm64@0.34.5': + optional: true + + '@img/sharp-win32-ia32@0.34.5': + optional: true + + '@img/sharp-win32-x64@0.34.5': + optional: true + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@mdx-js/mdx@3.1.1': + dependencies: + '@types/estree': 1.0.9 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdx': 2.0.14 + acorn: 8.17.0 + collapse-white-space: 2.1.0 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-util-scope: 1.0.0 + estree-walker: 3.0.3 + hast-util-to-jsx-runtime: 2.3.6 + markdown-extensions: 2.0.0 + recma-build-jsx: 1.0.0 + recma-jsx: 1.0.1(acorn@8.17.0) + recma-stringify: 1.0.0 + rehype-recma: 1.0.0 + remark-mdx: 3.1.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + source-map: 0.7.6 + unified: 11.0.5 + unist-util-position-from-estree: 2.0.0 + unist-util-stringify-position: 4.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': + dependencies: + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@tybys/wasm-util': 0.10.3 + optional: true + + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)': + dependencies: + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.2 + '@tybys/wasm-util': 0.10.3 + optional: true + + '@oslojs/encoding@1.1.0': {} + + '@oxc-project/types@0.138.0': {} + + '@pagefind/darwin-arm64@1.5.2': + optional: true + + '@pagefind/darwin-x64@1.5.2': + optional: true + + '@pagefind/default-ui@1.5.2': {} + + '@pagefind/freebsd-x64@1.5.2': + optional: true + + '@pagefind/linux-arm64@1.5.2': + optional: true + + '@pagefind/linux-x64@1.5.2': + optional: true + + '@pagefind/windows-arm64@1.5.2': + optional: true + + '@pagefind/windows-x64@1.5.2': + optional: true + + '@rolldown/binding-android-arm64@1.1.4': + optional: true + + '@rolldown/binding-darwin-arm64@1.1.4': + optional: true + + '@rolldown/binding-darwin-x64@1.1.4': + optional: true + + '@rolldown/binding-freebsd-x64@1.1.4': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.1.4': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.1.4': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.1.4': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.1.4': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.1.4': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.1.4': + optional: true + + '@rolldown/binding-linux-x64-musl@1.1.4': + optional: true + + '@rolldown/binding-openharmony-arm64@1.1.4': + optional: true + + '@rolldown/binding-wasm32-wasi@1.1.4': + dependencies: + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.1.4': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.1.4': + optional: true + + '@rolldown/pluginutils@1.0.1': {} + + '@rollup/pluginutils@5.4.0': + dependencies: + '@types/estree': 1.0.9 + estree-walker: 2.0.2 + picomatch: 4.0.5 + + '@shikijs/colorized-brackets@4.3.1': + dependencies: + shiki: 4.3.1 + + '@shikijs/core@4.3.1': + dependencies: + '@shikijs/primitive': 4.3.1 + '@shikijs/types': 4.3.1 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + + '@shikijs/engine-javascript@4.3.1': + dependencies: + '@shikijs/types': 4.3.1 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 4.3.6 + + '@shikijs/engine-oniguruma@4.3.1': + dependencies: + '@shikijs/types': 4.3.1 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@4.3.1': + dependencies: + '@shikijs/types': 4.3.1 + + '@shikijs/primitive@4.3.1': + dependencies: + '@shikijs/types': 4.3.1 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/themes@4.3.1': + dependencies: + '@shikijs/types': 4.3.1 + + '@shikijs/types@4.3.1': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.2': {} + + '@tybys/wasm-util@0.10.3': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.9 + + '@types/estree@1.0.9': {} + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/js-yaml@4.0.9': {} + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdx@2.0.14': {} + + '@types/ms@2.1.0': {} + + '@types/nlcst@2.0.3': + dependencies: + '@types/unist': 3.0.3 + + '@types/node@24.13.2': + dependencies: + undici-types: 7.18.2 + + '@types/node@26.1.0': + dependencies: + undici-types: 8.3.0 + + '@types/sax@1.2.7': + dependencies: + '@types/node': 26.1.0 + + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + + '@ungap/structured-clone@1.3.2': {} + + acorn-jsx@5.3.2(acorn@8.17.0): + dependencies: + acorn: 8.17.0 + + acorn@8.17.0: {} + + am-i-vibing@0.4.0: + dependencies: + process-ancestry: 0.1.0 + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.2 + + arg@5.0.2: {} + + argparse@2.0.1: {} + + aria-query@5.3.2: {} + + array-iterate@2.0.1: {} + + astring@1.9.0: {} + + astro-expressive-code@0.44.0(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0)): + dependencies: + astro: 7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0) + rehype-expressive-code: 0.44.0 + url-extras: 0.1.0 + + astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0): + dependencies: + '@astrojs/compiler-rs': 0.3.0(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2) + '@astrojs/internal-helpers': 0.10.1 + '@astrojs/markdown-satteri': 0.3.3 + '@astrojs/telemetry': 3.3.2 + '@capsizecss/unpack': 4.0.1 + '@clack/prompts': 1.7.0 + '@oslojs/encoding': 1.1.0 + '@rollup/pluginutils': 5.4.0 + am-i-vibing: 0.4.0 + aria-query: 5.3.2 + axobject-query: 4.1.0 + ci-info: 4.4.0 + clsx: 2.1.1 + common-ancestor-path: 2.0.0 + cookie: 1.1.1 + devalue: 5.8.1 + diff: 8.0.4 + dset: 3.1.4 + es-module-lexer: 2.3.0 + esbuild: 0.28.1 + flattie: 1.1.1 + fontace: 0.4.1 + get-tsconfig: 5.0.0-beta.4 + github-slugger: 2.0.0 + html-escaper: 3.0.3 + http-cache-semantics: 4.2.0 + js-yaml: 4.3.0 + jsonc-parser: 3.3.1 + magic-string: 0.30.21 + magicast: 0.5.3 + mrmime: 2.0.1 + neotraverse: 0.6.18 + obug: 2.1.3 + p-limit: 7.3.0 + p-queue: 9.3.1 + package-manager-detector: 1.7.0 + piccolore: 0.1.3 + picomatch: 4.0.5 + semver: 7.8.5 + shiki: 4.3.1 + smol-toml: 1.7.0 + svgo: 4.0.1 + tinyclip: 0.1.15 + tinyexec: 1.2.4 + tinyglobby: 0.2.17 + ultrahtml: 1.6.0 + unifont: 0.7.4 + unstorage: 1.17.5 + vite: 8.1.3(@types/node@26.1.0)(esbuild@0.28.1) + vitefu: 1.1.3(vite@8.1.3(@types/node@26.1.0)(esbuild@0.28.1)) + xxhash-wasm: 1.1.0 + yargs-parser: 22.0.0 + zod: 4.4.3 + optionalDependencies: + '@astrojs/markdown-remark': 7.2.1 + sharp: 0.34.5 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@emnapi/core' + - '@emnapi/runtime' + - '@netlify/blobs' + - '@planetscale/database' + - '@types/node' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - '@vitejs/devtools' + - aws4fetch + - db0 + - idb-keyval + - ioredis + - jiti + - less + - rollup + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - uploadthing + - yaml + + axobject-query@4.1.0: {} + + bail@2.0.2: {} + + bcp-47-match@2.0.3: {} + + bcp-47@2.1.1: + dependencies: + is-alphabetical: 2.0.1 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + + boolbase@1.0.0: {} + + ccount@2.0.1: {} + + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + character-reference-invalid@2.0.1: {} + + chokidar@5.0.0: + dependencies: + readdirp: 5.0.0 + + ci-info@4.4.0: {} + + clsx@2.1.1: {} + + collapse-white-space@2.1.0: {} + + comma-separated-tokens@2.0.3: {} + + commander@11.1.0: {} + + common-ancestor-path@2.0.0: {} + + cookie-es@1.2.3: {} + + cookie@1.1.1: {} + + crossws@0.3.5: + dependencies: + uncrypto: 0.1.3 + + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-selector-parser@3.3.0: {} + + css-tree@2.2.1: + dependencies: + mdn-data: 2.0.28 + source-map-js: 1.2.1 + + css-tree@3.2.1: + dependencies: + mdn-data: 2.27.1 + source-map-js: 1.2.1 + + css-what@6.2.2: {} + + cssesc@3.0.0: {} + + csso@5.0.5: + dependencies: + css-tree: 2.2.1 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + + defu@6.1.7: {} + + dequal@2.0.3: {} + + destr@2.0.5: {} + + detect-libc@2.1.2: {} + + devalue@5.8.1: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + diff@8.0.4: {} + + direction@2.0.1: {} + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dset@3.1.4: {} + + entities@4.5.0: {} + + entities@6.0.1: {} + + es-module-lexer@2.3.0: {} + + esast-util-from-estree@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + unist-util-position-from-estree: 2.0.0 + + esast-util-from-js@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + acorn: 8.17.0 + esast-util-from-estree: 2.0.0 + vfile-message: 4.0.3 + + esbuild@0.28.1: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.1 + '@esbuild/android-arm': 0.28.1 + '@esbuild/android-arm64': 0.28.1 + '@esbuild/android-x64': 0.28.1 + '@esbuild/darwin-arm64': 0.28.1 + '@esbuild/darwin-x64': 0.28.1 + '@esbuild/freebsd-arm64': 0.28.1 + '@esbuild/freebsd-x64': 0.28.1 + '@esbuild/linux-arm': 0.28.1 + '@esbuild/linux-arm64': 0.28.1 + '@esbuild/linux-ia32': 0.28.1 + '@esbuild/linux-loong64': 0.28.1 + '@esbuild/linux-mips64el': 0.28.1 + '@esbuild/linux-ppc64': 0.28.1 + '@esbuild/linux-riscv64': 0.28.1 + '@esbuild/linux-s390x': 0.28.1 + '@esbuild/linux-x64': 0.28.1 + '@esbuild/netbsd-arm64': 0.28.1 + '@esbuild/netbsd-x64': 0.28.1 + '@esbuild/openbsd-arm64': 0.28.1 + '@esbuild/openbsd-x64': 0.28.1 + '@esbuild/openharmony-arm64': 0.28.1 + '@esbuild/sunos-x64': 0.28.1 + '@esbuild/win32-arm64': 0.28.1 + '@esbuild/win32-ia32': 0.28.1 + '@esbuild/win32-x64': 0.28.1 + + escape-string-regexp@5.0.0: {} + + estree-util-attach-comments@3.0.0: + dependencies: + '@types/estree': 1.0.9 + + estree-util-build-jsx@3.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-walker: 3.0.3 + + estree-util-is-identifier-name@3.0.0: {} + + estree-util-scope@1.0.0: + dependencies: + '@types/estree': 1.0.9 + devlop: 1.1.0 + + estree-util-to-js@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + astring: 1.9.0 + source-map: 0.7.6 + + estree-util-visit@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/unist': 3.0.3 + + estree-walker@2.0.2: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.9 + + eventemitter3@5.0.4: {} + + expressive-code@0.44.0: + dependencies: + '@expressive-code/core': 0.44.0 + '@expressive-code/plugin-frames': 0.44.0 + '@expressive-code/plugin-shiki': 0.44.0 + '@expressive-code/plugin-text-markers': 0.44.0 + + extend@3.0.2: {} + + fast-string-truncated-width@3.0.3: {} + + fast-string-width@3.0.2: + dependencies: + fast-string-truncated-width: 3.0.3 + + fast-wrap-ansi@0.2.2: + dependencies: + fast-string-width: 3.0.2 + + fdir@6.5.0(picomatch@4.0.5): + optionalDependencies: + picomatch: 4.0.5 + + flattie@1.1.1: {} + + fontace@0.4.1: + dependencies: + fontkitten: 1.0.3 + + fontkitten@1.0.3: + dependencies: + tiny-inflate: 1.0.3 + + fsevents@2.3.3: + optional: true + + get-tsconfig@5.0.0-beta.4: + dependencies: + resolve-pkg-maps: 1.0.0 + + github-slugger@2.0.0: {} + + h3@1.15.11: + dependencies: + cookie-es: 1.2.3 + crossws: 0.3.5 + defu: 6.1.7 + destr: 2.0.5 + iron-webcrypto: 1.2.1 + node-mock-http: 1.0.4 + radix3: 1.1.2 + ufo: 1.6.4 + uncrypto: 0.1.3 + + hast-util-embedded@3.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-is-element: 3.0.0 + + hast-util-format@1.1.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-embedded: 3.0.0 + hast-util-minify-whitespace: 1.0.1 + hast-util-phrasing: 3.0.1 + hast-util-whitespace: 3.0.0 + html-whitespace-sensitive-tag-names: 3.0.1 + unist-util-visit-parents: 6.0.2 + + hast-util-from-html@2.0.3: + dependencies: + '@types/hast': 3.0.4 + devlop: 1.1.0 + hast-util-from-parse5: 8.0.3 + parse5: 7.3.0 + vfile: 6.0.3 + vfile-message: 4.0.3 + + hast-util-from-parse5@8.0.3: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + devlop: 1.1.0 + hastscript: 9.0.1 + property-information: 7.2.0 + vfile: 6.0.3 + vfile-location: 5.0.3 + web-namespaces: 2.0.1 + + hast-util-has-property@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-is-body-ok-link@3.0.1: + dependencies: + '@types/hast': 3.0.4 + + hast-util-is-element@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-minify-whitespace@1.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-embedded: 3.0.0 + hast-util-is-element: 3.0.0 + hast-util-whitespace: 3.0.0 + unist-util-is: 6.0.1 + + hast-util-parse-selector@4.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-phrasing@3.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-embedded: 3.0.0 + hast-util-has-property: 3.0.0 + hast-util-is-body-ok-link: 3.0.1 + hast-util-is-element: 3.0.0 + + hast-util-raw@9.1.0: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + '@ungap/structured-clone': 1.3.2 + hast-util-from-parse5: 8.0.3 + hast-util-to-parse5: 8.0.1 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + parse5: 7.3.0 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-select@6.0.4: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + bcp-47-match: 2.0.3 + comma-separated-tokens: 2.0.3 + css-selector-parser: 3.3.0 + devlop: 1.1.0 + direction: 2.0.1 + hast-util-has-property: 3.0.0 + hast-util-to-string: 3.0.1 + hast-util-whitespace: 3.0.0 + nth-check: 2.1.1 + property-information: 7.2.0 + space-separated-tokens: 2.0.2 + unist-util-visit: 5.1.0 + zwitch: 2.0.4 + + hast-util-to-estree@3.1.3: + dependencies: + '@types/estree': 1.0.9 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.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.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.2.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + zwitch: 2.0.4 + transitivePeerDependencies: + - supports-color + + hast-util-to-html@9.0.5: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + property-information: 7.2.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.9 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.2.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + hast-util-to-parse5@8.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + property-information: 7.2.0 + space-separated-tokens: 2.0.2 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-to-string@3.0.1: + dependencies: + '@types/hast': 3.0.4 + + hast-util-to-text@4.0.2: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + hast-util-is-element: 3.0.0 + unist-util-find-after: 5.0.0 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hastscript@9.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 7.2.0 + space-separated-tokens: 2.0.2 + + html-escaper@3.0.3: {} + + html-void-elements@3.0.0: {} + + html-whitespace-sensitive-tag-names@3.0.1: {} + + http-cache-semantics@4.2.0: {} + + i18next@26.3.4(typescript@6.0.3): + optionalDependencies: + typescript: 6.0.3 + + inline-style-parser@0.2.7: {} + + iron-webcrypto@1.2.1: {} + + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + + is-decimal@2.0.1: {} + + is-docker@3.0.0: {} + + is-docker@4.0.0: {} + + is-hexadecimal@2.0.1: {} + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-plain-obj@4.1.0: {} + + is-wsl@3.1.1: + dependencies: + is-inside-container: 1.0.0 + + js-yaml@4.3.0: + dependencies: + argparse: 2.0.1 + + jsonc-parser@3.3.1: {} + + klona@2.0.6: {} + + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + + longest-streak@3.1.0: {} + + lru-cache@11.5.1: {} + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + magicast@0.5.3: + dependencies: + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 + source-map-js: 1.2.1 + + markdown-extensions@2.0.0: {} + + markdown-table@3.0.4: {} + + mdast-util-definitions@6.0.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + unist-util-visit: 5.1.0 + + mdast-util-directive@3.1.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-visit-parents: 6.0.2 + transitivePeerDependencies: + - supports-color + + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + mdast-util-from-markdown@2.0.3: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.0.3 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.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.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx@3.0.0: + dependencies: + mdast-util-from-markdown: 2.0.3 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + + mdast-util-to-hast@13.2.1: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.2 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.1.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + mdn-data@2.0.28: {} + + mdn-data@2.27.1: {} + + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-directive@4.0.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + parse-entities: 4.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-expression@3.0.1: + dependencies: + '@types/estree': 1.0.9 + devlop: 1.1.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-jsx@3.0.2: + dependencies: + '@types/estree': 1.0.9 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-extension-mdx-md@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-mdxjs-esm@3.0.0: + dependencies: + '@types/estree': 1.0.9 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-extension-mdxjs@3.0.0: + dependencies: + acorn: 8.17.0 + acorn-jsx: 5.3.2(acorn@8.17.0) + micromark-extension-mdx-expression: 3.0.1 + micromark-extension-mdx-jsx: 3.0.2 + micromark-extension-mdx-md: 2.0.0 + micromark-extension-mdxjs-esm: 3.0.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-mdx-expression@2.0.3: + dependencies: + '@types/estree': 1.0.9 + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-events-to-acorn@2.0.3: + dependencies: + '@types/estree': 1.0.9 + '@types/unist': 3.0.3 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.13 + debug: 4.4.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + + mrmime@2.0.1: {} + + ms@2.1.3: {} + + nanoid@3.3.15: {} + + neotraverse@0.6.18: {} + + nlcst-to-string@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + + node-fetch-native@1.6.7: {} + + node-mock-http@1.0.4: {} + + normalize-path@3.0.0: {} + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + obug@2.1.3: {} + + ofetch@1.5.1: + dependencies: + destr: 2.0.5 + node-fetch-native: 1.6.7 + ufo: 1.6.4 + + ohash@2.0.11: {} + + oniguruma-parser@0.12.2: {} + + oniguruma-to-es@4.3.6: + dependencies: + oniguruma-parser: 0.12.2 + regex: 6.1.0 + regex-recursion: 6.0.2 + + p-limit@7.3.0: + dependencies: + yocto-queue: 1.2.2 + + p-queue@9.3.1: + dependencies: + eventemitter3: 5.0.4 + p-timeout: 7.0.1 + + p-timeout@7.0.1: {} + + package-manager-detector@1.7.0: {} + + pagefind@1.5.2: + optionalDependencies: + '@pagefind/darwin-arm64': 1.5.2 + '@pagefind/darwin-x64': 1.5.2 + '@pagefind/freebsd-x64': 1.5.2 + '@pagefind/linux-arm64': 1.5.2 + '@pagefind/linux-x64': 1.5.2 + '@pagefind/windows-arm64': 1.5.2 + '@pagefind/windows-x64': 1.5.2 + + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.3.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + + parse-latin@7.0.0: + dependencies: + '@types/nlcst': 2.0.3 + '@types/unist': 3.0.3 + nlcst-to-string: 4.0.0 + unist-util-modify-children: 4.0.0 + unist-util-visit-children: 3.0.0 + vfile: 6.0.3 + + parse5@7.3.0: + dependencies: + entities: 6.0.1 + + piccolore@0.1.3: {} + + picocolors@1.1.1: {} + + picomatch@2.3.2: {} + + picomatch@4.0.5: {} + + postcss-nested@6.2.0(postcss@8.5.16): + dependencies: + postcss: 8.5.16 + postcss-selector-parser: 6.1.4 + + postcss-selector-parser@6.1.4: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss@8.5.16: + dependencies: + nanoid: 3.3.15 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prismjs@1.30.0: {} + + process-ancestry@0.1.0: {} + + property-information@7.2.0: {} + + radix3@1.1.2: {} + + readdirp@5.0.0: {} + + recma-build-jsx@1.0.0: + dependencies: + '@types/estree': 1.0.9 + estree-util-build-jsx: 3.0.1 + vfile: 6.0.3 + + recma-jsx@1.0.1(acorn@8.17.0): + dependencies: + acorn: 8.17.0 + acorn-jsx: 5.3.2(acorn@8.17.0) + estree-util-to-js: 2.0.0 + recma-parse: 1.0.0 + recma-stringify: 1.0.0 + unified: 11.0.5 + + recma-parse@1.0.0: + dependencies: + '@types/estree': 1.0.9 + esast-util-from-js: 2.0.1 + unified: 11.0.5 + vfile: 6.0.3 + + recma-stringify@1.0.0: + dependencies: + '@types/estree': 1.0.9 + estree-util-to-js: 2.0.0 + unified: 11.0.5 + vfile: 6.0.3 + + regex-recursion@6.0.2: + dependencies: + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@6.1.0: + dependencies: + regex-utilities: 2.3.0 + + rehype-expressive-code@0.44.0: + dependencies: + expressive-code: 0.44.0 + + rehype-format@5.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-format: 1.1.0 + + rehype-parse@9.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-from-html: 2.0.3 + unified: 11.0.5 + + rehype-raw@7.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-raw: 9.1.0 + vfile: 6.0.3 + + rehype-recma@1.0.0: + dependencies: + '@types/estree': 1.0.9 + '@types/hast': 3.0.4 + hast-util-to-estree: 3.1.3 + transitivePeerDependencies: + - supports-color + + rehype-stringify@10.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + unified: 11.0.5 + + rehype@13.0.2: + dependencies: + '@types/hast': 3.0.4 + rehype-parse: 9.0.1 + rehype-stringify: 10.0.1 + unified: 11.0.5 + + remark-directive@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-directive: 3.1.0 + micromark-extension-directive: 4.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-mdx@3.1.1: + dependencies: + mdast-util-mdx: 3.0.0 + micromark-extension-mdxjs: 3.0.0 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-rehype@11.1.2: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.1 + unified: 11.0.5 + vfile: 6.0.3 + + remark-smartypants@3.0.2: + dependencies: + retext: 9.0.0 + retext-smartypants: 6.2.0 + unified: 11.0.5 + unist-util-visit: 5.1.0 + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + + resolve-pkg-maps@1.0.0: {} + + retext-latin@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + parse-latin: 7.0.0 + unified: 11.0.5 + + retext-smartypants@6.2.0: + dependencies: + '@types/nlcst': 2.0.3 + nlcst-to-string: 4.0.0 + unist-util-visit: 5.1.0 + + retext-stringify@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + nlcst-to-string: 4.0.0 + unified: 11.0.5 + + retext@9.0.0: + dependencies: + '@types/nlcst': 2.0.3 + retext-latin: 4.0.0 + retext-stringify: 4.0.0 + unified: 11.0.5 + + rolldown@1.1.4: + dependencies: + '@oxc-project/types': 0.138.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.1.4 + '@rolldown/binding-darwin-arm64': 1.1.4 + '@rolldown/binding-darwin-x64': 1.1.4 + '@rolldown/binding-freebsd-x64': 1.1.4 + '@rolldown/binding-linux-arm-gnueabihf': 1.1.4 + '@rolldown/binding-linux-arm64-gnu': 1.1.4 + '@rolldown/binding-linux-arm64-musl': 1.1.4 + '@rolldown/binding-linux-ppc64-gnu': 1.1.4 + '@rolldown/binding-linux-s390x-gnu': 1.1.4 + '@rolldown/binding-linux-x64-gnu': 1.1.4 + '@rolldown/binding-linux-x64-musl': 1.1.4 + '@rolldown/binding-openharmony-arm64': 1.1.4 + '@rolldown/binding-wasm32-wasi': 1.1.4 + '@rolldown/binding-win32-arm64-msvc': 1.1.4 + '@rolldown/binding-win32-x64-msvc': 1.1.4 + + satteri@0.9.4: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + optionalDependencies: + '@bruits/satteri-darwin-arm64': 0.9.4 + '@bruits/satteri-darwin-x64': 0.9.4 + '@bruits/satteri-linux-arm64-gnu': 0.9.4 + '@bruits/satteri-linux-arm64-musl': 0.9.4 + '@bruits/satteri-linux-x64-gnu': 0.9.4 + '@bruits/satteri-linux-x64-musl': 0.9.4 + '@bruits/satteri-wasm32-wasi': 0.9.4 + '@bruits/satteri-win32-arm64-msvc': 0.9.4 + '@bruits/satteri-win32-x64-msvc': 0.9.4 + + sax@1.6.0: {} + + semver@7.8.5: {} + + sharp@0.34.5: + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.8.5 + 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 + + shiki@4.3.1: + dependencies: + '@shikijs/core': 4.3.1 + '@shikijs/engine-javascript': 4.3.1 + '@shikijs/engine-oniguruma': 4.3.1 + '@shikijs/langs': 4.3.1 + '@shikijs/themes': 4.3.1 + '@shikijs/types': 4.3.1 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + sisteransi@1.0.5: {} + + sitemap@9.0.1: + dependencies: + '@types/node': 24.13.2 + '@types/sax': 1.2.7 + arg: 5.0.2 + sax: 1.6.0 + + smol-toml@1.7.0: {} + + source-map-js@1.2.1: {} + + source-map@0.7.6: {} + + space-separated-tokens@2.0.2: {} + + starlight-sidebar-topics@0.8.0(@astrojs/starlight@0.41.3(@astrojs/markdown-remark@7.2.1)(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0))(typescript@6.0.3)): + dependencies: + '@astrojs/starlight': 0.41.3(@astrojs/markdown-remark@7.2.1)(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0))(typescript@6.0.3) + picomatch: 4.0.5 + + stream-replace-string@2.0.0: {} + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + style-to-js@1.1.21: + dependencies: + style-to-object: 1.0.14 + + style-to-object@1.0.14: + dependencies: + inline-style-parser: 0.2.7 + + svgo@4.0.1: + dependencies: + commander: 11.1.0 + css-select: 5.2.2 + css-tree: 3.2.1 + css-what: 6.2.2 + csso: 5.0.5 + picocolors: 1.1.1 + sax: 1.6.0 + + tiny-inflate@1.0.3: {} + + tinyclip@0.1.15: {} + + tinyexec@1.2.4: {} + + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.5) + picomatch: 4.0.5 + + trim-lines@3.0.1: {} + + trough@2.2.0: {} + + tslib@2.8.1: + optional: true + + typescript@6.0.3: {} + + ufo@1.6.4: {} + + ultrahtml@1.6.0: {} + + uncrypto@0.1.3: {} + + undici-types@7.18.2: {} + + undici-types@8.3.0: {} + + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unifont@0.7.4: + dependencies: + css-tree: 3.2.1 + ofetch: 1.5.1 + ohash: 2.0.11 + + unist-util-find-after@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-modify-children@4.0.0: + dependencies: + '@types/unist': 3.0.3 + array-iterate: 2.0.1 + + unist-util-position-from-estree@2.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-remove-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-visit: 5.1.0 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-children@3.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.1.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + unstorage@1.17.5: + dependencies: + anymatch: 3.1.3 + chokidar: 5.0.0 + destr: 2.0.5 + h3: 1.15.11 + lru-cache: 11.5.1 + node-fetch-native: 1.6.7 + ofetch: 1.5.1 + ufo: 1.6.4 + + url-extras@0.1.0: {} + + util-deprecate@1.0.2: {} + + vfile-location@5.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile: 6.0.3 + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + vite@8.1.3(@types/node@26.1.0)(esbuild@0.28.1): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.5 + postcss: 8.5.16 + rolldown: 1.1.4 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 26.1.0 + esbuild: 0.28.1 + fsevents: 2.3.3 + + vitefu@1.1.3(vite@8.1.3(@types/node@26.1.0)(esbuild@0.28.1)): + optionalDependencies: + vite: 8.1.3(@types/node@26.1.0)(esbuild@0.28.1) + + web-namespaces@2.0.1: {} + + which-pm-runs@1.1.0: {} + + xxhash-wasm@1.1.0: {} + + yargs-parser@22.0.0: {} + + yocto-queue@1.2.2: {} + + zod@4.4.3: {} + + zwitch@2.0.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..dbb26c8 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,3 @@ +allowBuilds: + esbuild: true + sharp: true diff --git a/postcss.config.mjs b/postcss.config.mjs deleted file mode 100644 index c42f31c..0000000 --- a/postcss.config.mjs +++ /dev/null @@ -1,7 +0,0 @@ -const config = { - plugins: { - "@tailwindcss/postcss": {}, - }, -}; - -export default config; diff --git a/source.config.ts b/source.config.ts deleted file mode 100644 index 067c411..0000000 --- a/source.config.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { metaSchema, pageSchema } from "fumadocs-core/source/schema"; -import { defineConfig, defineDocs } from "fumadocs-mdx/config"; - -// You can customise Zod schemas for frontmatter and `meta.json` here -// see https://fumadocs.dev/docs/mdx/collections -export const docs = defineDocs({ - dir: "content/docs", - docs: { - schema: pageSchema, - postprocess: { - includeProcessedMarkdown: true, - }, - }, - meta: { - schema: metaSchema, - }, -}); - -export default defineConfig({ - mdxOptions: { - // MDX options - }, -}); diff --git a/src/app/(docs)/(main)/[[...slug]]/page.tsx b/src/app/(docs)/(main)/[[...slug]]/page.tsx deleted file mode 100644 index 54ce358..0000000 --- a/src/app/(docs)/(main)/[[...slug]]/page.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { - DocsBody, - DocsDescription, - DocsPage, - DocsTitle, -} from "fumadocs-ui/layouts/notebook/page"; -import type { Metadata } from "next"; -import { notFound } from "next/navigation"; -import { LLMCopyButton } from "@/components/ai/page-actions"; -import { APIPage } from "@/components/api-page"; -import { getPageImage, source } from "@/lib/source"; -import { getMDXComponents } from "@/mdx-components"; - -export default async function Page(props: PageProps<"/[[...slug]]">) { - const params = await props.params; - const page = source.getPage(params.slug); - if (!page) notFound(); - - if (page.type === "openapi") { - return ( - - {page.data.title} - - {page.data.description} - -
- -
- - - -
- ); - } - - const MDX = page.data.body; - - return ( - - {page.data.title} - - {page.data.description} - -
- -
- - - -
- ); -} - -export async function generateStaticParams() { - return source.generateParams(); -} - -export async function generateMetadata( - props: PageProps<"/[[...slug]]">, -): Promise { - const params = await props.params; - const page = source.getPage(params.slug); - if (!page) notFound(); - - return { - title: page.data.title, - description: page.data.description, - openGraph: { - images: getPageImage(page).url, - }, - }; -} diff --git a/src/app/(docs)/(main)/layout.tsx b/src/app/(docs)/(main)/layout.tsx deleted file mode 100644 index c8ed4e4..0000000 --- a/src/app/(docs)/(main)/layout.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { DocsLayout } from "fumadocs-ui/layouts/notebook"; -import { - DocsSidebarBanner, - DocsSidebarFooter, -} from "@/components/docs/docs-sidebar"; -import { getDocsTabs } from "@/lib/docs-tabs"; -import { baseOptions } from "@/lib/layout.shared"; -import { source } from "@/lib/source"; - -export default function Layout({ children }: LayoutProps<"/">) { - return ( - - {children} - - ); -} diff --git a/src/app/(docs)/not-found.tsx b/src/app/(docs)/not-found.tsx deleted file mode 100644 index 84abc7d..0000000 --- a/src/app/(docs)/not-found.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import type { Metadata } from "next"; -import { DocsNotFound } from "@/components/docs/docs-not-found"; - -export const metadata: Metadata = { - title: "Page not found", -}; - -export default function NotFound() { - return ; -} diff --git a/src/app/docs-search/route.ts b/src/app/docs-search/route.ts deleted file mode 100644 index 8c8c78a..0000000 --- a/src/app/docs-search/route.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { createFromSource } from "fumadocs-core/search/server"; -import { source } from "@/lib/source"; - -export const { GET } = createFromSource(source, { - language: "english", -}); diff --git a/src/app/global.css b/src/app/global.css deleted file mode 100644 index 32977bb..0000000 --- a/src/app/global.css +++ /dev/null @@ -1,182 +0,0 @@ -@import "tailwindcss"; -@import "@fontsource-variable/geist"; -@import "@fontsource-variable/geist-mono"; -@import "./tokens.css"; -@import "fumadocs-ui/css/shadcn.css"; -@import "fumadocs-ui/css/preset.css"; -@import "fumadocs-openapi/css/preset.css"; - -* { - border-radius: 0; -} - -#nd-sidebar { - background: color-mix(in oklch, var(--background) 90%, var(--muted)); - border-right: 1px solid var(--border); - font-family: var(--font-mono); -} - -#nd-sidebar [data-search-full] { - width: 100%; -} - -#nd-subnav [data-search-full] { - display: none; -} - -#nd-subnav, -#nd-toc { - font-family: var(--font-mono); -} - -#nd-page > h1 { - font-family: var(--font-mono); - font-size: 1.875rem; - font-weight: 500; - letter-spacing: -0.025em; - line-height: 1.2; -} - -@media (min-width: 768px) { - #nd-page > h1 { - font-size: 2.25rem; - } -} - -#nd-page > p { - max-width: 48rem; - line-height: 1.625; -} - -#nd-page .prose { - color: var(--muted-foreground); - font-size: 1.0625rem; -} - -#nd-page .prose > * + * { - margin-top: 1.25rem; -} - -#nd-page .prose > :is(h1, h2, h3, h4) { - font-family: var(--font-sans); - font-weight: 500; - line-height: 1.35; - letter-spacing: -0.02em; - color: var(--foreground); -} - -#nd-page .prose > :is(h1, h2) { - margin-top: 2.75rem; - font-size: 1.375rem; -} - -#nd-page .prose > h3 { - margin-top: 2rem; - font-size: 1.125rem; -} - -#nd-page .prose > h4 { - margin-top: 1.5rem; - font-size: 1rem; - color: color-mix(in oklch, var(--foreground) 88%, var(--muted-foreground)); -} - -#nd-page .prose > :first-child { - margin-top: 0; -} - -#nd-page .prose > :is(h1, h2, h3, h4) + * { - margin-top: 0.75rem; -} - -#nd-page .prose p { - line-height: 1.75; - max-width: 42rem; -} - -#nd-page .prose li { - max-width: 42rem; - line-height: 1.75; -} - -#nd-page .prose li + li { - margin-top: 0.35rem; -} - -#nd-page .prose > :is(h1, h2, h3, h4) a { - color: inherit; - font-weight: inherit; - text-decoration: none; -} - -#nd-page .prose > :is(h1, h2, h3, h4) a:hover { - text-decoration: none; -} - -#nd-page .prose :is(a) { - text-underline-offset: 2px; -} - -#nd-page .prose :is(code, pre, kbd) { - font-family: var(--font-mono); -} - -#nd-page .prose ul, -#nd-page .prose ol { - margin: 1.25rem 0; - padding-left: 1.5rem; -} - -#nd-page .prose ul { - list-style: square; -} - -#nd-page .prose ol { - list-style: decimal; -} - -#nd-page .prose blockquote { - margin: 1.75rem 0; - max-width: 42rem; - padding: 0 0 0 1.125rem; - border-left: 2px solid - color-mix(in oklch, var(--foreground) 18%, var(--border)); - color: var(--muted-foreground); -} - -#nd-page .prose blockquote p { - line-height: 1.7; -} - -#nd-page .prose blockquote p + p { - margin-top: 0.85rem; -} - -#nd-page .prose blockquote strong { - font-weight: 500; - color: var(--foreground); -} - -#nd-notebook-layout #nd-subnav { - border-bottom: 1px solid var(--border); - backdrop-filter: blur(4px); -} - -@media (min-width: 1024px) { - #nd-subnav:has([data-header-tabs]) { - --fd-header-height: 2.5rem; - } - - #nd-subnav:has([data-header-tabs]) [data-header-body] { - display: none; - } -} - -#nd-page .prose :is(table, blockquote) { - border-width: 1px; -} - -#nd-page .prose :is(strong, b) { - font-weight: 500; - color: var(--foreground); -} diff --git a/src/app/layout.tsx b/src/app/layout.tsx deleted file mode 100644 index 3e1e49d..0000000 --- a/src/app/layout.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { Analytics } from "@faststats/react"; -import { RootProvider } from "fumadocs-ui/provider/next"; -import "./global.css"; -import type { Metadata } from "next"; - -export const metadata: Metadata = { - icons: { - icon: [ - { url: "/icon-light.svg", media: "(prefers-color-scheme: light)" }, - { url: "/icon-dark.svg", media: "(prefers-color-scheme: dark)" }, - ], - }, -}; - -export default function Layout({ children }: LayoutProps<"/">) { - return ( - - - - - {children} - - - - ); -} diff --git a/src/app/llms-full.txt/route.ts b/src/app/llms-full.txt/route.ts deleted file mode 100644 index b5b8fe6..0000000 --- a/src/app/llms-full.txt/route.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { getLLMText, source } from "@/lib/source"; - -export const revalidate = false; - -export async function GET() { - const scan = source.getPages().map(getLLMText); - const scanned = await Promise.all(scan); - - return new Response(scanned.join("\n\n")); -} diff --git a/src/app/llms.mdx/docs/[[...slug]]/route.ts b/src/app/llms.mdx/docs/[[...slug]]/route.ts deleted file mode 100644 index 9c06412..0000000 --- a/src/app/llms.mdx/docs/[[...slug]]/route.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { notFound } from "next/navigation"; -import { getLLMText, source } from "@/lib/source"; - -export const revalidate = false; - -export async function GET( - _req: Request, - { params }: RouteContext<"/llms.mdx/docs/[[...slug]]">, -) { - const { slug } = await params; - const page = source.getPage(slug); - if (!page) notFound(); - - return new Response(await getLLMText(page), { - headers: { - "Content-Type": "text/markdown", - }, - }); -} - -export function generateStaticParams() { - return source.generateParams(); -} diff --git a/src/app/llms.txt/route.ts b/src/app/llms.txt/route.ts deleted file mode 100644 index 4f3f797..0000000 --- a/src/app/llms.txt/route.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { source } from "@/lib/source"; - -export const revalidate = false; - -export async function GET() { - const lines: string[] = []; - lines.push("# Documentation"); - lines.push(""); - for (const page of source.getPages()) { - lines.push(`- [${page.data.title}](${page.url}): ${page.data.description}`); - } - return new Response(lines.join("\n")); -} diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx deleted file mode 100644 index 84abc7d..0000000 --- a/src/app/not-found.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import type { Metadata } from "next"; -import { DocsNotFound } from "@/components/docs/docs-not-found"; - -export const metadata: Metadata = { - title: "Page not found", -}; - -export default function NotFound() { - return ; -} diff --git a/src/app/og/docs/[...slug]/route.tsx b/src/app/og/docs/[...slug]/route.tsx deleted file mode 100644 index 90ecf31..0000000 --- a/src/app/og/docs/[...slug]/route.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { ImageResponse } from "@takumi-rs/image-response"; -import { notFound } from "next/navigation"; -import { OgTemplate } from "@/components/og/og-template"; -import { getPageImage, source } from "@/lib/source"; - -export const revalidate = false; - -export async function GET( - _req: Request, - { params }: RouteContext<"/og/docs/[...slug]">, -) { - const { slug } = await params; - const page = source.getPage(slug.slice(0, -1)); - if (!page) notFound(); - - return new ImageResponse( - , - { - width: 1200, - height: 630, - format: "webp", - }, - ); -} - -export function generateStaticParams() { - return source.getPages().map((page) => ({ - slug: getPageImage(page).segments, - })); -} diff --git a/src/app/tokens.css b/src/app/tokens.css deleted file mode 100644 index 8e1b76e..0000000 --- a/src/app/tokens.css +++ /dev/null @@ -1,142 +0,0 @@ -@custom-variant dark (&:is(.dark *)); - -@theme inline { - --font-sans: "Geist Variable", sans-serif; - --font-mono: "Geist Mono Variable", monospace; - --color-background: var(--background); - --color-foreground: var(--foreground); - --color-card: var(--card); - --color-card-foreground: var(--card-foreground); - --color-popover: var(--popover); - --color-popover-foreground: var(--popover-foreground); - --color-primary: var(--primary); - --color-primary-foreground: var(--primary-foreground); - --color-secondary: var(--secondary); - --color-secondary-foreground: var(--secondary-foreground); - --color-muted: var(--muted); - --color-muted-foreground: var(--muted-foreground); - --color-accent: var(--accent); - --color-accent-foreground: var(--accent-foreground); - --color-destructive: var(--destructive); - --color-destructive-foreground: var(--destructive-foreground); - --color-border: var(--border); - --color-input: var(--input); - --color-ring: var(--ring); - --color-chart-1: var(--chart-1); - --color-chart-2: var(--chart-2); - --color-chart-3: var(--chart-3); - --color-chart-4: var(--chart-4); - --color-chart-5: var(--chart-5); - --color-sidebar: var(--sidebar); - --color-sidebar-foreground: var(--sidebar-foreground); - --color-sidebar-primary: var(--sidebar-primary); - --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); - --color-sidebar-accent: var(--sidebar-accent); - --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); - --color-sidebar-border: var(--sidebar-border); - --color-sidebar-ring: var(--sidebar-ring); - --radius-sm: calc(var(--radius) - 4px); - --radius-md: calc(var(--radius) - 2px); - --radius-lg: var(--radius); - --radius-xl: calc(var(--radius) + 4px); - --radius-2xl: calc(var(--radius) + 8px); - --radius-3xl: calc(var(--radius) + 12px); - --radius-4xl: calc(var(--radius) + 16px); -} - -:root { - --background: oklch(1 0 0); - --foreground: oklch(0.145 0 0); - --card: oklch(0.98 0.001 286.375); - --card-foreground: oklch(0.145 0 0); - --popover: oklch(0.98 0.001 286.375); - --popover-foreground: oklch(0.145 0 0); - --primary: oklch(0.646 0.222 41.116); - --primary-foreground: oklch(0.99 0 0); - --secondary: oklch(0.94 0.01 286); - --secondary-foreground: oklch(0.22 0.01 286); - --muted: oklch(0.93 0.005 286); - --muted-foreground: oklch(0.45 0.01 286); - --accent: oklch(0.93 0.005 286); - --accent-foreground: oklch(0.22 0 0); - --destructive: oklch(0.58 0.22 27); - --border: oklch(0.922 0 0); - --input: oklch(0.922 0 0); - --ring: oklch(0.708 0 0); - --chart-1: oklch(0.837 0.128 66.29); - --chart-2: oklch(0.705 0.213 47.604); - --chart-3: oklch(0.646 0.222 41.116); - --chart-4: oklch(0.553 0.195 38.402); - --chart-5: oklch(0.47 0.157 37.304); - --radius: 0.625rem; - --sidebar: oklch(0.985 0 0); - --sidebar-foreground: oklch(0.145 0 0); - --sidebar-primary: oklch(0.646 0.222 41.116); - --sidebar-primary-foreground: oklch(0.98 0.016 73.684); - --sidebar-accent: oklch(0.97 0 0); - --sidebar-accent-foreground: oklch(0.205 0 0); - --sidebar-border: oklch(0.922 0 0); - --sidebar-ring: oklch(0.708 0 0); - --selection: oklch(0.837 0.128 66.29 / 0.55); - --selection-foreground: oklch(0.32 0.16 38); - --button-emphasis-bg: color-mix(in oklch, var(--primary), white 30%); - --button-emphasis-ring: color-mix(in oklch, var(--primary), black 10%); - --button-emphasis-gradient-start: color-mix( - in oklch, - var(--primary), - white 15% - ); - --button-emphasis-gradient-end: var(--primary); -} - -.dark { - --background: oklch(0.16 0 0); - --foreground: oklch(0.985 0 0); - --card: oklch(0.205 0 0); - --card-foreground: oklch(0.985 0 0); - --popover: oklch(0.205 0 0); - --popover-foreground: oklch(0.985 0 0); - --primary: oklch(0.705 0.213 47.604); - --primary-foreground: oklch(0.98 0.016 73.684); - --secondary: oklch(0.274 0.006 286.033); - --secondary-foreground: oklch(0.985 0 0); - --muted: oklch(0.269 0 0); - --muted-foreground: oklch(0.708 0 0); - --accent: oklch(0.371 0 0); - --accent-foreground: oklch(0.985 0 0); - --destructive: oklch(0.704 0.191 22.216); - --border: oklch(1 0 0 / 10%); - --input: oklch(1 0 0 / 15%); - --ring: oklch(0.556 0 0); - --chart-1: oklch(0.837 0.128 66.29); - --chart-2: oklch(0.705 0.213 47.604); - --chart-3: oklch(0.646 0.222 41.116); - --chart-4: oklch(0.553 0.195 38.402); - --chart-5: oklch(0.47 0.157 37.304); - --sidebar: oklch(0.205 0 0); - --sidebar-foreground: oklch(0.985 0 0); - --sidebar-primary: oklch(0.705 0.213 47.604); - --sidebar-primary-foreground: oklch(0.98 0.016 73.684); - --sidebar-accent: oklch(0.269 0 0); - --sidebar-accent-foreground: oklch(0.985 0 0); - --sidebar-border: oklch(1 0 0 / 10%); - --sidebar-ring: oklch(0.556 0 0); - --selection: oklch(0.705 0.213 47.604 / 0.45); - --selection-foreground: oklch(0.98 0.04 75); -} - -@layer base { - html { - touch-action: manipulation; - } - * { - @apply border-border outline-ring/50; - } - body { - @apply bg-background text-foreground; - } - ::selection { - background-color: var(--selection); - color: var(--selection-foreground); - } -} diff --git a/src/assets/houston.webp b/src/assets/houston.webp new file mode 100644 index 0000000000000000000000000000000000000000..930c164974ad8eb528878f15a98016249b8cf546 GIT binary patch literal 98506 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 b6~t;_wBcJ3AWgga7~Sz~izoKbpAY~5r|m$8 literal 0 HcmV?d00001 diff --git a/src/assets/icon-dark.svg b/src/assets/icon-dark.svg new file mode 100644 index 0000000..c7481d9 --- /dev/null +++ b/src/assets/icon-dark.svg @@ -0,0 +1,4 @@ + + FastStats + + diff --git a/src/assets/icon-light.svg b/src/assets/icon-light.svg new file mode 100644 index 0000000..a9b202a --- /dev/null +++ b/src/assets/icon-light.svg @@ -0,0 +1,4 @@ + + FastStats + + diff --git a/src/components/LinkCard.astro b/src/components/LinkCard.astro new file mode 100644 index 0000000..e69de29 diff --git a/src/components/ReadMore.astro b/src/components/ReadMore.astro new file mode 100644 index 0000000..ccd33ca --- /dev/null +++ b/src/components/ReadMore.astro @@ -0,0 +1,24 @@ +--- +import { Icon } from '@astrojs/starlight/components'; +--- + +

+ + +
+ + \ No newline at end of file diff --git a/src/components/ai/page-actions.tsx b/src/components/ai/page-actions.tsx deleted file mode 100644 index 11a5055..0000000 --- a/src/components/ai/page-actions.tsx +++ /dev/null @@ -1,58 +0,0 @@ -"use client"; -import { cn } from "cnfast"; -import { buttonVariants } from "fumadocs-ui/components/ui/button"; -import { useCopyButton } from "fumadocs-ui/utils/use-copy-button"; -import { Check, Copy } from "lucide-react"; -import { useState } from "react"; - -const cache = new Map(); - -export function LLMCopyButton({ - /** - * A URL to fetch the raw Markdown/MDX content of page - */ - markdownUrl, -}: { - markdownUrl: string; -}) { - const [isLoading, setLoading] = useState(false); - const [checked, onClick] = useCopyButton(async () => { - const cached = cache.get(markdownUrl); - if (cached) return navigator.clipboard.writeText(cached); - - setLoading(true); - - try { - await navigator.clipboard.write([ - new ClipboardItem({ - "text/plain": fetch(markdownUrl).then(async (res) => { - const content = await res.text(); - cache.set(markdownUrl, content); - - return content; - }), - }), - ]); - } finally { - setLoading(false); - } - }); - - return ( - - ); -} diff --git a/src/components/api-page.tsx b/src/components/api-page.tsx deleted file mode 100644 index a66941a..0000000 --- a/src/components/api-page.tsx +++ /dev/null @@ -1,5 +0,0 @@ -"use client"; - -import { createOpenAPIPage } from "fumadocs-openapi/ui"; - -export const APIPage = createOpenAPIPage(); diff --git a/src/components/docs/docs-not-found.tsx b/src/components/docs/docs-not-found.tsx deleted file mode 100644 index 4ff97fd..0000000 --- a/src/components/docs/docs-not-found.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { ArrowLeft, Home } from "lucide-react"; -import Link from "next/link"; -import { SiteBrand } from "@/components/site-brand"; - -export function DocsNotFound() { - return ( -
-
- - - -
-
-
-
-

Error 404

-

- Page not found -

-

- The page you're looking for doesn't exist or has been - moved to a different URL. -

-
-
- - - Back to docs - - - - Go to FastStats - -
-
-
-
- ); -} diff --git a/src/components/docs/docs-sidebar.tsx b/src/components/docs/docs-sidebar.tsx deleted file mode 100644 index 0090420..0000000 --- a/src/components/docs/docs-sidebar.tsx +++ /dev/null @@ -1,75 +0,0 @@ -"use client"; - -import { cn } from "cnfast"; -import Link from "fumadocs-core/link"; -import { buttonVariants } from "fumadocs-ui/components/ui/button"; -import { FullSearchTrigger } from "fumadocs-ui/layouts/shared/slots/search-trigger"; -import { ThemeSwitch } from "fumadocs-ui/layouts/shared/slots/theme-switch"; -import type { ComponentProps, ReactNode, SVGProps } from "react"; -import { docsSocialLinks } from "@/lib/layout.shared"; - -function GitHubIcon({ - className, - ...props -}: SVGProps): ReactNode { - return ( - - ); -} - -export function DocsSidebarBanner({ - className, - children, - ...props -}: ComponentProps<"div">) { - return ( -
- {children} - -
- ); -} - -export function DocsSidebarFooter(props: ComponentProps<"div">) { - return ( -
- {docsSocialLinks.map((link) => ( - - {link.icon === "github" ? ( - - ) : ( - link.icon - )} - - ))} - -
- ); -} diff --git a/src/components/docs/node-preview.tsx b/src/components/docs/node-preview.tsx deleted file mode 100644 index 283d662..0000000 --- a/src/components/docs/node-preview.tsx +++ /dev/null @@ -1,433 +0,0 @@ -import { - ArrowRight, - Calculator, - CheckIcon, - ChevronDown, - CircleHelp, - Clock, - Clock3, - Database, - Filter, - Group, - ListFilter, - type LucideIcon, - Sigma, - Type, - Waves, - X, -} from "lucide-react"; -import type { ReactNode } from "react"; - -// --------------------------------------------------------------------------- -// Category palette (mirrors apps/tanstack .../nodes/node-category-badge.tsx) -// --------------------------------------------------------------------------- - -type NodeBadgeCategory = - | "source" - | "filter" - | "aggregate" - | "group" - | "transform" - | "formula" - | "time" - | "output"; - -const CATEGORY_STYLES: Record< - NodeBadgeCategory, - { border: string; bg: string; icon: string; text: string } -> = { - source: { - border: "border-sky-500/45", - bg: "bg-sky-500/20", - icon: "text-sky-700 dark:text-sky-400", - text: "text-sky-800 dark:text-sky-200/90", - }, - filter: { - border: "border-amber-500/45", - bg: "bg-amber-500/20", - icon: "text-amber-700 dark:text-amber-400", - text: "text-amber-800 dark:text-amber-200/90", - }, - aggregate: { - border: "border-emerald-500/45", - bg: "bg-emerald-500/20", - icon: "text-emerald-700 dark:text-emerald-400", - text: "text-emerald-800 dark:text-emerald-200/90", - }, - group: { - border: "border-teal-500/45", - bg: "bg-teal-500/20", - icon: "text-teal-700 dark:text-teal-400", - text: "text-teal-800 dark:text-teal-200/90", - }, - transform: { - border: "border-violet-500/45", - bg: "bg-violet-500/20", - icon: "text-violet-700 dark:text-violet-400", - text: "text-violet-800 dark:text-violet-200/90", - }, - formula: { - border: "border-fuchsia-500/45", - bg: "bg-fuchsia-500/20", - icon: "text-fuchsia-700 dark:text-fuchsia-400", - text: "text-fuchsia-800 dark:text-fuchsia-200/90", - }, - time: { - border: "border-blue-500/45", - bg: "bg-blue-500/20", - icon: "text-blue-700 dark:text-blue-400", - text: "text-blue-800 dark:text-blue-200/90", - }, - output: { - border: "border-rose-500/45", - bg: "bg-rose-500/20", - icon: "text-rose-700 dark:text-rose-400", - text: "text-rose-800 dark:text-rose-200/90", - }, -}; - -// --------------------------------------------------------------------------- -// Primitives -// --------------------------------------------------------------------------- - -function Handle({ side }: { side: "top" | "bottom" }) { - return ( -
- ); -} - -function CategoryBadge({ - label, - icon: Icon, - category, -}: { - label: string; - icon: LucideIcon; - category: NodeBadgeCategory; -}) { - const styles = CATEGORY_STYLES[category]; - return ( -
-
- - - {label} - -
-
- ); -} - -function NodeShell({ - label, - icon, - category, - handles = "both", - children, - width = 280, -}: { - label: string; - icon: LucideIcon; - category: NodeBadgeCategory; - handles?: "top" | "bottom" | "both"; - children: ReactNode; - width?: number; -}) { - return ( -
- {(handles === "top" || handles === "both") && } - {(handles === "bottom" || handles === "both") && } - -
-
{children}
-
-
- ); -} - -function FieldLabel({ children }: { children: ReactNode }) { - return ( -
- {children} - -
- ); -} - -function Field({ label, children }: { label: string; children: ReactNode }) { - return ( -
- {label} - {children} -
- ); -} - -function FakeInput({ - value, - placeholder, - mono = false, -}: { - value?: string; - placeholder?: string; - mono?: boolean; -}) { - const hasValue = value !== undefined && value !== ""; - return ( -
- {hasValue ? value : placeholder} -
- ); -} - -function FakeSelect({ - value, - mono = false, - icon, -}: { - value: string; - mono?: boolean; - icon?: ReactNode; -}) { - return ( -
- - {icon} - {value} - - -
- ); -} - -function FakeChips({ values }: { values: readonly string[] }) { - return ( -
- {values.map((v) => ( - - {v} - - - ))} -
- ); -} - -function FakeCheckbox({ - label, - checked = false, -}: { - label: string; - checked?: boolean; -}) { - return ( -
-
- {checked ? : null} -
- - {label} - - -
- ); -} - -// --------------------------------------------------------------------------- -// Node previews -// --------------------------------------------------------------------------- - -export function DatasourceNodePreview() { - return ( - - - - - - - - - - ); -} - -export function FilterNodePreview() { - return ( - - - - - - - - - - - - ); -} - -export function AggregateNodePreview() { - return ( - - - - - - ); -} - -export function GroupNodePreview() { - return ( - - - - - - - - - ); -} - -export function TimeGroupNodePreview() { - return ( - - - - - - } - /> - - - - - - ); -} - -export function TextTransformNodePreview() { - return ( - - - - - - ); -} - -export function FormulaNodePreview() { - return ( - - - - - - - - - - - - ); -} - -export function LimitNodePreview() { - return ( - - - - - - - ); -} - -export function MaxAgeNodePreview() { - return ( - - -
- -
- -
-
-
-
- ); -} - -export function MinAgeNodePreview() { - return ( - - -
- -
- -
-
-
-
- ); -} - -export function ResultNodePreview() { - return ( - - - - -

- Final query result for this chart -

-
- ); -} diff --git a/src/components/og/faststats-icon.tsx b/src/components/og/faststats-icon.tsx deleted file mode 100644 index 363d7ef..0000000 --- a/src/components/og/faststats-icon.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import type React from "react"; - -export function FastStatsIcon(props: React.SVGProps) { - return ( - - FastStats - - - ); -} diff --git a/src/components/og/og-template.tsx b/src/components/og/og-template.tsx deleted file mode 100644 index 4244650..0000000 --- a/src/components/og/og-template.tsx +++ /dev/null @@ -1,188 +0,0 @@ -import type React from "react"; -import { FastStatsIcon } from "./faststats-icon"; - -const BG = "#09090b"; -const LINE = "rgba(255, 255, 255, 0.1)"; -const BORDER = "rgba(255, 255, 255, 0.1)"; - -const WIDTH = 1200; -const HEIGHT = 630; -const PADDING = 40; -const MIDDLE_W = WIDTH - 2 * PADDING - 2; -const MIDDLE_H = HEIGHT - 2 * PADDING - 2; - -const frameGrid: React.CSSProperties = { - display: "grid", - width: "100%", - height: "100%", - boxSizing: "border-box", - gridTemplateColumns: `${PADDING}px 1px ${MIDDLE_W}px 1px ${PADDING}px`, - gridTemplateRows: `${PADDING}px 1px ${MIDDLE_H}px 1px ${PADDING}px`, - backgroundColor: BG, - color: "#fafafa", - fontFamily: "Geist Mono, monospace", -}; - -const line = { backgroundColor: LINE }; - -const corner: React.CSSProperties = { - width: "0.4375rem", - height: "0.4375rem", - boxSizing: "border-box", - backgroundColor: BG, - border: `1px solid ${BORDER}`, -}; - -export interface OgTemplateProps { - title: string; - description?: string; - label?: string; -} - -export function OgTemplate({ title, description, label }: OgTemplateProps) { - return ( -
-
-
-
-
-
-
-
-
-
-
-
- -
- FastStats -
-
- -
-
- {title} -
- {description && ( -
- {description} -
- )} -
-
- -
- {label && ( -
- {label} -
- )} -
- faststats.dev -
-
-
-
- ); -} diff --git a/src/components/site-brand.tsx b/src/components/site-brand.tsx deleted file mode 100644 index 895ebf6..0000000 --- a/src/components/site-brand.tsx +++ /dev/null @@ -1,16 +0,0 @@ -export function SiteBrand() { - return ( - - - FastStats - - - - FastStats Docs - - ); -} diff --git a/src/components/starlight/ContentPanel.astro b/src/components/starlight/ContentPanel.astro new file mode 100644 index 0000000..68ea66f --- /dev/null +++ b/src/components/starlight/ContentPanel.astro @@ -0,0 +1,38 @@ +--- +const { + entry: { data }, +} = Astro.locals.starlightRoute; + +const isAPIDoc = data.type === "api-doc"; +--- + +
+
+
+ + diff --git a/src/components/starlight/Sidebar.astro b/src/components/starlight/Sidebar.astro new file mode 100644 index 0000000..2b3dc7f --- /dev/null +++ b/src/components/starlight/Sidebar.astro @@ -0,0 +1,23 @@ +--- +import Default from "@astrojs/starlight/components/Sidebar.astro"; +import TopicsSelector from "./topics/TopicsSelector.astro"; +--- + + + + diff --git a/src/components/starlight/topics/Topics.astro b/src/components/starlight/topics/Topics.astro new file mode 100644 index 0000000..9c6353e --- /dev/null +++ b/src/components/starlight/topics/Topics.astro @@ -0,0 +1,134 @@ +--- +import starlightConfig from 'virtual:starlight/user-config'; +import { Badge, Icon } from '@astrojs/starlight/components'; +import { AstroError } from 'astro/errors'; +import type { ComponentProps } from 'astro/types'; + +const { topics } = Astro.locals.starlightSidebarTopics; + +const defaultLang = + starlightConfig.defaultLocale?.lang || starlightConfig.defaultLocale?.locale || 'en'; + +function getTranslation(translations: Record, link: string, description: string) { + const defaultTranslation = translations[defaultLang]; + + if (!defaultTranslation) { + throw new AstroError( + `The ${description} for "${link}" must have a key for the default language "${defaultLang}".`, + 'Update the Starlight config to include a topic label for the default language.' + ); + } + + let translation = defaultTranslation; + + if (Astro.currentLocale) { + translation = translations[Astro.currentLocale] ?? defaultTranslation; + } + + return translation; +} +--- + + + \ No newline at end of file diff --git a/src/components/starlight/topics/TopicsSelector.astro b/src/components/starlight/topics/TopicsSelector.astro new file mode 100644 index 0000000..ecb3233 --- /dev/null +++ b/src/components/starlight/topics/TopicsSelector.astro @@ -0,0 +1,8 @@ +--- +import Topics from './Topics.astro'; + +const { hasSidebar } = Astro.locals.starlightRoute; +const { isPageWithTopic } = Astro.locals.starlightSidebarTopics; +--- + +{hasSidebar && isPageWithTopic && } diff --git a/src/content.config.ts b/src/content.config.ts new file mode 100644 index 0000000..7386cd4 --- /dev/null +++ b/src/content.config.ts @@ -0,0 +1,30 @@ +import { defineCollection, type CollectionEntry } from 'astro:content'; +import { docsLoader } from '@astrojs/starlight/loaders'; +import { docsSchema } from '@astrojs/starlight/schema'; +import { topicSchema } from 'starlight-sidebar-topics/schema'; +import { z } from 'astro/zod'; + +const baseSchema = topicSchema.extend({ + type: z.literal('base').optional().default('base'), +}); + +const apiDocSchema = baseSchema.extend({ + type: z.literal('api-doc'), +}); + +export const docsCollectionSchema = z.union([baseSchema, apiDocSchema]); + +export type DocsEntryData = z.infer; + +export type DocsEntryType = DocsEntryData['type']; + +export type DocsEntry = CollectionEntry<'docs'> & { + data: Extract; +}; + +export const collections = { + docs: defineCollection({ + loader: docsLoader(), + schema: docsSchema({ extend: docsCollectionSchema }) + }), +}; diff --git a/content/docs/api/index.mdx b/src/content/docs/api/index.mdx similarity index 81% rename from content/docs/api/index.mdx rename to src/content/docs/api/index.mdx index c672b60..a5a778f 100644 --- a/content/docs/api/index.mdx +++ b/src/content/docs/api/index.mdx @@ -4,16 +4,18 @@ description: FastStats REST API reference icon: BookOpen --- +import { Aside } from "@astrojs/starlight/components" + Use the FastStats REST API to manage projects, dashboards, charts, and analytics data programmatically. Create an API key in your user or organization settings. - + - + The OpenAPI spec is available at [api.faststats.dev/openapi.json](https://api.faststats.dev/openapi.json). diff --git a/src/content/docs/index.mdx b/src/content/docs/index.mdx new file mode 100644 index 0000000..03f9896 --- /dev/null +++ b/src/content/docs/index.mdx @@ -0,0 +1,41 @@ +--- +title: Welcome to Starlight +description: Get started building your docs site with Starlight. +# template: splash # Remove or comment out this line to display the site sidebar on this page. +hero: + tagline: Congrats on setting up a new Starlight project! + image: + file: ../../assets/houston.webp + actions: + - text: Example Guide + link: /guides/example/ + icon: right-arrow + - text: Read the Starlight docs + link: https://starlight.astro.build + icon: external + variant: minimal +topic: platform +--- + +import { Card, CardGrid } from '@astrojs/starlight/components'; + +## Next steps + + + + Edit `src/content/docs/index.mdx` to see this page change. + + + Delete `template: splash` in `src/content/docs/index.mdx` to display a + sidebar on this page. + + + Add Markdown or MDX files to `src/content/docs` to create new pages. + + + Edit your `sidebar` and other config in `astro.config.mjs`. + + + Learn more in [the Starlight Docs](https://starlight.astro.build/). + + diff --git a/content/docs/platform/error-tracking/index.mdx b/src/content/docs/platform/error-tracking.mdx similarity index 100% rename from content/docs/platform/error-tracking/index.mdx rename to src/content/docs/platform/error-tracking.mdx diff --git a/content/docs/platform/guide/badges.mdx b/src/content/docs/platform/guide/badges.mdx similarity index 100% rename from content/docs/platform/guide/badges.mdx rename to src/content/docs/platform/guide/badges.mdx diff --git a/content/docs/platform/guide/embed.mdx b/src/content/docs/platform/guide/embed.mdx similarity index 100% rename from content/docs/platform/guide/embed.mdx rename to src/content/docs/platform/guide/embed.mdx diff --git a/content/docs/platform/hotkeys.mdx b/src/content/docs/platform/hotkeys.mdx similarity index 95% rename from content/docs/platform/hotkeys.mdx rename to src/content/docs/platform/hotkeys.mdx index f998327..3b93e68 100644 --- a/content/docs/platform/hotkeys.mdx +++ b/src/content/docs/platform/hotkeys.mdx @@ -4,14 +4,16 @@ description: Keyboard shortcuts in the FastStats dashboard icon: Keyboard --- +import { Aside } from '@astrojs/starlight/components'; + Use keyboard shortcuts to move around the dashboard and open common actions without reaching for the mouse. Most navigation shortcuts are **key sequences**: press the first key, then the second (for example, `G` then `S`). They only work when your focus is not inside a text field. - + ## Project navigation diff --git a/content/docs/platform/index.mdx b/src/content/docs/platform/index.mdx similarity index 80% rename from content/docs/platform/index.mdx rename to src/content/docs/platform/index.mdx index af84747..cdff7e5 100644 --- a/content/docs/platform/index.mdx +++ b/src/content/docs/platform/index.mdx @@ -4,18 +4,22 @@ description: Your introduction to FastStats icon: BookOpen --- +import { LinkCard, CardGrid } from '@astrojs/starlight/components'; + FastStats is a metrics platform made for developers. Collect custom events, monitor performance, and gain insights through focused dashboards. ## Get Started - - - Publish charts anywhere that supports images. - - - Shields.io badges for servers, players, events, and more. - - + + + + ## SDKs diff --git a/content/docs/platform/retention/index.mdx b/src/content/docs/platform/retention.mdx similarity index 100% rename from content/docs/platform/retention/index.mdx rename to src/content/docs/platform/retention.mdx diff --git a/src/integrations/dev-file-watcher.ts b/src/integrations/dev-file-watcher.ts new file mode 100644 index 0000000..5735040 --- /dev/null +++ b/src/integrations/dev-file-watcher.ts @@ -0,0 +1,35 @@ +import { glob } from 'node:fs/promises'; +import type { AstroIntegration } from 'astro'; +import { fileURLToPath } from 'node:url'; + +/** + * Astro integration that registers the passed paths so that saving them triggers a dev server + * restart. + * + * It also supports passing glob patterns to watch a set of files matching a specific pattern. + * + * @param paths Array of file paths relative to the project root. + * + * @example + * // astro.config.mjs + * export default { + * integrations: [ + * devServerFileWatcher(["./example.js", "./src/content/demo/*.yml"]), + * ], + * } + */ +export const devServerFileWatcher = (paths: string[]) => + ({ + name: 'dev-server-file-watcher', + hooks: { + async 'astro:config:setup'({ addWatchFile, config }) { + const cwd = fileURLToPath(config.root); + + for (const path of paths) { + for await (const file of glob(path, { cwd })) { + addWatchFile(new URL(file, config.root)); + } + } + }, + }, + }) satisfies AstroIntegration; diff --git a/src/lib/docs-tabs.tsx b/src/lib/docs-tabs.tsx deleted file mode 100644 index ef9dac0..0000000 --- a/src/lib/docs-tabs.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import type { Root } from "fumadocs-core/page-tree"; -import { - type GetLayoutTabsOptions, - getLayoutTabs, - type LayoutTab, -} from "fumadocs-ui/layouts/shared"; -import { BookOpen, Coffee, Globe, LayoutDashboard } from "lucide-react"; - -const transform: NonNullable = ( - option, - node, -) => { - if (node.$id === "platform") { - return { - ...option, - url: "/platform", - title: ( - - - Platform - - ), - }; - } - - if (node.$id === "java") { - return { - ...option, - url: "/java", - title: ( - - - Java - - ), - }; - } - - if (node.$id === "api") { - return { - ...option, - url: "/api", - title: ( - - - Rest API - - ), - }; - } - - if (node.$id === "web-analytics") { - return { - ...option, - url: "/web-analytics", - title: ( - - - Web Analytics - - Coming Soon - - - ), - }; - } - - return option; -}; - -export function getDocsTabs(tree: Root): LayoutTab[] { - return getLayoutTabs(tree, { transform }); -} diff --git a/src/lib/docs/repository.ts b/src/lib/docs/repository.ts deleted file mode 100644 index 8617a35..0000000 --- a/src/lib/docs/repository.ts +++ /dev/null @@ -1,19 +0,0 @@ -export async function latestVersion(project: string): Promise { - try { - const response = await fetch( - `https://repo.faststats.dev/api/maven/latest/version/releases/dev/faststats/metrics/${project}`, - { - cache: "force-cache", - }, - ); - - if (!response.ok) { - return "VERSION"; - } - - const data = await response.json(); - return data.version; - } catch { - return "VERSION"; - } -} diff --git a/src/lib/layout.shared.tsx b/src/lib/layout.shared.tsx deleted file mode 100644 index ce0371f..0000000 --- a/src/lib/layout.shared.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import type { BaseLayoutProps } from "fumadocs-ui/layouts/shared"; -import type { ReactNode, SVGProps } from "react"; -import { SiteBrand } from "@/components/site-brand"; - -function DiscordIcon({ - className, - ...props -}: SVGProps): ReactNode { - return ( - - ); -} - -export const docsSocialLinks = [ - { - url: "https://github.com/faststats-dev", - label: "GitHub", - icon: "github" as const, - external: true, - }, - { - url: "https://discord.com/invite/SKnDU5VwMS", - label: "Discord", - icon: , - external: true, - }, -]; - -export function baseOptions(): BaseLayoutProps { - return { - nav: { - title: , - url: "/platform", - }, - }; -} diff --git a/src/lib/openapi.ts b/src/lib/openapi.ts deleted file mode 100644 index ca33cef..0000000 --- a/src/lib/openapi.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { createOpenAPI } from "fumadocs-openapi/server"; - -const API_ORIGIN = "https://api.faststats.dev"; -const openApiUrl = `${API_ORIGIN}/openapi.json`; - -const schema = await fetch(openApiUrl).then((response) => { - if (!response.ok) { - throw new Error( - `Failed to fetch OpenAPI schema from ${openApiUrl}: ${response.status}`, - ); - } - - return response.json(); -}); - -export const openapi = createOpenAPI({ - input: { - [openApiUrl]: schema, - }, -}); diff --git a/src/lib/source.ts b/src/lib/source.ts deleted file mode 100644 index 4abe350..0000000 --- a/src/lib/source.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { type InferPageType, loader } from "fumadocs-core/source"; -import { lucideIconsPlugin } from "fumadocs-core/source/lucide-icons"; -import { docs } from "fumadocs-mdx:collections/server"; -import { openapiPlugin, openapiSource } from "fumadocs-openapi/server"; -import { openapi } from "@/lib/openapi"; - -const openapiDocs = await openapiSource(openapi, { - baseDir: "api", - meta: true, - groupBy: "tag", -}); - -const openapiRootMeta = openapiDocs.files.find( - (file) => file.path === "api/meta.json", -); -if (openapiRootMeta?.type === "meta") { - openapiRootMeta.data = { - ...openapiRootMeta.data, - root: true, - title: "Rest API", - icon: "BookOpen", - pages: ["index", ...(openapiRootMeta.data.pages ?? [])], - }; -} - -export const source = loader( - { - docs: docs.toFumadocsSource(), - openapi: openapiDocs, - }, - { - baseUrl: "/", - plugins: [lucideIconsPlugin(), openapiPlugin()], - }, -); - -export function getPageImage(page: InferPageType) { - const segments = [...page.slugs, "image.webp"]; - - return { - segments, - url: `/og/docs/${segments.join("/")}`, - }; -} - -export async function getLLMText(page: InferPageType) { - if (page.type === "openapi") { - return JSON.stringify(page.data.getSchema().bundled, null, 2); - } - - const processed = await page.data.getText("processed"); - - return `# ${page.data.title} - -${processed}`; -} diff --git a/src/mdx-components.tsx b/src/mdx-components.tsx deleted file mode 100644 index 269fc52..0000000 --- a/src/mdx-components.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import * as TabsComponents from "fumadocs-ui/components/tabs"; -import defaultMdxComponents from "fumadocs-ui/mdx"; -import type { MDXComponents } from "mdx/types"; -import { APIPage } from "@/components/api-page"; - -export function getMDXComponents(components?: MDXComponents): MDXComponents { - return { - ...defaultMdxComponents, - ...TabsComponents, - APIPage, - ...components, - }; -} diff --git a/src/styles/starlight.css b/src/styles/starlight.css new file mode 100644 index 0000000..0780e3a --- /dev/null +++ b/src/styles/starlight.css @@ -0,0 +1,117 @@ +/* Dark mode colors. */ +:root { + --sl-color-accent-low: oklch(0.47 0.157 37.304); + --sl-color-accent: oklch(0.646 0.222 41.116); + --sl-color-accent-high: oklch(0.837 0.128 66.29); + --sl-color-accent-bleached: rgba(205, 185, 248, 0.1); + --sl-color-white: #ffffff; + --sl-color-gray-1: #d1d1d1; + --sl-color-gray-2: #b4b4b4; + --sl-color-gray-3: #969696; + --sl-color-gray-4: #4d4d4d; + --sl-color-gray-5: #383838; + --sl-color-gray-6: #191919; + --sl-color-black: #0f0f0f; + + --landing-card-2nd-accent-low: oklch(0.47 0.157 37.304); + --landing-card-2nd-accent: oklch(0.646 0.222 41.116); + --landing-card-2nd-accent-high: oklch(0.837 0.128 66.29); + + --sl-custom-code-color: var(--sl-color-gray-5); + + /* --sl-font: "Onest Variable"; */ +} + +/* Light mode colors. */ +:root[data-theme="light"] { + --sl-color-accent-low: oklch(0.837 0.128 66.29); + --sl-color-accent: oklch(0.646 0.222 41.116); + --sl-color-accent-high: oklch(0.553 0.195 38.402); + --sl-color-accent-bleached: rgba(15, 15, 15, 0.1); + --sl-color-white: #1f1f1f; + --sl-color-gray-1: #202020; + --sl-color-gray-2: #383838; + --sl-color-gray-3: #5c5c5c; + --sl-color-gray-4: #838383; + --sl-color-gray-5: #afafaf; + --sl-color-gray-6: #cecece; + --sl-color-gray-7: #f8f4fe; + --sl-color-black: #ffffff; + + --landing-card-2nd-accent-low: oklch(0.646 0.222 41.116); + --landing-card-2nd-accent: oklch(0.837 0.128 66.29); + --landing-card-2nd-high: oklch(0.98 0 0); + + --sl-custom-code-color: var(--sl-color-gray-6); +} + +.sl-link-button:first-of-type:not(.discord-button) svg { + transition: transform .15s ease !important; +} + +.sl-link-button:first-of-type:hover:not(.discord-button)>svg { + transform: translateX(5px); +} + +.card { + border-radius: 8px; +} + +div.expressive-code, +starlight-file-tree { + border-radius: 8px; + overflow: hidden; +} + +starlight-file-tree { + border: 1px solid var(--ec-brdCol); +} + +aside.starlight-aside { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} + +@media (max-width: 50rem) { + .hero>img { + width: min(50%, 16rem); + } +} + +main[data-pagefind-body] { + overflow: hidden !important; +} + +#starlight__sidebar [aria-current="page"] span { + color: black !important; +} + +[data-theme="light"] #starlight__sidebar [aria-current="page"] span { + color: white !important; +} + +button[aria-label="Menu"][aria-controls="starlight__sidebar"] { + background-color: var(--sl-color-white); + padding: 0.5rem; +} + +[data-theme="light"] button[aria-label="Menu"][aria-controls="starlight__sidebar"] { + background-color: var(--sl-color-black); + padding: 0.5rem; +} + +.card-grid { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; +} + +a { + text-decoration: none; +} + +.expressive-code figcaption, +.expressive-code figcaption::before, +.expressive-code pre, +.expressive-code span.title { + border: none !important; +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index da20c06..9f43b62 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,34 +1,17 @@ { - "compilerOptions": { - "target": "ESNext", - "lib": ["dom", "dom.iterable", "esnext"], - "allowJs": true, - "skipLibCheck": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "noEmit": true, - "esModuleInterop": true, - "module": "esnext", - "moduleResolution": "bundler", - "resolveJsonModule": true, - "isolatedModules": true, - "jsx": "react-jsx", - "paths": { - "@/*": ["./src/*"], - "fumadocs-mdx:collections/*": ["./.source/*"] - }, - "plugins": [ - { - "name": "next" - } - ] - }, - "include": [ - "next-env.d.ts", - "**/*.ts", - "**/*.tsx", - ".next/types/**/*.ts", - ".next/dev/types/**/*.ts" - ], - "exclude": ["node_modules"] -} + "extends": "astro/tsconfigs/strict", + "include": [ + ".astro/types.d.ts", + "**/*" + ], + "exclude": [ + "dist" + ], + "compilerOptions": { + "paths": { + "$/*": [ + "./src/*" + ] + } + } +} \ No newline at end of file From 6cfb39bdabbc689615ced4e1fd243accc14037c1 Mon Sep 17 00:00:00 2001 From: Adam Matthiesen Date: Sun, 5 Jul 2026 16:41:30 -0700 Subject: [PATCH 02/40] Refactor ContentPanel component and update content configuration - Simplified ContentPanel by removing API doc specific logic and styles. - Updated content configuration to remove unused schemas and types, streamlining the docs collection. - Added variable font imports for Geist and Geist Mono, and updated font styles in CSS. --- astro.config.ts | 38 +- package.json | 4 + pnpm-lock.yaml | 624 ++++++++++++++++++++ src/components/starlight/ContentPanel.astro | 12 +- src/content.config.ts | 23 +- src/styles/starlight.css | 12 +- 6 files changed, 680 insertions(+), 33 deletions(-) diff --git a/astro.config.ts b/astro.config.ts index e6f83bf..be24674 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -3,6 +3,8 @@ import { defineConfig } from 'astro/config'; import starlight from '@astrojs/starlight'; import starlightSidebarTopicsPlugin from 'starlight-sidebar-topics'; import { devServerFileWatcher } from './src/integrations/dev-file-watcher'; +import starlightCopyButton from 'starlight-copy-button'; +import starlightOpenAPI, { openAPISidebarGroups } from 'starlight-openapi' // https://astro.build/config export default defineConfig({ @@ -49,6 +51,7 @@ export default defineConfig({ components: { Sidebar: './src/components/starlight/Sidebar.astro', + ContentPanel: './src/components/starlight/ContentPanel.astro', }, customCss: [ @@ -60,6 +63,33 @@ export default defineConfig({ }, plugins: [ + starlightCopyButton({ + label: "Copy Markdown", + }), + starlightOpenAPI([ + { + base: "api", + sidebar: { + label: "API Reference", + operations: { + badges: true, + labels: 'summary', + } + }, + snippets: { + operation: { + clients: { + shell: ['curl'], + javascript: ['fetch'], + go: ['nethttp'], + java: ['nethttp'], + csharp: ['httpclient'] + }, + } + }, + schema: "https://api.faststats.dev/openapi.json", + } + ]), starlightSidebarTopicsPlugin([ { label: 'Platform', @@ -87,7 +117,7 @@ export default defineConfig({ id: 'api', link: '/api/', icon: 'open-book', - items: [{ autogenerate: { directory: 'api' } }], + items: openAPISidebarGroups, }, { label: 'Web Analytics', @@ -100,7 +130,11 @@ export default defineConfig({ variant: 'tip' } } - ]) + ], { + topics: { + api: ['/api/**/*'] + } + }) ] }), ], diff --git a/package.json b/package.json index f6a528c..e09118a 100644 --- a/package.json +++ b/package.json @@ -11,10 +11,14 @@ }, "dependencies": { "@astrojs/starlight": "^0.41.3", + "@fontsource-variable/geist": "^5.2.9", + "@fontsource-variable/geist-mono": "^5.2.8", "@shikijs/colorized-brackets": "^4.3.1", "@types/node": "^26.1.0", "astro": "^7.0.2", "sharp": "^0.34.5", + "starlight-copy-button": "github:dionysuzx/starlight-copy-button", + "starlight-openapi": "^0.26.0", "starlight-sidebar-topics": "^0.8.0", "typescript": "^6.0.3" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4198528..b0cde8f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,12 @@ importers: '@astrojs/starlight': specifier: ^0.41.3 version: 0.41.3(@astrojs/markdown-remark@7.2.1)(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0))(typescript@6.0.3) + '@fontsource-variable/geist': + specifier: ^5.2.9 + version: 5.2.9 + '@fontsource-variable/geist-mono': + specifier: ^5.2.8 + version: 5.2.8 '@shikijs/colorized-brackets': specifier: ^4.3.1 version: 4.3.1 @@ -23,6 +29,12 @@ importers: sharp: specifier: ^0.34.5 version: 0.34.5 + starlight-copy-button: + specifier: github:dionysuzx/starlight-copy-button + version: https://codeload.github.com/dionysuzx/starlight-copy-button/tar.gz/d570fcab6824127f80076eb419f39fb4fbd9de09(@astrojs/starlight@0.41.3(@astrojs/markdown-remark@7.2.1)(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0))(typescript@6.0.3))(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0)) + starlight-openapi: + specifier: ^0.26.0 + version: 0.26.0(@astrojs/markdown-satteri@0.3.3)(@astrojs/starlight@0.41.3(@astrojs/markdown-remark@7.2.1)(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0))(typescript@6.0.3))(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0))(openapi-types@12.1.3) starlight-sidebar-topics: specifier: ^0.8.0 version: 0.8.0(@astrojs/starlight@0.41.3(@astrojs/markdown-remark@7.2.1)(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0))(typescript@6.0.3)) @@ -32,6 +44,10 @@ importers: packages: + '@apidevtools/json-schema-ref-parser@13.0.5': + resolution: {integrity: sha512-xfh4xVJD62gG6spIc7lwxoWT+l16nZu1ELyU8FkjaP/oD2yP09EvLAU6KhtudN9aML2Khhs9pY6Slr7KGTES3w==} + engines: {node: '>= 16'} + '@astrojs/compiler-binding-darwin-arm64@0.3.0': resolution: {integrity: sha512-3n0uu+uJpnCq8b4JFi3uGDsIisAvHctxSmH+cIO9Gbei1H1Y1QXaYboXyiWJugUmprr3OEYP7+LdodzpVFzLMQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -136,6 +152,10 @@ packages: resolution: {integrity: sha512-j8DNruA8ors99Al39RYZPJK4DC1bKkoNm93mAMuBhY9TCNC4R8n1q7ovFnJ5qhGh5Lsh7pa1gpQVpYpsJPeTHQ==} engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} + '@babel/code-frame@7.29.7': + resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.29.7': resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} engines: {node: '>=6.9.0'} @@ -149,6 +169,10 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/runtime@7.29.7': + resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==} + engines: {node: '>=6.9.0'} + '@babel/types@7.29.7': resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==} engines: {node: '>=6.9.0'} @@ -398,6 +422,16 @@ packages: '@expressive-code/plugin-text-markers@0.44.0': resolution: {integrity: sha512-0/m3A5b+lz2upyNq+wzZ1S69HRoJmyFs5LsR42lVZ9pmGRlBiSBYQpvqlji4DBj1+Riamxc0AvcCr5kuzOQeWA==} + '@fontsource-variable/geist-mono@5.2.8': + resolution: {integrity: sha512-KI5bj+hkkRiHttYHmccotUZ80ZuZyai+RwI1d7UId0clkx/jXxlo8qYK8j54WzmpBjtMoEMPyllV7faDcj+6RA==} + + '@fontsource-variable/geist@5.2.9': + resolution: {integrity: sha512-TP+QSBG3wxKGPE33CbMy/L0Nu3qvJ6Fy81Yc4LnQ95xH+i+cfEp8fyU8/kfV14YwszxIFPhnoMTbjL71waVpyQ==} + + '@humanwhocodes/momoa@2.0.4': + resolution: {integrity: sha512-RE815I4arJFtt+FVeU1Tgp9/Xvecacji8w/V6XtXsWWH/wz/eNkNbhb+ny/+PlVZjV0rxQpRSQKNKE3lcktHEA==} + engines: {node: '>=10.10.0'} + '@img/colour@1.1.0': resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} engines: {node: '>=18'} @@ -557,6 +591,9 @@ packages: '@mdx-js/mdx@3.1.1': resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} + '@mixmark-io/domino@2.2.0': + resolution: {integrity: sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==} + '@napi-rs/wasm-runtime@1.1.6': resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==} peerDependencies: @@ -607,6 +644,22 @@ packages: cpu: [x64] os: [win32] + '@readme/better-ajv-errors@2.4.0': + resolution: {integrity: sha512-9WODaOAKSl/mU+MYNZ2aHCrkoRSvmQ+1YkLj589OEqqjOAhbn8j7Z+ilYoiTu/he6X63/clsxxAB4qny9/dDzg==} + engines: {node: '>=18'} + peerDependencies: + ajv: 4.11.8 - 8 + + '@readme/openapi-parser@4.1.2': + resolution: {integrity: sha512-lAFH88r/CHs5VZDUocEda0OSMSQsr6801sziIjOKyVA+0hSFN+BPuelPF5XvkMROHecnPd+XEJN1iNQqCgER/g==} + engines: {node: '>=20'} + peerDependencies: + openapi-types: '>=7' + + '@readme/openapi-schemas@3.1.0': + resolution: {integrity: sha512-9FC/6ho8uFa8fV50+FPy/ngWN53jaUu4GRXlAjcxIRrzhltJnpKkBG2Tp0IDraFJeWrOpk84RJ9EMEEYzaI1Bw==} + engines: {node: '>=18'} + '@rolldown/binding-android-arm64@1.1.4': resolution: {integrity: sha512-EZLpf/8y7GXkkra90ML47kzik/GMP3EMcE9bPyHmRfxLC6z9+aW5A8poCsoxjrT5GfEcNAAvWwUHjvP1pUQkfw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -767,6 +820,9 @@ packages: '@types/js-yaml@4.0.9': resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} @@ -807,10 +863,29 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + ajv-draft-04@1.0.0: + resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} + peerDependencies: + ajv: ^8.5.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} + am-i-vibing@0.4.0: resolution: {integrity: sha512-MxT4XZL7pzLHpuvhDKdMaQHMGGkJDLluKBLsbstn+8wv9sWcFT6h+0ve9qkml95amVTZtZV83gQe2hY+ojgHLg==} hasBin: true + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} @@ -847,6 +922,9 @@ packages: '@astrojs/markdown-remark': optional: true + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} @@ -863,9 +941,17 @@ packages: boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + character-entities-html4@2.1.0: resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} @@ -886,6 +972,10 @@ packages: resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} engines: {node: '>=8'} + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} @@ -893,6 +983,17 @@ packages: collapse-white-space@2.1.0: resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} @@ -956,6 +1057,10 @@ packages: defu@6.1.7: resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} @@ -998,6 +1103,16 @@ packages: resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} engines: {node: '>=4'} + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -1006,9 +1121,25 @@ packages: resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} engines: {node: '>=0.12'} + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + es-module-lexer@2.3.0: resolution: {integrity: sha512-KLdwQm2NvGLDkQDCGvmiQrhkd0JbMzXthwQAUgWjQuQdBLFa3eiBP5arXZyA+f8x+x7OXgud6bq2rxjGtHV2tw==} + es-object-atoms@1.1.2: + resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + esast-util-from-estree@2.0.0: resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} @@ -1020,6 +1151,10 @@ packages: engines: {node: '>=18'} hasBin: true + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + escape-string-regexp@5.0.0: resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} engines: {node: '>=12'} @@ -1048,6 +1183,9 @@ packages: estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + event-stream@4.0.1: + resolution: {integrity: sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA==} + eventemitter3@5.0.4: resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} @@ -1057,12 +1195,18 @@ packages: extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-string-truncated-width@3.0.3: resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} fast-string-width@3.0.2: resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} + fast-uri@3.1.3: + resolution: {integrity: sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==} + fast-wrap-ansi@0.2.2: resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} @@ -1086,11 +1230,36 @@ packages: resolution: {integrity: sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw==} engines: {node: '>=20'} + form-data@4.0.4: + resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} + engines: {node: '>= 6'} + + from@0.1.7: + resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-own-enumerable-property-symbols@3.0.2: + resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + get-tsconfig@5.0.0-beta.4: resolution: {integrity: sha512-7nF7C9fIPFEMHgEMEfgIlO9wDdZ8CyHw27rWciFZfHvHDReIiPhsYuzPRXsfvBCqFy1l8RRyyWV7QLM+ZhUJsQ==} engines: {node: '>=20.20.0'} @@ -1098,9 +1267,32 @@ packages: github-slugger@2.0.0: resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + h3@1.15.11: resolution: {integrity: sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==} + har-validator-compiled@1.0.0: + resolution: {integrity: sha512-dher7nFSx+Ef6OoqVveLClh8itAR3vd8Qx70Lh/hEgP1iGeARAolbci7Y8JBrHIYgFCT6xRdvvL16AR9Zh07Dw==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} + engines: {node: '>= 0.4'} + hast-util-embedded@3.0.0: resolution: {integrity: sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==} @@ -1173,6 +1365,11 @@ packages: http-cache-semantics@4.2.0: resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + httpsnippet@3.0.10: + resolution: {integrity: sha512-1P102HsVslaT3IVfuUfVwxenfbogFiihqosnaKUScd/sON1omdZZCWdmzm6baRz4u1Va0CTI/7svLckCu9iNBw==} + engines: {node: '>=20'} + hasBin: true + i18next@26.3.4: resolution: {integrity: sha512-pa7m0d7pBDqGHZxljT+WPFeyFgQ7P7SciPPo1tTqYuO0z4sqADYhwnBESmmGp/wEof1inwdls/k8ZgTg8rxFHA==} peerDependencies: @@ -1206,6 +1403,10 @@ packages: engines: {node: '>=20'} hasBin: true + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + is-hexadecimal@2.0.1: resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} @@ -1214,25 +1415,47 @@ packages: engines: {node: '>=14.16'} hasBin: true + is-obj@1.0.1: + resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==} + engines: {node: '>=0.10.0'} + is-plain-obj@4.1.0: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} + is-regexp@1.0.0: + resolution: {integrity: sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==} + engines: {node: '>=0.10.0'} + is-wsl@3.1.1: resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} engines: {node: '>=16'} + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-yaml@4.3.0: resolution: {integrity: sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==} hasBin: true + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + jsonc-parser@3.3.1: resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + jsonpointer@5.0.1: + resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} + engines: {node: '>=0.10.0'} + klona@2.0.6: resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} engines: {node: '>= 8'} + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + lightningcss-android-arm64@1.32.0: resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} engines: {node: '>= 12.0.0'} @@ -1320,6 +1543,9 @@ packages: magicast@0.5.3: resolution: {integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==} + map-stream@0.0.7: + resolution: {integrity: sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==} + markdown-extensions@2.0.0: resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} engines: {node: '>=16'} @@ -1327,6 +1553,10 @@ packages: markdown-table@3.0.4: resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + mdast-util-definitions@6.0.0: resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==} @@ -1495,6 +1725,14 @@ packages: micromark@4.0.2: resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + mrmime@2.0.1: resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} engines: {node: '>=10'} @@ -1543,6 +1781,9 @@ packages: oniguruma-to-es@4.3.6: resolution: {integrity: sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==} + openapi-types@12.1.3: + resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} + p-limit@7.3.0: resolution: {integrity: sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==} engines: {node: '>=20'} @@ -1571,6 +1812,9 @@ packages: parse5@7.3.0: resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + pause-stream@0.0.11: + resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==} + piccolore@0.1.3: resolution: {integrity: sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==} @@ -1683,6 +1927,14 @@ packages: remark-stringify@11.0.0: resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} @@ -1746,29 +1998,70 @@ packages: space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + split@1.0.1: + resolution: {integrity: sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==} + + starlight-copy-button@https://codeload.github.com/dionysuzx/starlight-copy-button/tar.gz/d570fcab6824127f80076eb419f39fb4fbd9de09: + resolution: {gitHosted: true, integrity: sha512-NAOJG8sx00BCyXwS6rIQDMEq5dEAff9V2LQkEUAswujVBR8BtafucsyWKsZKVMgbirqqXH0NvHAYn5paW0wIDw==, tarball: https://codeload.github.com/dionysuzx/starlight-copy-button/tar.gz/d570fcab6824127f80076eb419f39fb4fbd9de09} + version: 0.1.0 + engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0} + peerDependencies: + '@astrojs/starlight': '>=0.31' + astro: ^5.15.9 + + starlight-openapi@0.26.0: + resolution: {integrity: sha512-+WJnS7nIW42KfgmtBvTdj0Sx0LR+3kYPCdXMoiiMxKWDTF9TBd8KhTRDqNiPPrksej+gItZV/ROKwsXoF2/qZQ==} + engines: {node: '>=22.12.0'} + peerDependencies: + '@astrojs/markdown-satteri': '>=0.3.2' + '@astrojs/starlight': '>=0.41.0' + astro: '>=7.0.2' + starlight-sidebar-topics@0.8.0: resolution: {integrity: sha512-hE8+w2vNL13h6cq3UJGl05milJQ3+1BSlhaV5V4a993YzYczU6uLAj6jfUDKQ2mmgkdVWp8/UNDF4Je/rQXNQw==} engines: {node: '>=22.12.0'} peerDependencies: '@astrojs/starlight': '>=0.38.0' + stream-combiner@0.2.2: + resolution: {integrity: sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==} + stream-replace-string@2.0.0: resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==} + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + stringify-entities@4.0.4: resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + stringify-object@3.3.0: + resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==} + engines: {node: '>=4'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + style-to-js@1.1.21: resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} style-to-object@1.0.14: resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + svgo@4.0.1: resolution: {integrity: sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==} engines: {node: '>=16'} hasBin: true + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + tiny-inflate@1.0.3: resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} @@ -1793,6 +2086,13 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + turndown-plugin-gfm@1.0.2: + resolution: {integrity: sha512-vwz9tfvF7XN/jE0dGoBei3FXWuvll78ohzCZQuOb+ZjWrs3a0XhQVomJEb2Qh4VHTPNRO4GPZh0V7VRbiWwkRg==} + + turndown@7.2.4: + resolution: {integrity: sha512-I8yFsfRzmzK0WV1pNNOA4A7y4RDfFxPRxb3t+e3ui14qSGOxGtiSP6GjeX+Y6CHb7HYaFj7ECUD7VE5kQMZWGQ==} + engines: {node: '>=18', npm: '>=9'} + typescript@6.0.3: resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} engines: {node: '>=14.17'} @@ -1915,6 +2215,10 @@ packages: resolution: {integrity: sha512-8tzwTeXFPuX/5PHuCDQE5Dd9Ts4rwoq2t9aIT+HS4iAVpmj5l4Ao7Q+BuuFjvWRqrLswBhQDk8O96ZicgCqQqw==} engines: {node: '>=20'} + url-template@3.1.1: + resolution: {integrity: sha512-4oszoaEKE/mQOtAmdMWqIRHmkxWkUZMnXFnjQ5i01CuRSK3uluxcH1MRVVVWmhlnzT1SCDfKxxficm2G37qzCA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -1985,13 +2289,29 @@ packages: resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==} engines: {node: '>=4'} + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + xxhash-wasm@1.1.0: resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==} + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + yargs-parser@22.0.0: resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} engines: {node: ^20.19.0 || ^22.12.0 || >=23} + yargs@17.7.3: + resolution: {integrity: sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==} + engines: {node: '>=12'} + yocto-queue@1.2.2: resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} engines: {node: '>=12.20'} @@ -2004,6 +2324,11 @@ packages: snapshots: + '@apidevtools/json-schema-ref-parser@13.0.5': + dependencies: + '@types/json-schema': 7.0.15 + js-yaml: 4.3.0 + '@astrojs/compiler-binding-darwin-arm64@0.3.0': optional: true @@ -2176,6 +2501,12 @@ snapshots: is-wsl: 3.1.1 which-pm-runs: 1.1.0 + '@babel/code-frame@7.29.7': + dependencies: + '@babel/helper-validator-identifier': 7.29.7 + js-tokens: 4.0.0 + picocolors: 1.1.1 + '@babel/helper-string-parser@7.29.7': {} '@babel/helper-validator-identifier@7.29.7': {} @@ -2184,6 +2515,8 @@ snapshots: dependencies: '@babel/types': 7.29.7 + '@babel/runtime@7.29.7': {} + '@babel/types@7.29.7': dependencies: '@babel/helper-string-parser': 7.29.7 @@ -2362,6 +2695,12 @@ snapshots: dependencies: '@expressive-code/core': 0.44.0 + '@fontsource-variable/geist-mono@5.2.8': {} + + '@fontsource-variable/geist@5.2.9': {} + + '@humanwhocodes/momoa@2.0.4': {} + '@img/colour@1.1.0': {} '@img/sharp-darwin-arm64@0.34.5': @@ -2490,6 +2829,8 @@ snapshots: transitivePeerDependencies: - supports-color + '@mixmark-io/domino@2.2.0': {} + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': dependencies: '@emnapi/core': 1.11.1 @@ -2531,6 +2872,28 @@ snapshots: '@pagefind/windows-x64@1.5.2': optional: true + '@readme/better-ajv-errors@2.4.0(ajv@8.20.0)': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/runtime': 7.29.7 + '@humanwhocodes/momoa': 2.0.4 + ajv: 8.20.0 + jsonpointer: 5.0.1 + leven: 3.1.0 + picocolors: 1.1.1 + + '@readme/openapi-parser@4.1.2(openapi-types@12.1.3)': + dependencies: + '@apidevtools/json-schema-ref-parser': 13.0.5 + '@readme/better-ajv-errors': 2.4.0(ajv@8.20.0) + '@readme/openapi-schemas': 3.1.0 + '@types/json-schema': 7.0.15 + ajv: 8.20.0 + ajv-draft-04: 1.0.0(ajv@8.20.0) + openapi-types: 12.1.3 + + '@readme/openapi-schemas@3.1.0': {} + '@rolldown/binding-android-arm64@1.1.4': optional: true @@ -2653,6 +3016,8 @@ snapshots: '@types/js-yaml@4.0.9': {} + '@types/json-schema@7.0.15': {} + '@types/mdast@4.0.4': dependencies: '@types/unist': 3.0.3 @@ -2689,10 +3054,27 @@ snapshots: acorn@8.17.0: {} + ajv-draft-04@1.0.0(ajv@8.20.0): + optionalDependencies: + ajv: 8.20.0 + + ajv@8.20.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + am-i-vibing@0.4.0: dependencies: process-ancestry: 0.1.0 + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + anymatch@3.1.3: dependencies: normalize-path: 3.0.0 @@ -2807,6 +3189,8 @@ snapshots: - uploadthing - yaml + asynckit@0.4.0: {} + axobject-query@4.1.0: {} bail@2.0.2: {} @@ -2821,8 +3205,18 @@ snapshots: boolbase@1.0.0: {} + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + ccount@2.0.1: {} + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + character-entities-html4@2.1.0: {} character-entities-legacy@3.0.0: {} @@ -2837,10 +3231,26 @@ snapshots: ci-info@4.4.0: {} + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + clsx@2.1.1: {} collapse-white-space@2.1.0: {} + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + comma-separated-tokens@2.0.3: {} commander@11.1.0: {} @@ -2893,6 +3303,8 @@ snapshots: defu@6.1.7: {} + delayed-stream@1.0.0: {} + dequal@2.0.3: {} destr@2.0.5: {} @@ -2929,12 +3341,37 @@ snapshots: dset@3.1.4: {} + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + duplexer@0.1.2: {} + + emoji-regex@8.0.0: {} + entities@4.5.0: {} entities@6.0.1: {} + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + es-module-lexer@2.3.0: {} + es-object-atoms@1.1.2: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.4 + esast-util-from-estree@2.0.0: dependencies: '@types/estree-jsx': 1.0.5 @@ -2978,6 +3415,8 @@ snapshots: '@esbuild/win32-ia32': 0.28.1 '@esbuild/win32-x64': 0.28.1 + escalade@3.2.0: {} + escape-string-regexp@5.0.0: {} estree-util-attach-comments@3.0.0: @@ -3015,6 +3454,16 @@ snapshots: dependencies: '@types/estree': 1.0.9 + event-stream@4.0.1: + dependencies: + duplexer: 0.1.2 + from: 0.1.7 + map-stream: 0.0.7 + pause-stream: 0.0.11 + split: 1.0.1 + stream-combiner: 0.2.2 + through: 2.3.8 + eventemitter3@5.0.4: {} expressive-code@0.44.0: @@ -3026,12 +3475,16 @@ snapshots: extend@3.0.2: {} + fast-deep-equal@3.1.3: {} + fast-string-truncated-width@3.0.3: {} fast-string-width@3.0.2: dependencies: fast-string-truncated-width: 3.0.3 + fast-uri@3.1.3: {} + fast-wrap-ansi@0.2.2: dependencies: fast-string-width: 3.0.2 @@ -3050,15 +3503,51 @@ snapshots: dependencies: tiny-inflate: 1.0.3 + form-data@4.0.4: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.4 + mime-types: 2.1.35 + + from@0.1.7: {} + fsevents@2.3.3: optional: true + function-bind@1.1.2: {} + + get-caller-file@2.0.5: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.4 + math-intrinsics: 1.1.0 + + get-own-enumerable-property-symbols@3.0.2: {} + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.2 + get-tsconfig@5.0.0-beta.4: dependencies: resolve-pkg-maps: 1.0.0 github-slugger@2.0.0: {} + gopd@1.2.0: {} + h3@1.15.11: dependencies: cookie-es: 1.2.3 @@ -3071,6 +3560,20 @@ snapshots: ufo: 1.6.4 uncrypto: 0.1.3 + har-validator-compiled@1.0.0: {} + + has-flag@4.0.0: {} + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.4: + dependencies: + function-bind: 1.1.2 + hast-util-embedded@3.0.0: dependencies: '@types/hast': 3.0.4 @@ -3268,6 +3771,15 @@ snapshots: http-cache-semantics@4.2.0: {} + httpsnippet@3.0.10: + dependencies: + chalk: 4.1.2 + event-stream: 4.0.1 + form-data: 4.0.4 + har-validator-compiled: 1.0.0 + stringify-object: 3.3.0 + yargs: 17.7.3 + i18next@26.3.4(typescript@6.0.3): optionalDependencies: typescript: 6.0.3 @@ -3289,26 +3801,40 @@ snapshots: is-docker@4.0.0: {} + is-fullwidth-code-point@3.0.0: {} + is-hexadecimal@2.0.1: {} is-inside-container@1.0.0: dependencies: is-docker: 3.0.0 + is-obj@1.0.1: {} + is-plain-obj@4.1.0: {} + is-regexp@1.0.0: {} + is-wsl@3.1.1: dependencies: is-inside-container: 1.0.0 + js-tokens@4.0.0: {} + js-yaml@4.3.0: dependencies: argparse: 2.0.1 + json-schema-traverse@1.0.0: {} + jsonc-parser@3.3.1: {} + jsonpointer@5.0.1: {} + klona@2.0.6: {} + leven@3.1.0: {} + lightningcss-android-arm64@1.32.0: optional: true @@ -3372,10 +3898,14 @@ snapshots: '@babel/types': 7.29.7 source-map-js: 1.2.1 + map-stream@0.0.7: {} + markdown-extensions@2.0.0: {} markdown-table@3.0.4: {} + math-intrinsics@1.1.0: {} + mdast-util-definitions@6.0.0: dependencies: '@types/mdast': 4.0.4 @@ -3837,6 +4367,12 @@ snapshots: transitivePeerDependencies: - supports-color + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + mrmime@2.0.1: {} ms@2.1.3: {} @@ -3877,6 +4413,8 @@ snapshots: regex: 6.1.0 regex-recursion: 6.0.2 + openapi-types@12.1.3: {} + p-limit@7.3.0: dependencies: yocto-queue: 1.2.2 @@ -3923,6 +4461,10 @@ snapshots: dependencies: entities: 6.0.1 + pause-stream@0.0.11: + dependencies: + through: 2.3.8 + piccolore@0.1.3: {} picocolors@1.1.1: {} @@ -4095,6 +4637,10 @@ snapshots: mdast-util-to-markdown: 2.1.2 unified: 11.0.5 + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + resolve-pkg-maps@1.0.0: {} retext-latin@4.0.0: @@ -4223,18 +4769,62 @@ snapshots: space-separated-tokens@2.0.2: {} + split@1.0.1: + dependencies: + through: 2.3.8 + + starlight-copy-button@https://codeload.github.com/dionysuzx/starlight-copy-button/tar.gz/d570fcab6824127f80076eb419f39fb4fbd9de09(@astrojs/starlight@0.41.3(@astrojs/markdown-remark@7.2.1)(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0))(typescript@6.0.3))(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0)): + dependencies: + '@astrojs/starlight': 0.41.3(@astrojs/markdown-remark@7.2.1)(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0))(typescript@6.0.3) + astro: 7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0) + turndown: 7.2.4 + turndown-plugin-gfm: 1.0.2 + + starlight-openapi@0.26.0(@astrojs/markdown-satteri@0.3.3)(@astrojs/starlight@0.41.3(@astrojs/markdown-remark@7.2.1)(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0))(typescript@6.0.3))(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0))(openapi-types@12.1.3): + dependencies: + '@astrojs/markdown-satteri': 0.3.3 + '@astrojs/starlight': 0.41.3(@astrojs/markdown-remark@7.2.1)(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0))(typescript@6.0.3) + '@readme/openapi-parser': 4.1.2(openapi-types@12.1.3) + astro: 7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0) + github-slugger: 2.0.0 + httpsnippet: 3.0.10 + url-template: 3.1.1 + transitivePeerDependencies: + - openapi-types + starlight-sidebar-topics@0.8.0(@astrojs/starlight@0.41.3(@astrojs/markdown-remark@7.2.1)(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0))(typescript@6.0.3)): dependencies: '@astrojs/starlight': 0.41.3(@astrojs/markdown-remark@7.2.1)(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0))(typescript@6.0.3) picomatch: 4.0.5 + stream-combiner@0.2.2: + dependencies: + duplexer: 0.1.2 + through: 2.3.8 + stream-replace-string@2.0.0: {} + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + stringify-entities@4.0.4: dependencies: character-entities-html4: 2.1.0 character-entities-legacy: 3.0.0 + stringify-object@3.3.0: + dependencies: + get-own-enumerable-property-symbols: 3.0.2 + is-obj: 1.0.1 + is-regexp: 1.0.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + style-to-js@1.1.21: dependencies: style-to-object: 1.0.14 @@ -4243,6 +4833,10 @@ snapshots: dependencies: inline-style-parser: 0.2.7 + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + svgo@4.0.1: dependencies: commander: 11.1.0 @@ -4253,6 +4847,8 @@ snapshots: picocolors: 1.1.1 sax: 1.6.0 + through@2.3.8: {} + tiny-inflate@1.0.3: {} tinyclip@0.1.15: {} @@ -4271,6 +4867,12 @@ snapshots: tslib@2.8.1: optional: true + turndown-plugin-gfm@1.0.2: {} + + turndown@7.2.4: + dependencies: + '@mixmark-io/domino': 2.2.0 + typescript@6.0.3: {} ufo@1.6.4: {} @@ -4358,6 +4960,8 @@ snapshots: url-extras@0.1.0: {} + url-template@3.1.1: {} + util-deprecate@1.0.2: {} vfile-location@5.0.3: @@ -4395,10 +4999,30 @@ snapshots: which-pm-runs@1.1.0: {} + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + xxhash-wasm@1.1.0: {} + y18n@5.0.8: {} + + yargs-parser@21.1.1: {} + yargs-parser@22.0.0: {} + yargs@17.7.3: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + yocto-queue@1.2.2: {} zod@4.4.3: {} diff --git a/src/components/starlight/ContentPanel.astro b/src/components/starlight/ContentPanel.astro index 68ea66f..a411e5a 100644 --- a/src/components/starlight/ContentPanel.astro +++ b/src/components/starlight/ContentPanel.astro @@ -1,13 +1,9 @@ --- -const { - entry: { data }, -} = Astro.locals.starlightRoute; -const isAPIDoc = data.type === "api-doc"; ---
-
+
diff --git a/src/components/docs/node-preview.tsx b/src/components/docs/node-preview.tsx new file mode 100644 index 0000000..3afa7e8 --- /dev/null +++ b/src/components/docs/node-preview.tsx @@ -0,0 +1,429 @@ +import { + ArrowRight, + Calculator, + CheckIcon, + ChevronDown, + CircleHelp, + Clock, + Clock3, + Database, + Filter, + Group, + ListFilter, + type LucideIcon, + Sigma, + Type, + Waves, + X, +} from "lucide-react"; +import type { ReactNode } from "react"; + +// --------------------------------------------------------------------------- +// Category palette (mirrors apps/tanstack .../nodes/node-category-badge.tsx) +// --------------------------------------------------------------------------- + +type NodeBadgeCategory = + | "source" + | "filter" + | "aggregate" + | "group" + | "transform" + | "formula" + | "time" + | "output"; + +const CATEGORY_STYLES: Record< + NodeBadgeCategory, + { border: string; bg: string; icon: string; text: string } +> = { + source: { + border: "border-sky-500/45", + bg: "bg-sky-500/20", + icon: "text-sky-700 dark:text-sky-400", + text: "text-sky-800 dark:text-sky-200/90", + }, + filter: { + border: "border-amber-500/45", + bg: "bg-amber-500/20", + icon: "text-amber-700 dark:text-amber-400", + text: "text-amber-800 dark:text-amber-200/90", + }, + aggregate: { + border: "border-emerald-500/45", + bg: "bg-emerald-500/20", + icon: "text-emerald-700 dark:text-emerald-400", + text: "text-emerald-800 dark:text-emerald-200/90", + }, + group: { + border: "border-teal-500/45", + bg: "bg-teal-500/20", + icon: "text-teal-700 dark:text-teal-400", + text: "text-teal-800 dark:text-teal-200/90", + }, + transform: { + border: "border-violet-500/45", + bg: "bg-violet-500/20", + icon: "text-violet-700 dark:text-violet-400", + text: "text-violet-800 dark:text-violet-200/90", + }, + formula: { + border: "border-fuchsia-500/45", + bg: "bg-fuchsia-500/20", + icon: "text-fuchsia-700 dark:text-fuchsia-400", + text: "text-fuchsia-800 dark:text-fuchsia-200/90", + }, + time: { + border: "border-blue-500/45", + bg: "bg-blue-500/20", + icon: "text-blue-700 dark:text-blue-400", + text: "text-blue-800 dark:text-blue-200/90", + }, + output: { + border: "border-rose-500/45", + bg: "bg-rose-500/20", + icon: "text-rose-700 dark:text-rose-400", + text: "text-rose-800 dark:text-rose-200/90", + }, +}; + +// --------------------------------------------------------------------------- +// Primitives +// --------------------------------------------------------------------------- + +function Handle({ side }: { side: "top" | "bottom" }) { + return ( +
+ ); +} + +function CategoryBadge({ + label, + icon: Icon, + category, +}: { + label: string; + icon: LucideIcon; + category: NodeBadgeCategory; +}) { + const styles = CATEGORY_STYLES[category]; + return ( +
+
+ + + {label} + +
+
+ ); +} + +function NodeShell({ + label, + icon, + category, + handles = "both", + children, + width = 280, +}: { + label: string; + icon: LucideIcon; + category: NodeBadgeCategory; + handles?: "top" | "bottom" | "both"; + children: ReactNode; + width?: number; +}) { + return ( +
+ {(handles === "top" || handles === "both") && } + {(handles === "bottom" || handles === "both") && } + +
+
{children}
+
+
+ ); +} + +function FieldLabel({ children }: { children: ReactNode }) { + return ( +
+ {children} + +
+ ); +} + +function Field({ label, children }: { label: string; children: ReactNode }) { + return ( +
+ {label} + {children} +
+ ); +} + +function FakeInput({ + value, + placeholder, + mono = false, +}: { + value?: string; + placeholder?: string; + mono?: boolean; +}) { + const hasValue = value !== undefined && value !== ""; + return ( +
+ {hasValue ? value : placeholder} +
+ ); +} + +function FakeSelect({ + value, + mono = false, + icon, +}: { + value: string; + mono?: boolean; + icon?: ReactNode; +}) { + return ( +
+ + {icon} + {value} + + +
+ ); +} + +function FakeChips({ values }: { values: readonly string[] }) { + return ( +
+ {values.map((v) => ( + + {v} + + + ))} +
+ ); +} + +function FakeCheckbox({ + label, + checked = false, +}: { + label: string; + checked?: boolean; +}) { + return ( +
+
+ {checked ? : null} +
+ + {label} + + +
+ ); +} + +// --------------------------------------------------------------------------- +// Node previews +// --------------------------------------------------------------------------- + +export function DatasourceNodePreview() { + return ( + + + + + + + + + + ); +} + +export function FilterNodePreview() { + return ( + + + + + + + + + + + + ); +} + +export function AggregateNodePreview() { + return ( + + + + + + ); +} + +export function GroupNodePreview() { + return ( + + + + + + + + + ); +} + +export function TimeGroupNodePreview() { + return ( + + + + + + } + /> + + + + + + ); +} + +export function TextTransformNodePreview() { + return ( + + + + + + ); +} + +export function FormulaNodePreview() { + return ( + + + + + + + + + + + + ); +} + +export function LimitNodePreview() { + return ( + + + + + + + ); +} + +export function MaxAgeNodePreview() { + return ( + + +
+ +
+ +
+
+
+
+ ); +} + +export function MinAgeNodePreview() { + return ( + + +
+ +
+ +
+
+
+
+ ); +} + +export function ResultNodePreview() { + return ( + + + + +

+ Final query result for this chart +

+
+ ); +} diff --git a/src/content/docs/platform/chart-editor/flow-nodes.mdx b/src/content/docs/platform/chart-editor/flow-nodes.mdx new file mode 100644 index 0000000..5375d11 --- /dev/null +++ b/src/content/docs/platform/chart-editor/flow-nodes.mdx @@ -0,0 +1,269 @@ +--- +title: Flow Nodes +description: All available nodes for building data pipelines in the flow editor +icon: Workflow +--- + +import { + DatasourceNodePreview, + FilterNodePreview, + AggregateNodePreview, + GroupNodePreview, + TimeGroupNodePreview, + TextTransformNodePreview, + FormulaNodePreview, + LimitNodePreview, + MaxAgeNodePreview, + MinAgeNodePreview, + ResultNodePreview, +} from "@/components/docs/node-preview"; + +import NodeDocCard from "@/components/NodeDocCard.astro"; + +The Flow Editor lets you build chart queries by connecting nodes in a pipeline. Drag nodes onto the canvas, configure them, and wire them together. Data flows from top to bottom, starting at a **Data Source**, passing through transformations, and ending at an **Output**. + +## Getting started + +1. Add a **Data Source** node to choose which adapter and field to read from +2. Connect transformation nodes like **Filter**, **Group By**, or **Aggregate** to shape the data +3. Finish with an **Output** node to produce the chart result + +Each node has handles on its top and/or bottom edge. Connect the bottom handle of one node to the top handle of the next to build the pipeline. The colored badge on each node shows its category. Sources, filters, aggregates, groupings, transforms, time operations, and outputs each have their own color. + +## Nodes + +### Data Source + + + + + +--- + +### Filter + + + + + +--- + +### Aggregate + + + + + +--- + +### Group By + + + + + +--- + +### Time Group + + + + + +--- + +### Text Transform + + + + + +--- + +### Formula + + + + + +--- + +### Limit + +Other bucket so totals still match." + } + ]}> + + + +--- + +### Max Age + +ms, seconds, minutes, hours, days." + } + ]}> + + + +--- + +### Min Age + +Max Age." + } + ]}> + + + +--- + +### Output + +/ to split a URL path)." + } + ]}> + + \ No newline at end of file diff --git a/src/content/docs/platform/chart-editor/index.mdx b/src/content/docs/platform/chart-editor/index.mdx new file mode 100644 index 0000000..503f450 --- /dev/null +++ b/src/content/docs/platform/chart-editor/index.mdx @@ -0,0 +1,37 @@ +--- +title: Overview +description: Build and configure charts using the visual flow editor +icon: ChartArea +--- + +import { LinkCard, CardGrid } from '@astrojs/starlight/components'; + +The Chart Editor is where you build charts in fastStats. Connect nodes on a canvas to choose your data, transform it, and decide how it shows up in the chart. + + + + + + +## How it works + +Every chart is a pipeline of nodes. Drag nodes onto the canvas and connect them from top to bottom: + +1. **Pick your data** with a Data Source node +2. **Shape it** using Filter, Group By, Aggregate, or other transformation nodes +3. **Display it** with one or more Output nodes + +How many Output nodes you use changes what the chart shows: + +| Output nodes | Result | +| ------------ | -------------------------------------------------------- | +| 1 | One series: a single line, bar group, or widget value | +| 2+ | Multiple series: extra lines, stacked bars, or list tabs | diff --git a/src/content/docs/platform/chart-editor/output-nodes.mdx b/src/content/docs/platform/chart-editor/output-nodes.mdx new file mode 100644 index 0000000..1c5e5bf --- /dev/null +++ b/src/content/docs/platform/chart-editor/output-nodes.mdx @@ -0,0 +1,75 @@ +--- +title: Output & Multi-Series +description: How to create tabs, multi-line charts, and stacked bars using multiple Output nodes +icon: GitFork +--- + +import { Aside } from '@astrojs/starlight/components'; +import { ResultNodePreview } from "@/components/docs/node-preview"; + +The Output node is the last step in every pipeline. One Output gives you a simple chart. Add more Output nodes to build multi-line charts, stacked bars, or tabbed lists. + +
+ +
+ +## Output settings + +| Setting | Description | +| ----------- | ---------------------------------------------------------------------------------- | +| Output name | Label for this series in the legend (or tab name on list charts) | +| Icon set | Optional icons next to each row (list charts only) | +| Nest by | Split rows into nested sections by field or custom delimiter (list and pie charts) | +| Delimiter | Character or string used to split values when nesting by a custom pattern | + +The **output name** matters most. It shows up in the chart legend or as a tab title on list charts. Leave it blank on a single-output chart and it defaults to "Output". With multiple outputs, unnamed series are numbered automatically ("Output 1", "Output 2", and so on). + +## Multiple outputs + +When a flow has more than one Output node, each one runs as its own pipeline. The results are merged so the chart can show several series at once. + +### Ordering + +Output nodes are ordered by where they sit on the canvas. The leftmost Output becomes the first series, the next one becomes the second, and so on. + + + +## Multi-line charts + +To compare two metrics over time (for example, page views and unique visitors): + +1. Create two pipelines, each starting with a **Data Source** node +2. Add a **Time Group** node to each (use the same interval) +3. Add an **Aggregate** node to each (for example, `count` on one and `distinct` on the other) +4. End each pipeline with its own **Output** node +5. Give each one a name (for example, "Page Views" and "Unique Visitors") + +Both pipelines run together. Each time bucket gets both values as separate lines on the chart. + +## Stacked bar charts + +Stacked bars work like multi-line charts: use multiple Output nodes and set the chart type to **Bar**. The chart type decides whether series render as lines or stacked bars. + +1. Build two or more pipelines with **Group By** and **Aggregate** +2. End each with a named **Output** node +3. Set the chart type to **Bar** + +Series stack in the same order as your Output nodes on the canvas. + +## Tabbed lists + +On list charts, multiple Output nodes become **tabs** instead of overlapping series. Each Output is its own tab. + +1. Build a separate pipeline for each tab +2. Name each Output node with the tab label (for example, "Browsers" or "Countries") +3. Set the chart type to **List** + +Each output name becomes a tab header. Pipelines run independently, and each tab shows its own result set. + +## Tips + +- **Disconnected outputs are ignored.** If an Output node is not wired to anything, it will not appear in the chart. +- **Pipelines can be shared.** Multiple Output nodes can connect to the same upstream nodes, so you do not always need to duplicate the whole flow. +- **Widget charts use one pipeline only.** Extra Output nodes are ignored for widget chart types. diff --git a/src/styles/global.css b/src/styles/global.css new file mode 100644 index 0000000..ed6d76d --- /dev/null +++ b/src/styles/global.css @@ -0,0 +1,140 @@ +@layer base, starlight, theme, components, utilities; + +@import '@astrojs/starlight-tailwind'; +@import 'tailwindcss/theme.css' layer(theme); +@import 'tailwindcss/utilities.css' layer(utilities); + +/* Dark mode colors. */ +:root { + --sl-color-accent-low: oklch(0.47 0.157 37.304); + --sl-color-accent: oklch(0.646 0.222 41.116); + --sl-color-accent-high: oklch(0.837 0.128 66.29); + --sl-color-accent-bleached: rgba(205, 185, 248, 0.1); + --sl-color-white: #ffffff; + --sl-color-gray-1: #d1d1d1; + --sl-color-gray-2: #b4b4b4; + --sl-color-gray-3: #969696; + --sl-color-gray-4: #4d4d4d; + --sl-color-gray-5: #383838; + --sl-color-gray-6: #191919; + --sl-color-black: #0f0f0f; + + --landing-card-2nd-accent-low: oklch(0.47 0.157 37.304); + --landing-card-2nd-accent: oklch(0.646 0.222 41.116); + --landing-card-2nd-accent-high: oklch(0.837 0.128 66.29); + + --sl-custom-code-color: var(--sl-color-gray-5); + + --sl-font: "Geist Variable"; + --sl-font-mono: "Geist Mono Variable"; +} + +/* Light mode colors. */ +:root[data-theme="light"] { + --sl-color-accent-low: oklch(0.837 0.128 66.29); + --sl-color-accent: oklch(0.646 0.222 41.116); + --sl-color-accent-high: oklch(0.553 0.195 38.402); + --sl-color-accent-bleached: rgba(15, 15, 15, 0.1); + --sl-color-white: #1f1f1f; + --sl-color-gray-1: #202020; + --sl-color-gray-2: #383838; + --sl-color-gray-3: #5c5c5c; + --sl-color-gray-4: #838383; + --sl-color-gray-5: #afafaf; + --sl-color-gray-6: #cecece; + --sl-color-gray-7: #f8f4fe; + --sl-color-black: #ffffff; + + --landing-card-2nd-accent-low: oklch(0.646 0.222 41.116); + --landing-card-2nd-accent: oklch(0.837 0.128 66.29); + --landing-card-2nd-high: oklch(0.98 0 0); + + --sl-custom-code-color: var(--sl-color-gray-6); +} + +.sl-link-button:first-of-type:not(.discord-button) svg { + transition: transform .15s ease !important; +} + +.sl-link-button:first-of-type:hover:not(.discord-button)>svg { + transform: translateX(5px); +} + +.card { + border-radius: 8px; +} + +.sidebar-content, +.site-title span, +.sl-container h1 { + font-family: var(--sl-font-mono); +} + +.justify-center { + display: flex; + justify-content: center; +} + +.py-4 { + padding-top: 1rem; + padding-bottom: 1rem; +} + +div.expressive-code, +starlight-file-tree { + border-radius: 8px; + overflow: hidden; +} + +starlight-file-tree { + border: 1px solid var(--ec-brdCol); +} + +aside.starlight-aside { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} + +@media (max-width: 50rem) { + .hero>img { + width: min(50%, 16rem); + } +} + +main[data-pagefind-body] { + overflow: hidden !important; +} + +#starlight__sidebar [aria-current="page"] span { + color: black !important; +} + +[data-theme="light"] #starlight__sidebar [aria-current="page"] span { + color: white !important; +} + +button[aria-label="Menu"][aria-controls="starlight__sidebar"] { + background-color: var(--sl-color-white); + padding: 0.5rem; +} + +[data-theme="light"] button[aria-label="Menu"][aria-controls="starlight__sidebar"] { + background-color: var(--sl-color-black); + padding: 0.5rem; +} + +.card-grid { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; +} + +a { + text-decoration: none; +} + +.expressive-code figcaption, +.expressive-code figcaption::before, +.expressive-code pre, +.expressive-code span.title { + border: none !important; +} \ No newline at end of file diff --git a/src/styles/starlight.css b/src/styles/starlight.css deleted file mode 100644 index da90277..0000000 --- a/src/styles/starlight.css +++ /dev/null @@ -1,127 +0,0 @@ -@import "@fontsource-variable/geist"; -@import "@fontsource-variable/geist-mono"; - -/* Dark mode colors. */ -:root { - --sl-color-accent-low: oklch(0.47 0.157 37.304); - --sl-color-accent: oklch(0.646 0.222 41.116); - --sl-color-accent-high: oklch(0.837 0.128 66.29); - --sl-color-accent-bleached: rgba(205, 185, 248, 0.1); - --sl-color-white: #ffffff; - --sl-color-gray-1: #d1d1d1; - --sl-color-gray-2: #b4b4b4; - --sl-color-gray-3: #969696; - --sl-color-gray-4: #4d4d4d; - --sl-color-gray-5: #383838; - --sl-color-gray-6: #191919; - --sl-color-black: #0f0f0f; - - --landing-card-2nd-accent-low: oklch(0.47 0.157 37.304); - --landing-card-2nd-accent: oklch(0.646 0.222 41.116); - --landing-card-2nd-accent-high: oklch(0.837 0.128 66.29); - - --sl-custom-code-color: var(--sl-color-gray-5); - - --sl-font: "Geist Variable"; - --sl-font-mono: "Geist Mono Variable"; -} - -/* Light mode colors. */ -:root[data-theme="light"] { - --sl-color-accent-low: oklch(0.837 0.128 66.29); - --sl-color-accent: oklch(0.646 0.222 41.116); - --sl-color-accent-high: oklch(0.553 0.195 38.402); - --sl-color-accent-bleached: rgba(15, 15, 15, 0.1); - --sl-color-white: #1f1f1f; - --sl-color-gray-1: #202020; - --sl-color-gray-2: #383838; - --sl-color-gray-3: #5c5c5c; - --sl-color-gray-4: #838383; - --sl-color-gray-5: #afafaf; - --sl-color-gray-6: #cecece; - --sl-color-gray-7: #f8f4fe; - --sl-color-black: #ffffff; - - --landing-card-2nd-accent-low: oklch(0.646 0.222 41.116); - --landing-card-2nd-accent: oklch(0.837 0.128 66.29); - --landing-card-2nd-high: oklch(0.98 0 0); - - --sl-custom-code-color: var(--sl-color-gray-6); -} - -.sl-link-button:first-of-type:not(.discord-button) svg { - transition: transform .15s ease !important; -} - -.sl-link-button:first-of-type:hover:not(.discord-button)>svg { - transform: translateX(5px); -} - -.card { - border-radius: 8px; -} - -.sidebar-content, -.site-title span, -.sl-container h1 { - font-family: var(--sl-font-mono); -} - -div.expressive-code, -starlight-file-tree { - border-radius: 8px; - overflow: hidden; -} - -starlight-file-tree { - border: 1px solid var(--ec-brdCol); -} - -aside.starlight-aside { - border-top-right-radius: 4px; - border-bottom-right-radius: 4px; -} - -@media (max-width: 50rem) { - .hero>img { - width: min(50%, 16rem); - } -} - -main[data-pagefind-body] { - overflow: hidden !important; -} - -#starlight__sidebar [aria-current="page"] span { - color: black !important; -} - -[data-theme="light"] #starlight__sidebar [aria-current="page"] span { - color: white !important; -} - -button[aria-label="Menu"][aria-controls="starlight__sidebar"] { - background-color: var(--sl-color-white); - padding: 0.5rem; -} - -[data-theme="light"] button[aria-label="Menu"][aria-controls="starlight__sidebar"] { - background-color: var(--sl-color-black); - padding: 0.5rem; -} - -.card-grid { - margin-top: 1.5rem !important; - margin-bottom: 1.5rem !important; -} - -a { - text-decoration: none; -} - -.expressive-code figcaption, -.expressive-code figcaption::before, -.expressive-code pre, -.expressive-code span.title { - border: none !important; -} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 9f43b62..2291221 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,9 +9,11 @@ ], "compilerOptions": { "paths": { - "$/*": [ + "@/*": [ "./src/*" ] - } + }, + "jsx": "react-jsx", + "jsxImportSource": "react" } } \ No newline at end of file From 675c89bffc0d242beaa2c49945590a4506a34e28 Mon Sep 17 00:00:00 2001 From: Adam Matthiesen Date: Sun, 5 Jul 2026 18:09:55 -0700 Subject: [PATCH 06/40] feat: add OG image generation support with astro-og-canvas and update dependencies --- package.json | 2 ++ pnpm-lock.yaml | 49 ++++++++++++++++++++++++++++++ src/content.ts | 3 ++ src/pages/og/[...path].ts | 63 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 117 insertions(+) create mode 100644 src/content.ts create mode 100644 src/pages/og/[...path].ts diff --git a/package.json b/package.json index 3a1b5eb..a073cb8 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,8 @@ "@types/react": "^19.2.17", "@types/react-dom": "^19.2.3", "astro": "^7.0.2", + "astro-og-canvas": "^0.13.0", + "canvaskit-wasm": "^0.41.1", "lucide-react": "^1.23.0", "react": "^19.2.7", "react-dom": "^19.2.7", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8d31ebc..f7ded7c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,6 +41,12 @@ importers: astro: specifier: ^7.0.2 version: 7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0)(jiti@2.7.0) + astro-og-canvas: + specifier: ^0.13.0 + version: 0.13.0(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0)(jiti@2.7.0)) + canvaskit-wasm: + specifier: ^0.41.1 + version: 0.41.1 lucide-react: specifier: ^1.23.0 version: 1.23.0(react@19.2.7) @@ -1093,6 +1099,9 @@ packages: peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + '@webgpu/types@0.1.21': + resolution: {integrity: sha512-pUrWq3V5PiSGFLeLxoGqReTZmiiXwY3jRkIG5sLLKjyqNxrwm/04b4nw7LSmGWJcKk59XOM/YRTUwOzo4MMlow==} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -1152,6 +1161,11 @@ packages: peerDependencies: astro: ^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta || ^7.0.0 + astro-og-canvas@0.13.0: + resolution: {integrity: sha512-jcIDhE9OGIbd7LstZQ4CyzOpbbEKAlxJqEgdkVu6r26m7yJKlQjKysszfDxlox717cnCLPXKivyFjsufcq8sYA==} + peerDependencies: + astro: ^5.0.0 || ^6.0.0 || ^7.0.0 + astro@7.0.6: resolution: {integrity: sha512-Myw0sFia+zs/Y0yqfZEsUYXfDPh3ELcLf1f0Q/qQzVXBh/af1qO62WNT+P89DCcfGVV51nMoQhEfkBYqJmoUOQ==} engines: {node: '>=22.12.0', npm: '>=9.6.5', pnpm: '>=7.1.0'} @@ -1172,6 +1186,9 @@ packages: bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + base-64@1.0.0: + resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==} + baseline-browser-mapping@2.10.42: resolution: {integrity: sha512-c/jurFrDLyui7o1J86yLkRu4LMsTYcBohveus7/I2Hzdn9KIP2bdJPTue/lR1KH46enoPbD77GKeSYNdyPoD3Q==} engines: {node: '>=6.0.0'} @@ -1198,6 +1215,9 @@ packages: caniuse-lite@1.0.30001800: resolution: {integrity: sha512-MMHtuAz9Ys840zAY5F4k6fV5GaivZ9sPk+nz0mY+GYVzRBnYkN0mpqkSR92oWRQ19yQWo4HvBV/FnC16AJX8MA==} + canvaskit-wasm@0.41.1: + resolution: {integrity: sha512-gO2rNMIE0lOQ8MaarM4qNeq2zZAEknAObKP2XAKidMSAY8P5sURGdFkrx1TSdHuBFqTf5w35JqjuUzjibqkD5g==} + ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -1331,6 +1351,10 @@ packages: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} + deterministic-object-hash@2.0.2: + resolution: {integrity: sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==} + engines: {node: '>=18'} + devalue@5.8.1: resolution: {integrity: sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw==} @@ -1387,6 +1411,10 @@ packages: resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} engines: {node: '>=0.12'} + entities@8.0.0: + resolution: {integrity: sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==} + engines: {node: '>=20.19.0'} + es-define-property@1.0.1: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} engines: {node: '>= 0.4'} @@ -3635,6 +3663,8 @@ snapshots: transitivePeerDependencies: - supports-color + '@webgpu/types@0.1.21': {} + acorn-jsx@5.3.2(acorn@8.17.0): dependencies: acorn: 8.17.0 @@ -3683,6 +3713,13 @@ snapshots: rehype-expressive-code: 0.44.0 url-extras: 0.1.0 + astro-og-canvas@0.13.0(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0)(jiti@2.7.0)): + dependencies: + astro: 7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0)(jiti@2.7.0) + canvaskit-wasm: 0.41.1 + deterministic-object-hash: 2.0.2 + entities: 8.0.0 + astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0)(jiti@2.7.0): dependencies: '@astrojs/compiler-rs': 0.3.0(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2) @@ -3782,6 +3819,8 @@ snapshots: bail@2.0.2: {} + base-64@1.0.0: {} + baseline-browser-mapping@2.10.42: {} bcp-47-match@2.0.3: {} @@ -3809,6 +3848,10 @@ snapshots: caniuse-lite@1.0.30001800: {} + canvaskit-wasm@0.41.1: + dependencies: + '@webgpu/types': 0.1.21 + ccount@2.0.1: {} chalk@4.1.2: @@ -3914,6 +3957,10 @@ snapshots: detect-libc@2.1.2: {} + deterministic-object-hash@2.0.2: + dependencies: + base-64: 1.0.0 + devalue@5.8.1: {} devlop@1.1.0: @@ -3965,6 +4012,8 @@ snapshots: entities@6.0.1: {} + entities@8.0.0: {} + es-define-property@1.0.1: {} es-errors@1.3.0: {} diff --git a/src/content.ts b/src/content.ts new file mode 100644 index 0000000..6b8d73e --- /dev/null +++ b/src/content.ts @@ -0,0 +1,3 @@ +import { getCollection } from "astro:content"; + +export const allPages = await getCollection('docs'); \ No newline at end of file diff --git a/src/pages/og/[...path].ts b/src/pages/og/[...path].ts new file mode 100644 index 0000000..6a9830c --- /dev/null +++ b/src/pages/og/[...path].ts @@ -0,0 +1,63 @@ +import { allPages } from "@/content"; +import type { CollectionEntry } from "astro:content"; +import { OGImageRoute, type OGImageOptions } from 'astro-og-canvas'; + +/** Paths for all of our Markdown content we want to generate OG images for. */ +const paths = process.env.SKIP_OG ? [] : allPages; + +/** An object mapping file paths to file metadata. */ +const pages = Object.fromEntries( + paths.map( + ({ filePath, id, data }) => + [filePath, { data, id }] as [string, Pick, 'data' | 'id'>] + ) +); + +export const { getStaticPaths, GET } = await OGImageRoute({ + pages, + getSlug(_, page: (typeof pages)[string]) { + return page.id + '.webp'; + }, + getImageOptions: async (_, { data, id }: (typeof pages)[string]): Promise => { + return { + format: 'WEBP', + quality: 90, + title: data.title, + description: data.description, + dir: 'ltr', + logo: { + path: './src/pages/og/_images/docs-logo.png', + size: [300], + }, + border: { width: 32, side: 'inline-start' }, + padding: 80, + bgImage: { + path: `./src/pages/og/_images/background.png`, + }, + font: { + title: { + size: 72, + lineHeight: 1.2, + families: [ + 'Inter', + ], + weight: 'Medium', + color: [255, 255, 255], + }, + description: { + size: 42, + lineHeight: 1.2, + families: [ + 'Inter', + ], + weight: 'Normal', + color: [191, 193, 201], + }, + }, + fonts: [ + './src/pages/og/_fonts/inter/inter-400-normal.ttf', + './src/pages/og/_fonts/inter/inter-500-normal.ttf', + ].filter((val): val is string => typeof val === 'string'), + }; + }, +}); \ No newline at end of file From fd9a52c85a282dfcde22f5f7363481d68954ce6a Mon Sep 17 00:00:00 2001 From: Adam Matthiesen Date: Sun, 5 Jul 2026 18:52:47 -0700 Subject: [PATCH 07/40] Add OpenGraph image generation and routing - Introduced background and logo images for OpenGraph sharing. - Implemented route middleware to update OpenGraph meta tags dynamically. - Created utility function to retrieve OpenGraph image paths based on page routes. --- astro.config.ts | 2 ++ src/content.ts | 15 +++++++-- src/pages/og/[...path].ts | 29 ++++++------------ .../og/_fonts/geist-latin-400-normal.ttf | Bin 0 -> 31404 bytes .../og/_fonts/geist-latin-500-normal.ttf | Bin 0 -> 31404 bytes .../og/_fonts/geist-mono-latin-400-normal.ttf | Bin 0 -> 26936 bytes .../og/_fonts/geist-mono-latin-500-normal.ttf | Bin 0 -> 26936 bytes src/pages/og/_images/background.png | Bin 0 -> 3546 bytes src/pages/og/_images/docs-logo.png | Bin 0 -> 4329 bytes src/routeData.ts | 19 ++++++++++++ src/util/getOgImageUrl.ts | 25 +++++++++++++++ 11 files changed, 69 insertions(+), 21 deletions(-) create mode 100644 src/pages/og/_fonts/geist-latin-400-normal.ttf create mode 100644 src/pages/og/_fonts/geist-latin-500-normal.ttf create mode 100644 src/pages/og/_fonts/geist-mono-latin-400-normal.ttf create mode 100644 src/pages/og/_fonts/geist-mono-latin-500-normal.ttf create mode 100644 src/pages/og/_images/background.png create mode 100644 src/pages/og/_images/docs-logo.png create mode 100644 src/routeData.ts create mode 100644 src/util/getOgImageUrl.ts diff --git a/astro.config.ts b/astro.config.ts index 4c5818a..f2def00 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -58,6 +58,8 @@ export default defineConfig({ ContentPanel: './src/components/starlight/ContentPanel.astro', }, + routeMiddleware: './src/routeData.ts', + customCss: [ './src/styles/global.css', ], diff --git a/src/content.ts b/src/content.ts index 6b8d73e..4e2d861 100644 --- a/src/content.ts +++ b/src/content.ts @@ -1,3 +1,14 @@ -import { getCollection } from "astro:content"; +import { getCollection, type CollectionEntry } from "astro:content"; -export const allPages = await getCollection('docs'); \ No newline at end of file +export const allPages = await getCollection('docs'); + +/** Paths for all of our Markdown content we want to generate OG images for. */ +const paths = process.env.SKIP_OG ? [] : allPages; + +/** An object mapping file paths to file metadata. */ +export const pages = Object.fromEntries( + paths.map( + ({ filePath, id, data }) => + [filePath, { data, id }] as [string, Pick, 'data' | 'id'>] + ) +); \ No newline at end of file diff --git a/src/pages/og/[...path].ts b/src/pages/og/[...path].ts index 6a9830c..31d462d 100644 --- a/src/pages/og/[...path].ts +++ b/src/pages/og/[...path].ts @@ -1,24 +1,13 @@ -import { allPages } from "@/content"; +import { allPages, pages } from "@/content"; import type { CollectionEntry } from "astro:content"; import { OGImageRoute, type OGImageOptions } from 'astro-og-canvas'; -/** Paths for all of our Markdown content we want to generate OG images for. */ -const paths = process.env.SKIP_OG ? [] : allPages; - -/** An object mapping file paths to file metadata. */ -const pages = Object.fromEntries( - paths.map( - ({ filePath, id, data }) => - [filePath, { data, id }] as [string, Pick, 'data' | 'id'>] - ) -); - export const { getStaticPaths, GET } = await OGImageRoute({ pages, getSlug(_, page: (typeof pages)[string]) { return page.id + '.webp'; }, - getImageOptions: async (_, { data, id }: (typeof pages)[string]): Promise => { + getImageOptions: async (_, { data }: (typeof pages)[string]): Promise => { return { format: 'WEBP', quality: 90, @@ -36,27 +25,29 @@ export const { getStaticPaths, GET } = await OGImageRoute({ }, font: { title: { - size: 72, + size: 64, lineHeight: 1.2, families: [ - 'Inter', + 'Geist Mono', ], weight: 'Medium', color: [255, 255, 255], }, description: { - size: 42, + size: 28, lineHeight: 1.2, families: [ - 'Inter', + 'Geist', ], weight: 'Normal', color: [191, 193, 201], }, }, fonts: [ - './src/pages/og/_fonts/inter/inter-400-normal.ttf', - './src/pages/og/_fonts/inter/inter-500-normal.ttf', + './src/pages/og/_fonts/geist-latin-400-normal.ttf', + './src/pages/og/_fonts/geist-latin-500-normal.ttf', + './src/pages/og/_fonts/geist-mono-latin-400-normal.ttf', + './src/pages/og/_fonts/geist-mono-latin-500-normal.ttf', ].filter((val): val is string => typeof val === 'string'), }; }, diff --git a/src/pages/og/_fonts/geist-latin-400-normal.ttf b/src/pages/og/_fonts/geist-latin-400-normal.ttf new file mode 100644 index 0000000000000000000000000000000000000000..625aeeda27d967db24200f0d76778bddc7a8c109 GIT binary patch literal 31404 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

WVjBhDO z>wwEea7%?-f~ONM3oZpN7cL);;>;B0H$gwqzUor!we{iIgMFz{)VB++5brCo=dufF ze`h{+$XBYsmwdnW~Mq#`9~efx+=S@FpDEnuTx7 z6q1w5(H}UG-ikc;;a%aoz(2x*&`FlY?#AjcmAwn`T`UW~u*#D1@NUJLm=!d?2G48o zTmjfCa7KXgUIX_Zh=;?s6@(M@)B+EKNF%ob@lRqc4DF+K2HLB*4LpA}@VyexQdXiU z$MZ6lqxc5ke;4h18!*i7p7PRM0(=rQ4T;28_|ZMc6 z%6F81Q`M_FRSQ&0Rclq3sIF9fq_(KL)OV7 z^~Pr70^>^K2IFqyw~cojA2A*=o-&>_{>7v+C7H5K^`-@;4W^sp!s8al?TmXjzCHf- z_-Et)82@=fXo4XjGhtK0i-{$P`x2i`{6peIQdp8TX?D_*q)kazCEc0yV$!QgA0(G2 z&rM#Ld`a?E$u}k6nfy@lsT4(uCZ#Z?DrITP=9FD2SEPJ1<>r*zQvNIDhbfPyJVW}A zC*nIL8u5ieyaiqKl_Q4rl>@LIcnI_|e)svlKg{v? z3w@_Qj|%Zi{o!cL`RLn;fRD-|aq?UaCn0R~hwTW9FGC@Z10jZQudKz_Vuo?%w-w)u z8OC>7R(2ra`mST+f_3EyPdh_x*GMk9TnWfWz{5L$zDxirOW zM0_4%H=ty*fI#1)$(;td7x5dAbA>2P>jZh2Qy1W#3RU2%33Kqxn+}{;{4zLm0B0H6 zI*#^l2+C!iR$GH;?RMk{^oD*RSpZke%vcLw4k+enrMr-KExxBS3XE(*S{>>j98j+| z;yvRce9-rID92`e!6px-2)Fq-KTQ1`fj^G7Wq7VYdBR2jZ#aVi3W>}2U9{*6uKx$j Cg4ja< literal 0 HcmV?d00001 diff --git a/src/pages/og/_fonts/geist-mono-latin-400-normal.ttf b/src/pages/og/_fonts/geist-mono-latin-400-normal.ttf new file mode 100644 index 0000000000000000000000000000000000000000..03bdb8e3efd14962c963497cb34e07454e0c9ac0 GIT binary patch literal 26936 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 Cnh*~F literal 0 HcmV?d00001 diff --git a/src/pages/og/_fonts/geist-mono-latin-500-normal.ttf b/src/pages/og/_fonts/geist-mono-latin-500-normal.ttf new file mode 100644 index 0000000000000000000000000000000000000000..86258bfbb1fb0c9ebc1935c2b325aa241c4820f9 GIT binary patch literal 26936 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 literal 0 HcmV?d00001 diff --git a/src/pages/og/_images/background.png b/src/pages/og/_images/background.png new file mode 100644 index 0000000000000000000000000000000000000000..a8f6060a4e9a21824d297aef7e7751028441142f GIT binary patch literal 3546 zcmeH~?Kj(L8plJMss@?XN=*_8Q`WW;Q5lcFkYq?ykrbVZQK`-tc55o>P>GVHYaZ-O zcFgQJ!zhs#7TdEyT74qYR5PVYLN=`;R6WG=LyANQvU>I}m^WVR>5J>!=X<@muk-nS z&vowmyEC*X$3yT#AP~qg`cz~B2((`c0@>yr+_&4|RtvLt51X8XsE=$0yD)-XVb4C5 zoC5+uoZprW=th<6ZgcER>{*JvJ>&xqPv;{p2)LW01JvH$5#|D?(-LD&)5#=?mzTGf z=W!$wh4aNbA32IdxF;qgVX-Hvlvw+NP%`-ao`2 zAA7~9|VMwPaOAibT}NJkQ@*gMj}$ZJbgUez3}(|5}87ye@r4r!C5|wf~42Yo7lIXOLBdM`5(eYsfvOhlP#0g9!^>i44NTVl)0z@E;934aV^zuQY zkHK7!7%bie2KPXFlZcT3Kt#aNSS*fAjsTZ-xPU+oKSxKB&vL64b)zii=QfYttmg4# z4Z2TYzXkujpK|5^{OjL-eU0;NdxJJnosEzGb@FfSHYXwf{MFv}v)sNCO?K0=uJK;V zBgq}eMxD5qLbp_TPlp9>Zi(~9M}HmWFsV^|%Jr`fW85R8*B#nz{r5wj zzPA^mB$&a;_zR5v-0A0Xi$j0%Gg{@5@^-f2vN= zTdISuI8S-kG}y6|+lwYL2shwVgqUaQk@A=O1~uN5>kinsek;pR7L|e)j3KrPi@=>K z^TMBVc>}aQ?f_P^#F@}vTzqwFwbVG$EbDxtNnfl^wuGm-qTnOvEj>BK#~AD$Om$_0 zw6XWxsZ8~cRF-J11I#n^h4~7b9VP6FpG1IhH@TP1hA7N8mXE{rdJ5X>G6P!_v;*zOyvd$j6xM8%KeVhooWF3bU@2v_e7e5<25)_Ca?&_9`;u6}d-_-mEm-~^1@DyR zhN0T~-U#JmE-#0HN_{}Ulmv#0stZ3gcbWp1?CP1W=XQ(>=z3jiGm!FFzM(X$%UIk? z8#t|Tuvsv`F}9$$t};TbW3sG?7H_88IdvTVuGFk5FK(%YG`X4j!H|;5WNAhmyqC{i zn446pzImb-K$XwtrXHqkr?1t|_URWlN{zDVW$=7vjnBV<=Df?qY_!$a7XI2*;?`6m!m{O?LvvV#+gb!80_Wn745WVnBqWsRe7b&N`bZNSdz9o9OG>3+@@*c2bMtU{FT02`JbEh0-_Fv zDobm>(u|M@q4F;?g`8OgOX8&bPOCL)%@)>WMZe#=kjQdSmRhS+=aW+u1v`E_vpzuk zrUuZ;C)GI(z_K4kb(!B9vNLp(6U5(qrqs&ES6OWVBI`Ev9xDHh;l3|}J-l#WeygJk zQB&Vo_3-xH+|`ZISpLrV%G?)g9jgjdwxbfSjKC4rW%brjQGVV|MX3UHc~K>1PV_YV zFxb6v)EXujZ|PdTC#H$QLkf~}w-!dLWvzKjQ@h@6=z8Vsta;5K&CpZZVwIqF-a03` zP{I!Y2zmNR_Gdc}(DtSV7^R^9@H#wNu=yz4qED|ObioGYzsLz~>ut-)iBTII}; zpY{2N5#qwkg68|ql8bzTDDRSKX8Tt0g;Dt&cWEujS6~`Je!a^q07YY21#0y^qo!l2 zdqHU$;4<=;|M5b8OC_6HE>SVBiH9Fd2bh0Z4_vCMG`(ILEcRrOzD=`vzX+Uu5cZSD z|BZ-3N`U4MA;FjIy1ID>vTm=tygumWi7NsZ-gNqd#NyMhc2OAIYznLQO+Goa`w$*H zV*5VSodMXj+m;MztiQ0OZMG;^T#4=8lj-11>lJmZTJ87S&#vx%#X!*%T4du#X+{49 D6aP5B literal 0 HcmV?d00001 diff --git a/src/pages/og/_images/docs-logo.png b/src/pages/og/_images/docs-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..006c3294042c19e8915d771adf5a504bd03c815e GIT binary patch literal 4329 zcmeH~_ct5<_s3)JP$Q@ntyO|r?+8_b+CtT+8nw3wwMmgG)f%xEoz$2_?yeRZZczFd;D{$A>jO7E`>$<;x$x4e1&DjF3s zDX1&rC3#TN#h9=dCkFBc+C*}C7H4EGOKOT;3&8~aLOxS{-AM$|7~@&wo`XViI~D<; zys1-E+*+mC|J~qe_Ive>4Bc2*fpEsI(<}EX6(2&my`3x{+~xfjE*Fq#SGY>JkjAX5 z)y1>*1pAxRn%HxbFDE{2HPO_OB)MSmmn1T$>TBi89lRPCQZ$_my--B^6^xq<2*(VO z6$RvnnBiZme8EVot%Z(Xg~;0TvjZU-wFx|-<1vF&BHvI}aOGQsCJ)~kEiq1F5Z|`; z2TzT!Dk6<2%BNT*Co^$EQL>>dCyH`-lP0CyWMK{Gwa8EfE~l|-5FK><*SMu_)vy=| z$?sSURl)j(L{6UXXEAJ9vvz?Fp;+f>63~l9235GS2p4(kc+k?)Tdue0TRpqIx@5G? z;8|)oQHhvSq!h)~GWXG8(ar#8H(A#Q@yfpGA^PuVL$$Fc>Sl1ORiV)DABvf<{bf)d z{Zz?7pqhtJdZ5K?3+ziXCERKzhw|GjNpZhI@Z|vmUEO${*+q2TzNCBkjk@MM{#1B*U~n}CLmz6KbR7oL_B*PmLjoepoA@ z#Zi_hDaYj4-A-2Kp5Hp_TGhj=y`J92{HBmW&d7Io3+a ztsp{0IqfWi5IZj0&*tOh<8VD*1c+Y;G^#6dGTF7gp;1H>-AL|Kl%l$mPpG7Vu*yl)ua?(BP z1n4`CS&qI;(mKHbh0a0>=B&{bsvM>V^S!6!ZPdOkvD&A;tW2w-%)u-nIJfnvqinb5 z`~{`;eo_Z{E8R}NkrRQ9>ECQa7y6faN;vR0dGdLtDMKSeHi|?)P#{j%Ixf}8yCqlsRAH`;vLTZ`4=Wk5vxi#((t@i=Vu5ORm=N3ZlQ+v8A4JRGgfpNQWRK z!K111-8L5XOs8jHh_isdjVx{J_NrIaUB|Y=gHzt!ey$?!1J!*8&yPW`8WX|5kXq5B zz;|v2u?;q^S@++SgN7%#id!tZp zG148y8ckC_#~g!dKTB*zcnO9z`qrTM?ZpEMcfxtB>5UjR)X6itC;dR$x7NPbqtXN| zViJXy7l~+s##lyj)6zPVMth3e>0uN2kI9(ci^ZkSY6+>qESBsU9;lL|QtQUv4qRHtc8YSe-=X3Ql4`8JkpLxog7x;A52l|Q6){E~XxT+cH+3xk zHS9GR8duoD{#L*KCDlNn%93pT^?;3e25mmQ;ymo{dHh~yr-Ly3!F7CG8clz@JH0>V zF%;X(o`PY%T`5A9+)grKL)|Xb89vF>pl8sehMqvAjLvD>d+w`gbMlpYPTc3E#54zp zA6wJ~FH8k#XM4&+LEOpm+6?Vmd5@LPtpzxdMB3O~KnKulsCM^v2X7Tw0FE%PEav?J z$tXlYOAE(*Tua|`@=O!gbD?6x*hx!X*BonUeF~+ec!HI>Rlvlcl0_^A?plPfVS-Oe zoISUSBtWP|h7=4bb82!y_-AKol1L(NxC2Y2qzJJ6TYFU*u?1F2JT)1lgZ9E@2QDeG zcGa;Yu&Hd-ETQNO;T1E|G2c^5B{cnr6xfPUHr~S!f$Tv85l-mhYiA5N!uH)b7`n#b0+jnub9%HcIsBfur}BZg99hzwN@eC54-v w`tS2bP9#8d>cY2_&}j)f{_9U!N_(JadN(15Omh`+^GgG0K0>HgC|hCv1IIn1CIA2c literal 0 HcmV?d00001 diff --git a/src/routeData.ts b/src/routeData.ts new file mode 100644 index 0000000..94b2373 --- /dev/null +++ b/src/routeData.ts @@ -0,0 +1,19 @@ + +import { defineRouteMiddleware } from '@astrojs/starlight/route-data'; +import type { APIContext } from 'astro'; +import { getOgImageUrl } from './util/getOgImageUrl'; + +export const onRequest = defineRouteMiddleware((context) => { + updateHead(context); +}); + +function updateHead(context: APIContext) { + const { head, isFallback } = context.locals.starlightRoute; + + const ogImageUrl = getOgImageUrl(context.url.pathname, !!isFallback); + const imageSrc = ogImageUrl ?? '/platform.webp'; + const canonicalImageSrc = new URL(imageSrc, context.site); + + head.push({ tag: 'meta', attrs: { property: 'og:image', content: canonicalImageSrc.href } }); + head.push({ tag: 'meta', attrs: { name: 'twitter:image', content: canonicalImageSrc.href } }); +} \ No newline at end of file diff --git a/src/util/getOgImageUrl.ts b/src/util/getOgImageUrl.ts new file mode 100644 index 0000000..4a9c833 --- /dev/null +++ b/src/util/getOgImageUrl.ts @@ -0,0 +1,25 @@ + +import { pages } from '@/content'; + +const routes = Object.values(pages).map(({ id }) => { + const path = id + '.webp'; + return { params: { path } }; +}); + +/** All the OpenGraph image paths as generated by our `getStaticPaths`. */ +const paths = new Set(routes.map(({ params }) => params.path)); + +/** + * Get the path to the OpenGraph image for a page + * @param path Pathname of the page URL. + * @param isFallback Whether or not this page is displaying fallback content. + * @returns Path to the OpenGraph image if found. Otherwise, `undefined`. + */ +export function getOgImageUrl(path: string, isFallback: boolean): string | undefined { + let imagePath = path.replace(/^\//, '').replace(/\/$/, '') + '.webp'; + if (isFallback) { + // Replace the language segment with 'en' for fallback pages. + imagePath = 'en' + imagePath.slice(imagePath.indexOf('/')); + } + if (paths.has(imagePath)) return '/og/' + imagePath; +} \ No newline at end of file From 816637b0d14f085265fa0170b7b4d74afd74ce06 Mon Sep 17 00:00:00 2001 From: Adam Matthiesen Date: Sun, 5 Jul 2026 18:53:42 -0700 Subject: [PATCH 08/40] refactor: remove unused import of allPages and CollectionEntry from OG image route --- src/pages/og/[...path].ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/og/[...path].ts b/src/pages/og/[...path].ts index 31d462d..1b7f90c 100644 --- a/src/pages/og/[...path].ts +++ b/src/pages/og/[...path].ts @@ -1,5 +1,4 @@ -import { allPages, pages } from "@/content"; -import type { CollectionEntry } from "astro:content"; +import { pages } from "@/content"; import { OGImageRoute, type OGImageOptions } from 'astro-og-canvas'; export const { getStaticPaths, GET } = await OGImageRoute({ From 320e15cdea52d6283cff5023d74d585210adbda4 Mon Sep 17 00:00:00 2001 From: Adam Matthiesen Date: Sun, 5 Jul 2026 18:58:09 -0700 Subject: [PATCH 09/40] feat: add font imports for Geist and Geist Mono in global.css --- src/styles/global.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/styles/global.css b/src/styles/global.css index ed6d76d..303239a 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -4,6 +4,9 @@ @import 'tailwindcss/theme.css' layer(theme); @import 'tailwindcss/utilities.css' layer(utilities); +@import '@fontsource-variable/geist'; +@import '@fontsource-variable/geist-mono'; + /* Dark mode colors. */ :root { --sl-color-accent-low: oklch(0.47 0.157 37.304); From 3359225c747292373e7f90440b0f7c8cd92365e1 Mon Sep 17 00:00:00 2001 From: Adam Matthiesen Date: Sun, 5 Jul 2026 19:22:40 -0700 Subject: [PATCH 10/40] feat: implement custom 404 page with DocsNotFound component and disable 404 route --- astro.config.ts | 2 ++ src/components/docs/docs-not-found.tsx | 36 ++++++++++++++++++++++++++ src/pages/404.astro | 16 ++++++++++++ src/styles/global.css | 4 +++ 4 files changed, 58 insertions(+) create mode 100644 src/components/docs/docs-not-found.tsx create mode 100644 src/pages/404.astro diff --git a/astro.config.ts b/astro.config.ts index f2def00..85205b0 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -29,6 +29,8 @@ export default defineConfig({ light: './src/assets/icon-light.svg', }, + disable404Route: true, + head: [ { tag: 'link', diff --git a/src/components/docs/docs-not-found.tsx b/src/components/docs/docs-not-found.tsx new file mode 100644 index 0000000..f25301d --- /dev/null +++ b/src/components/docs/docs-not-found.tsx @@ -0,0 +1,36 @@ +import { ArrowLeft, Home } from "lucide-react"; + +export function DocsNotFound() { + return ( +

+
+
+

Error 404

+

+ Page not found +

+

+ The page you're looking for doesn't exist or has been + moved to a different URL. +

+
+ +
+
+ ); +} diff --git a/src/pages/404.astro b/src/pages/404.astro new file mode 100644 index 0000000..2582d48 --- /dev/null +++ b/src/pages/404.astro @@ -0,0 +1,16 @@ +--- +import { DocsNotFound } from "@/components/docs/docs-not-found"; +import StarlightPage from "@astrojs/starlight/components/StarlightPage.astro"; +--- + + + + + + diff --git a/src/styles/global.css b/src/styles/global.css index 303239a..ec8a310 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -140,4 +140,8 @@ a { .expressive-code pre, .expressive-code span.title { border: none !important; +} + +[data-is-404="true"] .sl-copy-button-row { + display: none !important; } \ No newline at end of file From c979ae05fb1ea6588886ab6ac9250643deb8f9c9 Mon Sep 17 00:00:00 2001 From: Adam Matthiesen Date: Sun, 5 Jul 2026 20:12:29 -0700 Subject: [PATCH 11/40] feat: reorganize platform documentation structure and update icons for consistency --- astro.config.ts | 23 ++++++++++++------- .../docs/platform/chart-editor/flow-nodes.mdx | 1 - .../docs/platform/chart-editor/index.mdx | 1 - .../platform/chart-editor/output-nodes.mdx | 1 - src/content/docs/platform/error-tracking.mdx | 1 - src/content/docs/platform/guide/badges.mdx | 1 - src/content/docs/platform/guide/embed.mdx | 1 - src/content/docs/platform/hotkeys.mdx | 1 - src/content/docs/platform/index.mdx | 1 - src/content/docs/platform/retention.mdx | 3 +-- 10 files changed, 16 insertions(+), 18 deletions(-) diff --git a/astro.config.ts b/astro.config.ts index 85205b0..4700f2d 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -105,16 +105,23 @@ export default defineConfig({ link: '/platform/', icon: 'puzzle', items: [ - 'platform', - 'platform/hotkeys', - 'platform/guide/embed', - 'platform/guide/badges', + { + label: 'Overview', + items: [ + 'platform', + 'platform/hotkeys', + 'platform/error-tracking', + 'platform/retention' + ] + }, + { + label: 'Guides', + items: [{ autogenerate: { directory: 'platform/guide' } }], + }, { label: 'Chart Editor', items: [{ autogenerate: { directory: 'platform/chart-editor' } }], - }, - 'platform/error-tracking', - 'platform/retention' + } ], }, { @@ -129,7 +136,7 @@ export default defineConfig({ id: 'api', link: '/api/', icon: 'open-book', - items: [{ autogenerate: { directory: 'api' } }, ...openAPISidebarGroups], + items: openAPISidebarGroups, }, { label: 'Web Analytics', diff --git a/src/content/docs/platform/chart-editor/flow-nodes.mdx b/src/content/docs/platform/chart-editor/flow-nodes.mdx index 5375d11..e63b800 100644 --- a/src/content/docs/platform/chart-editor/flow-nodes.mdx +++ b/src/content/docs/platform/chart-editor/flow-nodes.mdx @@ -1,7 +1,6 @@ --- title: Flow Nodes description: All available nodes for building data pipelines in the flow editor -icon: Workflow --- import { diff --git a/src/content/docs/platform/chart-editor/index.mdx b/src/content/docs/platform/chart-editor/index.mdx index 503f450..637fcd4 100644 --- a/src/content/docs/platform/chart-editor/index.mdx +++ b/src/content/docs/platform/chart-editor/index.mdx @@ -1,7 +1,6 @@ --- title: Overview description: Build and configure charts using the visual flow editor -icon: ChartArea --- import { LinkCard, CardGrid } from '@astrojs/starlight/components'; diff --git a/src/content/docs/platform/chart-editor/output-nodes.mdx b/src/content/docs/platform/chart-editor/output-nodes.mdx index 1c5e5bf..c50b190 100644 --- a/src/content/docs/platform/chart-editor/output-nodes.mdx +++ b/src/content/docs/platform/chart-editor/output-nodes.mdx @@ -1,7 +1,6 @@ --- title: Output & Multi-Series description: How to create tabs, multi-line charts, and stacked bars using multiple Output nodes -icon: GitFork --- import { Aside } from '@astrojs/starlight/components'; diff --git a/src/content/docs/platform/error-tracking.mdx b/src/content/docs/platform/error-tracking.mdx index b8adc0d..f01cd6a 100644 --- a/src/content/docs/platform/error-tracking.mdx +++ b/src/content/docs/platform/error-tracking.mdx @@ -1,7 +1,6 @@ --- title: Error Tracking description: How to track errors in your application -icon: Bug --- FastStats allows you to track errors in your application. diff --git a/src/content/docs/platform/guide/badges.mdx b/src/content/docs/platform/guide/badges.mdx index 6c5bcd7..7e2a7cd 100644 --- a/src/content/docs/platform/guide/badges.mdx +++ b/src/content/docs/platform/guide/badges.mdx @@ -1,7 +1,6 @@ --- title: Status badges description: Shields.io badges for public project stats -icon: Award --- Show live numbers from a **public** FastStats project in READMEs, wikis, or any page that supports images. Badges use [Shields.io](https://shields.io) [endpoint badges](https://shields.io/badges/endpoint-badge), which read a small JSON document from FastStats. diff --git a/src/content/docs/platform/guide/embed.mdx b/src/content/docs/platform/guide/embed.mdx index 7f0d862..22f9e1f 100644 --- a/src/content/docs/platform/guide/embed.mdx +++ b/src/content/docs/platform/guide/embed.mdx @@ -1,7 +1,6 @@ --- title: Chart Embeds description: Embed charts in your documentation or website -icon: Image --- Embed your FastStats charts anywhere diff --git a/src/content/docs/platform/hotkeys.mdx b/src/content/docs/platform/hotkeys.mdx index 3b93e68..f1281d2 100644 --- a/src/content/docs/platform/hotkeys.mdx +++ b/src/content/docs/platform/hotkeys.mdx @@ -1,7 +1,6 @@ --- title: Hotkeys description: Keyboard shortcuts in the FastStats dashboard -icon: Keyboard --- import { Aside } from '@astrojs/starlight/components'; diff --git a/src/content/docs/platform/index.mdx b/src/content/docs/platform/index.mdx index cdff7e5..935ea98 100644 --- a/src/content/docs/platform/index.mdx +++ b/src/content/docs/platform/index.mdx @@ -1,7 +1,6 @@ --- title: Introduction description: Your introduction to FastStats -icon: BookOpen --- import { LinkCard, CardGrid } from '@astrojs/starlight/components'; diff --git a/src/content/docs/platform/retention.mdx b/src/content/docs/platform/retention.mdx index cba3424..c0d31c6 100644 --- a/src/content/docs/platform/retention.mdx +++ b/src/content/docs/platform/retention.mdx @@ -1,7 +1,6 @@ --- title: Retention description: Measure how many users come back over time with cohort-based retention charts. -icon: RefreshCcw --- export const mockCohortRows = [ @@ -17,7 +16,7 @@ Retention shows how many users return after their first seen period. FastStats g Static preview from the retention page. This example is not interactive. -
+
From 320a5493fb646efa33eca11a76ea69a5313258f5 Mon Sep 17 00:00:00 2001 From: Adam Matthiesen Date: Sun, 5 Jul 2026 20:15:14 -0700 Subject: [PATCH 12/40] feat: enhance configuration structure for Java and Web Analytics sections --- astro.config.ts | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/astro.config.ts b/astro.config.ts index 4700f2d..f045e10 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -129,7 +129,20 @@ export default defineConfig({ id: 'java', link: '/java/', icon: 'seti:java', - items: [{ autogenerate: { directory: 'java' } }], + items: [ + { + label: 'Configuration', + items: [] + }, + { + label: 'Platforms', + items: [{ autogenerate: { directory: 'java/platforms' } }], + }, + { + label: 'Advanced', + items: [] + } + ], }, { label: 'Rest API', @@ -143,11 +156,24 @@ export default defineConfig({ id: 'web-analytics', link: '/web-analytics/', icon: 'analytics', - items: [{ autogenerate: { directory: 'web-analytics' } }], badge: { text: "Coming Soon", variant: 'tip' - } + }, + items: [ + { + label: 'Getting Started', + items: [] + }, + { + label: 'Usage', + items: [] + }, + { + label: 'Features', + items: [] + } + ] } ], { topics: { From 6eaf32592010c84d26b75b7a6cda9226d307def3 Mon Sep 17 00:00:00 2001 From: Adam Matthiesen Date: Sun, 5 Jul 2026 20:15:40 -0700 Subject: [PATCH 13/40] fix: correct directory name for Java platform autogeneration --- astro.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/astro.config.ts b/astro.config.ts index f045e10..d43ce81 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -136,7 +136,7 @@ export default defineConfig({ }, { label: 'Platforms', - items: [{ autogenerate: { directory: 'java/platforms' } }], + items: [{ autogenerate: { directory: 'java/platform' } }], }, { label: 'Advanced', From fea41f4191c53c8c4043afdf47f406a65c615dd4 Mon Sep 17 00:00:00 2001 From: Adam Matthiesen Date: Sun, 5 Jul 2026 20:16:37 -0700 Subject: [PATCH 14/40] feat: add latestVersion function to fetch the latest project version from the API --- src/util/repository.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/util/repository.ts diff --git a/src/util/repository.ts b/src/util/repository.ts new file mode 100644 index 0000000..8617a35 --- /dev/null +++ b/src/util/repository.ts @@ -0,0 +1,19 @@ +export async function latestVersion(project: string): Promise { + try { + const response = await fetch( + `https://repo.faststats.dev/api/maven/latest/version/releases/dev/faststats/metrics/${project}`, + { + cache: "force-cache", + }, + ); + + if (!response.ok) { + return "VERSION"; + } + + const data = await response.json(); + return data.version; + } catch { + return "VERSION"; + } +} From 4360c889b5bc297bffa4bbb58f57e91146698545 Mon Sep 17 00:00:00 2001 From: Adam Matthiesen Date: Sun, 5 Jul 2026 20:46:46 -0700 Subject: [PATCH 15/40] Add documentation for FastStats Java SDK features - Introduced new pages for Custom Metrics, Error Tracking, Feature Flags, and Installation. - Added Migration Guide for upgrading from version 0.23.0 to 0.24.0. - Included Obfuscation Mappings documentation for uploading ProGuard/R8 mappings. - Created platform-specific integration guides for Bukkit, BungeeCord, Fabric, Hytale, Minestom, NeoForge, Nukkit, Sponge, and Velocity. - Documented system properties for configuring FastStats behavior at runtime. --- astro.config.ts | 14 +- src/content/docs/java/configuration.mdx | 76 ++++++ src/content/docs/java/custom-metrics.mdx | 146 +++++++++++ src/content/docs/java/error-tracking.mdx | 178 +++++++++++++ src/content/docs/java/feature-flags.mdx | 110 ++++++++ src/content/docs/java/index.mdx | 154 ++++++++++++ src/content/docs/java/migration.mdx | 236 ++++++++++++++++++ .../docs/java/obfuscation-mappings.mdx | 150 +++++++++++ src/content/docs/java/platform/bukkit.mdx | 38 +++ src/content/docs/java/platform/bungeecord.mdx | 38 +++ src/content/docs/java/platform/fabric.mdx | 42 ++++ src/content/docs/java/platform/hytale.mdx | 44 ++++ src/content/docs/java/platform/minestom.mdx | 33 +++ src/content/docs/java/platform/neoforge.mdx | 38 +++ src/content/docs/java/platform/nukkit.mdx | 41 +++ src/content/docs/java/platform/sponge.mdx | 48 ++++ src/content/docs/java/platform/velocity.mdx | 49 ++++ src/content/docs/java/system-properties.mdx | 53 ++++ 18 files changed, 1486 insertions(+), 2 deletions(-) create mode 100644 src/content/docs/java/configuration.mdx create mode 100644 src/content/docs/java/custom-metrics.mdx create mode 100644 src/content/docs/java/error-tracking.mdx create mode 100644 src/content/docs/java/feature-flags.mdx create mode 100644 src/content/docs/java/index.mdx create mode 100644 src/content/docs/java/migration.mdx create mode 100644 src/content/docs/java/obfuscation-mappings.mdx create mode 100644 src/content/docs/java/platform/bukkit.mdx create mode 100644 src/content/docs/java/platform/bungeecord.mdx create mode 100644 src/content/docs/java/platform/fabric.mdx create mode 100644 src/content/docs/java/platform/hytale.mdx create mode 100644 src/content/docs/java/platform/minestom.mdx create mode 100644 src/content/docs/java/platform/neoforge.mdx create mode 100644 src/content/docs/java/platform/nukkit.mdx create mode 100644 src/content/docs/java/platform/sponge.mdx create mode 100644 src/content/docs/java/platform/velocity.mdx create mode 100644 src/content/docs/java/system-properties.mdx diff --git a/astro.config.ts b/astro.config.ts index d43ce81..e206d53 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -132,7 +132,14 @@ export default defineConfig({ items: [ { label: 'Configuration', - items: [] + items: [ + 'java', + 'java/migration', + 'java/configuration', + 'java/custom-metrics', + 'java/error-tracking', + 'java/feature-flags', + ] }, { label: 'Platforms', @@ -140,7 +147,10 @@ export default defineConfig({ }, { label: 'Advanced', - items: [] + items: [ + 'java/obfuscation-mappings', + 'java/system-properties', + ] } ], }, diff --git a/src/content/docs/java/configuration.mdx b/src/content/docs/java/configuration.mdx new file mode 100644 index 0000000..77ea017 --- /dev/null +++ b/src/content/docs/java/configuration.mdx @@ -0,0 +1,76 @@ +--- +title: Configuration +description: Advanced configuration options for FastStats Java SDK +--- + +Configure FastStats by creating a platform context and attaching the services +your project uses. + +## Basic Configuration + +The minimal metrics configuration requires only a token: + +```java title='ExamplePlugin.java' +import dev.faststats.Metrics; +import dev.faststats.bukkit.BukkitContext; + +private final BukkitContext context = new BukkitContext.Factory(plugin, "YOUR_TOKEN") + .metrics(Metrics.Factory::create) + .create(); + +public void onEnable() { + context.ready(); +} +``` + +## Complete Configuration Example + +Here's a configured Bukkit context with error tracking, custom metrics, and a +flush callback: + +```java title='ExamplePlugin.java' +import dev.faststats.ErrorTracker; +import dev.faststats.bukkit.BukkitContext; +import dev.faststats.data.Metric; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.concurrent.atomic.AtomicInteger; + +public final class MyBukkitPlugin extends JavaPlugin { + public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); + private final AtomicInteger arenaMatches = new AtomicInteger(); + + private final BukkitContext context = new BukkitContext.Factory(this, "YOUR_TOKEN") + .errorTrackerService(ERROR_TRACKER) + .metrics(factory -> factory + .addMetric(Metric.number("arena_matches", arenaMatches::get)) + .addMetric(Metric.string("active_ruleset", () -> "ranked_duels")) + .addMetric(Metric.bool("ranked_mode", () -> true)) + .addMetric(Metric.stringArray("used_hooks", () -> new String[]{"Vault", "PlaceholderAPI"})) + .onFlush(() -> arenaMatches.set(0)) + .create()) + .create(); + + @Override + public void onEnable() { + context.ready(); + } + + @Override + public void onDisable() { + context.shutdown(); + } +} +``` + +Metrics submission and error tracking start after `context.ready()` is called. +Call `context.ready()` from the platform startup hook, and call +`context.shutdown()` during shutdown. + +For error tracking configuration, see [Error Tracking](/java/error-tracking). For platform-specific setup, see the platform pages in the sidebar. + +## Best Practices + +- Keep metric suppliers lightweight +- Cache expensive calculations and values that never change +- Metric suppliers must be thread-safe and pure diff --git a/src/content/docs/java/custom-metrics.mdx b/src/content/docs/java/custom-metrics.mdx new file mode 100644 index 0000000..9700be3 --- /dev/null +++ b/src/content/docs/java/custom-metrics.mdx @@ -0,0 +1,146 @@ +--- +title: Custom Metrics +description: Send custom values from your Java project +--- + +Custom metrics let you submit project-specific values alongside the built-in +platform metrics. Each custom metric must match a data source configured in your +FastStats project settings. + +## Add Metrics + +Attach custom metrics when you create the platform context: + +```java title='ExamplePlugin.java' +import dev.faststats.bukkit.BukkitContext; +import dev.faststats.data.Metric; + +import java.util.concurrent.atomic.AtomicInteger; + +private final AtomicInteger arenaMatches = new AtomicInteger(); + +private final BukkitContext context = new BukkitContext.Factory(this, "YOUR_TOKEN") + .metrics(factory -> factory + .addMetric(Metric.number("arena_matches", arenaMatches::get)) + .addMetric(Metric.stringArray("used_hooks", () -> new String[]{"Vault", "PlaceholderAPI"})) + .onFlush(() -> arenaMatches.set(0)) + .create()) + .create(); + +public void onEnable() { + context.ready(); +} +``` + +Metrics submission starts after `context.ready()` is called. Call +`context.shutdown()` during your platform's shutdown hook. + +## Data Source IDs + +The first argument passed to `Metric.*` is the source ID. It must match the data +source ID in your FastStats project. + +```java +Metric.number("arena_matches", arenaMatches::get); +``` + +Source IDs must use lowercase letters and underscores only, for example +`arena_matches`, `used_hooks`, or `active_ruleset`. + +## Supported Types + +Use the factory method that matches the data source type: + +| Method | Value type | +| ----------------------------------- | ------------------------------- | +| `Metric.number(id, supplier)` | `Number` | +| `Metric.string(id, supplier)` | `String` | +| `Metric.bool(id, supplier)` | `Boolean` | +| `Metric.numberArray(id, supplier)` | `Number[]` | +| `Metric.stringArray(id, supplier)` | `String[]` | +| `Metric.booleanArray(id, supplier)` | `Boolean[]` | +| `Metric.numberMap(id, supplier)` | `Map` | +| `Metric.stringMap(id, supplier)` | `Map` | +| `Metric.booleanMap(id, supplier)` | `Map` | + +```java +Metric.number("active_arenas", () -> 4); +Metric.string("active_ruleset", () -> "ranked_duels"); +Metric.bool("ranked_mode", () -> true); + +Metric.stringArray("used_hooks", () -> new String[]{"Vault", "PlaceholderAPI"}); +Metric.numberArray("match_durations", () -> new Number[]{310, 428, 275}); +Metric.booleanArray("enabled_features", () -> new Boolean[]{true, false}); +``` + +Map metrics are useful when the set of keys is dynamic: + +```java +Metric.numberMap("hook_usage", () -> Map.of( + "vault", 12, + "placeholderapi", 4, + "luckperms", 9 +)); +``` + +## Supplier Behavior + +Metric suppliers are called by the SDK during submission. Keep them: + +- lightweight +- thread-safe +- side-effect free +- resilient to missing or temporarily unavailable platform state + +Return `null` from a supplier when a value should be skipped for that +submission. + +```java +Metric.string("active_event", () -> currentEvent != null ? currentEvent.id() : null); +``` + +If a value is expensive to compute, update a cached value from your own platform +events and read the cached value from the metric supplier. + +```java +private volatile int cachedQueueDepth = 0; + +public void updateQueueDepth() { + cachedQueueDepth = matchmakingQueue.size(); +} + +Metric.number("queue_depth", () -> cachedQueueDepth); +``` + +## Flush Callback + +Use `onFlush` to clear counters after FastStats accepts a metrics submission. + +```java +private final AtomicInteger arenaMatches = new AtomicInteger(); + +.metrics(factory -> factory + .addMetric(Metric.number("arena_matches", arenaMatches::get)) + .onFlush(() -> arenaMatches.set(0)) + .create()) +``` + +Do not reset counters inside the metric supplier itself. Suppliers may be called +without a successful submission. + +## Built-In Metrics Only + +If you do not need custom metrics, create the metrics service without adding any +metrics: + +```java title='ExamplePlugin.java' +import dev.faststats.Metrics; + +private final BukkitContext context = new BukkitContext.Factory(this, "YOUR_TOKEN") + .metrics(Metrics.Factory::create) + .create(); + +public void onEnable() { + context.ready(); +} +``` diff --git a/src/content/docs/java/error-tracking.mdx b/src/content/docs/java/error-tracking.mdx new file mode 100644 index 0000000..71f954d --- /dev/null +++ b/src/content/docs/java/error-tracking.mdx @@ -0,0 +1,178 @@ +--- +title: Error Tracking +description: Monitor and report errors from your Minecraft server plugin +--- + +import { Aside } from '@astrojs/starlight/components'; + +FastStats can automatically track errors in your project. + + + + + +## Context-Aware Error Tracker + +The context-aware error tracker automatically tracks uncaught errors from the +same class loader: + +```java title='MyBukkitPlugin.java' +import dev.faststats.ErrorTracker; +import dev.faststats.bukkit.BukkitContext; +import org.bukkit.plugin.java.JavaPlugin; + +public final class MyBukkitPlugin extends JavaPlugin { + public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); + + private final BukkitContext context = new BukkitContext.Factory(this, "YOUR_TOKEN") + .errorTrackerService(ERROR_TRACKER) + .create(); + + @Override + public void onEnable() { + context.ready(); + } + + @Override + public void onDisable() { + context.shutdown(); + } + + public void doSomethingWrong() { + try { + throw new RuntimeException("Something went wrong!"); + } catch (Exception e) { + // This exception will be reported as handled. + ERROR_TRACKER.trackError(e); + } + } +} +``` + + + +## Context-Unaware Error Tracker + +The context-unaware error tracker only tracks errors passed to `trackError()`: + +```java title='MyBukkitPlugin.java' +import dev.faststats.ErrorTracker; +import dev.faststats.bukkit.BukkitContext; +import org.bukkit.plugin.java.JavaPlugin; + +public final class MyBukkitPlugin extends JavaPlugin { + public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextUnaware(); + + private final BukkitContext context = new BukkitContext.Factory(this, "YOUR_TOKEN") + .errorTrackerService(ERROR_TRACKER) + .create(); + + @Override + public void onEnable() { + context.ready(); + } + + public void doSomethingWrong() { + try { + throw new RuntimeException("Something went wrong!"); + } catch (Exception e) { + ERROR_TRACKER.trackError(e); + } + } +} +``` + +## Ignoring and Anonymizing Errors + +You can ignore specific error types or messages, and anonymize sensitive data in error messages: + +```java +public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware() + .ignoreError(InvocationTargetException.class, "Expected .* but got .*") + .ignoreError(AccessDeniedException.class); + +public static final ErrorTracker MANUAL_ERROR_TRACKER = ErrorTracker.contextUnaware() + .anonymize("^[\\w-.]+@([\\w-]+\\.)+[\\w-]{2,4}$", "[email hidden]") + .anonymize("Bearer [A-Za-z0-9._~+/=-]+", "Bearer [token hidden]") + .anonymize("AKIA[0-9A-Z]{16}", "[aws-key hidden]") + .anonymize("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}", "[uuid hidden]") + .anonymize("([?&](?:api_?key|token|secret)=)[^&\\s]+", "$1[redacted]"); + +private final BukkitContext context = new BukkitContext.Factory(plugin, "YOUR_TOKEN") + .errorTrackerService(ERROR_TRACKER) + .create(); + +{ + context.errorTrackerService().orElseThrow().registerErrorTracker(MANUAL_ERROR_TRACKER); +} +``` + +## Tracker Attributes + +Attributes stored on an error tracker are attached to reports submitted through +that tracker. Use them for stable context such as environment or component. + +All enabled metrics are already added to the error context by default. This +includes the standard runtime and platform details FastStats collects, such as +Java version and plugin version. Add tracker attributes only for extra context +that FastStats cannot infer automatically. + +```java +public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); +public static final ErrorTracker MANUAL_ERROR_TRACKER = ErrorTracker.contextUnaware(); + +{ + ERROR_TRACKER.getAttributes() + .put("environment", "production") + .put("component", "global-error-handler"); + + MANUAL_ERROR_TRACKER.getAttributes() + .put("component", "manual-error-handler"); +} +``` + +Attributes on the global/internal tracker are used for every error report, +including reports submitted through additional registered trackers. Additional +trackers can override global attributes with the same key. + +Attribute precedence is: + +1. Global tracker attributes +2. Per-tracker attributes +3. Per-error attributes + +## Per-Error Attributes and Options + +`trackError(...)` returns a tracked error, so you can add context that only +applies to that specific report. Per-error attributes are useful for operation +names, severity, retry state, player or request context, and other values that +change per failure. They override both global and per-tracker attributes with +the same key. + +```java +import dev.faststats.Attributes; + +try { + throw new RuntimeException("Something went wrong!"); +} catch (Exception e) { + MANUAL_ERROR_TRACKER.trackError(e) + .attributes(Attributes.empty() + .put("operation", "manualTracking") + .put("severity", "warning") + .put("retryable", false)) + .handled(false); +} +``` + +Use `.handled(false)` when the error was not recovered from properly and should +be treated as unhandled. Errors tracked manually are handled by default unless +you override that option. diff --git a/src/content/docs/java/feature-flags.mdx b/src/content/docs/java/feature-flags.mdx new file mode 100644 index 0000000..e1221cb --- /dev/null +++ b/src/content/docs/java/feature-flags.mdx @@ -0,0 +1,110 @@ +--- +title: Feature Flags +description: Evaluate FastStats feature flags from Java projects +--- + +import { Aside } from '@astrojs/starlight/components'; + + + +Feature flags are configured on a FastStats context. A context may enable +metrics, error tracking, feature flags, or any combination of those services. + +## Configure a Service + +```java title='ExamplePlugin.java' +import dev.faststats.Attributes; +import dev.faststats.FastStatsContext; +import dev.faststats.FeatureFlagService; +import dev.faststats.bukkit.BukkitContext; + +import java.time.Duration; + +BukkitContext context = new BukkitContext.Factory(plugin, "YOUR_TOKEN") + .featureFlagService(factory -> factory + .attributes(Attributes.empty() + .put("version", "1.2.3") + .put("java_version", System.getProperty("java.version"))) + .ttl(Duration.ofMinutes(10)) + .create()) + .create(); + +FeatureFlagService flags = context.featureFlagService().orElseThrow(); +``` + +Use `.featureFlagService(FeatureFlagService.Factory::create)` when you want the +default settings. + +## Define Flags + +Define flags with a key and a local default value. The default is used before a +server value is available or when evaluation fails. + +```java +var newCommands = flags.define("new_commands", false); +var compression = flags.define("compression", "zstd"); +var maxPlayers = flags.define("max_players", 100); +``` + +Supported value types are boolean, string, and number. + +## Read Values + +```java +newCommands.whenReady().thenAccept(enabled -> { + if (enabled) { + // Register the new commands. + } +}); + +compression.getCached().ifPresent(value -> { + // Use the cached value without starting a request. +}); + +if (compression.isExpired()) { + compression.fetch().thenAccept(value -> { + // React to the refreshed value. + }); +} +``` + +`whenReady()` returns the cached value when it is still valid. Otherwise it +fetches the latest value. `fetch()` always requests a fresh value from the +server. + +## Per-Flag Attributes + +Global attributes configured on the service are sent with every evaluation. You +can add per-flag attributes when a specific flag needs more targeting context. + +```java +var betaUi = flags.define( + "beta_ui", + false, + Attributes.empty().put("world", "lobby") +); +``` + +Per-flag attributes override global attributes with the same key. + +## Opt In and Opt Out + +Flags that allow specific opt-in can be changed from the SDK: + +```java +newCommands.optIn().thenAccept(enabled -> { + if (enabled) { + // The server accepted the opt-in and returned the current value. + } +}); + +newCommands.optOut(); +``` + +Opt-in and opt-out invalidate the local value and fetch the current server value +again. + +For platform concepts and dashboard setup, see [Feature Flags](/platform/feature-flags). diff --git a/src/content/docs/java/index.mdx b/src/content/docs/java/index.mdx new file mode 100644 index 0000000..c58f907 --- /dev/null +++ b/src/content/docs/java/index.mdx @@ -0,0 +1,154 @@ +--- +title: Installation +description: Add FastStats to your Minecraft server project +--- + +import { Tabs, TabItem, Code } from '@astrojs/starlight/components'; +import { latestVersion } from "@/util/repository"; +export const version = await latestVersion("core"); + +Add the FastStats SDK to your project using Maven or Gradle. + + + + + ```xml title='pom.xml' + + faststats-releases + FastStats + https://repo.faststats.dev/releases + + ``` + + + + ```kts title='build.gradle.kts' + maven { + name = "faststatsReleases" + url = uri("https://repo.faststats.dev/releases") + } + ``` + + + + ```groovy title='build.gradle' + maven { + name "faststatsReleases" + url "https://repo.faststats.dev/releases" + } + ``` + + + + ```scala title='build.sbt' + resolvers += + "faststats-releases" + at "https://repo.faststats.dev/releases" + ``` + + + + +## Platform-Specific Artifacts + +Choose the artifact for your platform: + +| Platform | Artifact ID | Java Versions | +| -------------------------- | ----------------------------------------- | ------------- | +| Bukkit/Spigot/Paper/Folia… | [`bukkit`](/java/platform/bukkit) | 17+ | +| BungeeCord | [`bungeecord`](/java/platform/bungeecord) | 17+ | +| Fabric | [`fabric`](/java/platform/fabric) | 25+ | +| Hytale | [`hytale`](/java/platform/hytale) | 25+ | +| Minestom | [`minestom`](/java/platform/minestom) | 25+ | +| NeoForge | [`neoforge`](/java/platform/neoforge) | 25+ | +| Nukkit | [`nukkit`](/java/platform/nukkit) | 17+ | +| Sponge | [`sponge`](/java/platform/sponge) | 17+ | +| Velocity | [`velocity`](/java/platform/velocity) | 21+ | + + + + + + dev.faststats.metrics + bukkit + ${version} +`} /> + + + + + + + + + + + + + + + + +## Shading + +To include FastStats directly in your plugin JAR, you can use the Maven Shade or Gradle Shadow Plugin. + + + + + + + ```xml title='pom.xml' + + + + org.apache.maven.plugins + maven-shade-plugin + 3.5.0 + + + package + + shade + + + + + dev.faststats + your.plugin.libs.faststats + + + + + + + + + ``` + + + + ```kts title='build.gradle.kts' + plugins { + id("com.gradleup.shadow") version "9.4.1" + } + + tasks.shadowJar { + relocate("dev.faststats", "your.plugin.libs.faststats") // optionally relocate the package + } + ``` + + + + ```groovy title='build.gradle' + plugins { + id 'com.gradleup.shadow' version '9.4.1' + } + + tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { + relocate('dev.faststats', 'your.plugin.libs.faststats') // optionally relocate the package + } + ``` + + + \ No newline at end of file diff --git a/src/content/docs/java/migration.mdx b/src/content/docs/java/migration.mdx new file mode 100644 index 0000000..2be673f --- /dev/null +++ b/src/content/docs/java/migration.mdx @@ -0,0 +1,236 @@ +--- +title: Migration Guide +description: Upgrade FastStats Java SDK from 0.23.0 to 0.24.0 +--- + +This guide covers the breaking Java SDK changes between `0.23.0` and `0.24.0`. + +Version `0.24.0` moves FastStats from standalone metrics instances to a shared +platform context. The context owns the token, config, metrics, error tracking, +feature flags, and lifecycle. + +## Imports + +All core classes moved out of `dev.faststats.core`. + +```java +// 0.23.0 +import dev.faststats.core.ErrorTracker; +import dev.faststats.core.Metrics; +import dev.faststats.core.data.Metric; + +// 0.24.0 +import dev.faststats.ErrorTracker; +import dev.faststats.Metrics; +import dev.faststats.data.Metric; +``` + +## Metrics Setup + +Platform metrics factories such as `BukkitMetrics.factory()` were replaced by +platform context factories such as `BukkitContext.Factory`. + +**Old Code** + +```java +// 0.23.0 +private final BukkitMetrics metrics = BukkitMetrics.factory() + .addMetric(Metric.number("arena_matches", arenaMatches::get)) + .onFlush(() -> arenaMatches.set(0)) + .token("YOUR_TOKEN") + .create(this); + +@Override +public void onEnable() { + metrics.ready(); +} + +@Override +public void onDisable() { + metrics.shutdown(); +} +``` + +**Updated Code** + +```java +// 0.24.0 +private final BukkitContext context = new BukkitContext.Factory(this, "YOUR_TOKEN") + .metrics(factory -> factory + .addMetric(Metric.number("arena_matches", arenaMatches::get)) + .onFlush(() -> arenaMatches.set(0)) + .create()) + .create(); + +@Override +public void onEnable() { + context.ready(); +} + +@Override +public void onDisable() { + context.shutdown(); +} +``` + +Use `.metrics(Metrics.Factory::create)` if you only need the built-in metrics +without custom metrics. + +## Token, URL, and Debug + +The token is now passed to the context factory constructor or builder. Per-metrics +`.token(...)`, `.url(...)`, and `.debug(...)` calls were removed. + +```java +// 0.23.0 +BukkitMetrics.factory() + .url(URI.create("https://metrics.example.com/v1/collect")) + .debug(true) + .token("YOUR_TOKEN") + .create(this); +``` + +```java +// 0.24.0 +new BukkitContext.Factory(this, "YOUR_TOKEN") + .metrics(Metrics.Factory::create) + .create(); +``` + +Call `context.ready()` from your platform startup hook before metrics are used. +For runtime configuration, use the FastStats config and system properties. For +example, use `-Dfaststats.debug=true` to enable debug logging. + +## Error Tracking + +Error trackers are now attached to the context with `.errorTrackerService(...)`. +They are no longer configured on the metrics factory. + +```java +// 0.23.0 +public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); + +private final BukkitMetrics metrics = BukkitMetrics.factory() + .errorTracker(ERROR_TRACKER) + .token("YOUR_TOKEN") + .create(this); +``` + +```java +// 0.24.0 +public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); + +private final BukkitContext context = new BukkitContext.Factory(this, "YOUR_TOKEN") + .errorTrackerService(ERROR_TRACKER) + .metrics(Metrics.Factory::create) + .create(); + +public void onEnable() { + context.ready(); +} +``` + +Context-unaware trackers still exist, but additional trackers must be registered +with the context error tracker service. + +```java +public static final ErrorTracker MANUAL_TRACKER = ErrorTracker.contextUnaware(); + +{ + context.errorTrackerService().orElseThrow().registerErrorTracker(MANUAL_TRACKER); +} +``` + +`trackError(...)` now returns a `TrackedError`, so callers may attach additional +data to the tracked error after creating it. + +```java +MANUAL_TRACKER.trackError(error) + .handled(false) + .attributes(Attributes.empty() + .put("version", "1.0.0")); +``` + +## Platform Factories + +Use the new platform context factory for your platform: + +| Platform | 0.23.0 | 0.24.0 | +| ---------- | ------------------------------------------ | --------------------------------------------------- | +| Bukkit | `BukkitMetrics.factory().create(plugin)` | `new BukkitContext.Factory(plugin, token).create()` | +| BungeeCord | `BungeeMetrics.factory().create(plugin)` | `new BungeeContext.Factory(plugin, token).create()` | +| Fabric | `FabricMetrics.factory().create(modId)` | `new FabricContext.Factory(modId, token).create()` | +| Hytale | `HytaleMetrics.factory().create(plugin)` | `new HytaleContext.Factory(plugin, token).create()` | +| Minestom | `MinestomMetrics.factory().create(server)` | `new MinestomContext.Factory(token).create()` | +| Nukkit | `NukkitMetrics.factory().create(plugin)` | `new NukkitContext.Factory(plugin, token).create()` | +| Sponge | injected `SpongeMetrics.Factory` | injected `SpongeContext.Builder` | +| Velocity | injected `VelocityMetrics.Factory` | injected `VelocityContext.Builder` | + +Sponge and Velocity builders receive the platform objects from dependency +injection, so configure the token on the injected builder: + +```java +// Sponge +private @Inject SpongeContext.Builder contextBuilder; + +@Listener +public void onServerStart(final StartedEngineEvent event) { + this.context = contextBuilder + .token("YOUR_TOKEN") + .metrics(Metrics.Factory::create) + .create(); + context.ready(); +} +``` + +```java +// Velocity +@Inject +public ExamplePlugin(final VelocityContext.Builder contextBuilder) { + this.context = contextBuilder + .token("YOUR_TOKEN") + .metrics(Metrics.Factory::create) + .create(); +} + +@Subscribe +public void onProxyInitialize(final ProxyInitializeEvent event) { + context.ready(); +} +``` + +## Configuration Access + +Metrics no longer expose token and config directly. Read them from the context: + +```java +// 0.23.0 +metrics.getToken(); +metrics.getConfig(); + +// 0.24.0 +context.getToken(); +context.getConfig(); +``` + +The config API also separates global enablement from metrics submission: + +```java +context.getConfig().enabled(); +context.getConfig().submitMetrics(); +context.getConfig().errorTracking(); +context.getConfig().additionalMetrics(); +context.getConfig().debug(); +``` + +## Checklist + +- Replace `dev.faststats.core.*` imports with `dev.faststats.*`. +- Replace `dev.faststats.core.data.*` imports with `dev.faststats.data.*`. +- Replace platform **metrics** factories with platform **context** factories. +- Move `.token(...)` to the context factory constructor or injected builder. +- Move `.errorTracker(...)` to `.errorTrackerService(...)`. +- Move custom metrics into `.metrics(factory -> factory ... .create())`. +- Replace `metrics.ready()` and `metrics.shutdown()` with `context.ready()` and `context.shutdown()`. +- Call `context.ready()` when using metrics or error tracking. +- Use context accessors for token, config, metrics, error tracker service, and feature flag service. diff --git a/src/content/docs/java/obfuscation-mappings.mdx b/src/content/docs/java/obfuscation-mappings.mdx new file mode 100644 index 0000000..05c8c79 --- /dev/null +++ b/src/content/docs/java/obfuscation-mappings.mdx @@ -0,0 +1,150 @@ +--- +title: Obfuscation Mappings +description: Upload ProGuard/R8 obfuscation mapping files for stack traces deobfuscation. +--- + +import { Tabs, TabItem, Aside } from '@astrojs/starlight/components'; + +FastStats resolves obfuscated Java stack traces using uploaded ProGuard/R8 mapping files. +The recommended workflow is the `dev.faststats.proguard-mappings-upload` Gradle plugin. + +## Installation + + + + ```kotlin title='build.gradle.kts' + plugins { + id("dev.faststats.proguard-mappings-upload") version "0.1.0" + } + ``` + + + + ```groovy title='build.gradle' + plugins { + id 'dev.faststats.proguard-mappings-upload' version '0.1.0' + } + ``` + + + + +## Configuration + +### Android Projects + +The plugin automatically detects Android R8/ProGuard mapping file outputs when the Android Gradle Plugin is present. +No additional configuration is needed beyond the auth token: + +```kotlin +mappingsUpload { + authToken.set("your-auth-token") +} +``` + +### Custom ProGuard Task + +If you're using a standalone ProGuard task, point the plugin to your mapping file and task: + +```kotlin +mappingsUpload { + authToken.set("your-auth-token") + proguardTask.set(tasks.getByName("proguard")) + mappingFiles.from(layout.buildDirectory.file("proguard/mapping.txt")) +} +``` + +Setting `proguardTask` ensures the upload task runs after ProGuard finishes. `mappingFiles` must match the location +configured in your `printmapping` setting. + + + +## Upload Authentication + +Generate an API key in your FastStats project settings. The plugin accepts it via the `authToken` option +or the `FASTSTATS_AUTH_TOKEN` environment variable. + + + +## All Options + +| Option | Description | +| -------------- | ------------------------------------------------------------------------------------ | +| `authToken` | Bearer token for upload authentication. Falls back to `FASTSTATS_AUTH_TOKEN` env var | +| `endpoint` | Upload API URL (default: `https://sourcemaps.faststats.dev/api/sourcemaps`) | +| `buildId` | Explicit build ID (default: `project.version`) | +| `proguardTask` | Task that produces the mapping file (adds a `dependsOn`) | +| `mappingFiles` | Mapping files to upload | + +## Usage + +Run the upload task directly: + +```bash +./gradlew uploadProguardMappings +``` + +Or chain it after your obfuscation task: + +```bash +./gradlew proguard uploadProguardMappings +``` + +## CI Configuration + +### GitHub Actions + +```yaml title='github-actions.yml' +name: Build & Upload Mappings + +on: + push: + branches: [main] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 17 + + - name: Build & Upload + run: ./gradlew proguard uploadProguardMappings + env: + FASTSTATS_AUTH_TOKEN: ${{ secrets.FASTSTATS_AUTH_TOKEN }} +``` + +### GitLab CI + +```yaml title='gitlab-ci.yml' +build: + stage: build + script: + - ./gradlew proguard uploadProguardMappings + variables: + FASTSTATS_AUTH_TOKEN: $FASTSTATS_AUTH_TOKEN +``` + +## How It Works + +1. The plugin collects mapping files added via `mappingFiles.from(...)`, or auto-detected Android build outputs. +2. If `proguardTask` is set, the upload task automatically depends on it. +3. `project.version` is used as the `buildId` by default. +4. Each mapping file is split by class sections and uploaded in batches of up to 50 MB, ensuring no class mapping is split across batches. + +## Requirements + +- Gradle 7.0+ +- JDK 11+ diff --git a/src/content/docs/java/platform/bukkit.mdx b/src/content/docs/java/platform/bukkit.mdx new file mode 100644 index 0000000..83f8429 --- /dev/null +++ b/src/content/docs/java/platform/bukkit.mdx @@ -0,0 +1,38 @@ +--- +title: Bukkit +description: Integrate FastStats with any Bukkit-based plugins +--- + +Use `dev.faststats.bukkit.BukkitContext` for Bukkit-based server plugins. Requires Java 17+. + +**Artifact:** `dev.faststats.metrics:bukkit` + +```java +import dev.faststats.ErrorTracker; +import dev.faststats.Metrics; +import dev.faststats.bukkit.BukkitContext; +import org.bukkit.plugin.java.JavaPlugin; + +public final class ExamplePlugin extends JavaPlugin { + public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); + + private final BukkitContext context = new BukkitContext.Factory(this, "YOUR_TOKEN") + .errorTrackerService(ERROR_TRACKER) + .metrics(Metrics.Factory::create) + .create(); + + @Override + public void onEnable() { + context.ready(); + } + + @Override + public void onDisable() { + context.shutdown(); + } +} +``` + +Call `context.ready()` in `onEnable()` before using metrics or error tracking. On Paper-based servers, this also registers additional exception handlers. See [Error Tracking](/java/error-tracking) for configuring error reporting. + +[View full example on GitHub](https://github.com/faststats-dev/faststats-java/blob/main/bukkit/example-plugin/src/main/java/com/example/ExamplePlugin.java) diff --git a/src/content/docs/java/platform/bungeecord.mdx b/src/content/docs/java/platform/bungeecord.mdx new file mode 100644 index 0000000..3abe7ad --- /dev/null +++ b/src/content/docs/java/platform/bungeecord.mdx @@ -0,0 +1,38 @@ +--- +title: BungeeCord +description: Integrate FastStats with BungeeCord proxy plugins +--- + +Use `dev.faststats.bungee.BungeeContext` for BungeeCord proxy plugins. Requires Java 17+. + +**Artifact:** `dev.faststats.metrics:bungeecord` + +```java +import dev.faststats.ErrorTracker; +import dev.faststats.Metrics; +import dev.faststats.bungee.BungeeContext; +import net.md_5.bungee.api.plugin.Plugin; + +public class ExamplePlugin extends Plugin { + public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); + + private final BungeeContext context = new BungeeContext.Factory(this, "YOUR_TOKEN") + .errorTrackerService(ERROR_TRACKER) + .metrics(Metrics.Factory::create) + .create(); + + @Override + public void onEnable() { + context.ready(); + } + + @Override + public void onDisable() { + context.shutdown(); + } +} +``` + +See [Error Tracking](/java/error-tracking) for configuring error reporting. + +[View full example on GitHub](https://github.com/faststats-dev/faststats-java/blob/main/bungeecord/example-plugin/src/main/java/com/example/ExamplePlugin.java) diff --git a/src/content/docs/java/platform/fabric.mdx b/src/content/docs/java/platform/fabric.mdx new file mode 100644 index 0000000..1ec7ff8 --- /dev/null +++ b/src/content/docs/java/platform/fabric.mdx @@ -0,0 +1,42 @@ +--- +title: Fabric +description: Integrate FastStats with Fabric mods +--- + +import { Aside } from '@astrojs/starlight/components'; + +Use `dev.faststats.fabric.FabricContext` for Fabric mods. Requires Java 25+. + + + +**Artifact:** `dev.faststats.metrics:fabric` + +```java +import dev.faststats.ErrorTracker; +import dev.faststats.Metrics; +import dev.faststats.fabric.FabricContext; +import net.fabricmc.api.ModInitializer; + +public class ExampleMod implements ModInitializer { + public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); + + private final FabricContext context = new FabricContext.Factory("example-mod", "YOUR_TOKEN") + .errorTrackerService(ERROR_TRACKER) + .metrics(Metrics.Factory::create) + .create(); + + @Override + public void onInitialize() { + // your actual logic + } +} +``` + +Pass your mod ID, as defined in `fabric.mod.json`, to `FabricContext.Factory`. + +See [Error Tracking](/java/error-tracking) for configuring error reporting. + +[View full example on GitHub](https://github.com/faststats-dev/faststats-java/blob/main/fabric/example-mod/src/main/java/com/example/ExampleMod.java) diff --git a/src/content/docs/java/platform/hytale.mdx b/src/content/docs/java/platform/hytale.mdx new file mode 100644 index 0000000..d0d9ddd --- /dev/null +++ b/src/content/docs/java/platform/hytale.mdx @@ -0,0 +1,44 @@ +--- +title: Hytale +description: Integrate FastStats with Hytale server plugins +--- + +Use `dev.faststats.hytale.HytaleContext` for Hytale server plugins. Requires Java 25+. + +**Artifact:** `dev.faststats.metrics:hytale` + +```java +import com.hypixel.hytale.server.core.plugin.JavaPlugin; +import com.hypixel.hytale.server.core.plugin.JavaPluginInit; +import dev.faststats.ErrorTracker; +import dev.faststats.Metrics; +import dev.faststats.hytale.HytaleContext; + +public class ExamplePlugin extends JavaPlugin { + public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); + + private final HytaleContext context = new HytaleContext.Factory(this, "YOUR_TOKEN") + .errorTrackerService(ERROR_TRACKER) + .metrics(Metrics.Factory::create) + .create(); + + public ExamplePlugin(final JavaPluginInit init) { + super(init); + context.ready(); + } + + @Override + protected void setup() { + context.ready(); + } + + @Override + protected void shutdown() { + context.shutdown(); + } +} +``` + +See [Error Tracking](/java/error-tracking) for configuring error reporting. + +[View full example on GitHub](https://github.com/faststats-dev/faststats-java/blob/main/hytale/example-plugin/src/main/java/com/example/ExamplePlugin.java) diff --git a/src/content/docs/java/platform/minestom.mdx b/src/content/docs/java/platform/minestom.mdx new file mode 100644 index 0000000..1bd8997 --- /dev/null +++ b/src/content/docs/java/platform/minestom.mdx @@ -0,0 +1,33 @@ +--- +title: Minestom +description: Integrate FastStats with Minestom servers +--- + +Use `dev.faststats.minestom.MinestomContext` for Minestom servers. Requires Java 25+. + +**Artifact:** `dev.faststats.metrics:minestom` + +```java +import dev.faststats.ErrorTracker; +import dev.faststats.Metrics; +import dev.faststats.minestom.MinestomContext; +import net.minestom.server.MinecraftServer; + +public final class ExampleServer { + public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); + + public static void main(String[] args) { + MinecraftServer server = MinecraftServer.init(); + + MinestomContext context = new MinestomContext.Factory("YOUR_TOKEN") + .errorTrackerService(ERROR_TRACKER) + .metrics(Metrics.Factory::create) + .create(); + + server.start("0.0.0.0", 25565); + context.ready(); + } +} +``` + +Call `context.ready()` after `MinecraftServer.init()` before using metrics or error tracking. This also registers exception handlers. See [Error Tracking](/java/error-tracking) for configuring error reporting. diff --git a/src/content/docs/java/platform/neoforge.mdx b/src/content/docs/java/platform/neoforge.mdx new file mode 100644 index 0000000..67719d6 --- /dev/null +++ b/src/content/docs/java/platform/neoforge.mdx @@ -0,0 +1,38 @@ +--- +title: NeoForge +description: Integrate FastStats with NeoForge mods +--- + +import { Aside } from '@astrojs/starlight/components'; + +Use `dev.faststats.neoforge.NeoForgeContext` for NeoForge mods. Requires Java 25+. + + + +**Artifact:** `dev.faststats.metrics:neoforge` + +```java +import dev.faststats.ErrorTracker; +import dev.faststats.Metrics; +import dev.faststats.neoforge.NeoForgeContext; +import net.neoforged.fml.common.Mod; + +@Mod("example_mod") +public class ExampleMod { + public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); + + private final NeoForgeContext context = new NeoForgeContext.Factory("example_mod", "YOUR_TOKEN") + .errorTrackerService(ERROR_TRACKER) + .metrics(Metrics.Factory::create) + .create(); +} +``` + +Pass your mod ID, as defined in `neoforge.mods.toml`, to `NeoForgeContext.Factory`. + +See [Error Tracking](/java/error-tracking) for configuring error reporting. + +[View full example on GitHub](https://github.com/faststats-dev/faststats-java/blob/main/neoforge/example-mod/src/main/java/com/example/ExampleMod.java) diff --git a/src/content/docs/java/platform/nukkit.mdx b/src/content/docs/java/platform/nukkit.mdx new file mode 100644 index 0000000..3772481 --- /dev/null +++ b/src/content/docs/java/platform/nukkit.mdx @@ -0,0 +1,41 @@ +--- +title: Nukkit +description: Integrate FastStats with Nukkit plugins +--- + +Use `dev.faststats.nukkit.NukkitContext` for Nukkit plugins. Requires Java 17+. + +**Artifact:** `dev.faststats.metrics:nukkit` + +```java +import cn.nukkit.plugin.PluginBase; +import dev.faststats.ErrorTracker; +import dev.faststats.Metrics; +import dev.faststats.nukkit.NukkitContext; + +public final class ExamplePlugin extends PluginBase { + public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); + + private NukkitContext context; + + @Override + public void onLoad() { + context = new NukkitContext.Factory(this, "YOUR_TOKEN") + .errorTrackerService(ERROR_TRACKER) + .metrics(Metrics.Factory::create) + .create(); + } + + @Override + public void onEnable() { + context.ready(); + } + + @Override + public void onDisable() { + context.shutdown(); + } +} +``` + +See [Error Tracking](/java/error-tracking) for configuring error reporting. diff --git a/src/content/docs/java/platform/sponge.mdx b/src/content/docs/java/platform/sponge.mdx new file mode 100644 index 0000000..d105e48 --- /dev/null +++ b/src/content/docs/java/platform/sponge.mdx @@ -0,0 +1,48 @@ +--- +title: Sponge +description: Integrate FastStats with Sponge plugins +--- + +Use `dev.faststats.sponge.SpongeContext` for Sponge plugins. Requires Java 17+. + +**Artifact:** `dev.faststats.metrics:sponge` + +```java +import com.google.inject.Inject; +import dev.faststats.ErrorTracker; +import dev.faststats.Metrics; +import dev.faststats.sponge.SpongeContext; +import org.jspecify.annotations.Nullable; +import org.spongepowered.api.Server; +import org.spongepowered.api.event.Listener; +import org.spongepowered.api.event.lifecycle.StartedEngineEvent; +import org.spongepowered.api.event.lifecycle.StoppingEngineEvent; +import org.spongepowered.plugin.builtin.jvm.Plugin; + +@Plugin("example") +public class ExamplePlugin { + public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); + private @Inject SpongeContext.Builder contextBuilder; + + private @Nullable SpongeContext context = null; + + @Listener + public void onServerStart(final StartedEngineEvent event) { + this.context = contextBuilder + .token("YOUR_TOKEN") + .errorTrackerService(ERROR_TRACKER) + .metrics(Metrics.Factory::create) + .create(); + context.ready(); + } + + @Listener + public void onServerStop(final StoppingEngineEvent event) { + if (context != null) context.shutdown(); + } +} +``` + +See [Error Tracking](/java/error-tracking) for configuring error reporting. + +[View full example on GitHub](https://github.com/faststats-dev/faststats-java/blob/main/sponge/example-plugin/src/main/java/com/example/ExamplePlugin.java) diff --git a/src/content/docs/java/platform/velocity.mdx b/src/content/docs/java/platform/velocity.mdx new file mode 100644 index 0000000..3d03cb7 --- /dev/null +++ b/src/content/docs/java/platform/velocity.mdx @@ -0,0 +1,49 @@ +--- +title: Velocity +description: Integrate FastStats with Velocity proxy plugins +--- + +Use `dev.faststats.velocity.VelocityContext` for Velocity proxy plugins. Requires Java 21+. + +**Artifact:** `dev.faststats.metrics:velocity` + +```java +import com.google.inject.Inject; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; +import com.velocitypowered.api.event.proxy.ProxyShutdownEvent; +import com.velocitypowered.api.plugin.Plugin; +import dev.faststats.ErrorTracker; +import dev.faststats.Metrics; +import dev.faststats.velocity.VelocityContext; + +@Plugin(id = "example", name = "Example Plugin", version = "1.0.0") +public class ExamplePlugin { + public static final ErrorTracker ERROR_TRACKER = ErrorTracker.contextAware(); + + private final VelocityContext context; + + @Inject + public ExamplePlugin(final VelocityContext.Builder contextBuilder) { + this.context = contextBuilder + .token("YOUR_TOKEN") + .errorTrackerService(ERROR_TRACKER) + .metrics(Metrics.Factory::create) + .create(); + } + + @Subscribe + public void onProxyInitialize(final ProxyInitializeEvent event) { + context.ready(); + } + + @Subscribe + public void onProxyStop(final ProxyShutdownEvent event) { + context.shutdown(); + } +} +``` + +See [Error Tracking](/java/error-tracking) for configuring error reporting. + +[View full example on GitHub](https://github.com/faststats-dev/faststats-java/blob/main/velocity/example-plugin/src/main/java/com/example/ExamplePlugin.java) diff --git a/src/content/docs/java/system-properties.mdx b/src/content/docs/java/system-properties.mdx new file mode 100644 index 0000000..25856b2 --- /dev/null +++ b/src/content/docs/java/system-properties.mdx @@ -0,0 +1,53 @@ +--- +title: System Properties +description: Configure FastStats using system properties +--- + +System properties provide runtime control over FastStats behavior. +These flags only affect the current running server session/instance and are not persisted. + +## `faststats.debug` + +Enable debug logging for all FastStats projects. + +**Usage:** + +```bash +java -Dfaststats.debug=true -jar server.jar +``` + +**Values:** + +- `true` - Enable debug logging +- `false` - Disable debug logging + +## `faststats.enabled` + +Enable or disable FastStats data transmission globally. + +**Usage:** + +```bash +java -Dfaststats.enabled=false -jar server.jar +``` + +**Values:** + +- `true` - Enable data transmission +- `false` - Disable data transmission + +## `faststats.initial-delay` + +Configure the initial delay before FastStats starts collecting metrics. + +_This flag is meant to be used during development to delay or speed up the start of metric collection._ + +**Usage:** + +```bash +java -Dfaststats.initial-delay=5 -jar server.jar +``` + +**Values:** + +- Time in seconds (default: `30`) From 58bb0cfabb8ab04fb57bfc38bdb432d85a2a36de Mon Sep 17 00:00:00 2001 From: Adam Matthiesen Date: Sun, 5 Jul 2026 21:00:27 -0700 Subject: [PATCH 16/40] feat: add ReadMore component to enhance documentation readability across Java platform guides --- astro.config.ts | 8 ++++---- src/content/docs/java/configuration.mdx | 6 +++++- src/content/docs/java/feature-flags.mdx | 5 ++++- src/content/docs/java/platform/bukkit.mdx | 12 +++++++++--- src/content/docs/java/platform/bungeecord.mdx | 12 +++++++++--- src/content/docs/java/platform/fabric.mdx | 11 ++++++++--- src/content/docs/java/platform/hytale.mdx | 8 +++++++- src/content/docs/java/platform/minestom.mdx | 6 +++++- src/content/docs/java/platform/neoforge.mdx | 7 ++++++- src/content/docs/java/platform/nukkit.mdx | 6 +++++- src/content/docs/java/platform/sponge.mdx | 8 +++++++- src/content/docs/java/platform/velocity.mdx | 8 +++++++- src/content/docs/platform/error-tracking.mdx | 16 +++++++++------- src/content/docs/platform/guide/embed.mdx | 3 +-- 14 files changed, 86 insertions(+), 30 deletions(-) diff --git a/astro.config.ts b/astro.config.ts index e206d53..ec7b92e 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -13,6 +13,10 @@ import tailwindcss from '@tailwindcss/vite'; export default defineConfig({ site: "https://docs.faststats.dev", + vite: { + plugins: [tailwindcss()], + }, + integrations: [ react(), devServerFileWatcher([ @@ -193,8 +197,4 @@ export default defineConfig({ ] }) ], - - vite: { - plugins: [tailwindcss()], - }, }); \ No newline at end of file diff --git a/src/content/docs/java/configuration.mdx b/src/content/docs/java/configuration.mdx index 77ea017..c54d6e5 100644 --- a/src/content/docs/java/configuration.mdx +++ b/src/content/docs/java/configuration.mdx @@ -3,6 +3,8 @@ title: Configuration description: Advanced configuration options for FastStats Java SDK --- +import ReadMore from '@/components/ReadMore.astro'; + Configure FastStats by creating a platform context and attaching the services your project uses. @@ -67,7 +69,9 @@ Metrics submission and error tracking start after `context.ready()` is called. Call `context.ready()` from the platform startup hook, and call `context.shutdown()` during shutdown. -For error tracking configuration, see [Error Tracking](/java/error-tracking). For platform-specific setup, see the platform pages in the sidebar. + + For error tracking configuration, see [Error Tracking](/java/error-tracking). For platform-specific setup, see the platform pages in the sidebar. + ## Best Practices diff --git a/src/content/docs/java/feature-flags.mdx b/src/content/docs/java/feature-flags.mdx index e1221cb..6be1f90 100644 --- a/src/content/docs/java/feature-flags.mdx +++ b/src/content/docs/java/feature-flags.mdx @@ -3,6 +3,7 @@ title: Feature Flags description: Evaluate FastStats feature flags from Java projects --- +import ReadMore from '@/components/ReadMore.astro'; import { Aside } from '@astrojs/starlight/components'; -The OpenAPI spec is available at [api.faststats.dev/openapi.json](https://api.faststats.dev/openapi.json). + + The OpenAPI spec is available at [api.faststats.dev/openapi.json](https://api.faststats.dev/openapi.json). + From b8eb9d64b950ca720a348e95b2dd4bc7b28c115d Mon Sep 17 00:00:00 2001 From: Adam Matthiesen Date: Sun, 5 Jul 2026 21:06:07 -0700 Subject: [PATCH 18/40] chore: remove unused LinkCard component --- src/components/LinkCard.astro | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/components/LinkCard.astro diff --git a/src/components/LinkCard.astro b/src/components/LinkCard.astro deleted file mode 100644 index e69de29..0000000 From 97d65c94a29c2f19c61716e28d3899b861b7dae8 Mon Sep 17 00:00:00 2001 From: Adam Matthiesen Date: Sun, 5 Jul 2026 21:08:14 -0700 Subject: [PATCH 19/40] chore: update .prototools with additional comments and ensure correct versions of node and pnpm --- .prototools | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.prototools b/.prototools index a574098..1017178 100644 --- a/.prototools +++ b/.prototools @@ -1 +1,5 @@ +## Adam's favorite tool... please don't mind this (Ensure's the current shell is using the right versions of node, and pnpm) +## More info: https://moonrepo.dev/proto + node = "22.20.0" +pnpm = "11.10.0" From aefaee90fa2806b18c0b509047c94be332473002 Mon Sep 17 00:00:00 2001 From: Adam Matthiesen Date: Sun, 5 Jul 2026 21:09:06 -0700 Subject: [PATCH 20/40] chore: update package.json to specify package manager and node engine requirements --- package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package.json b/package.json index a073cb8..a3bc0eb 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,10 @@ "name": "docs", "type": "module", "version": "0.0.1", + "packageManager": "pnpm@11.10.0", + "engines": { + "node": ">=22.20.0" + }, "scripts": { "dev": "astro dev", "start": "astro dev", From 0612541dce3520e9f58b4f3fe968f381c249ecc3 Mon Sep 17 00:00:00 2001 From: Adam Matthiesen Date: Sun, 5 Jul 2026 21:19:03 -0700 Subject: [PATCH 21/40] feat: refactor starlight configuration and add OpenAPI integration --- astro.config.ts | 179 +++---------------------------------------- openapi.config.ts | 29 +++++++ starlight.config.ts | 54 +++++++++++++ starlight.sidebar.ts | 98 +++++++++++++++++++++++ 4 files changed, 191 insertions(+), 169 deletions(-) create mode 100644 openapi.config.ts create mode 100644 starlight.config.ts create mode 100644 starlight.sidebar.ts diff --git a/astro.config.ts b/astro.config.ts index ec7b92e..efdd941 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -4,10 +4,12 @@ import starlight from '@astrojs/starlight'; import starlightSidebarTopicsPlugin from 'starlight-sidebar-topics'; import { devServerFileWatcher } from './src/integrations/dev-file-watcher'; import starlightCopyButton from 'starlight-copy-button'; -import starlightOpenAPI, { openAPISidebarGroups } from 'starlight-openapi'; +import starlightOpenAPI from 'starlight-openapi'; import react from '@astrojs/react'; - import tailwindcss from '@tailwindcss/vite'; +import { sidebarConfig, sidebarTopicsExtras } from './starlight.sidebar'; +import { baseStarlightOptions } from './starlight.config'; +import { openAPIConfig } from './openapi.config'; // https://astro.build/config export default defineConfig({ @@ -21,179 +23,18 @@ export default defineConfig({ react(), devServerFileWatcher([ './src/integrations/*.ts', + './openapi.config.ts', + './starlight.config.ts', + './starlight.sidebar.ts', ]), starlight({ - title: 'FastStats Docs', - description: 'Error tracking, session replays, web vitals, funnels, and retention in one platform β€” stop stitching five tools together. Free during closed beta.', - tagline: 'Product Analytics That Makes Sense', - - favicon: '/icon-dark.svg', - logo: { - dark: './src/assets/icon-dark.svg', - light: './src/assets/icon-light.svg', - }, - - disable404Route: true, - - head: [ - { - tag: 'link', - attrs: { - rel: 'icon', - href: '/icon-light.svg', - media: '(prefers-color-scheme: light)', - }, - }, - { - tag: 'link', - attrs: { - rel: 'icon', - href: '/icon-dark.svg', - media: '(prefers-color-scheme: dark)', - }, - } - ], - - social: [ - { icon: 'github', label: 'GitHub', href: 'https://github.com/faststats-dev' }, - { icon: 'discord', label: 'Discord', href: 'https://discord.com/invite/SKnDU5VwMS' }, - ], - - components: { - Sidebar: './src/components/starlight/Sidebar.astro', - ContentPanel: './src/components/starlight/ContentPanel.astro', - }, - - routeMiddleware: './src/routeData.ts', - - customCss: [ - './src/styles/global.css', - ], - - editLink: { - baseUrl: 'https://github.com/faststats-dev/docs/tree/main', - }, - + ...baseStarlightOptions, plugins: [ starlightCopyButton({ label: "Copy Markdown", }), - starlightOpenAPI([ - { - base: "api", - sidebar: { - label: "API Reference", - operations: { - badges: true, - labels: 'summary', - } - }, - snippets: { - operation: { - clients: { - shell: ['curl'], - javascript: ['fetch'], - go: ['nethttp'], - java: ['nethttp'], - csharp: ['httpclient'] - }, - } - }, - schema: "https://api.faststats.dev/openapi.json", - } - ]), - starlightSidebarTopicsPlugin([ - { - label: 'Platform', - id: 'platform', - link: '/platform/', - icon: 'puzzle', - items: [ - { - label: 'Overview', - items: [ - 'platform', - 'platform/hotkeys', - 'platform/error-tracking', - 'platform/retention' - ] - }, - { - label: 'Guides', - items: [{ autogenerate: { directory: 'platform/guide' } }], - }, - { - label: 'Chart Editor', - items: [{ autogenerate: { directory: 'platform/chart-editor' } }], - } - ], - }, - { - label: 'Java', - id: 'java', - link: '/java/', - icon: 'seti:java', - items: [ - { - label: 'Configuration', - items: [ - 'java', - 'java/migration', - 'java/configuration', - 'java/custom-metrics', - 'java/error-tracking', - 'java/feature-flags', - ] - }, - { - label: 'Platforms', - items: [{ autogenerate: { directory: 'java/platform' } }], - }, - { - label: 'Advanced', - items: [ - 'java/obfuscation-mappings', - 'java/system-properties', - ] - } - ], - }, - { - label: 'Rest API', - id: 'api', - link: '/api/', - icon: 'open-book', - items: openAPISidebarGroups, - }, - { - label: 'Web Analytics', - id: 'web-analytics', - link: '/web-analytics/', - icon: 'analytics', - badge: { - text: "Coming Soon", - variant: 'tip' - }, - items: [ - { - label: 'Getting Started', - items: [] - }, - { - label: 'Usage', - items: [] - }, - { - label: 'Features', - items: [] - } - ] - } - ], { - topics: { - api: ['/api/**/*'] - } - }) + starlightOpenAPI(openAPIConfig), + starlightSidebarTopicsPlugin(sidebarConfig, sidebarTopicsExtras) ] }) ], diff --git a/openapi.config.ts b/openapi.config.ts new file mode 100644 index 0000000..bdc3578 --- /dev/null +++ b/openapi.config.ts @@ -0,0 +1,29 @@ + +import integration from 'starlight-openapi'; + +export type StarlightOpenAPIUserConfig = Parameters[0]; + +export const openAPIConfig: StarlightOpenAPIUserConfig = [ + { + base: "api", + sidebar: { + label: "API Reference", + operations: { + badges: true, + labels: 'summary', + } + }, + snippets: { + operation: { + clients: { + shell: ['curl'], + javascript: ['fetch'], + go: ['nethttp'], + java: ['nethttp'], + csharp: ['httpclient'] + }, + } + }, + schema: "https://api.faststats.dev/openapi.json", + } +]; \ No newline at end of file diff --git a/starlight.config.ts b/starlight.config.ts new file mode 100644 index 0000000..91f49a9 --- /dev/null +++ b/starlight.config.ts @@ -0,0 +1,54 @@ +import type { StarlightUserConfig } from '@astrojs/starlight/types'; + +export const baseStarlightOptions: StarlightUserConfig = { + title: 'FastStats Docs', + description: 'Error tracking, session replays, web vitals, funnels, and retention in one platform β€” stop stitching five tools together. Free during closed beta.', + tagline: 'Product Analytics That Makes Sense', + + favicon: '/icon-dark.svg', + logo: { + dark: './src/assets/icon-dark.svg', + light: './src/assets/icon-light.svg', + }, + + disable404Route: true, + + head: [ + { + tag: 'link', + attrs: { + rel: 'icon', + href: '/icon-light.svg', + media: '(prefers-color-scheme: light)', + }, + }, + { + tag: 'link', + attrs: { + rel: 'icon', + href: '/icon-dark.svg', + media: '(prefers-color-scheme: dark)', + }, + } + ], + + social: [ + { icon: 'github', label: 'GitHub', href: 'https://github.com/faststats-dev' }, + { icon: 'discord', label: 'Discord', href: 'https://discord.com/invite/SKnDU5VwMS' }, + ], + + components: { + Sidebar: './src/components/starlight/Sidebar.astro', + ContentPanel: './src/components/starlight/ContentPanel.astro', + }, + + routeMiddleware: './src/routeData.ts', + + customCss: [ + './src/styles/global.css', + ], + + editLink: { + baseUrl: 'https://github.com/faststats-dev/docs/tree/main', + }, +} \ No newline at end of file diff --git a/starlight.sidebar.ts b/starlight.sidebar.ts new file mode 100644 index 0000000..c529ffc --- /dev/null +++ b/starlight.sidebar.ts @@ -0,0 +1,98 @@ + +import { openAPISidebarGroups } from 'starlight-openapi'; +import type { StarlightSidebarTopicsUserConfig, StarlightSidebarTopicsUserOptions } from 'starlight-sidebar-topics'; + +export const sidebarTopicsExtras: StarlightSidebarTopicsUserOptions = { + topics: { + api: ['/api/**/*'] + } +} + +export const sidebarConfig: StarlightSidebarTopicsUserConfig = [ + { + label: 'Platform', + id: 'platform', + link: '/platform/', + icon: 'puzzle', + items: [ + { + label: 'Overview', + items: [ + 'platform', + 'platform/hotkeys', + 'platform/error-tracking', + 'platform/retention' + ] + }, + { + label: 'Guides', + items: [{ autogenerate: { directory: 'platform/guide' } }], + }, + { + label: 'Chart Editor', + items: [{ autogenerate: { directory: 'platform/chart-editor' } }], + } + ], + }, + { + label: 'Java', + id: 'java', + link: '/java/', + icon: 'seti:java', + items: [ + { + label: 'Configuration', + items: [ + 'java', + 'java/migration', + 'java/configuration', + 'java/custom-metrics', + 'java/error-tracking', + 'java/feature-flags', + ] + }, + { + label: 'Platforms', + items: [{ autogenerate: { directory: 'java/platform' } }], + }, + { + label: 'Advanced', + items: [ + 'java/obfuscation-mappings', + 'java/system-properties', + ] + } + ], + }, + { + label: 'Rest API', + id: 'api', + link: '/api/', + icon: 'open-book', + items: openAPISidebarGroups, + }, + { + label: 'Web Analytics', + id: 'web-analytics', + link: '/web-analytics/', + icon: 'analytics', + badge: { + text: "Coming Soon", + variant: 'tip' + }, + items: [ + { + label: 'Getting Started', + items: [] + }, + { + label: 'Usage', + items: [] + }, + { + label: 'Features', + items: [] + } + ] + } +]; \ No newline at end of file From 95904099099e29f2ed5b4b41b608552d5ca2d064 Mon Sep 17 00:00:00 2001 From: Adam Matthiesen Date: Sun, 5 Jul 2026 21:33:48 -0700 Subject: [PATCH 22/40] feat: update site configuration and enable Starlight credits display --- astro.config.ts | 7 ++++--- starlight.config.ts | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/astro.config.ts b/astro.config.ts index efdd941..60b4786 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -11,18 +11,19 @@ import { sidebarConfig, sidebarTopicsExtras } from './starlight.sidebar'; import { baseStarlightOptions } from './starlight.config'; import { openAPIConfig } from './openapi.config'; +const site = process.env.NODE_ENV === 'production' ? 'https://docs.faststats.dev' : 'http://localhost:4321'; + // https://astro.build/config export default defineConfig({ - site: "https://docs.faststats.dev", - + site, vite: { plugins: [tailwindcss()], }, - integrations: [ react(), devServerFileWatcher([ './src/integrations/*.ts', + './ec.config.mjs', './openapi.config.ts', './starlight.config.ts', './starlight.sidebar.ts', diff --git a/starlight.config.ts b/starlight.config.ts index 91f49a9..4c2741d 100644 --- a/starlight.config.ts +++ b/starlight.config.ts @@ -1,6 +1,8 @@ import type { StarlightUserConfig } from '@astrojs/starlight/types'; export const baseStarlightOptions: StarlightUserConfig = { + credits: true, // Display the "Powered by Starlight" credits in the footer of the site + title: 'FastStats Docs', description: 'Error tracking, session replays, web vitals, funnels, and retention in one platform β€” stop stitching five tools together. Free during closed beta.', tagline: 'Product Analytics That Makes Sense', From a1ef1ec8ade5a5ddb91dde1df9aae1422e79cb47 Mon Sep 17 00:00:00 2001 From: Adam Matthiesen Date: Sun, 5 Jul 2026 21:58:12 -0700 Subject: [PATCH 23/40] refactor: improve code formatting and enhance translation error handling in Topics component --- src/components/starlight/topics/Topics.astro | 251 ++++++++++--------- 1 file changed, 135 insertions(+), 116 deletions(-) diff --git a/src/components/starlight/topics/Topics.astro b/src/components/starlight/topics/Topics.astro index 9c6353e..272cc47 100644 --- a/src/components/starlight/topics/Topics.astro +++ b/src/components/starlight/topics/Topics.astro @@ -1,134 +1,153 @@ --- -import starlightConfig from 'virtual:starlight/user-config'; -import { Badge, Icon } from '@astrojs/starlight/components'; -import { AstroError } from 'astro/errors'; -import type { ComponentProps } from 'astro/types'; +import starlightConfig from "virtual:starlight/user-config"; +import { Badge, Icon } from "@astrojs/starlight/components"; +import { AstroError } from "astro/errors"; +import type { ComponentProps } from "astro/types"; const { topics } = Astro.locals.starlightSidebarTopics; const defaultLang = - starlightConfig.defaultLocale?.lang || starlightConfig.defaultLocale?.locale || 'en'; + starlightConfig.defaultLocale?.lang || + starlightConfig.defaultLocale?.locale || + "en"; -function getTranslation(translations: Record, link: string, description: string) { - const defaultTranslation = translations[defaultLang]; +function getTranslation( + translations: Record, + link: string, + description: string, +) { + const defaultTranslation = translations[defaultLang]; - if (!defaultTranslation) { - throw new AstroError( - `The ${description} for "${link}" must have a key for the default language "${defaultLang}".`, - 'Update the Starlight config to include a topic label for the default language.' - ); - } + if (!defaultTranslation) { + throw new AstroError( + `The ${description} for "${link}" must have a key for the default language "${defaultLang}".`, + "Update the Starlight config to include a topic label for the default language.", + ); + } - let translation = defaultTranslation; + let translation = defaultTranslation; - if (Astro.currentLocale) { - translation = translations[Astro.currentLocale] ?? defaultTranslation; - } + if (Astro.currentLocale) { + translation = translations[Astro.currentLocale] ?? defaultTranslation; + } - return translation; + return translation; } --- + \ No newline at end of file + background-color: var(--sl-color-text-accent); + border-color: var(--sl-color-text-accent); + color: var(--sl-color-text-invert); + } + + .starlight-sidebar-topics-badge { + margin-inline-start: 0.25em; + } + From 99737d2f4d6d9b90175e2a7cebaf18a86cc52b2c Mon Sep 17 00:00:00 2001 From: Adam Matthiesen Date: Mon, 6 Jul 2026 14:39:15 -0700 Subject: [PATCH 24/40] Add documentation for web analytics features - Introduced consent and cookieless mode documentation. - Added error tracking guidelines for browser and server errors. - Documented automatic and custom event tracking. - Explained feature flags usage in the browser. - Provided instructions for identifying users and managing sessions. - Created installation and setup guides for FastStats Web Analytics. - Detailed JavaScript SDK usage and configuration. - Added Nuxt integration instructions for FastStats Web Analytics. - Documented React and Next.js integration with FastStats Web Analytics. - Explained session replay functionality and configuration. - Added sourcemaps upload instructions for better error tracking. - Documented reporting of Core Web Vitals from the browser SDK. --- package.json | 3 +- pnpm-lock.yaml | 122 +++++++++ src/components/starlight/PageFrame.astro | 118 +++++++++ src/content/docs/java/index.mdx | 21 +- src/content/docs/java/platform/fabric.mdx | 16 +- src/content/docs/java/platform/neoforge.mdx | 16 +- .../docs/web-analytics/configuration.mdx | 117 +++++++++ src/content/docs/web-analytics/consent.mdx | 120 +++++++++ .../docs/web-analytics/error-tracking.mdx | 144 +++++++++++ src/content/docs/web-analytics/events.mdx | 89 +++++++ .../docs/web-analytics/feature-flags.mdx | 96 +++++++ src/content/docs/web-analytics/identify.mdx | 87 +++++++ src/content/docs/web-analytics/index.mdx | 52 ++++ src/content/docs/web-analytics/javascript.mdx | 90 +++++++ src/content/docs/web-analytics/nuxt.mdx | 93 +++++++ src/content/docs/web-analytics/react.mdx | 151 +++++++++++ .../docs/web-analytics/session-replay.mdx | 98 +++++++ src/content/docs/web-analytics/sourcemaps.mdx | 242 ++++++++++++++++++ src/content/docs/web-analytics/web-vitals.mdx | 73 ++++++ starlight.config.ts | 1 + starlight.sidebar.ts | 22 +- 21 files changed, 1759 insertions(+), 12 deletions(-) create mode 100644 src/components/starlight/PageFrame.astro create mode 100644 src/content/docs/web-analytics/configuration.mdx create mode 100644 src/content/docs/web-analytics/consent.mdx create mode 100644 src/content/docs/web-analytics/error-tracking.mdx create mode 100644 src/content/docs/web-analytics/events.mdx create mode 100644 src/content/docs/web-analytics/feature-flags.mdx create mode 100644 src/content/docs/web-analytics/identify.mdx create mode 100644 src/content/docs/web-analytics/index.mdx create mode 100644 src/content/docs/web-analytics/javascript.mdx create mode 100644 src/content/docs/web-analytics/nuxt.mdx create mode 100644 src/content/docs/web-analytics/react.mdx create mode 100644 src/content/docs/web-analytics/session-replay.mdx create mode 100644 src/content/docs/web-analytics/sourcemaps.mdx create mode 100644 src/content/docs/web-analytics/web-vitals.mdx diff --git a/package.json b/package.json index a3bc0eb..0f69bfc 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "version": "0.0.1", "packageManager": "pnpm@11.10.0", "engines": { - "node": ">=22.20.0" + "node": "22.20.0" }, "scripts": { "dev": "astro dev", @@ -17,6 +17,7 @@ "@astrojs/react": "^6.0.1", "@astrojs/starlight": "^0.41.3", "@astrojs/starlight-tailwind": "^5.0.0", + "@faststats/react": "^0.5.0", "@fontsource-variable/geist": "^5.2.9", "@fontsource-variable/geist-mono": "^5.2.8", "@shikijs/colorized-brackets": "^4.3.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f7ded7c..0702afa 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,6 +17,9 @@ importers: '@astrojs/starlight-tailwind': specifier: ^5.0.0 version: 5.0.0(@astrojs/starlight@0.41.3(@astrojs/markdown-remark@7.2.1)(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0)(jiti@2.7.0))(typescript@6.0.3))(tailwindcss@4.3.2) + '@faststats/react': + specifier: ^0.5.0 + version: 0.5.0(@rrweb/utils@2.1.0)(react@19.2.7)(rrweb@2.1.0) '@fontsource-variable/geist': specifier: ^5.2.9 version: 5.2.9 @@ -532,6 +535,14 @@ packages: '@expressive-code/plugin-text-markers@0.44.0': resolution: {integrity: sha512-0/m3A5b+lz2upyNq+wzZ1S69HRoJmyFs5LsR42lVZ9pmGRlBiSBYQpvqlji4DBj1+Riamxc0AvcCr5kuzOQeWA==} + '@faststats/react@0.5.0': + resolution: {integrity: sha512-utETA4H+RAw2TaB/4chcrj2j2Ptw0pNt2QyxocrfnryNHaJKia+HkRTNnNN7+v5IEnC30PcxL/LBtUILcQwq6A==} + peerDependencies: + react: '>=18' + + '@faststats/web@0.5.0': + resolution: {integrity: sha512-p9+JqCMJAHyElC9mR3VnQwSYwzMYmtZZjg/3r5NdG9CRr2R8Fmvdt7fJR+MdacxYkVPrrRIbeNZlRJxALy+rWg==} + '@fontsource-variable/geist-mono@5.2.8': resolution: {integrity: sha512-KI5bj+hkkRiHttYHmccotUZ80ZuZyai+RwI1d7UId0clkx/jXxlo8qYK8j54WzmpBjtMoEMPyllV7faDcj+6RA==} @@ -893,6 +904,26 @@ packages: rollup: optional: true + '@rrweb/record@2.1.0': + resolution: {integrity: sha512-jnbpYQED6QdKn1MuEoqJyILkYhuWDhb3kzA/l1i+Di5sfP7apf3HvrlVIMoyZgATMlk2if65BUUrc5R+vabCjQ==} + + '@rrweb/rrweb-plugin-console-record@2.1.0': + resolution: {integrity: sha512-pwzkwkE++pyg7TqSdkBkV7g+Rhi2IkVflNCzOagCguUyyz0KhRRjJyjJ1gZe313tNh42I8wVEMsOaU9lcQdAvA==} + peerDependencies: + '@rrweb/utils': ^2.0.1 + rrweb: ^2.0.1 + + '@rrweb/rrweb-plugin-sequential-id-record@2.1.0': + resolution: {integrity: sha512-TTsqWzfOxqKFAXEZBGvAhfJ7uBv7OJkjij7BedI9/Xo8spOJJ8Wy22FseuqMXD6PBH87mLwGeTEhnSPetrxsjg==} + peerDependencies: + rrweb: ^2.0.1 + + '@rrweb/types@2.1.0': + resolution: {integrity: sha512-svOHkcuukP6rIjz2umwVsS7uYct+2h0N97+bg+8IJYKIUj5+YjwIvqx5y9NILFKPIu3yk+Mb+KDFfJ8RV+4JlA==} + + '@rrweb/utils@2.1.0': + resolution: {integrity: sha512-hU7MT3TSdD+Do7FmMoHrBfPevFCheN5vo2mn97Y4vbXuwemopAmo8dqo5KJeMaA6oQQt7FinHJ0Xqb7k68Ci6Q==} + '@shikijs/colorized-brackets@4.3.1': resolution: {integrity: sha512-hyp9iRV7iEnU/sT1DL3eLevY0wOwIeFMp6ss8U8FfWdwT5LLhv4sO5Xt6r0dD3eteeswDngBiuEv6nQzQEwv2w==} engines: {node: '>=20'} @@ -1037,6 +1068,9 @@ packages: '@types/babel__traverse@7.28.0': resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + '@types/css-font-loading-module@0.0.7': + resolution: {integrity: sha512-nl09VhutdjINdWyXxHWN/w9zlNCfr60JUqJbd24YXUuCwgeL0TpFSdElCwb6cxfB6ybE19Gjj4g0jsgkXxKv1Q==} + '@types/debug@4.1.13': resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} @@ -1102,6 +1136,9 @@ packages: '@webgpu/types@0.1.21': resolution: {integrity: sha512-pUrWq3V5PiSGFLeLxoGqReTZmiiXwY3jRkIG5sLLKjyqNxrwm/04b4nw7LSmGWJcKk59XOM/YRTUwOzo4MMlow==} + '@xstate/fsm@1.6.5': + resolution: {integrity: sha512-b5o1I6aLNeYlU/3CPlj/Z91ybk1gUsKT+5NAJI+2W4UjvS5KLG28K9v5UvNoFVjHV8PajVZ00RH3vnjyQO7ZAw==} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -1189,6 +1226,10 @@ packages: base-64@1.0.0: resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==} + base64-arraybuffer@1.0.2: + resolution: {integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==} + engines: {node: '>= 0.6.0'} + baseline-browser-mapping@2.10.42: resolution: {integrity: sha512-c/jurFrDLyui7o1J86yLkRu4LMsTYcBohveus7/I2Hzdn9KIP2bdJPTue/lR1KH46enoPbD77GKeSYNdyPoD3Q==} engines: {node: '>=6.0.0'} @@ -2056,6 +2097,9 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + mrmime@2.0.1: resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} engines: {node: '>=10'} @@ -2295,6 +2339,15 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} hasBin: true + rrdom@2.1.0: + resolution: {integrity: sha512-d7oaIHzwffxI74UJMZDGq/f97/Yfm3QX4CcTIlQelt2HsLavItLjp8x8nQ0g9Pet5+5wG1RGr9yvsxb1gJlo8A==} + + rrweb-snapshot@2.1.0: + resolution: {integrity: sha512-CFjUKWlO+Dl72gk8qwcDcNE/Pj9yr6IvGRAiRAx12pmJaSWaOKFoFgpQQ1j/mW0WKwEZXbHnMJL8M92gIsdwUQ==} + + rrweb@2.1.0: + resolution: {integrity: sha512-gGGvd1eXWnOuJpQumH7+gPmBwTXzNrjmQyedWVePcEx0S5fe3VkQW4vw5f5ItY+vuigaaktte9cZKOg0OEvv+w==} + satteri@0.9.4: resolution: {integrity: sha512-BKob126Tay84diOZsnVNH/Q/c+3njPJTCad3w5zLKa6j8bVjxskPNHDtxrMwYK4bN/RlqUSdMnPwKY4k65EMOQ==} @@ -2645,6 +2698,9 @@ packages: web-namespaces@2.0.1: resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + web-vitals@5.3.0: + resolution: {integrity: sha512-q6LWsLatGYZp5VGBIOvbTj6JBV2nOmC8KvWztXBmwJcfFAzhwKwbOxhUH306XY3CcaZDUlSmSuNPBsCn0bFu+g==} + which-pm-runs@1.1.0: resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==} engines: {node: '>=4'} @@ -3182,6 +3238,24 @@ snapshots: dependencies: '@expressive-code/core': 0.44.0 + '@faststats/react@0.5.0(@rrweb/utils@2.1.0)(react@19.2.7)(rrweb@2.1.0)': + dependencies: + '@faststats/web': 0.5.0(@rrweb/utils@2.1.0)(rrweb@2.1.0) + react: 19.2.7 + transitivePeerDependencies: + - '@rrweb/utils' + - rrweb + + '@faststats/web@0.5.0(@rrweb/utils@2.1.0)(rrweb@2.1.0)': + dependencies: + '@rrweb/record': 2.1.0 + '@rrweb/rrweb-plugin-console-record': 2.1.0(@rrweb/utils@2.1.0)(rrweb@2.1.0) + '@rrweb/rrweb-plugin-sequential-id-record': 2.1.0(rrweb@2.1.0) + web-vitals: 5.3.0 + transitivePeerDependencies: + - '@rrweb/utils' + - rrweb + '@fontsource-variable/geist-mono@5.2.8': {} '@fontsource-variable/geist@5.2.9': {} @@ -3457,6 +3531,25 @@ snapshots: estree-walker: 2.0.2 picomatch: 4.0.5 + '@rrweb/record@2.1.0': + dependencies: + '@rrweb/types': 2.1.0 + '@rrweb/utils': 2.1.0 + rrweb: 2.1.0 + + '@rrweb/rrweb-plugin-console-record@2.1.0(@rrweb/utils@2.1.0)(rrweb@2.1.0)': + dependencies: + '@rrweb/utils': 2.1.0 + rrweb: 2.1.0 + + '@rrweb/rrweb-plugin-sequential-id-record@2.1.0(rrweb@2.1.0)': + dependencies: + rrweb: 2.1.0 + + '@rrweb/types@2.1.0': {} + + '@rrweb/utils@2.1.0': {} + '@shikijs/colorized-brackets@4.3.1': dependencies: shiki: 4.3.1 @@ -3595,6 +3688,8 @@ snapshots: dependencies: '@babel/types': 7.29.7 + '@types/css-font-loading-module@0.0.7': {} + '@types/debug@4.1.13': dependencies: '@types/ms': 2.1.0 @@ -3665,6 +3760,8 @@ snapshots: '@webgpu/types@0.1.21': {} + '@xstate/fsm@1.6.5': {} + acorn-jsx@5.3.2(acorn@8.17.0): dependencies: acorn: 8.17.0 @@ -3821,6 +3918,8 @@ snapshots: base-64@1.0.0: {} + base64-arraybuffer@1.0.2: {} + baseline-browser-mapping@2.10.42: {} bcp-47-match@2.0.3: {} @@ -5050,6 +5149,8 @@ snapshots: dependencies: mime-db: 1.52.0 + mitt@3.0.1: {} + mrmime@2.0.1: {} ms@2.1.3: {} @@ -5377,6 +5478,25 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.1.4 '@rolldown/binding-win32-x64-msvc': 1.1.4 + rrdom@2.1.0: + dependencies: + rrweb-snapshot: 2.1.0 + + rrweb-snapshot@2.1.0: + dependencies: + postcss: 8.5.16 + + rrweb@2.1.0: + dependencies: + '@rrweb/types': 2.1.0 + '@rrweb/utils': 2.1.0 + '@types/css-font-loading-module': 0.0.7 + '@xstate/fsm': 1.6.5 + base64-arraybuffer: 1.0.2 + mitt: 3.0.1 + rrdom: 2.1.0 + rrweb-snapshot: 2.1.0 + satteri@0.9.4: dependencies: '@types/estree-jsx': 1.0.5 @@ -5700,6 +5820,8 @@ snapshots: web-namespaces@2.0.1: {} + web-vitals@5.3.0: {} + which-pm-runs@1.1.0: {} wrap-ansi@7.0.0: diff --git a/src/components/starlight/PageFrame.astro b/src/components/starlight/PageFrame.astro new file mode 100644 index 0000000..0229cfa --- /dev/null +++ b/src/components/starlight/PageFrame.astro @@ -0,0 +1,118 @@ +--- +// @ts-expect-error - Virtual Module for MobileMenuToggle component +import MobileMenuToggle from "virtual:starlight/components/MobileMenuToggle"; +import { Analytics } from "@faststats/react"; + +const { hasSidebar } = Astro.locals.starlightRoute; +--- + +{ + process.env.NODE_ENV === "production" && ( + + ) +} + +
+
+ { + hasSidebar && ( + + ) + } +
+
+ + diff --git a/src/content/docs/java/index.mdx b/src/content/docs/java/index.mdx index c58f907..f3fdbfd 100644 --- a/src/content/docs/java/index.mdx +++ b/src/content/docs/java/index.mdx @@ -57,14 +57,31 @@ Choose the artifact for your platform: | -------------------------- | ----------------------------------------- | ------------- | | Bukkit/Spigot/Paper/Folia… | [`bukkit`](/java/platform/bukkit) | 17+ | | BungeeCord | [`bungeecord`](/java/platform/bungeecord) | 17+ | -| Fabric | [`fabric`](/java/platform/fabric) | 25+ | +| Fabric | [`fabric`](/java/platform/fabric) | 21+ | | Hytale | [`hytale`](/java/platform/hytale) | 25+ | | Minestom | [`minestom`](/java/platform/minestom) | 25+ | -| NeoForge | [`neoforge`](/java/platform/neoforge) | 25+ | +| NeoForge | [`neoforge`](/java/platform/neoforge) | 21+ | | Nukkit | [`nukkit`](/java/platform/nukkit) | 17+ | | Sponge | [`sponge`](/java/platform/sponge) | 17+ | | Velocity | [`velocity`](/java/platform/velocity) | 21+ | +Fabric and NeoForge artifacts include the SDK version and the Minecraft version range you want to target: + +```kts +implementation("dev.faststats.metrics:fabric:0.27.2+mc26.1-26.3") +implementation("dev.faststats.metrics:neoforge:0.27.2+mc26.1-26.2") +``` + +The version format is `{sdk-version}+mc{from}-{to}`, where `{sdk-version}` is +the FastStats SDK version and `{from}-{to}` is the supported Minecraft version +range for that artifact. + +You can find the available versions in the Maven repository: +[Fabric](https://repo.faststats.dev/#/releases/dev/faststats/metrics/fabric/) and +[NeoForge](https://repo.faststats.dev/#/releases/dev/faststats/metrics/neoforge/). + +All other platforms use the SDK version without a Minecraft version suffix. + diff --git a/src/content/docs/java/platform/fabric.mdx b/src/content/docs/java/platform/fabric.mdx index caf601e..177fe8d 100644 --- a/src/content/docs/java/platform/fabric.mdx +++ b/src/content/docs/java/platform/fabric.mdx @@ -6,15 +6,25 @@ description: Integrate FastStats with Fabric mods import ReadMore from '@/components/ReadMore.astro'; import { Aside } from '@astrojs/starlight/components'; -Use `dev.faststats.fabric.FabricContext` for Fabric mods. Requires Java 25+. +Use `dev.faststats.fabric.FabricContext` for Fabric mods. Requires Java 21+. **Artifact:** `dev.faststats.metrics:fabric` +```kts +implementation("dev.faststats.metrics:fabric:0.27.2+mc26.1-26.3") +``` + +The version format is `{sdk-version}+mc{from}-{to}`, where `{sdk-version}` is +the FastStats SDK version and `{from}-{to}` is the supported Minecraft version +range for that artifact. + ```java title="ExampleMod.java" import dev.faststats.ErrorTracker; import dev.faststats.Metrics; diff --git a/src/content/docs/java/platform/neoforge.mdx b/src/content/docs/java/platform/neoforge.mdx index 1b83a7e..08574a6 100644 --- a/src/content/docs/java/platform/neoforge.mdx +++ b/src/content/docs/java/platform/neoforge.mdx @@ -6,15 +6,25 @@ description: Integrate FastStats with NeoForge mods import ReadMore from '@/components/ReadMore.astro'; import { Aside } from '@astrojs/starlight/components'; -Use `dev.faststats.neoforge.NeoForgeContext` for NeoForge mods. Requires Java 25+. +Use `dev.faststats.neoforge.NeoForgeContext` for NeoForge mods. Requires Java 21+. **Artifact:** `dev.faststats.metrics:neoforge` +```kts +implementation("dev.faststats.metrics:neoforge:0.27.2+mc26.1-26.2") +``` + +The version format is `{sdk-version}+mc{from}-{to}`, where `{sdk-version}` is +the FastStats SDK version and `{from}-{to}` is the supported Minecraft version +range for that artifact. + ```java title="ExampleMod.java" import dev.faststats.ErrorTracker; import dev.faststats.Metrics; diff --git a/src/content/docs/web-analytics/configuration.mdx b/src/content/docs/web-analytics/configuration.mdx new file mode 100644 index 0000000..13c8a1a --- /dev/null +++ b/src/content/docs/web-analytics/configuration.mdx @@ -0,0 +1,117 @@ +--- +title: Configuration +description: Every option you can pass to FastStats Web Analytics +--- + +All packages share the same set of options. In React you pass them as props on +the `Analytics` component, in Nuxt you set them under the `faststats` key, and in +plain JavaScript you pass them to the `WebAnalytics` constructor. + +## Core Options + +| Option | Type | Default | Description | +| --------------------- | --------- | ------------------------------- | -------------------------------------------------------------- | +| `siteKey` | `string` | required | The project key that ties events to your FastStats project | +| `baseUrl` | `string` | `https://metrics.faststats.dev` | Where events, identify calls, vitals and replays are sent | +| `featureFlagsBaseUrl` | `string` | `https://flags.faststats.dev` | Where feature flag checks are sent | +| `debug` | `boolean` | `false` | Logs every action to the console | +| `autoTrack` | `boolean` | `true` | Starts tracking automatically. Set to `false` to start by hand | +| `trackHash` | `boolean` | `false` | Treats hash changes as page views for hash based routers | +| `cookieless` | `boolean` | `false` | Forces cookieless mode with no stored identifiers | + +## Error Tracking + +```ts +errorTracking: { + enabled: true, +} +``` + +| Field | Type | Default | Description | +| --------- | --------- | ------- | -------------------- | +| `enabled` | `boolean` | `false` | Turns the tracker on | + +Read more in [Error Tracking](/web-analytics/error-tracking). + +### Web Vitals + +```ts +webVitals: { + enabled: true, + attribution: false, +} +``` + +| Field | Type | Default | Description | +| ------------- | --------- | ------- | ------------------------------------------ | +| `enabled` | `boolean` | `false` | Turns the tracker on | +| `attribution` | `boolean` | `false` | Adds debug attribution data to each metric | + +Read more in [Web Vitals](/web-analytics/web-vitals). + +### Session Replays + +```ts +sessionReplays: { + enabled: true, +}, +replayOptions: { + flushInterval: 5_000, + maxEvents: 1000, + maxBatchSizeBytes: 512 * 1024, +} +``` + +| Field | Type | Default | Description | +| --------------------------------- | --------- | -------- | -------------------------------------------------------- | +| `enabled` | `boolean` | `false` | Turns the recorder on | +| `replayOptions.flushInterval` | `number` | `5000` | Flush interval in milliseconds | +| `replayOptions.maxEvents` | `number` | `1000` | Flush after this many buffered rrweb events | +| `replayOptions.maxBatchSizeBytes` | `number` | `524288` | Flush after the buffered event payload reaches this size | + +For masking and recording details see +[Session Replay](/web-analytics/session-replay). + +### Consent + +```ts +consent: { + mode: "granted", + pendingBehavior: "anonymous", +} +``` + +| Field | Type | Default | Description | +| ----------------- | ------------------------------------ | ------------- | ------------------------------------------------------------------- | +| `mode` | `"pending" \| "granted" \| "denied"` | `"granted"` | The current consent state | +| `pendingBehavior` | `"anonymous" \| "disabled"` | `"anonymous"` | Cookieless tracking while consent is pending, or no tracking at all | + +Read more in [Consent and Cookieless](/web-analytics/consent). + +## Manual Start + +When `autoTrack` is `false` the SDK does not begin until you call `start`. This +lets you wait for a cookie banner or any other gate. + +```ts +import { WebAnalytics } from "@faststats/web"; + +const analytics = new WebAnalytics({ + siteKey: "your_site_key", + autoTrack: false, +}); + +// once you are ready +analytics.start(); +``` + +## Disable Tracking on a Device + +The SDK checks `localStorage` for a flag before it sends anything. Set it to opt +a single browser out, which is useful for your own devices. + +```ts +localStorage.setItem("disable-faststats", "true"); +``` + +Remove the key to turn tracking back on. diff --git a/src/content/docs/web-analytics/consent.mdx b/src/content/docs/web-analytics/consent.mdx new file mode 100644 index 0000000..db0baca --- /dev/null +++ b/src/content/docs/web-analytics/consent.mdx @@ -0,0 +1,120 @@ +--- +title: Consent and Cookieless +description: Run analytics with or without stored identifiers +--- + +import { Aside, Tabs, TabItem } from '@astrojs/starlight/components'; + + + +The SDK supports cookieless mode and three consent states: `pending`, `granted`, +and `denied`. Switch modes at runtime with `setConsentMode`, `optIn`, or +`optOut`. + +## How Identifiers Work + +In the normal mode the SDK keeps an anonymous id in `localStorage` and a session +in storage so returning visits and sessions can be measured. In cookieless mode +no anonymous id is stored and events are sent without a user id, which means +visitors cannot be recognized across reloads. + +## Cookieless Mode + +Set `cookieless` to `true` to never store an identifier. + + + + +```tsx + +``` + + + + +```ts title="nuxt.config.ts" +faststats: { + siteKey: "your_site_key", + cookieless: true, +} +``` + + + + +```ts +new WebAnalytics({ siteKey: "your_site_key", cookieless: true }); +``` + + + + + +## Consent Modes + +When you use a consent banner, start in `pending` and update the mode once the +user decides. There are three modes. + +| Mode | Meaning | +| --------- | --------------------------------------------- | +| `pending` | The user has not chosen yet | +| `granted` | The user accepted, the SDK stores identifiers | +| `denied` | The user declined, the SDK runs cookieless | + +While the mode is `pending` the SDK runs cookieless by default, so you can still +count page views without storing anything. Set `pendingBehavior` to `"disabled"` +if you prefer to send nothing at all until consent. + +```ts +new WebAnalytics({ + siteKey: "your_site_key", + consent: { mode: "pending", pendingBehavior: "anonymous" }, +}); +``` + +## Update Consent at Runtime + +Call `optIn` or `optOut` from your banner buttons, or call `setConsentMode` for +full control. The SDK switches storage behavior right away and tells the replay +and other trackers about the change. + + + + +```tsx +import { optIn, optOut } from "@faststats/react"; + + + +``` + + + + +```ts +import { optIn, optOut, setConsentMode } from "@faststats/web"; + +optIn(); // same as setConsentMode("granted") +optOut(); // same as setConsentMode("denied") +setConsentMode("pending"); +``` + + + + + + + +## React Consent Prop + +In React you can also drive the mode through the `consent.mode` prop. When the +prop changes the component updates the running instance for you. + +```tsx + +``` diff --git a/src/content/docs/web-analytics/error-tracking.mdx b/src/content/docs/web-analytics/error-tracking.mdx new file mode 100644 index 0000000..80921fb --- /dev/null +++ b/src/content/docs/web-analytics/error-tracking.mdx @@ -0,0 +1,144 @@ +--- +title: Error Tracking +description: Capture client and server errors +--- + +import { Tabs, TabItem } from '@astrojs/starlight/components'; + +Browser errors are reported by the web SDK. Server errors in Nitro routes are +reported by `@faststats/nitro`. + +## Browser Errors + +Turn on `errorTracking.enabled` to capture uncaught errors and unhandled promise +rejections. The tracker batches them and drops noise from browser extensions +automatically. + + + + +```tsx + +``` + + + + +```ts title="nuxt.config.ts" +faststats: { + siteKey: "your_site_key", + errorTracking: { enabled: true }, +} +``` + + + + +```ts +new WebAnalytics({ + siteKey: "your_site_key", + errorTracking: { enabled: true }, +}); +``` + + + + + +Errors are grouped by their type and message so the same error from many +visitors does not flood your dashboard. Identical errors within a batch are +counted instead of repeated. + +## Report Errors by Hand + +When you catch an error yourself you can still send it with `reportError`. This +only works when `errorTracking.enabled` is `true`. + +```ts +import { reportError } from "@faststats/web"; + +try { + doRiskyThing(); +} catch (error) { + reportError(error as Error); +} +``` + +In Nuxt the module already hooks into the Vue error handler, so component errors +are reported without extra code. + +## Server Errors with Nitro + +If you run Nitro, either standalone or through Nuxt, you can report errors thrown +in server routes with `@faststats/nitro`. The package ships a plugin for Nitro +v2 and one for Nitro v3. + +`npm install @faststats/nitro ` + + + + +```ts title="nuxt.config.ts" +import { createRequire } from "node:module"; + +const require = createRequire(import.meta.url); +const errorTrackingPlugin = require.resolve("@faststats/nitro/v2"); + +export default defineNuxtConfig({ + nitro: { + plugins: [errorTrackingPlugin], + }, +}); +``` + + + + +```ts title="nitro.config.ts" +export default defineNitroConfig({ + plugins: ["@faststats/nitro/v2"], +}); +``` + + + + + +Use the `/v3` import instead when you are on Nitro v3. + +### Server Configuration + +The server plugin reads its settings from environment variables. The token is a +project token, not the browser site key, so keep it on the server only. + +| Variable | Default | Description | +| -------------------------- | ---------------------------------------- | ---------------------------------------- | +| `FASTSTATS_TOKEN` | required | Project token used to authorize reports | +| `FASTSTATS_ERROR_ENDPOINT` | `https://metrics.faststats.dev/v1/error` | Where server errors are sent | +| `FASTSTATS_BUILD_ID` | none | Tags errors with a build for source maps | +| `FASTSTATS_DEBUG` | `0` | Set to `1` to log reporter activity | + +```bash title=".env" +FASTSTATS_TOKEN=your_project_token +``` + +If `FASTSTATS_TOKEN` is not set the plugin stays silent and skips reporting, so +it is safe to leave installed in environments without a token. + +### Custom Configuration + +You can also create a plugin with explicit options instead of environment +variables. This lets you attach extra context to every error. + +```ts title="server/plugins/faststats.ts" +import { createFaststatsNitroPluginV2 } from "@faststats/nitro/v2"; + +export default createFaststatsNitroPluginV2({ + token: process.env.FASTSTATS_TOKEN, + getContext: ({ path }) => ({ route: path }), +}); +``` + +The reporter batches errors, retries failed sends and opens a short circuit +breaker after repeated failures so a broken endpoint never slows your server +down. diff --git a/src/content/docs/web-analytics/events.mdx b/src/content/docs/web-analytics/events.mdx new file mode 100644 index 0000000..3df70ce --- /dev/null +++ b/src/content/docs/web-analytics/events.mdx @@ -0,0 +1,89 @@ +--- +title: Events +description: Automatic tracking and custom events +--- + +import { Tabs, TabItem } from '@astrojs/starlight/components'; + +The SDK sends `pageview`, `page_leave`, and `outbound_link` events +automatically. Use `trackEvent` for custom events. + +## Automatic Tracking + +Once the SDK starts it records these without any extra code. + +| Event | When it fires | +| --------------- | ------------------------------------------------------- | +| `pageview` | On the first load and on every client side route change | +| `page_leave` | When the page is hidden or the user navigates away | +| `outbound_link` | When a user clicks a link that points to another host | + +Each page view carries the path, full URL, referrer, page title and any UTM +parameters from the query string. The `page_leave` event also includes the time +spent on the page, the deepest scroll depth in percent and the session duration. + +Single page navigation is detected through the History API, so `pushState`, +`replaceState` and the back and forward buttons all create new page views. Hash +based routers need `trackHash` turned on. See +[Configuration](/web-analytics/configuration). + +## Custom Events + +Call `trackEvent` with a name and an optional object of properties. Use clear, +lower case names so they read well in your dashboard. + + + + +```tsx +import { trackEvent } from "@faststats/react"; + +trackEvent("signup", { plan: "pro", source: "hero" }); +``` + + + + +```ts +import { trackEvent } from "@faststats/web"; + +trackEvent("signup", { plan: "pro", source: "hero" }); +``` + + + + + +The event name is trimmed and empty names are ignored, so a stray space never +creates a broken event. + +## Properties and Dimensions + +You can attach any JSON friendly values as properties. A few keys are treated as +known dimensions and are stored as first class fields instead of free form +properties. These are `browser`, `browser_version`, `device`, `os`, +`os_version`, `referrer`, `utm_source`, `utm_medium`, `utm_campaign`, +`utm_term`, `utm_content`, `title`, `page` and `url`. + +Everything else you pass lands in the properties bag. + +```ts +trackEvent("video_play", { + // stored as a dimension + page: "/courses/intro", + // stored as custom properties + video_id: "abc123", + position_seconds: 12, +}); +``` + +## Good Practices + +Keep a small, stable set of event names and put varying details in properties. +Use one event name with a `step` property instead of separate names per step. + +```ts +trackEvent("checkout", { step: "cart" }); +trackEvent("checkout", { step: "shipping" }); +trackEvent("checkout", { step: "payment" }); +``` diff --git a/src/content/docs/web-analytics/feature-flags.mdx b/src/content/docs/web-analytics/feature-flags.mdx new file mode 100644 index 0000000..b938238 --- /dev/null +++ b/src/content/docs/web-analytics/feature-flags.mdx @@ -0,0 +1,96 @@ +--- +title: Feature Flags +description: Evaluate FastStats feature flags in the browser +--- + +import { Aside } from '@astrojs/starlight/components'; + + + +Evaluate a flag for the current visitor with `useFlag` in React or +`checkFeatureFlag` on the SDK instance. The response includes the value and, +for multivariate flags, the chosen variant. + +## React Hook + +The `useFlag` hook is the simplest way to read a flag in React. It returns the +value together with loading and error state, and a `refetch` helper. + +```tsx +"use client"; + +import { useFlag } from "@faststats/react"; + +export function NewDashboard() { + const { value, isLoading } = useFlag("new_dashboard"); + + if (isLoading) return ; + if (value === "true") return ; + return ; +} +``` + +The hook needs an active `Analytics` component on the page. It uses the current +visitor identity to evaluate the flag. + +### Hook Options + +```tsx +const { value, error, refetch } = useFlag("pricing_test", { + attributes: { country: "DE", plan: "pro" }, + externalId: "user_123", + skip: false, +}); +``` + +| Option | Type | Description | +| ------------ | ------------------------- | --------------------------------------------------- | +| `attributes` | `Record` | Extra context used by the targeting rules | +| `externalId` | `string` | Evaluate for a specific user instead of the visitor | +| `skip` | `boolean` | Skip the request, for example until you are ready | + +### Result Shape + +| Field | Type | Description | +| -------------- | --------------- | ---------------------------------------------- | +| `value` | `string` | The flag value, defaults to `"false"` | +| `variantKey` | `string` | The chosen variant key when the flag is a test | +| `variantValue` | `string` | The value attached to that variant | +| `isLoading` | `boolean` | True while the request is in flight | +| `error` | `Error \| null` | Set when the evaluation failed | +| `refetch` | `() => void` | Run the evaluation again | + +## Outside React + +When you do not use React, evaluate a flag through the instance. + +```ts +import { getInstance } from "@faststats/web"; + +const result = await getInstance()?.checkFeatureFlag("new_dashboard", { + country: "DE", +}); + +if (result?.value === "true") { + // turn the feature on +} +``` + +## Values are Strings + +Flag values come back as strings, so a boolean flag returns `"true"` or +`"false"`. Compare against the string form rather than a real boolean. + +```ts +if (value === "true") { + // correct +} +``` + +## Custom Flags Endpoint + +Flag checks go to `https://flags.faststats.dev` by default. To send them through +your own domain, set `featureFlagsBaseUrl`. diff --git a/src/content/docs/web-analytics/identify.mdx b/src/content/docs/web-analytics/identify.mdx new file mode 100644 index 0000000..219a9e7 --- /dev/null +++ b/src/content/docs/web-analytics/identify.mdx @@ -0,0 +1,87 @@ +--- +title: Identify Users +description: Attach a known identity to a visitor +--- + +import { Aside, Tabs, TabItem } from '@astrojs/starlight/components'; + +Call `identify` after sign-in to link the anonymous visitor id to an external +user id and profile fields. + +## Identify a User + +Pass a stable external id and an email. The external id should be the same value +your own system uses for that user, such as a database id. + + + + +```tsx +import { identify } from "@faststats/react"; + +await identify("user_123", "ada@example.com", { + name: "Ada Lovelace", + traits: { plan: "pro" }, +}); +``` + + + + +```ts +import { identify } from "@faststats/web"; + +await identify("user_123", "ada@example.com", { + name: "Ada Lovelace", + traits: { plan: "pro" }, +}); +``` + + + + + +The third argument is optional and accepts a few profile fields. + +| Field | Type | Description | +| ----------- | ------------------------- | -------------------------------------------- | +| `name` | `string` | The display name of the user | +| `phone` | `string` | A phone number | +| `avatarUrl` | `string` | A link to an avatar image | +| `traits` | `Record` | Any extra attributes you want on the profile | + +## What identify Returns + +`identify` returns a promise that resolves to a boolean. It is `false` when the +call was skipped, for example when the external id or email is empty or when the +visitor is in cookieless mode, and `true` once the call is on its way. + +```ts +const ok = await identify("user_123", "ada@example.com"); +if (!ok) { + // the visitor is cookieless or the input was empty +} +``` + + + +## Log Out + +When a user signs out, call `logout` to start a fresh anonymous session so their +next activity is not tied to the old profile. + +```ts +import { logout } from "@faststats/web"; + +logout(); +``` + +By default this also resets the anonymous identifier. Pass `false` if you want +to keep the same anonymous id and only rotate the session. + +```ts +logout(false); +``` diff --git a/src/content/docs/web-analytics/index.mdx b/src/content/docs/web-analytics/index.mdx new file mode 100644 index 0000000..6f32d50 --- /dev/null +++ b/src/content/docs/web-analytics/index.mdx @@ -0,0 +1,52 @@ +--- +title: Installation +description: Add FastStats Web Analytics to your website or web app +--- + +import { Aside, Tabs, TabItem } from '@astrojs/starlight/components'; + + + +Install one of the packages below and pass your site key. + +## Choose a Package + +| Package | Use it when | Guide | +| ------------------ | ----------------------------------------------- | --------------------------------------- | +| `@faststats/react` | You build with React or Next.js | [React](/web-analytics/react) | +| `@faststats/nuxt` | You build with Nuxt | [Nuxt](/web-analytics/nuxt) | +| `@faststats/web` | You use plain JavaScript or any other framework | [JavaScript](/web-analytics/javascript) | + +## Install + + + + ```sh + npm install @faststats/react + ``` + + + ```sh + npm install @faststats/nuxt + ``` + + + ```sh + npm install @faststats/web + ``` + + + +## Get Your Site Key + +Every request is tied to a site key. You can find it in your FastStats project +settings. The key is safe to ship in the browser because it only allows writing +events for that one project. + +## Next Steps + +- [Configuration](/web-analytics/configuration): all SDK options +- [Events](/web-analytics/events): automatic and custom tracking +- [Consent and Cookieless](/web-analytics/consent): cookieless mode and consent states diff --git a/src/content/docs/web-analytics/javascript.mdx b/src/content/docs/web-analytics/javascript.mdx new file mode 100644 index 0000000..7470c30 --- /dev/null +++ b/src/content/docs/web-analytics/javascript.mdx @@ -0,0 +1,90 @@ +--- +title: JavaScript +description: Add FastStats Web Analytics with the plain browser SDK +--- + +The `@faststats/web` package is the core browser SDK. The React and Nuxt +packages are built on top of it. Use it directly when you work with plain +JavaScript, with a framework that has no dedicated package yet, or when you want +full control over the lifecycle. + +## Install + +```sh + npm install @faststats/web +``` + +## Create an Instance + +Create one `WebAnalytics` instance as early as possible. It starts tracking +automatically once the page is ready. + +```ts title="analytics.ts" +import { WebAnalytics } from "@faststats/web"; + +new WebAnalytics({ + siteKey: "your_site_key", +}); +``` + +That single line already records page views, page leaves, sessions, outbound +link clicks and scroll depth. To enable more features pass extra options. + +```ts +new WebAnalytics({ + siteKey: "your_site_key", + errorTracking: { enabled: true }, + webVitals: { enabled: true }, + sessionReplays: { enabled: true }, +}); +``` + +## Track Custom Events + +The package exports functions that talk to the active instance. You can call +them from any module without holding a reference yourself. + +```ts +import { trackEvent } from "@faststats/web"; + +document.querySelector("#buy")?.addEventListener("click", () => { + trackEvent("purchase", { plan: "pro", price: 29 }); +}); +``` + +## Single Page Apps + +The SDK patches `pushState` and `replaceState` and listens for `popstate`, so +client side route changes are tracked as new page views with no extra work. If +your router uses the hash for routing, turn on `trackHash`. + +```ts +new WebAnalytics({ + siteKey: "your_site_key", + trackHash: true, +}); +``` + +## Reach the Instance Later + +`getInstance` returns the active instance once it has started. This is handy for +debugging in the console or for advanced calls such as feature flag checks. + +```ts +import { getInstance } from "@faststats/web"; + +const analytics = getInstance(); +analytics?.getSessionId(); +``` + +## Clean Up + +If you manage the lifecycle yourself, call `destroy` to remove all listeners and +stop the child trackers. This is mostly useful in tests or in micro frontends +that mount and unmount whole apps. + +```ts +const analytics = new WebAnalytics({ siteKey: "your_site_key" }); +// later +analytics.destroy(); +``` diff --git a/src/content/docs/web-analytics/nuxt.mdx b/src/content/docs/web-analytics/nuxt.mdx new file mode 100644 index 0000000..d7c6a82 --- /dev/null +++ b/src/content/docs/web-analytics/nuxt.mdx @@ -0,0 +1,93 @@ +--- +title: Nuxt +description: Add FastStats Web Analytics to a Nuxt app +--- + +The `@faststats/nuxt` module sets up the browser SDK for you. It reads its +configuration from your `nuxt.config`, starts tracking on the client and wires +the SDK into the Vue error handler so unhandled component errors are reported. + +## Install + +```sh + npm install @faststats/nuxt +``` + +## Register the Module + +Add the module and your settings under the `faststats` key. + +```ts title="nuxt.config.ts" +export default defineNuxtConfig({ + modules: ["@faststats/nuxt"], + faststats: { + siteKey: "your_site_key", + errorTracking: { enabled: true }, + webVitals: { enabled: true }, + sessionReplays: { enabled: true }, + }, +}); +``` + +The module accepts every option from the SDK. See +[Configuration](/web-analytics/configuration) for the full list. + +## Use Environment Variables + +Anything under `faststats` lives in the public runtime config, so you can set it +through environment variables. The site key maps to +`NUXT_PUBLIC_FASTSTATS_SITE_KEY`. + +```bash title=".env" +NUXT_PUBLIC_FASTSTATS_SITE_KEY=your_site_key +``` + +If the site key is missing the module logs a warning during build so you notice +early. + +## Track Custom Events + +Import the functions from `@faststats/web` anywhere on the client. + +```vue title="pages/pricing.vue" + + + +``` + +## Track Server Errors + +Nuxt runs on Nitro, so you can report errors thrown in server routes with the +`@faststats/nitro` plugin. Install it and register the plugin that matches your +Nitro version. + +```sh +npm install @faststats/nitro +``` + +```ts title="nuxt.config.ts" +import { createRequire } from "node:module"; + +const require = createRequire(import.meta.url); +const errorTrackingPlugin = require.resolve("@faststats/nitro/v2"); + +export default defineNuxtConfig({ + modules: ["@faststats/nuxt"], + faststats: { + siteKey: "your_site_key", + }, + nitro: { + plugins: [errorTrackingPlugin], + }, +}); +``` + +The server plugin needs its own project token through `FASTSTATS_TOKEN`. Read the server section in [Error Tracking](/web-analytics/error-tracking) for the details. diff --git a/src/content/docs/web-analytics/react.mdx b/src/content/docs/web-analytics/react.mdx new file mode 100644 index 0000000..def0a1f --- /dev/null +++ b/src/content/docs/web-analytics/react.mdx @@ -0,0 +1,151 @@ +--- +title: React and Next.js +description: Add FastStats Web Analytics to a React or Next.js app +--- + +import { Aside, Tabs, TabItem } from '@astrojs/starlight/components'; + +The `@faststats/react` package wraps the browser SDK in a single component and a +set of hooks. It works with any React app and with the Next.js App Router. + +## Install + +```sh + npm install @faststats/react +``` + +## Add the Analytics Component + +Render the `Analytics` component once, near the root of your app. It starts +tracking when it mounts and cleans up when it unmounts. You never have to create +an instance by hand. + + + + +```tsx title="app/layout.tsx" +import { Analytics } from "@faststats/react"; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + + + {children} + + + ); +} +``` + + + + +```tsx title="src/main.tsx" +import { Analytics } from "@faststats/react"; +import { StrictMode } from "react"; +import { createRoot } from "react-dom/client"; +import App from "./App"; + +createRoot(document.getElementById("root")!).render( + + + + , +); +``` + + + + + +The component accepts every option from the SDK. Here is a fuller example that +turns on a few extra features. + +```tsx title="app/layout.tsx" + +``` + +See [Configuration](/web-analytics/configuration) for the full list. + +## Track Custom Events + +You can call the plain functions from anywhere, or use the hooks inside +components. Both reach the same active instance. + +```tsx title="components/buy-button.tsx" +"use client"; + +import { trackEvent } from "@faststats/react"; + +export function BuyButton() { + return ( + + ); +} +``` + +The same call through a hook looks like this. + +```tsx +"use client"; + +import { useTrack } from "@faststats/react"; + +export function BuyButton() { + const track = useTrack(); + return ( + + ); +} +``` + +`useEvent` builds a stable handler when the name and properties do not change. + +```tsx +const onSignup = useEvent("signup", { source: "hero" }); +return ( + +); +``` + +## Available Hooks + +| Hook | Returns | +| ---------------- | ------------------------------------------------- | +| `useTrack` | The `trackEvent` function | +| `useEvent` | A memoized handler for one named event | +| `useIdentify` | The `identify` function | +| `useLogout` | The `logout` function | +| `useConsentMode` | The `setConsentMode` function | +| `useOptIn` | The `optIn` function | +| `useOptOut` | The `optOut` function | +| `useFlag` | A feature flag value with loading and error state | + +Read more in [Events](/web-analytics/events), +[Identify](/web-analytics/identify) and +[Feature Flags](/web-analytics/feature-flags). + +## Server Side Routes + +The React package only runs in the browser. If you also want to capture errors +thrown in Next.js route handlers or server functions, read the server section in +[Error Tracking](/web-analytics/error-tracking). diff --git a/src/content/docs/web-analytics/session-replay.mdx b/src/content/docs/web-analytics/session-replay.mdx new file mode 100644 index 0000000..cff2f73 --- /dev/null +++ b/src/content/docs/web-analytics/session-replay.mdx @@ -0,0 +1,98 @@ +--- +title: Session Replay +description: Record DOM sessions with rrweb +--- + +import { Aside, Tabs, TabItem } from '@astrojs/starlight/components'; + +Session replay records DOM mutations and user interactions using +[rrweb](https://www.rrweb.io/). Recordings are serialized events, not video. + +## Enable Replay + +Turn it on with the object form. + + + + +```tsx + +``` + + + + +```ts title="nuxt.config.ts" +faststats: { + siteKey: "your_site_key", + sessionReplays: { enabled: true }, +} +``` + + + + +```ts +new WebAnalytics({ + siteKey: "your_site_key", + sessionReplays: { enabled: true }, +}); +``` + + + + + +## Batching + +Replay events are buffered in the browser and uploaded in chunks. The defaults +prefer fewer, larger chunks so a normal one-minute replay should usually create +single-digit storage objects instead of dozens. + +```ts +sessionReplays: { enabled: true }, +replayOptions: { + flushInterval: 5_000, + maxEvents: 1000, + maxBatchSizeBytes: 512 * 1024, +} +``` + +The collector coalesces these small reliable browser flushes into fewer storage +objects. The recorder still flushes early on page hide, session rotation, +periodic full snapshots, and when a batch reaches the byte limit. + +## Privacy and Masking + +The recorder masks inputs by default and lets you hide elements with +`replayOptions`. + +```ts +new WebAnalytics({ + siteKey: "your_site_key", + sessionReplays: { enabled: true }, + replayOptions: { + maskAllInputs: true, + maskTextSelector: ".sensitive", + blockSelector: ".no-record", + }, +}); +``` + +| Option | Type | Description | +| ------------------ | --------- | ------------------------------------------------- | +| `maskAllInputs` | `boolean` | Masks the value of every input field | +| `maskTextSelector` | `string` | Masks text inside elements matching this selector | +| `maskTextClass` | `string` | Masks text inside elements with this class | +| `blockSelector` | `string` | Skips recording elements matching this selector | +| `blockClass` | `string` | Skips recording elements with this class | +| `recordConsole` | `boolean` | Records console output during the session | + +Any element you mark with the block selector is replaced with a placeholder, so +its content never leaves the browser. + +## Cookieless Behavior + +Replay follows your consent setup. In cookieless or denied mode the recorder +stops and clears any buffered events, so nothing is recorded until consent is +granted. See [Consent and Cookieless](/web-analytics/consent). diff --git a/src/content/docs/web-analytics/sourcemaps.mdx b/src/content/docs/web-analytics/sourcemaps.mdx new file mode 100644 index 0000000..afeb65c --- /dev/null +++ b/src/content/docs/web-analytics/sourcemaps.mdx @@ -0,0 +1,242 @@ +--- +title: Sourcemaps +description: Upload JavaScript sourcemaps so FastStats can show readable stack traces. +--- + +import { Aside, Tabs, TabItem } from '@astrojs/starlight/components'; + +FastStats can turn minified browser stack traces back into the original file, +line and column when you upload the sourcemaps from the same build. + +The easiest way to do this is with `@faststats/sourcemap-uploader-plugin`. The +plugin runs during your production build, uploads every `.map` file it finds and +adds the build ID to your JavaScript bundle. The FastStats web SDK reads that +build ID when it reports an error, so FastStats can choose the matching +sourcemap. + +## Install the plugin + +Install the package in the app that builds your frontend. + +```sh +npm install --save-dev @faststats/sourcemap-uploader-plugin +``` + +You also need a sourcemap upload key from your FastStats project settings. Store +it as a secret in CI and pass it to the plugin with `authToken`. + +```bash title=".env" +FASTSTATS_SOURCEMAP_KEY=your_sourcemap_upload_key +``` + +## Add it to your bundler + +Turn on sourcemap output in your bundler, then add the FastStats plugin. The +default upload endpoint is `https://sourcemaps.faststats.dev/v0/upload`, so most +projects only need to pass `authToken`. + + + + +```ts title="vite.config.ts" +import { defineConfig } from "vite"; +import sourcemapsPlugin from "@faststats/sourcemap-uploader-plugin/vite"; + +export default defineConfig({ + build: { + sourcemap: true, + }, + plugins: [ + sourcemapsPlugin({ + authToken: process.env.FASTSTATS_SOURCEMAP_KEY, + }), + ], +}); +``` + + + + +```ts title="rollup.config.ts" +import sourcemapsPlugin from "@faststats/sourcemap-uploader-plugin/rollup"; + +export default { + input: "src/index.ts", + output: { + dir: "dist", + format: "es", + sourcemap: true, + }, + plugins: [ + sourcemapsPlugin({ + authToken: process.env.FASTSTATS_SOURCEMAP_KEY, + }), + ], +}; +``` + + + + +```ts title="webpack.config.ts" +import sourcemapsPlugin from "@faststats/sourcemap-uploader-plugin/webpack"; + +export default { + devtool: "source-map", + plugins: [ + sourcemapsPlugin({ + authToken: process.env.FASTSTATS_SOURCEMAP_KEY, + }), + ], +}; +``` + + + + +```ts title="rspack.config.ts" +import sourcemapsPlugin from "@faststats/sourcemap-uploader-plugin/rspack"; + +export default { + devtool: "source-map", + plugins: [ + sourcemapsPlugin({ + authToken: process.env.FASTSTATS_SOURCEMAP_KEY, + }), + ], +}; +``` + + + + +```ts title="build.ts" +import { build } from "esbuild"; +import sourcemapsPlugin from "@faststats/sourcemap-uploader-plugin/esbuild"; + +await build({ + entryPoints: ["src/index.ts"], + bundle: true, + sourcemap: true, + outfile: "dist/app.js", + plugins: [ + sourcemapsPlugin({ + authToken: process.env.FASTSTATS_SOURCEMAP_KEY, + }), + ], +}); +``` + + + + +The package also exports `rolldown`, `farm`, `bun` and `unloader` adapters. Use +the adapter that matches your bundler and keep sourcemap output enabled. + +## Recommended production setup + +Run the upload as part of the same CI job that builds and deploys your frontend. +Keep the upload key in your CI secrets. + +```yaml title="GitHub Actions" +name: Build + +on: + push: + branches: + - main + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + + - run: npm ci + - run: npm run build + env: + FASTSTATS_SOURCEMAP_KEY: ${{ secrets.FASTSTATS_SOURCEMAP_KEY }} +``` + +If your public site does not need to serve sourcemaps, set +`deleteAfterUpload: true`. The plugin deletes local `.map` files only after a +successful upload. + +```ts +sourcemapsPlugin({ + authToken: process.env.FASTSTATS_SOURCEMAP_KEY, + deleteAfterUpload: true, +}); +``` + +## Build IDs + +Every upload has a `buildId`. The browser error reporter sends the same build ID +with each error, which is how FastStats finds the right sourcemap. + +By default the plugin uses the current git commit hash. If git is not available, +it creates a random ID for that build. You can also set the ID yourself. + +```ts +sourcemapsPlugin({ + authToken: process.env.FASTSTATS_SOURCEMAP_KEY, + buildId: process.env.GITHUB_SHA, +}); +``` + +## Options + +`authToken` is the bearer token used to upload sourcemaps. You should almost +always set it from an environment variable. + +`endpoint` changes where sourcemaps are uploaded. Use this only if you are using +a self hosted sourcemap service. + +`buildId` sets the build ID manually. If you leave it empty, the plugin uses the +current git commit hash when it can. + +`deleteAfterUpload` removes `.map` files after a successful upload. + +`failOnError` controls whether a failed upload fails the build. It is `true` by +default. + +`enabled` can turn the plugin on or off. It accepts a boolean or a function that +receives the bundler name. + +`maxUploadBodyBytes` controls the largest upload request body. The default is 50 +MB. Larger sourcemap sets are split into multiple upload requests. + +`globalKey` changes the runtime global used for build metadata. The default is +`__SOURCEMAPS_BUILD__`. + +`onUploadSuccess` and `onUploadError` let you run custom code after an upload +succeeds or fails. + +## What the plugin uploads + +The plugin sends JSON to `/v0/upload` with the mapping type, build ID, upload +time and sourcemap files. + +```json +{ + "type": "javascript", + "buildId": "build-123", + "uploadedAt": "2026-04-01T12:00:00.000Z", + "files": [ + { + "fileName": "assets/app.js.map", + "content": "{...}" + } + ] +} +``` + +The request uses bearer auth with your sourcemap upload key. + +```txt +Authorization: Bearer +``` diff --git a/src/content/docs/web-analytics/web-vitals.mdx b/src/content/docs/web-analytics/web-vitals.mdx new file mode 100644 index 0000000..8ddf443 --- /dev/null +++ b/src/content/docs/web-analytics/web-vitals.mdx @@ -0,0 +1,73 @@ +--- +title: Web Vitals +description: Report Core Web Vitals from the browser SDK +--- + +import { Aside, Tabs, TabItem } from '@astrojs/starlight/components'; + +Set `webVitals.enabled` to report LCP, CLS, INP, FCP, and TTFB from visitor +sessions. + +## Enable Web Vitals + +Turn the feature on with the object form so you can also set attribution. + + + + +```tsx + +``` + + + + +```ts title="nuxt.config.ts" +faststats: { + siteKey: "your_site_key", + webVitals: { enabled: true }, +} +``` + + + + +```ts +new WebAnalytics({ + siteKey: "your_site_key", + webVitals: { enabled: true }, +}); +``` + + + + + +## Collected Metrics + +The tracker reports the standard set of Core Web Vitals. + +| Metric | Name | +| ------ | ------------------------- | +| `LCP` | Largest Contentful Paint | +| `CLS` | Cumulative Layout Shift | +| `INP` | Interaction to Next Paint | +| `FCP` | First Contentful Paint | +| `TTFB` | Time to First Byte | + +Each metric is sent with its value, an id, a rating and the navigation type. +Metrics are flushed when the page is hidden and when the route changes in a +single page app. + +## Attribution + +Turn on `attribution` to include extra debugging data that points to the element +or event responsible for a metric. This payload is larger, so leave it off +unless you are chasing a specific issue. + +```ts +webVitals: { + enabled: true, + attribution: true, +} +``` diff --git a/starlight.config.ts b/starlight.config.ts index 4c2741d..044b229 100644 --- a/starlight.config.ts +++ b/starlight.config.ts @@ -42,6 +42,7 @@ export const baseStarlightOptions: StarlightUserConfig = { components: { Sidebar: './src/components/starlight/Sidebar.astro', ContentPanel: './src/components/starlight/ContentPanel.astro', + PageFrame: './src/components/starlight/PageFrame.astro', }, routeMiddleware: './src/routeData.ts', diff --git a/starlight.sidebar.ts b/starlight.sidebar.ts index c529ffc..caf845d 100644 --- a/starlight.sidebar.ts +++ b/starlight.sidebar.ts @@ -83,15 +83,31 @@ export const sidebarConfig: StarlightSidebarTopicsUserConfig = [ items: [ { label: 'Getting Started', - items: [] + items: [ + 'web-analytics', + 'web-analytics/react', + 'web-analytics/nuxt', + 'web-analytics/javascript', + ] }, { label: 'Usage', - items: [] + items: [ + 'web-analytics/configuration', + 'web-analytics/events', + 'web-analytics/identify', + 'web-analytics/consent', + ] }, { label: 'Features', - items: [] + items: [ + 'web-analytics/error-tracking', + 'web-analytics/sourcemaps', + 'web-analytics/web-vitals', + 'web-analytics/session-replay', + 'web-analytics/feature-flags', + ] } ] } From d5c416fe92feaa317e4a316edab561fa54b75ddc Mon Sep 17 00:00:00 2001 From: Adam Matthiesen Date: Mon, 6 Jul 2026 14:44:03 -0700 Subject: [PATCH 25/40] feat: enhance documentation with ReadMore components for better navigation --- src/content/docs/web-analytics/configuration.mdx | 10 ++++++++++ src/content/docs/web-analytics/events.mdx | 8 ++++++-- src/content/docs/web-analytics/index.mdx | 9 ++++++--- src/content/docs/web-analytics/nuxt.mdx | 6 ++++++ src/content/docs/web-analytics/react.mdx | 7 +++++++ 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/content/docs/web-analytics/configuration.mdx b/src/content/docs/web-analytics/configuration.mdx index 13c8a1a..70fa60f 100644 --- a/src/content/docs/web-analytics/configuration.mdx +++ b/src/content/docs/web-analytics/configuration.mdx @@ -3,6 +3,8 @@ title: Configuration description: Every option you can pass to FastStats Web Analytics --- +import ReadMore from '@/components/ReadMore.astro'; + All packages share the same set of options. In React you pass them as props on the `Analytics` component, in Nuxt you set them under the `faststats` key, and in plain JavaScript you pass them to the `WebAnalytics` constructor. @@ -31,7 +33,9 @@ errorTracking: { | --------- | --------- | ------- | -------------------- | | `enabled` | `boolean` | `false` | Turns the tracker on | + Read more in [Error Tracking](/web-analytics/error-tracking). + ### Web Vitals @@ -47,7 +51,9 @@ webVitals: { | `enabled` | `boolean` | `false` | Turns the tracker on | | `attribution` | `boolean` | `false` | Adds debug attribution data to each metric | + Read more in [Web Vitals](/web-analytics/web-vitals). + ### Session Replays @@ -69,8 +75,10 @@ replayOptions: { | `replayOptions.maxEvents` | `number` | `1000` | Flush after this many buffered rrweb events | | `replayOptions.maxBatchSizeBytes` | `number` | `524288` | Flush after the buffered event payload reaches this size | + For masking and recording details see [Session Replay](/web-analytics/session-replay). + ### Consent @@ -86,7 +94,9 @@ consent: { | `mode` | `"pending" \| "granted" \| "denied"` | `"granted"` | The current consent state | | `pendingBehavior` | `"anonymous" \| "disabled"` | `"anonymous"` | Cookieless tracking while consent is pending, or no tracking at all | + Read more in [Consent and Cookieless](/web-analytics/consent). + ## Manual Start diff --git a/src/content/docs/web-analytics/events.mdx b/src/content/docs/web-analytics/events.mdx index 3df70ce..b116015 100644 --- a/src/content/docs/web-analytics/events.mdx +++ b/src/content/docs/web-analytics/events.mdx @@ -3,6 +3,7 @@ title: Events description: Automatic tracking and custom events --- +import ReadMore from '@/components/ReadMore.astro'; import { Tabs, TabItem } from '@astrojs/starlight/components'; The SDK sends `pageview`, `page_leave`, and `outbound_link` events @@ -24,8 +25,11 @@ spent on the page, the deepest scroll depth in percent and the session duration. Single page navigation is detected through the History API, so `pushState`, `replaceState` and the back and forward buttons all create new page views. Hash -based routers need `trackHash` turned on. See -[Configuration](/web-analytics/configuration). +based routers need `trackHash` turned on. + + +See [Configuration](/web-analytics/configuration). + ## Custom Events diff --git a/src/content/docs/web-analytics/index.mdx b/src/content/docs/web-analytics/index.mdx index 6f32d50..0a3f449 100644 --- a/src/content/docs/web-analytics/index.mdx +++ b/src/content/docs/web-analytics/index.mdx @@ -3,6 +3,7 @@ title: Installation description: Add FastStats Web Analytics to your website or web app --- +import ReadMore from '@/components/ReadMore.astro'; import { Aside, Tabs, TabItem } from '@astrojs/starlight/components';