From 80ad5a7d71893e5d3289ae34d7e053afb28200c5 Mon Sep 17 00:00:00 2001 From: Nate Date: Fri, 20 Mar 2026 13:46:07 -0700 Subject: [PATCH 1/7] docs: add BUILD_DEPENDENCIES.md cataloging all secrets and env vars Documents all GitHub Actions secrets, publishing tokens, AI provider keys, and CI/CD dependencies organized by category. Co-Authored-By: Claude Opus 4.6 (1M context) --- BUILD_DEPENDENCIES.md | 104 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 BUILD_DEPENDENCIES.md diff --git a/BUILD_DEPENDENCIES.md b/BUILD_DEPENDENCIES.md new file mode 100644 index 0000000000..d174daa37e --- /dev/null +++ b/BUILD_DEPENDENCIES.md @@ -0,0 +1,104 @@ +# Build Dependencies & Secrets + +This document catalogs all build dependencies, secrets, and environment variables required by the continue-fork repository. + +--- + +## VS Code Extension + +| Secret | Purpose | Referenced In | +|--------|---------|---------------| +| `VSCE_TOKEN` | Personal access token for publishing to the VS Code Marketplace (set as `VSCE_PAT`) | `main.yaml`, `preview.yaml` | +| `VSX_REGISTRY_TOKEN` | Token for publishing to the Open VSX Registry | `main.yaml`, `preview.yaml` | + +--- + +## JetBrains Extension + +| Secret | Purpose | Referenced In | +|--------|---------|---------------| +| `APPLE_CERT_DATA` | Base64-encoded Apple signing certificate (p12) for macOS code signing | `jetbrains-release.yaml` | +| `APPLE_CERT_PASSWORD` | Password for the Apple signing certificate | `jetbrains-release.yaml` | +| `APPLE_NOTARY_USER` | Apple notarization username (currently commented out) | `jetbrains-release.yaml` | +| `APPLE_NOTARY_PASSWORD` | Apple notarization password (currently commented out) | `jetbrains-release.yaml` | +| `JETBRAINS_PUBLISH_TOKEN` | Token for publishing to JetBrains Marketplace | `jetbrains-release.yaml` | +| `JETBRAINS_CERTIFICATE_CHAIN` | Certificate chain for signing the JetBrains plugin | `jetbrains-release.yaml` | +| `JETBRAINS_PRIVATE_KEY` | Private key for signing the JetBrains plugin | `jetbrains-release.yaml` | +| `JETBRAINS_PRIVATE_KEY_PASSWORD` | Password for the JetBrains signing private key | `jetbrains-release.yaml` | + +--- + +## CLI + +| Variable | Purpose | Referenced In | +|----------|---------|---------------| +| `CONTINUE_API_BASE` | Base URL for the Continue API (defaults to `https://api.continue.dev/`) | `extensions/cli/.env.example` | +| `CONTINUE_API_KEY` | API key for Continue authentication | `extensions/cli/.env.example`, `packages/continue-sdk/typescript/.env.example`, multiple workflows | + +--- + +## NPM Package Releases + +| Secret | Purpose | Referenced In | +|--------|---------|---------------| +| `SEMANTIC_RELEASE_GITHUB_TOKEN` | GitHub token used by semantic-release for creating releases | `release-openai-adapters.yml`, `release-config-yaml.yml`, `release-fetch.yml`, `release-llm-info.yml`, `reusable-release.yml` | +| `SEMANTIC_RELEASE_NPM_TOKEN` | npm token used by semantic-release for publishing packages | `release-openai-adapters.yml`, `release-config-yaml.yml`, `release-fetch.yml`, `release-llm-info.yml`, `reusable-release.yml` | +| `SEMANTIC_RELEASE_TOKEN` | GitHub token for stable release workflow | `stable-release.yml` | + +--- + +## AI Provider API Keys (Testing & Releases) + +Used for integration tests in PR checks and package releases. + +| Secret | Purpose | Referenced In | +|--------|---------|---------------| +| `OPENAI_API_KEY` | OpenAI API key | `pr-checks.yaml`, `reusable-release.yml`, `release-*.yml` | +| `ANTHROPIC_API_KEY` | Anthropic API key | `pr-checks.yaml`, `reusable-release.yml`, `release-*.yml`, `cli-pr-checks.yml`, `continue-agents.yml` | +| `GEMINI_API_KEY` | Google Gemini API key | `pr-checks.yaml`, `reusable-release.yml`, `release-*.yml` | +| `MISTRAL_API_KEY` | Mistral API key | `pr-checks.yaml`, `reusable-release.yml`, `release-*.yml` | +| `AZURE_OPENAI_API_KEY` | Azure OpenAI API key | `pr-checks.yaml`, `reusable-release.yml`, `release-*.yml` | +| `AZURE_FOUNDRY_CODESTRAL_API_KEY` | Azure AI Foundry Codestral API key | `pr-checks.yaml`, `reusable-release.yml`, `release-*.yml` | +| `AZURE_FOUNDRY_MISTRAL_SMALL_API_KEY` | Azure AI Foundry Mistral Small API key | `pr-checks.yaml`, `reusable-release.yml`, `release-*.yml` | +| `AZURE_OPENAI_GPT41_API_KEY` | Azure OpenAI GPT-4.1 API key | `pr-checks.yaml`, `reusable-release.yml`, `release-*.yml` | +| `VOYAGE_API_KEY` | Voyage AI embeddings API key | `pr-checks.yaml`, `reusable-release.yml`, `release-*.yml` | +| `RELACE_API_KEY` | Relace API key | `pr-checks.yaml`, `reusable-release.yml`, `release-*.yml` | +| `INCEPTION_API_KEY` | Inception API key | `pr-checks.yaml`, `reusable-release.yml`, `release-*.yml` | + +--- + +## CI/CD & GitHub + +| Secret | Purpose | Referenced In | +|--------|---------|---------------| +| `GITHUB_TOKEN` | Default GitHub Actions token (automatic) | Many workflows | +| `CI_GITHUB_TOKEN` | Elevated GitHub PAT for cross-repo operations and PR management | `jetbrains-release.yaml`, `preview.yaml`, `main.yaml`, `pr-checks.yaml`, `auto-assign-issue.yaml` | +| `CONTINUE_API_KEY` | Continue platform API key for agent workflows | `run-continue-agent.yml`, `tidy-up-codebase.yml`, `snyk-agent.yaml`, `auto-fix-failed-tests.yml`, `cli-pr-checks.yml` | +| `RUNLOOP_API_KEY` | Runloop API key for uploading sandbox blueprints | `stable-release.yml`, `upload-runloop-blueprint.yml` | +| `SNYK_TOKEN` | Snyk security scanning token | `snyk-agent.yaml` | + +--- + +## Issue/PR Tooling + +| Secret | Purpose | Referenced In | +|--------|---------|---------------| +| `CHROMA_CLOUD_API_KEY` | Chroma vector DB API key for similar issue detection | `similar-issues.yml` | +| `CHROMA_TENANT` | Chroma tenant identifier | `similar-issues.yml` | +| `CHROMA_DATABASE` | Chroma database name | `similar-issues.yml` | +| `ISSUE_PR_METRICS_SLACK_WEBHOOK_URL` | Slack webhook for PR/issue metrics notifications | `metrics.yaml` | + +--- + +## SSH Testing + +| Secret | Purpose | Referenced In | +|--------|---------|---------------| +| `GH_ACTIONS_SSH_TEST_KEY_PEM` | SSH private key for remote connection tests | `pr-checks.yaml` | +| `GH_ACTIONS_SSH_TEST_DNS_NAME` | DNS name of the SSH test host | `pr-checks.yaml` | + +--- + +All workflow files are located under `.github/workflows/`. Environment example files are at: +- `extensions/cli/.env.example` +- `packages/continue-sdk/typescript/.env.example` From 606fba91a3c5f33d148679072bd4cde4d398a49d Mon Sep 17 00:00:00 2001 From: Nate Date: Fri, 20 Mar 2026 13:52:25 -0700 Subject: [PATCH 2/7] feat: add docs site as static Next.js export Migrates the docs site from remote-config-server to this repo as a standalone static Next.js app. Key changes: - Copy app-docs from remote-config-server to docs-site/ - Configure `output: 'export'` for static HTML generation - Replace API routes with build-time scripts (search index, image copy) - Add generateStaticParams() to enumerate all doc slugs at build time - Convert server-side redirects to client-side redirects - Point DOCS_DIR to sibling ../docs directory - Add GitHub Actions workflow for deploying to GitHub Pages - Add missing Radix UI dependencies (accordion, tabs) to package.json Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/docs-gh-pages.yml | 55 + .gitignore | 1 + docs-site/.gitignore | 5 + docs-site/app/[[...slug]]/page.tsx | 118 + docs-site/app/components/ClientRedirect.tsx | 17 + docs-site/app/components/NotFoundPage.tsx | 12 + docs-site/app/docs.css | 336 + docs-site/app/globals.css | 3 + docs-site/app/layout.tsx | 42 + docs-site/components/docs/CopyPageButton.tsx | 28 + docs-site/components/docs/DocsSearch.tsx | 142 + docs-site/components/docs/DocsShell.tsx | 402 ++ docs-site/components/docs/PageNav.tsx | 42 + docs-site/components/docs/TableOfContents.tsx | 59 + docs-site/components/docs/mdx/Callout.tsx | 48 + docs-site/components/docs/mdx/CardGroup.tsx | 79 + docs-site/components/docs/mdx/CodeBlock.tsx | 80 + docs-site/components/docs/mdx/CodeGroup.tsx | 75 + docs-site/components/docs/mdx/Columns.tsx | 21 + .../components/docs/mdx/DocsAccordion.tsx | 88 + docs-site/components/docs/mdx/DocsTabs.tsx | 55 + docs-site/components/docs/mdx/MdxLink.tsx | 18 + .../docs/mdx/ModelRecommendations.tsx | 162 + .../components/docs/mdx/OSAutoDetect.tsx | 25 + docs-site/components/docs/mdx/Steps.tsx | 55 + docs-site/components/docs/mdx/index.tsx | 70 + docs-site/components/ui/command.tsx | 161 + docs-site/components/ui/dialog.tsx | 123 + docs-site/config/docsNav.ts | 72 + docs-site/lib/docs.ts | 296 + docs-site/lib/resolveHref.ts | 19 + docs-site/lib/utils.ts | 6 + docs-site/next-env.d.ts | 6 + docs-site/next.config.js | 12 + docs-site/package-lock.json | 6041 +++++++++++++++++ docs-site/package.json | 50 + docs-site/postcss.config.js | 6 + .../public/images/continue-logo-light.png | Bin 0 -> 32528 bytes docs-site/scripts/build-search-index.ts | 107 + docs-site/scripts/copy-doc-images.ts | 62 + docs-site/tailwind.config.ts | 14 + docs-site/tsconfig.json | 41 + 42 files changed, 9054 insertions(+) create mode 100644 .github/workflows/docs-gh-pages.yml create mode 100644 docs-site/.gitignore create mode 100644 docs-site/app/[[...slug]]/page.tsx create mode 100644 docs-site/app/components/ClientRedirect.tsx create mode 100644 docs-site/app/components/NotFoundPage.tsx create mode 100644 docs-site/app/docs.css create mode 100644 docs-site/app/globals.css create mode 100644 docs-site/app/layout.tsx create mode 100644 docs-site/components/docs/CopyPageButton.tsx create mode 100644 docs-site/components/docs/DocsSearch.tsx create mode 100644 docs-site/components/docs/DocsShell.tsx create mode 100644 docs-site/components/docs/PageNav.tsx create mode 100644 docs-site/components/docs/TableOfContents.tsx create mode 100644 docs-site/components/docs/mdx/Callout.tsx create mode 100644 docs-site/components/docs/mdx/CardGroup.tsx create mode 100644 docs-site/components/docs/mdx/CodeBlock.tsx create mode 100644 docs-site/components/docs/mdx/CodeGroup.tsx create mode 100644 docs-site/components/docs/mdx/Columns.tsx create mode 100644 docs-site/components/docs/mdx/DocsAccordion.tsx create mode 100644 docs-site/components/docs/mdx/DocsTabs.tsx create mode 100644 docs-site/components/docs/mdx/MdxLink.tsx create mode 100644 docs-site/components/docs/mdx/ModelRecommendations.tsx create mode 100644 docs-site/components/docs/mdx/OSAutoDetect.tsx create mode 100644 docs-site/components/docs/mdx/Steps.tsx create mode 100644 docs-site/components/docs/mdx/index.tsx create mode 100644 docs-site/components/ui/command.tsx create mode 100644 docs-site/components/ui/dialog.tsx create mode 100644 docs-site/config/docsNav.ts create mode 100644 docs-site/lib/docs.ts create mode 100644 docs-site/lib/resolveHref.ts create mode 100644 docs-site/lib/utils.ts create mode 100644 docs-site/next-env.d.ts create mode 100644 docs-site/next.config.js create mode 100644 docs-site/package-lock.json create mode 100644 docs-site/package.json create mode 100644 docs-site/postcss.config.js create mode 100644 docs-site/public/images/continue-logo-light.png create mode 100644 docs-site/scripts/build-search-index.ts create mode 100644 docs-site/scripts/copy-doc-images.ts create mode 100644 docs-site/tailwind.config.ts create mode 100644 docs-site/tsconfig.json diff --git a/.github/workflows/docs-gh-pages.yml b/.github/workflows/docs-gh-pages.yml new file mode 100644 index 0000000000..7a01eaefa7 --- /dev/null +++ b/.github/workflows/docs-gh-pages.yml @@ -0,0 +1,55 @@ +name: Deploy Docs to GitHub Pages + +on: + push: + branches: [main] + paths: + - "docs/**" + - "docs-site/**" + + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm + cache-dependency-path: docs-site/package-lock.json + + - name: Install dependencies + working-directory: docs-site + run: npm ci + + - name: Build + working-directory: docs-site + run: npm run build + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: docs-site/out + + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index eeafe223e9..60305a04b6 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ downloads/ eggs/ .eggs/ lib/ +!docs-site/lib/ lib64/ parts/ sdist/ diff --git a/docs-site/.gitignore b/docs-site/.gitignore new file mode 100644 index 0000000000..9cb0d1a1e6 --- /dev/null +++ b/docs-site/.gitignore @@ -0,0 +1,5 @@ +.next/ +out/ +node_modules/ +public/search-index.json +public/images/docs/ diff --git a/docs-site/app/[[...slug]]/page.tsx b/docs-site/app/[[...slug]]/page.tsx new file mode 100644 index 0000000000..873aa13703 --- /dev/null +++ b/docs-site/app/[[...slug]]/page.tsx @@ -0,0 +1,118 @@ +import { compileMDX } from "next-mdx-remote/rsc"; +import NotFoundPage from "@/app/components/NotFoundPage"; +import { ClientRedirect } from "@/app/components/ClientRedirect"; +import { Metadata } from "next/types"; +import remarkGfm from "remark-gfm"; +import rehypeSlug from "rehype-slug"; +import rehypeAutolinkHeadings from "rehype-autolink-headings"; +import rehypePrismPlus from "rehype-prism-plus"; +import { loadMdxFile, getHeadings, getAllDocTitles, getAllDocSlugs, docsNav, resolveDocsRedirect, docsRedirects } from "@/lib/docs"; +import { getPageNavigation } from "@/config/docsNav"; +import { mdxComponents } from "@/components/docs/mdx"; +import { DocsShell } from "@/components/docs/DocsShell"; +import { PageNav } from "@/components/docs/PageNav"; +import { CopyPageButton } from "@/components/docs/CopyPageButton"; +import "../docs.css"; + +interface Props { + params: Promise<{ slug?: string[] }>; +} + +export async function generateStaticParams() { + const docSlugs = getAllDocSlugs(); + const params: { slug: string[] }[] = []; + + // Root page (index) + params.push({ slug: [] }); + + // All doc pages from navigation + for (const slug of docSlugs) { + params.push({ slug: slug.split("/") }); + } + + // All redirect source pages + for (const source of docsRedirects.keys()) { + params.push({ slug: source.split("/") }); + } + + return params; +} + +export async function generateMetadata({ params }: Props): Promise { + const { slug } = await params; + const doc = await loadMdxFile(slug || ["index"]); + if (!doc) return {}; + + return { + title: doc.frontmatter.title + ? `${doc.frontmatter.title} | Continue Docs` + : "Continue Docs", + description: doc.frontmatter.description || "", + }; +} + +export default async function DocsPage({ params }: Props) { + const { slug } = await params; + const slugPath = slug || ["index"]; + + // Check redirect first + const redirectTo = resolveDocsRedirect(slugPath); + if (redirectTo) { + const target = redirectTo.startsWith("http") ? redirectTo : `/docs${redirectTo}`; + return ; + } + + const doc = await loadMdxFile(slugPath); + if (!doc) { + return ; + } + + const headings = getHeadings(doc.content); + const titleMap = getAllDocTitles(); + + const { content } = await compileMDX({ + source: doc.content, + options: { + mdxOptions: { + remarkPlugins: [remarkGfm], + rehypePlugins: [ + rehypeSlug, + [ + rehypeAutolinkHeadings, + { + behavior: "wrap", + properties: { className: ["heading-anchor"] }, + }, + ], + [rehypePrismPlus, { ignoreMissing: true }], + ], + }, + }, + components: mdxComponents, + }); + + const currentSlug = (slug || ["index"]).join("/"); + const { prev, next } = getPageNavigation(docsNav, currentSlug, titleMap); + + return ( + + {doc.frontmatter.title && ( +
+

+ {doc.frontmatter.title} +

+ +
+ )} + {doc.frontmatter.description && ( +

+ {doc.frontmatter.description.replace(/\*\*/g, "")} +

+ )} +
{content}
+
+ +
+
+ ); +} diff --git a/docs-site/app/components/ClientRedirect.tsx b/docs-site/app/components/ClientRedirect.tsx new file mode 100644 index 0000000000..1623c4e998 --- /dev/null +++ b/docs-site/app/components/ClientRedirect.tsx @@ -0,0 +1,17 @@ +"use client"; + +import { useEffect } from "react"; + +export function ClientRedirect({ to }: { to: string }) { + useEffect(() => { + window.location.replace(to); + }, [to]); + + return ( +
+

+ Redirecting... +

+
+ ); +} diff --git a/docs-site/app/components/NotFoundPage.tsx b/docs-site/app/components/NotFoundPage.tsx new file mode 100644 index 0000000000..f0bd602d5c --- /dev/null +++ b/docs-site/app/components/NotFoundPage.tsx @@ -0,0 +1,12 @@ +import Link from "next/link"; + +export default function NotFoundPage() { + return ( +
+

Page not found

+ + Back to docs + +
+ ); +} diff --git a/docs-site/app/docs.css b/docs-site/app/docs.css new file mode 100644 index 0000000000..27a6d4dd90 --- /dev/null +++ b/docs-site/app/docs.css @@ -0,0 +1,336 @@ +/* Docs content typography — matches homepage palette */ + +:root { + --docs-text: rgb(0 0 0 / 0.7); + --docs-heading: rgb(0 0 0 / 0.85); + --docs-link: rgb(0 0 0 / 0.8); + --docs-link-underline: rgb(0 0 0 / 0.2); + --docs-link-underline-hover: rgb(0 0 0 / 0.6); + --docs-muted: rgb(0 0 0 / 0.5); + --docs-border: rgb(0 0 0 / 0.1); + --docs-border-light: rgb(0 0 0 / 0.06); + --docs-border-faint: rgb(0 0 0 / 0.05); + --docs-code-bg: rgb(0 0 0 / 0.03); + --docs-code-bg-solid: #f7f7f8; + --docs-code-border: rgb(0 0 0 / 0.06); + --docs-inline-code-bg: rgb(0 0 0 / 0.04); + --docs-anchor: rgb(0 0 0 / 0.2); + --docs-video-bg: rgb(0 0 0 / 0.03); +} + +.dark { + --docs-text: rgb(255 255 255 / 0.7); + --docs-heading: rgb(255 255 255 / 0.85); + --docs-link: rgb(255 255 255 / 0.8); + --docs-link-underline: rgb(255 255 255 / 0.2); + --docs-link-underline-hover: rgb(255 255 255 / 0.6); + --docs-muted: rgb(255 255 255 / 0.5); + --docs-border: rgb(255 255 255 / 0.1); + --docs-border-light: rgb(255 255 255 / 0.06); + --docs-border-faint: rgb(255 255 255 / 0.05); + --docs-code-bg: rgb(255 255 255 / 0.05); + --docs-code-bg-solid: #171717; + --docs-code-border: rgb(255 255 255 / 0.06); + --docs-inline-code-bg: rgb(255 255 255 / 0.06); + --docs-anchor: rgb(255 255 255 / 0.2); + --docs-video-bg: rgb(255 255 255 / 0.05); +} + +.docs-content { + color: var(--docs-text); + line-height: 1.75; +} + +.docs-content h1, +.docs-content h2, +.docs-content h3, +.docs-content h4 { + color: var(--docs-heading); + font-weight: 500; + letter-spacing: -0.01em; +} + +.docs-content h1 { + font-size: 2rem; + margin-bottom: 1em; +} + +.docs-content h2 { + margin-top: 2.5em; + margin-bottom: 0.75em; + font-size: 1.5rem; +} + +.docs-content h3 { + margin-top: 2em; + margin-bottom: 0.5em; + font-size: 1.25rem; +} + +.docs-content h4 { + margin-top: 1.5em; + margin-bottom: 0.5em; + font-size: 1.1rem; +} + +.docs-content p, +.docs-content .docs-p { + margin-bottom: 1.5em; +} + +.docs-content a:not(.no-underline) { + color: var(--docs-link); + text-decoration: underline; + text-underline-offset: 2px; + text-decoration-color: var(--docs-link-underline); + transition: text-decoration-color 0.2s; +} + +.docs-content a:not(.no-underline):hover { + text-decoration-color: var(--docs-link-underline-hover); +} + +.docs-content blockquote { + border-left: 2px solid var(--docs-border); + padding-left: 1.25em; + color: var(--docs-muted); + font-style: italic; +} + +.docs-content hr { + border: none; + border-top: 1px solid var(--docs-border-light); + margin: 2.5em 0; +} + +/* Code blocks */ +.docs-content pre { + background: var(--docs-code-bg); + border: 1px solid var(--docs-code-border); + border-radius: 6px; + padding: 0.75em 4em 0.75em 1em; + white-space: pre-wrap; + word-wrap: break-word; + font-size: 0.875em; + line-height: 1.6; + font-family: var(--font-geist-mono), ui-monospace, monospace; + margin-bottom: 1.5em; +} + +.docs-content code { + font-family: var(--font-geist-mono), ui-monospace, monospace; + font-size: 0.875em; +} + +.docs-content :not(pre) > code { + background: var(--docs-inline-code-bg); + padding: 0.15em 0.4em; + border-radius: 3px; +} + +/* Tables */ +.docs-content table { + width: 100%; + border-collapse: collapse; + margin: 1.5em 0; + font-size: 0.9em; +} + +.docs-content th { + text-align: left; + border-bottom: 1px solid var(--docs-border); + padding: 0.75em 1em; + font-weight: 500; + color: var(--docs-heading); +} + +.docs-content td { + border-bottom: 1px solid var(--docs-border-faint); + padding: 0.75em 1em; +} + +/* Lists */ +.docs-content ul { + padding-left: 1.5em; + margin-bottom: 1.5em; + list-style-type: disc; +} + +.docs-content ol { + padding-left: 1.5em; + margin-bottom: 1.5em; + list-style-type: decimal; +} + +.docs-content li { + margin-bottom: 0.5em; +} + +.docs-content li > ul, +.docs-content li > ol { + margin-top: 0.5em; + margin-bottom: 0; +} + +/* Images */ +.docs-content img { + max-width: 100%; + height: auto; + border-radius: 6px; + margin: 1.5em 0; +} + +/* Videos and iframes */ +.docs-content iframe { + max-width: 100%; + border-radius: 6px; + margin: 1.5em 0; +} + +.docs-content video { + max-width: 100%; + height: auto; + border-radius: 6px; + margin: 1.5em 0; + background: var(--docs-video-bg); +} + +/* Syntax highlighting — light GitHub-style theme */ +.docs-content .token.comment, +.docs-content .token.prolog, +.docs-content .token.doctype, +.docs-content .token.cdata { + color: #6a737d; +} + +.docs-content .token.punctuation { + color: #24292e; +} + +.docs-content .token.property, +.docs-content .token.tag, +.docs-content .token.constant, +.docs-content .token.symbol, +.docs-content .token.deleted { + color: #22863a; +} + +.docs-content .token.boolean, +.docs-content .token.number { + color: #005cc5; +} + +.docs-content .token.selector, +.docs-content .token.attr-name, +.docs-content .token.string, +.docs-content .token.char, +.docs-content .token.builtin, +.docs-content .token.inserted { + color: #032f62; +} + +.docs-content .token.operator, +.docs-content .token.entity, +.docs-content .token.url, +.docs-content .language-css .token.string, +.docs-content .style .token.string { + color: #d73a49; +} + +.docs-content .token.atrule, +.docs-content .token.attr-value, +.docs-content .token.keyword { + color: #d73a49; +} + +.docs-content .token.function, +.docs-content .token.class-name { + color: #6f42c1; +} + +.docs-content .token.regex, +.docs-content .token.important, +.docs-content .token.variable { + color: #e36209; +} + +.docs-content .token.key { + color: #005cc5; +} + +/* Syntax highlighting — dark GitHub-style theme */ +.dark .docs-content .token.comment, +.dark .docs-content .token.prolog, +.dark .docs-content .token.doctype, +.dark .docs-content .token.cdata { + color: #8b949e; +} + +.dark .docs-content .token.punctuation { + color: #c9d1d9; +} + +.dark .docs-content .token.property, +.dark .docs-content .token.tag, +.dark .docs-content .token.constant, +.dark .docs-content .token.symbol, +.dark .docs-content .token.deleted { + color: #7ee787; +} + +.dark .docs-content .token.boolean, +.dark .docs-content .token.number { + color: #79c0ff; +} + +.dark .docs-content .token.selector, +.dark .docs-content .token.attr-name, +.dark .docs-content .token.string, +.dark .docs-content .token.char, +.dark .docs-content .token.builtin, +.dark .docs-content .token.inserted { + color: #a5d6ff; +} + +.dark .docs-content .token.operator, +.dark .docs-content .token.entity, +.dark .docs-content .token.url, +.dark .docs-content .language-css .token.string, +.dark .docs-content .style .token.string { + color: #ff7b72; +} + +.dark .docs-content .token.atrule, +.dark .docs-content .token.attr-value, +.dark .docs-content .token.keyword { + color: #ff7b72; +} + +.dark .docs-content .token.function, +.dark .docs-content .token.class-name { + color: #d2a8ff; +} + +.dark .docs-content .token.regex, +.dark .docs-content .token.important, +.dark .docs-content .token.variable { + color: #ffa657; +} + +.dark .docs-content .token.key { + color: #79c0ff; +} + +/* Heading anchors from rehype-autolink-headings (behavior: wrap) */ +.docs-content h2 > a.heading-anchor, +.docs-content h3 > a.heading-anchor, +.docs-content h4 > a.heading-anchor { + color: inherit; + text-decoration: none !important; +} + +.docs-content h2 > a.heading-anchor:hover, +.docs-content h3 > a.heading-anchor:hover, +.docs-content h4 > a.heading-anchor:hover { + text-decoration: none !important; +} diff --git a/docs-site/app/globals.css b/docs-site/app/globals.css new file mode 100644 index 0000000000..b5c61c9567 --- /dev/null +++ b/docs-site/app/globals.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/docs-site/app/layout.tsx b/docs-site/app/layout.tsx new file mode 100644 index 0000000000..ea2ca44cdc --- /dev/null +++ b/docs-site/app/layout.tsx @@ -0,0 +1,42 @@ +import type { Metadata } from "next"; +import { GeistSans } from "geist/font/sans"; +import { GeistMono } from "geist/font/mono"; +import { ThemeProvider } from "next-themes"; +import "./globals.css"; +import "./docs.css"; + +export const metadata: Metadata = { + title: "Continue Docs", + description: "Documentation for Continue — the open-source AI code assistant.", +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + + + + + +
+ + {children} +
+
+ + + ); +} diff --git a/docs-site/components/docs/CopyPageButton.tsx b/docs-site/components/docs/CopyPageButton.tsx new file mode 100644 index 0000000000..73ec5c08a0 --- /dev/null +++ b/docs-site/components/docs/CopyPageButton.tsx @@ -0,0 +1,28 @@ +"use client"; + +import { useState } from "react"; +import { Check, Copy } from "lucide-react"; + +export function CopyPageButton({ slug }: { slug: string }) { + const [copied, setCopied] = useState(false); + + const handleCopy = async () => { + // Copy the visible page content + const content = document.querySelector(".docs-content"); + if (content) { + await navigator.clipboard.writeText(content.textContent || ""); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + } + }; + + return ( + + ); +} diff --git a/docs-site/components/docs/DocsSearch.tsx b/docs-site/components/docs/DocsSearch.tsx new file mode 100644 index 0000000000..c5857be98a --- /dev/null +++ b/docs-site/components/docs/DocsSearch.tsx @@ -0,0 +1,142 @@ +"use client"; + +import { useEffect, useRef, useState } from "react"; +import { useRouter } from "next/navigation"; +import { Search } from "lucide-react"; +import { + CommandDialog, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, +} from "@/components/ui/command"; +import { create, load, search, type AnyOrama } from "@orama/orama"; + +interface SearchResult { + title: string; + path: string; + content: string; + section: string; +} + +export function DocsSearch({ resolve }: { resolve: (path: string) => string }) { + const [open, setOpen] = useState(false); + const [query, setQuery] = useState(""); + const [results, setResults] = useState([]); + const [allDocs, setAllDocs] = useState([]); + const [loading, setLoading] = useState(false); + const dbRef = useRef(null); + const router = useRouter(); + + // Cmd+K keyboard shortcut + useEffect(() => { + function onKeyDown(e: KeyboardEvent) { + if (e.key === "k" && (e.metaKey || e.ctrlKey)) { + e.preventDefault(); + setOpen((prev) => !prev); + } + } + document.addEventListener("keydown", onKeyDown); + return () => document.removeEventListener("keydown", onKeyDown); + }, []); + + useEffect(() => { + if (!open || dbRef.current) return; + setLoading(true); + fetch("/search-index.json") + .then((res) => res.json()) + .then((data) => { + const db = create({ + schema: { + title: "string" as const, + path: "string" as const, + content: "string" as const, + section: "string" as const, + }, + }); + load(db, data); + dbRef.current = db; + // Get all docs for showing when query is empty + const allResult = search(db, { term: "", limit: 100 }); + const toResults = (r: typeof allResult) => + (r as Awaited).hits.map((hit: { document: unknown }) => hit.document as SearchResult); + setAllDocs(toResults(allResult)); + }) + .finally(() => setLoading(false)); + }, [open]); + + // Search when query changes + useEffect(() => { + if (!dbRef.current || !query.trim()) { + setResults([]); + return; + } + const res = search(dbRef.current, { + term: query, + limit: 10, + tolerance: 1, + boost: { title: 3, section: 1.5 }, + }) as Awaited>; + setResults(res.hits.map((hit: { document: unknown }) => hit.document as SearchResult)); + }, [query]); + + const displayResults = query.trim() ? results : allDocs; + + function handleSelect(path: string) { + setOpen(false); + setQuery(""); + router.push(resolve(`/docs/${path}`)); + } + + return ( + <> + + + + + {loading ? ( +
+ Loading search index... +
+ ) : ( + <> + No results found. + {displayResults.length > 0 && ( + + {displayResults.map((result) => ( + handleSelect(result.path)} + > +
+ {result.title} + + {result.content.slice(0, 120)} + +
+
+ ))} +
+ )} + + )} +
+
+ + ); +} diff --git a/docs-site/components/docs/DocsShell.tsx b/docs-site/components/docs/DocsShell.tsx new file mode 100644 index 0000000000..ec7ef01cca --- /dev/null +++ b/docs-site/components/docs/DocsShell.tsx @@ -0,0 +1,402 @@ +"use client"; + +import { useEffect, useState } from "react"; +import Link from "next/link"; +import { ChevronDown, Menu, Moon, Sun, X } from "lucide-react"; +import { useTheme } from "next-themes"; +import { type NavGroup, type NavItem, type NavTab } from "@/config/docsNav"; +import { TableOfContents } from "./TableOfContents"; +import { DocsSearch } from "./DocsSearch"; +import { resolveHref } from "@/lib/resolveHref"; +import type { Heading } from "@/lib/docs"; + +/* ------------------------------------------------------------------ */ +/* Helpers */ +/* ------------------------------------------------------------------ */ + +function containsSlug(group: NavGroup, slug: string): boolean { + return group.pages.some((item) => { + if (typeof item === "string") return item === slug; + return containsSlug(item, slug); + }); +} + +function findActiveTab(nav: NavTab[], slug: string) { + for (const tab of nav) { + for (const group of tab.groups) { + if (containsSlug(group, slug)) { + return tab; + } + } + } + return nav[nav.length - 1]; +} + +function slugToLabel(slug: string, titleMap?: Record) { + if (titleMap?.[slug]) return titleMap[slug]; + const name = slug.split("/").pop() || slug; + return name + .replace(/^\d+-/, "") + .replace(/-/g, " ") + .replace(/\b\w/g, (l) => l.toUpperCase()); +} + +/* ------------------------------------------------------------------ */ +/* Top nav constants */ +/* ------------------------------------------------------------------ */ + +const NAV_LINK_DEFS = [ + { label: "Docs", path: "/docs" }, + { label: "Blog", path: "/blog" }, +]; + +const NAV_LINKS = NAV_LINK_DEFS.map((d) => ({ + label: d.label, + href: resolveHref(d.path), +})); + +const NAV_LINK_CLASSES = + "text-[13px] text-black/40 dark:text-white/40 hover:text-black/70 dark:hover:text-white/70 transition-colors tracking-wide uppercase font-mono"; + +const SIDEBAR_W = "w-64"; // shared sidebar width token + +function ThemeToggle() { + const { resolvedTheme, setTheme } = useTheme(); + const [mounted, setMounted] = useState(false); + useEffect(() => setMounted(true), []); + + if (!mounted) { + return
; + } + + return ( + + ); +} + +/* ------------------------------------------------------------------ */ +/* Sidebar primitives */ +/* ------------------------------------------------------------------ */ + +function SidebarGroup({ + group, + currentSlug, + titleMap, + resolve, + depth = 0, +}: { + group: NavGroup; + currentSlug: string; + titleMap?: Record; + resolve: (path: string) => string; + depth?: number; +}) { + const isActive = containsSlug(group, currentSlug); + const [open, setOpen] = useState(group.expanded === true || isActive); + + // Top-level groups are static section headers (always open, not toggleable) + if (depth === 0) { + return ( +
+
+ {group.group} +
+
+ {group.pages.map((item, i) => ( + + ))} +
+
+ ); + } + + return ( +
+ + {open && ( +
+ {group.pages.map((item, i) => ( + + ))} +
+ )} +
+ ); +} + +function SidebarItem({ + item, + currentSlug, + titleMap, + resolve, + depth = 0, +}: { + item: NavItem; + currentSlug: string; + titleMap?: Record; + resolve: (path: string) => string; + depth?: number; +}) { + if (typeof item === "string") { + const isActive = item === currentSlug; + return ( + + {slugToLabel(item, titleMap)} + + ); + } + + return ( + + ); +} + +/* ------------------------------------------------------------------ */ +/* Main shell */ +/* ------------------------------------------------------------------ */ + +export function DocsShell({ + currentSlug, + headings, + titleMap, + docsNav, + children, +}: { + currentSlug: string; + headings: Heading[]; + titleMap?: Record; + docsNav: NavTab[]; + children: React.ReactNode; +}) { + const activeTab = findActiveTab(docsNav, currentSlug) ?? docsNav[0]!; + const [selectedTab, setSelectedTab] = useState(activeTab.tab); + const [mobileOpen, setMobileOpen] = useState(false); + const [mobileMenuOpen, setMobileMenuOpen] = useState(false); + const currentTab = + docsNav.find((t) => t.tab === selectedTab) ?? docsNav[0]!; + const navLinks = NAV_LINKS; + + return ( +
+ {/* ---- Header: nav + tabs ---- */} +
+ {/* Top nav bar */} + + + {/* Tab bar — aligned with sidebar */} +
+
+ {docsNav.map((tab) => ( + + ))} +
+
+
+ + {/* ---- Content area ---- */} +
+ {/* Desktop sidebar */} + + + {/* Main content */} +
{children}
+ + {/* Table of contents */} + +
+ + {/* ---- Mobile sidebar ---- */} + + + {mobileOpen && ( + <> +
setMobileOpen(false)} + /> + + + )} +
+ ); +} diff --git a/docs-site/components/docs/PageNav.tsx b/docs-site/components/docs/PageNav.tsx new file mode 100644 index 0000000000..decde67235 --- /dev/null +++ b/docs-site/components/docs/PageNav.tsx @@ -0,0 +1,42 @@ +"use client"; + +import Link from "next/link"; +import { ChevronLeft, ChevronRight } from "lucide-react"; +import { resolveHref } from "@/lib/resolveHref"; + +export function PageNav({ + prev, + next, +}: { + prev: { slug: string; title: string } | null; + next: { slug: string; title: string } | null; +}) { + if (!prev && !next) return null; + + return ( +
+ {prev ? ( + + + {prev.title} + + ) : ( +
+ )} + {next ? ( + + {next.title} + + + ) : ( +
+ )} +
+ ); +} diff --git a/docs-site/components/docs/TableOfContents.tsx b/docs-site/components/docs/TableOfContents.tsx new file mode 100644 index 0000000000..c9f5147ab9 --- /dev/null +++ b/docs-site/components/docs/TableOfContents.tsx @@ -0,0 +1,59 @@ +"use client"; + +import { useEffect, useState } from "react"; +import type { Heading } from "@/lib/docs"; + +export function TableOfContents({ headings }: { headings: Heading[] }) { + const [activeId, setActiveId] = useState(""); + + useEffect(() => { + const observer = new IntersectionObserver( + (entries) => { + for (const entry of entries) { + if (entry.isIntersecting) { + setActiveId(entry.target.id); + } + } + }, + { rootMargin: "0px 0px -80% 0px", threshold: 0 }, + ); + + for (const heading of headings) { + const el = document.getElementById(heading.id); + if (el) observer.observe(el); + } + + return () => observer.disconnect(); + }, [headings]); + + if (headings.length === 0) return null; + + return ( + + ); +} diff --git a/docs-site/components/docs/mdx/Callout.tsx b/docs-site/components/docs/mdx/Callout.tsx new file mode 100644 index 0000000000..468cf39769 --- /dev/null +++ b/docs-site/components/docs/mdx/Callout.tsx @@ -0,0 +1,48 @@ +import { Info, Lightbulb, AlertTriangle, FileText } from "lucide-react"; + +const variants = { + info: { + icon: Info, + borderColor: "border-blue-400", + bgColor: "bg-blue-50 dark:bg-blue-950", + iconColor: "text-blue-500", + }, + tip: { + icon: Lightbulb, + borderColor: "border-green-400", + bgColor: "bg-green-50 dark:bg-green-950", + iconColor: "text-green-500", + }, + warning: { + icon: AlertTriangle, + borderColor: "border-amber-400", + bgColor: "bg-amber-50 dark:bg-amber-950", + iconColor: "text-amber-500", + }, + note: { + icon: FileText, + borderColor: "border-gray-400", + bgColor: "bg-gray-50 dark:bg-gray-950", + iconColor: "text-gray-500", + }, +}; + +export function Callout({ + variant = "info", + children, +}: { + variant?: keyof typeof variants; + children: React.ReactNode; +}) { + const config = variants[variant] || variants.info; + const Icon = config.icon; + + return ( +
+ +
{children}
+
+ ); +} diff --git a/docs-site/components/docs/mdx/CardGroup.tsx b/docs-site/components/docs/mdx/CardGroup.tsx new file mode 100644 index 0000000000..f64e5498c2 --- /dev/null +++ b/docs-site/components/docs/mdx/CardGroup.tsx @@ -0,0 +1,79 @@ +"use client"; + +import Link from "next/link"; +import { resolveHref } from "@/lib/resolveHref"; + +export function CardGroup({ + cols = 2, + children, +}: { + cols?: number; + children: React.ReactNode; +}) { + const colClasses = { + 1: "grid-cols-1", + 2: "grid-cols-1 sm:grid-cols-2", + 3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3", + 4: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-4", + }; + const colClass = colClasses[Math.min(cols, 4) as 1 | 2 | 3 | 4] || colClasses[2]; + + return ( +
+ {children} +
+ ); +} + +export function Card({ + title, + icon, + href, + children, +}: { + title: string; + icon?: string; + href?: string; + children?: React.ReactNode; +}) { + const inner = ( +
+ {title && ( +

+ {title} +

+ )} + {children &&
{children}
} +
+ ); + + const resolve = resolveHref; + + if (href) { + const isExternal = href.startsWith("http"); + + if (isExternal) { + return ( + + {inner} + + ); + } + + const internalPath = href.startsWith("/docs") ? href : `/docs${href}`; + const resolved = resolve(internalPath); + + return ( + + {inner} + + ); + } + + return inner; +} diff --git a/docs-site/components/docs/mdx/CodeBlock.tsx b/docs-site/components/docs/mdx/CodeBlock.tsx new file mode 100644 index 0000000000..70281bdbbb --- /dev/null +++ b/docs-site/components/docs/mdx/CodeBlock.tsx @@ -0,0 +1,80 @@ +"use client"; + +import { useRef, useState } from "react"; + +// Hoisted static SVG elements to avoid recreation on every render (Rule 6.2) +const checkIcon = ( + + + +); + +const copyIcon = ( + + + + +); + +export function CodeBlock({ + children, + ...props +}: { + children: React.ReactNode; + className?: string; +}) { + const preRef = useRef(null); + const [copied, setCopied] = useState(false); + + const handleCopy = () => { + const text = preRef.current?.textContent || ""; + navigator.clipboard.writeText(text).then(() => { + setCopied(true); + setTimeout(() => setCopied(false), 2000); + }); + }; + + return ( +
+
+        {children}
+      
+ {/* Overlay: inset matches pre's border (1px) so gradient fills to the edge */} +
+
+ +
+
+
+ ); +} diff --git a/docs-site/components/docs/mdx/CodeGroup.tsx b/docs-site/components/docs/mdx/CodeGroup.tsx new file mode 100644 index 0000000000..141faa1472 --- /dev/null +++ b/docs-site/components/docs/mdx/CodeGroup.tsx @@ -0,0 +1,75 @@ +"use client"; + +import * as TabsPrimitive from "@radix-ui/react-tabs"; +import React, { Children, isValidElement } from "react"; + +/** + * CodeGroup renders multiple code blocks as tabs. + * Tab labels are derived from code block data-title attributes + * or fall back to "Tab 1", "Tab 2", etc. + */ +export function CodeGroup({ children }: { children: React.ReactNode }) { + const blocks: { label: string; content: React.ReactNode }[] = []; + + Children.forEach(children, (child) => { + if (!isValidElement(child)) return; + // After MDX compilation, each code block is wrapped by CodeBlock (a div > pre > code) + // Try to find a label from props + const props = child.props as Record; + let label = props["data-title"] || props.title || ""; + + if (!label && props.children) { + // Try to find label from the inner pre/code className + const text = extractTextContent(child); + // Guess label from package manager command (check longer names first) + if (text.includes("pnpm ")) label = "pnpm"; + else if (text.includes("yarn ")) label = "yarn"; + else if (text.includes("npm ")) label = "npm"; + else if (text.includes("bun ")) label = "bun"; + else if (text.includes("brew ")) label = "brew"; + else if (text.includes("pip ")) label = "pip"; + else if (text.includes("cargo ")) label = "cargo"; + } + + if (!label) label = `Tab ${blocks.length + 1}`; + blocks.push({ label, content: child }); + }); + + if (blocks.length === 0) return <>{children}; + if (blocks.length === 1) return <>{blocks[0]!.content}; + + return ( + + + {blocks.map((block, i) => ( + + {block.label} + + ))} + + {blocks.map((block, i) => ( + + {block.content} + + ))} + + ); +} + +function extractTextContent(element: React.ReactElement): string { + const props = element.props as Record; + if (typeof props.children === "string") return props.children; + if (Array.isArray(props.children)) { + return props.children + .map((c: any) => (typeof c === "string" ? c : isValidElement(c) ? extractTextContent(c) : "")) + .join(""); + } + if (isValidElement(props.children)) { + return extractTextContent(props.children); + } + return ""; +} diff --git a/docs-site/components/docs/mdx/Columns.tsx b/docs-site/components/docs/mdx/Columns.tsx new file mode 100644 index 0000000000..72676ee1e2 --- /dev/null +++ b/docs-site/components/docs/mdx/Columns.tsx @@ -0,0 +1,21 @@ +export function Columns({ + cols = 2, + children, +}: { + cols?: number; + children: React.ReactNode; +}) { + const colClasses = { + 1: "grid-cols-1", + 2: "grid-cols-1 sm:grid-cols-2", + 3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3", + 4: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-4", + }; + const colClass = colClasses[Math.min(cols, 4) as 1 | 2 | 3 | 4] || colClasses[2]; + + return ( +
+ {children} +
+ ); +} diff --git a/docs-site/components/docs/mdx/DocsAccordion.tsx b/docs-site/components/docs/mdx/DocsAccordion.tsx new file mode 100644 index 0000000000..a011cbd247 --- /dev/null +++ b/docs-site/components/docs/mdx/DocsAccordion.tsx @@ -0,0 +1,88 @@ +"use client"; + +import * as AccordionPrimitive from "@radix-ui/react-accordion"; +import { ChevronDown } from "lucide-react"; +import React, { Children, isValidElement } from "react"; + +export function DocsAccordionGroup({ + children, +}: { + children: React.ReactNode; +}) { + // Collect accordion items and assign unique values + const items: { title: string; content: React.ReactNode; value: string }[] = + []; + Children.forEach(children, (child, i) => { + if (isValidElement(child)) { + const props = child.props as Record; + if (props.title) { + items.push({ + title: props.title, + content: props.children, + value: `item-${i}`, + }); + } + } + }); + + if (items.length === 0) return <>{children}; + + return ( + + {items.map((item, i) => ( + 0 + ? "border-t border-black/[0.06] dark:border-white/[0.06]" + : "" + } + > + + {item.title} + + + +
+ {item.content} +
+
+
+ ))} +
+ ); +} + +export function DocsAccordion({ + title, + children, +}: { + title: string; + children: React.ReactNode; +}) { + // Standalone accordion (not inside a group) + return ( + + + + {title} + + + +
+ {children} +
+
+
+
+ ); +} diff --git a/docs-site/components/docs/mdx/DocsTabs.tsx b/docs-site/components/docs/mdx/DocsTabs.tsx new file mode 100644 index 0000000000..0aa31bc77c --- /dev/null +++ b/docs-site/components/docs/mdx/DocsTabs.tsx @@ -0,0 +1,55 @@ +"use client"; + +import * as TabsPrimitive from "@radix-ui/react-tabs"; +import React, { Children, isValidElement } from "react"; + +export function DocsTabs({ children }: { children: React.ReactNode }) { + const tabs: { title: string; content: React.ReactNode }[] = []; + + Children.forEach(children, (child) => { + if (isValidElement(child)) { + const props = child.props as Record; + // Check for title prop — the signature of a Tab child. + // We can't rely on displayName across the RSC serialization boundary. + if ("title" in props) { + tabs.push({ + title: props.title || `Tab ${tabs.length + 1}`, + content: props.children, + }); + } + } + }); + + if (tabs.length === 0) return <>{children}; + + return ( + + + {tabs.map((tab, i) => ( + + {tab.title} + + ))} + + {tabs.map((tab, i) => ( + + {tab.content} + + ))} + + ); +} + +export function DocsTab({ + children, +}: { + title?: string; + children: React.ReactNode; +}) { + return <>{children}; +} +DocsTab.displayName = "DocsTab"; diff --git a/docs-site/components/docs/mdx/MdxLink.tsx b/docs-site/components/docs/mdx/MdxLink.tsx new file mode 100644 index 0000000000..54738fd8e9 --- /dev/null +++ b/docs-site/components/docs/mdx/MdxLink.tsx @@ -0,0 +1,18 @@ +import { resolveHref } from "@/lib/resolveHref"; + +export function MdxLink({ + href, + children, + ...props +}: React.AnchorHTMLAttributes) { + if (href?.startsWith("/")) { + const internalPath = href.startsWith("/docs") ? href : `/docs${href}`; + href = resolveHref(internalPath); + } + + return ( + + {children} + + ); +} diff --git a/docs-site/components/docs/mdx/ModelRecommendations.tsx b/docs-site/components/docs/mdx/ModelRecommendations.tsx new file mode 100644 index 0000000000..af5d6e77e2 --- /dev/null +++ b/docs-site/components/docs/mdx/ModelRecommendations.tsx @@ -0,0 +1,162 @@ +const modelRecs: Record< + string, + { open: string[]; closed: string[]; notes: string } +> = { + agent_plan: { + open: [ + "[Qwen3 Coder (480B)](https://continue.dev/openrouter/qwen3-coder)", + "[Qwen3 Coder (30B)](https://continue.dev/ollama/qwen3-coder-30b)", + "[Devstral (27B)](https://continue.dev/ollama/devstral)", + "[Kimi K2 (1T)](https://continue.dev/openrouter/kimi-k2)", + ], + closed: [ + "[Claude Opus 4.1](https://continue.dev/anthropic/claude-4-1-opus)", + "[Claude Sonnet 4.6](https://continue.dev/anthropic/claude-sonnet-4-6)", + "[GPT-5](https://continue.dev/openai/gpt-5)", + "[Gemini 2.5 Pro](https://continue.dev/google/gemini-2.5-pro)", + ], + notes: "Closed models are slightly better than open models", + }, + chat_edit: { + open: [ + "[Qwen3 Coder (480B)](https://continue.dev/openrouter/qwen3-coder)", + "[Qwen3 Coder (30B)](https://continue.dev/ollama/qwen3-coder-30b)", + ], + closed: [ + "[Claude Opus 4.1](https://continue.dev/anthropic/claude-4-1-opus)", + "[Claude Sonnet 4.6](https://continue.dev/anthropic/claude-sonnet-4-6)", + "[GPT-5](https://continue.dev/openai/gpt-5)", + "[Gemini 2.5 Pro](https://continue.dev/google/gemini-2.5-pro)", + ], + notes: "Closed and open models have similar performance", + }, + autocomplete: { + open: [ + "[QwenCoder2.5 (1.5B)](https://continue.dev/ollama/qwen2.5-coder-1.5b)", + "[QwenCoder2.5 (7B)](https://continue.dev/ollama/qwen2.5-coder-7b)", + ], + closed: [ + "[Codestral](https://continue.dev/mistral/codestral)", + "[Mercury Coder](https://continue.dev/inception/mercury-coder)", + ], + notes: "Closed models are slightly better than open models", + }, + apply: { + open: ["[FastApply](https://continue.dev/mdpauley/fast-apply-15b-v10)"], + closed: [ + "[Relace Instant Apply](https://continue.dev/relace/instant-apply)", + "[Morph Fast Apply](https://continue.dev/morphllm/morph-v2)", + ], + notes: "Closed models are better than open models", + }, + embed: { + open: [ + "[Nomic Embed Text](https://continue.dev/ollama/nomic-embed-text-latest)", + ], + closed: [ + "[Voyage Code 3](https://continue.dev/voyageai/voyage-code-3)", + "[Morph Embeddings](https://continue.dev/morphllm/morph-embedding-v2)", + ], + notes: "Closed models are slightly better than open models", + }, + rerank: { + open: ["zerank-1", "zerank-1-small"], + closed: [ + "[Voyage Rerank 2.5](https://continue.dev/voyageai/rerank-2-5)", + "[Morph Rerank](https://continue.dev/morphllm/morph-rerank-v2)", + ], + notes: "Open models are beginning to emerge for this model role", + }, +}; + +function parseMarkdownLinks(text: string) { + const regex = /\[([^\]]+)\]\(([^)]+)\)/g; + const parts: React.ReactNode[] = []; + let lastIndex = 0; + let match; + let key = 0; + + while ((match = regex.exec(text)) !== null) { + if (match.index > lastIndex) { + parts.push({text.slice(lastIndex, match.index)}); + } + parts.push( + + {match[1]} + , + ); + lastIndex = regex.lastIndex; + } + + if (lastIndex < text.length) { + parts.push({text.slice(lastIndex)}); + } + + return parts.length > 0 ? parts : text; +} + +export function ModelRecommendations({ role = "all" }: { role?: string }) { + let rolesToShow: string[]; + + if (!role || role === "all") { + rolesToShow = Object.keys(modelRecs); + } else { + const key = role.toLowerCase().replace(/[\s/]/g, "_").replace(/-/g, "_"); + rolesToShow = modelRecs[key] ? [key] : []; + } + + if (rolesToShow.length === 0) { + return
No recommendations found for role: {role}
; + } + + return ( +
+ + + + + + + + + + + {rolesToShow.map((roleKey) => { + const rec = modelRecs[roleKey]; + if (!rec) return null; + return ( + + + + + + + ); + })} + +
Model roleBest open modelsBest closed modelsNotes
+ {roleKey + .replace(/_/g, " ") + .replace(/\b\w/g, (l) => l.toUpperCase())} + + {rec.open.map((m, i) => ( +
+ {parseMarkdownLinks(m)} +
+ ))} +
+ {rec.closed.map((m, i) => ( +
+ {parseMarkdownLinks(m)} +
+ ))} +
{rec.notes}
+
+ ); +} diff --git a/docs-site/components/docs/mdx/OSAutoDetect.tsx b/docs-site/components/docs/mdx/OSAutoDetect.tsx new file mode 100644 index 0000000000..9e7f388bfd --- /dev/null +++ b/docs-site/components/docs/mdx/OSAutoDetect.tsx @@ -0,0 +1,25 @@ +"use client"; + +import { useEffect } from "react"; + +export function OSAutoDetect() { + useEffect(() => { + const ua = navigator.userAgent.toLowerCase(); + const isWindows = ua.includes("win"); + const isMac = ua.includes("mac"); + const isLinux = ua.includes("linux"); + + let tabIndex = 2; // default: npm + if (isMac || isLinux) tabIndex = 0; + else if (isWindows) tabIndex = 1; + + const tabButtons = document.querySelectorAll( + '[role="tablist"] button', + ); + if (tabButtons[tabIndex]) { + (tabButtons[tabIndex] as HTMLButtonElement).click(); + } + }, []); + + return null; +} diff --git a/docs-site/components/docs/mdx/Steps.tsx b/docs-site/components/docs/mdx/Steps.tsx new file mode 100644 index 0000000000..792de0ec51 --- /dev/null +++ b/docs-site/components/docs/mdx/Steps.tsx @@ -0,0 +1,55 @@ +import React from "react"; + +export function Steps({ children }: { children: React.ReactNode }) { + const childArray = React.Children.toArray(children).filter( + React.isValidElement, + ); + return ( +
+ {childArray.map((child, index) => + React.cloneElement(child as React.ReactElement, { + stepNumber: index + 1, + isLast: index === childArray.length - 1, + }), + )} +
+ ); +} + +export function Step({ + title, + stepNumber, + isLast, + children, +}: { + title?: string; + stepNumber?: number; + isLast?: boolean; + children: React.ReactNode; +}) { + return ( +
+ {/* Numbered circle */} +
+ + {stepNumber} + +
+ {/* Connecting line */} + {!isLast && ( +
+ )} + {/* Content */} +
+ {title && ( +

+ {title} +

+ )} +
+ {children} +
+
+
+ ); +} diff --git a/docs-site/components/docs/mdx/index.tsx b/docs-site/components/docs/mdx/index.tsx new file mode 100644 index 0000000000..9f13d40b7a --- /dev/null +++ b/docs-site/components/docs/mdx/index.tsx @@ -0,0 +1,70 @@ +import type { MDXComponents } from "mdx/types"; +import { Callout } from "./Callout"; +import { CardGroup, Card } from "./CardGroup"; +import { Steps, Step } from "./Steps"; +import { DocsTabs, DocsTab } from "./DocsTabs"; +import { DocsAccordion, DocsAccordionGroup } from "./DocsAccordion"; +import { Columns } from "./Columns"; +import { ModelRecommendations } from "./ModelRecommendations"; +import { OSAutoDetect } from "./OSAutoDetect"; +import { CodeBlock } from "./CodeBlock"; +import { CodeGroup } from "./CodeGroup"; +import { MdxLink } from "./MdxLink"; + +export const mdxComponents: MDXComponents = { + // Mintlify callout variants + Info: (props: any) => , + Tip: (props: any) => , + Warning: (props: any) => , + Note: (props: any) => , + Check: (props: any) => , + Danger: (props: any) => , + Callout, + + // Cards + Card, + CardGroup, + + // Steps + Steps, + Step, + + // Tabs + Tabs: DocsTabs, + Tab: DocsTab, + + // Accordion + Accordion: DocsAccordion, + AccordionGroup: DocsAccordionGroup, + + // Layout + Columns, + Frame: ({ children, ...props }: any) => ( +
+ {children} +
+ ), + + // Custom snippets + ModelRecommendations, + OSAutoDetect, + + // Code blocks + pre: (props: any) => , + CodeGroup, + + // Use div instead of p to avoid hydration errors when MDX wraps + // block-level components (Callout, Card, etc.) in paragraph tags. + p: (props: any) =>
, + + // Rewrite internal doc links to include /docs prefix and resolve subdomain URLs + a: MdxLink, + + // Rewrite image paths — images are copied to public/images/docs/ at build time + img: ({ src, alt, ...props }: any) => { + if (src && src.startsWith("/images/")) { + src = `/images/docs${src.slice("/images".length)}`; + } + return {alt; + }, +}; diff --git a/docs-site/components/ui/command.tsx b/docs-site/components/ui/command.tsx new file mode 100644 index 0000000000..8abae0c805 --- /dev/null +++ b/docs-site/components/ui/command.tsx @@ -0,0 +1,161 @@ +"use client"; + +import { type DialogProps } from "@radix-ui/react-dialog"; +import { Command as CommandPrimitive } from "cmdk"; +import { Search } from "lucide-react"; +import * as React from "react"; + +import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog"; +import { VisuallyHidden } from "@radix-ui/react-visually-hidden"; +import { cn } from "@/lib/utils"; + +const Command = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +Command.displayName = CommandPrimitive.displayName; + +interface CommandDialogProps extends DialogProps { + dialogClassName?: string; +} + +const CommandDialog = ({ children, dialogClassName, ...props }: CommandDialogProps) => { + return ( + + + + Search + + + {children} + + + + ); +}; + +const CommandInput = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( +
+ + +
+)); + +CommandInput.displayName = CommandPrimitive.Input.displayName; + +const CommandList = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); + +CommandList.displayName = CommandPrimitive.List.displayName; + +const CommandEmpty = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>((props, ref) => ( + +)); + +CommandEmpty.displayName = CommandPrimitive.Empty.displayName; + +const CommandGroup = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); + +CommandGroup.displayName = CommandPrimitive.Group.displayName; + +const CommandSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +CommandSeparator.displayName = CommandPrimitive.Separator.displayName; + +const CommandItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); + +CommandItem.displayName = CommandPrimitive.Item.displayName; + +const CommandShortcut = ({ + className, + ...props +}: React.HTMLAttributes) => { + return ( + + ); +}; +CommandShortcut.displayName = "CommandShortcut"; + +export { + Command, + CommandDialog, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, + CommandSeparator, + CommandShortcut, +}; diff --git a/docs-site/components/ui/dialog.tsx b/docs-site/components/ui/dialog.tsx new file mode 100644 index 0000000000..88452a4ddc --- /dev/null +++ b/docs-site/components/ui/dialog.tsx @@ -0,0 +1,123 @@ +"use client"; + +import * as React from "react"; +import * as DialogPrimitive from "@radix-ui/react-dialog"; +import { X } from "lucide-react"; + +import { cn } from "@/lib/utils"; + +const Dialog = DialogPrimitive.Root; + +const DialogTrigger = DialogPrimitive.Trigger; + +const DialogPortal = DialogPrimitive.Portal; + +const DialogClose = DialogPrimitive.Close; + +const DialogOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DialogOverlay.displayName = DialogPrimitive.Overlay.displayName; + +const DialogContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + {children} + + + Close + + + + +)); +DialogContent.displayName = DialogPrimitive.Content.displayName; + +const DialogHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+); +DialogHeader.displayName = "DialogHeader"; + +const DialogFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+); +DialogFooter.displayName = "DialogFooter"; + +const DialogTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DialogTitle.displayName = DialogPrimitive.Title.displayName; + +const DialogDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DialogDescription.displayName = DialogPrimitive.Description.displayName; + +export { + Dialog, + DialogPortal, + DialogOverlay, + DialogClose, + DialogTrigger, + DialogContent, + DialogHeader, + DialogFooter, + DialogTitle, + DialogDescription, +}; diff --git a/docs-site/config/docsNav.ts b/docs-site/config/docsNav.ts new file mode 100644 index 0000000000..b5eadb722a --- /dev/null +++ b/docs-site/config/docsNav.ts @@ -0,0 +1,72 @@ +// Navigation types and pure helpers for docs sidebar. +// Data loading happens server-side in lib/docs.ts — these are safe for client components. + +export type NavItem = string | NavGroup; + +export interface NavGroup { + group: string; + icon?: string; + expanded?: boolean; + pages: NavItem[]; +} + +export interface NavTab { + tab: string; + groups: NavGroup[]; +} + +// Flatten all page slugs in order for prev/next navigation +function flattenPages(items: NavItem[]): string[] { + const result: string[] = []; + for (const item of items) { + if (typeof item === "string") { + result.push(item); + } else { + result.push(...flattenPages(item.pages)); + } + } + return result; +} + +function getAllPagesFlat(nav: NavTab[]): string[] { + const all: string[] = []; + for (const tab of nav) { + for (const group of tab.groups) { + all.push(...flattenPages(group.pages)); + } + } + // Deduplicate while preserving order + return Array.from(new Set(all)); +} + +function slugToTitle(slug: string): string { + const name = slug.split("/").pop() || slug; + return name + .replace(/^\d+-/, "") + .replace(/-/g, " ") + .replace(/\b\w/g, (l) => l.toUpperCase()); +} + +export function getPageNavigation( + nav: NavTab[], + currentSlug: string, + titleMap?: Record, +): { + prev: { slug: string; title: string } | null; + next: { slug: string; title: string } | null; +} { + const pages = getAllPagesFlat(nav); + const idx = pages.indexOf(currentSlug); + + if (idx === -1) return { prev: null, next: null }; + + const prevSlug = idx > 0 ? pages[idx - 1] : undefined; + const nextSlug = idx < pages.length - 1 ? pages[idx + 1] : undefined; + + const getTitle = (slug: string) => titleMap?.[slug] || slugToTitle(slug); + + const prev = prevSlug ? { slug: prevSlug, title: getTitle(prevSlug) } : null; + const next = nextSlug ? { slug: nextSlug, title: getTitle(nextSlug) } : null; + + return { prev, next }; +} diff --git a/docs-site/lib/docs.ts b/docs-site/lib/docs.ts new file mode 100644 index 0000000000..ff030eb1ee --- /dev/null +++ b/docs-site/lib/docs.ts @@ -0,0 +1,296 @@ +import fs from "fs"; +import path from "path"; +import matter from "gray-matter"; +import { type NavItem, type NavTab } from "@/config/docsNav"; + +const DOCS_DIR = + process.env.DOCS_DIR || path.resolve(process.cwd(), "../docs"); + +export function getDocsDir() { + return DOCS_DIR; +} + +export function loadDocsNav(): NavTab[] { + const docsJsonPath = path.join(DOCS_DIR, "docs.json"); + if (!fs.existsSync(docsJsonPath)) { + console.warn(`docs.json not found at ${docsJsonPath}, using empty nav`); + return []; + } + + const raw = JSON.parse(fs.readFileSync(docsJsonPath, "utf8")); + return raw.navigation?.tabs ?? []; +} + +export const docsNav: NavTab[] = loadDocsNav(); + +function loadDocsRedirects(): Map { + const docsJsonPath = path.join(DOCS_DIR, "docs.json"); + if (!fs.existsSync(docsJsonPath)) return new Map(); + + const raw = JSON.parse(fs.readFileSync(docsJsonPath, "utf8")); + const redirects = new Map(); + for (const entry of raw.redirects ?? []) { + const source = (entry.source as string).replace(/^\//, ""); + redirects.set(source, entry.destination as string); + } + return redirects; +} + +export const docsRedirects: Map = loadDocsRedirects(); + +// Whitelist of allowed external redirect domains for security +const ALLOWED_REDIRECT_DOMAINS = [ + "continue.dev", + "docs.continue.dev", + "www.continue.dev", + "changelog.continue.dev", +]; + +export function resolveDocsRedirect(slug: string[]): string | null { + const key = slug.join("/"); + const dest = docsRedirects.get(key); + if (!dest) return null; + + // Handle external URLs + if (dest.startsWith("https://") || dest.startsWith("http://")) { + try { + const url = new URL(dest); + // Only allow redirects to whitelisted domains + if (!ALLOWED_REDIRECT_DOMAINS.includes(url.hostname)) { + console.warn(`Blocked redirect to untrusted domain: ${url.hostname}`); + return null; + } + return dest; + } catch { + console.warn(`Invalid redirect URL: ${dest}`); + return null; + } + } + + // Internal redirects - ensure they start with / + return dest.startsWith("/") ? dest : `/${dest}`; +} + +export interface DocFile { + frontmatter: Record; + content: string; + slug: string[]; +} + +export async function loadMdxFile( + slug: string[], +): Promise { + const slugPath = slug.join("/"); + const filePath = path.join(DOCS_DIR, slugPath + ".mdx"); + + if (fs.existsSync(filePath)) { + return readDocFile(filePath, slug); + } + + // Try index.mdx inside directory + const indexPath = path.join(DOCS_DIR, slugPath, "index.mdx"); + if (fs.existsSync(indexPath)) { + return readDocFile(indexPath, slug); + } + + return null; +} + +export async function loadRawMdxFile( + slug: string[], +): Promise<{ raw: string; fileName: string } | null> { + const slugPath = slug.join("/"); + const filePath = path.join(DOCS_DIR, slugPath + ".mdx"); + + // Prevent path traversal — ensure the resolved path stays inside DOCS_DIR. + const docsDirNormalized = DOCS_DIR.endsWith(path.sep) ? DOCS_DIR : DOCS_DIR + path.sep; + const isWithinDocsDir = (p: string) => p.startsWith(docsDirNormalized); + + if (isWithinDocsDir(filePath) && fs.existsSync(filePath)) { + return { + raw: fs.readFileSync(filePath, "utf8"), + fileName: slug[slug.length - 1] + ".md", + }; + } + + const indexPath = path.join(DOCS_DIR, slugPath, "index.mdx"); + if (isWithinDocsDir(indexPath) && fs.existsSync(indexPath)) { + return { + raw: fs.readFileSync(indexPath, "utf8"), + fileName: slug[slug.length - 1] + ".md", + }; + } + + return null; +} + +function readDocFile(filePath: string, slug: string[]): DocFile { + const raw = fs.readFileSync(filePath, "utf8"); + const { data: frontmatter, content } = matter(raw); + + const processed = preprocessMdx(content, slug); + + return { frontmatter, content: processed, slug }; +} + +/** + * Preprocess MDX content: + * 1. Find MDX snippet imports (import X from '/snippets/foo.mdx') + * 2. Inline the snippet content in place of usage + * 3. Strip JSX component imports (handled via components map) + */ +function preprocessMdx(content: string, slug: string[]): string { + // Collect MDX snippet imports: import Name from '/snippets/file.mdx' + const mdxImportRegex = + /^import\s+(\w+)\s+from\s+['"]\/snippets\/([^'"]+\.mdx)['"];?\s*$/gm; + const snippets = new Map(); + let match; + + while ((match = mdxImportRegex.exec(content)) !== null) { + const componentName = match[1]!; + const snippetFile = match[2]!; + const snippetPath = path.join(DOCS_DIR, "snippets", snippetFile); + + if (fs.existsSync(snippetPath)) { + const snippetRaw = fs.readFileSync(snippetPath, "utf8"); + const { content: snippetContent } = matter(snippetRaw); + snippets.set(componentName, snippetContent.trim()); + } + } + + let result = content; + + // Replace with inlined content + for (const [name, body] of Array.from(snippets.entries())) { + const selfClosing = new RegExp(`<${name}\\s*/>`, "g"); + const withChildren = new RegExp( + `<${name}\\s*>[\\s\\S]*?`, + "g", + ); + result = result.replace(selfClosing, body); + result = result.replace(withChildren, body); + } + + // Strip all remaining import statements (JSX snippets handled via components map) + result = result.replace( + /^import\s+.*from\s+['"].*['"];?\s*$/gm, + "", + ); + + // Convert :::warning / :::info / :::tip admonitions to JSX components + result = result.replace( + /^:::(warning|info|tip|note|danger)\s*\n([\s\S]*?)^:::\s*$/gm, + (_match, type: string, body: string) => { + const tag = type.charAt(0).toUpperCase() + type.slice(1); + return `<${tag}>${body.trim()}`; + }, + ); + + // Ensure --- horizontal rules have blank lines before them + // (prevents Setext h2 interpretation when preceded by text) + // Only apply outside of fenced code blocks. + result = result.replace( + /(```[\s\S]*?```)|([^\n])\n---\n/g, + (match, codeBlock, prev) => { + if (codeBlock) return codeBlock; // leave code blocks untouched + return `${prev}\n\n---\n`; + }, + ); + + // Rewrite image paths: /images/... → /images/docs/... + result = result.replace( + /src=["']\/images\//g, + 'src="/images/docs/', + ); + + // Rewrite markdown image paths: ![alt](/images/...) → ![alt](/images/docs/...) + result = result.replace( + /\]\(\/images\//g, + "](/images/docs/", + ); + + // Rewrite relative image paths: ![alt](../images/...) → ![alt](/images/docs/...) + // Resolve relative to the current file's directory + const fileDir = slug.slice(0, -1).join("/"); + result = result.replace( + /\]\((\.\.?\/[^)]*\.(png|jpg|jpeg|gif|svg|webp))\)/gi, + (_match, relPath: string) => { + const resolved = path.posix.normalize( + fileDir ? `${fileDir}/${relPath}` : relPath, + ); + return `](/images/docs/${resolved})`; + }, + ); + + return result; +} + +export interface Heading { + level: number; + text: string; + id: string; +} + +export function getHeadings(content: string): Heading[] { + const regex = /^(#{2,4})\s+(.+)$/gm; + const headings: Heading[] = []; + let match; + + while ((match = regex.exec(content)) !== null) { + const level = match[1]!.length; + const text = match[2]!.trim(); + const id = text + .toLowerCase() + .replace(/[^\w\s-]/g, "") + .replace(/\s+/g, "-"); + headings.push({ level, text, id }); + } + + return headings; +} + +export function getAllDocSlugs(): string[] { + const slugs: string[] = []; + function walk(items: NavItem[]) { + for (const item of items) { + if (typeof item === "string") slugs.push(item); + else if (item.pages) walk(item.pages); + } + } + for (const tab of docsNav) { + for (const group of tab.groups) { + walk(group.pages); + } + } + return Array.from(new Set(slugs)); +} + +/** + * Build a map of slug → display title by reading frontmatter from all docs. + * Prefers sidebarTitle over title, falls back to slug-derived name. + */ +export function getAllDocTitles(): Record { + const slugs = getAllDocSlugs(); + const titles: Record = {}; + + for (const slug of slugs) { + const slugPath = slug; + const filePath = path.join(DOCS_DIR, slugPath + ".mdx"); + const indexPath = path.join(DOCS_DIR, slugPath, "index.mdx"); + + let resolved: string | null = null; + if (fs.existsSync(filePath)) resolved = filePath; + else if (fs.existsSync(indexPath)) resolved = indexPath; + + if (resolved) { + const raw = fs.readFileSync(resolved, "utf8"); + const { data } = matter(raw); + const title = data.sidebarTitle || data.title; + if (title) { + titles[slug] = title; + } + } + } + + return titles; +} diff --git a/docs-site/lib/resolveHref.ts b/docs-site/lib/resolveHref.ts new file mode 100644 index 0000000000..207c8206f9 --- /dev/null +++ b/docs-site/lib/resolveHref.ts @@ -0,0 +1,19 @@ +/** + * Resolve internal paths for the standalone docs app. + * + * On the docs subdomain, /docs/X becomes /X (we're already on docs.continue.dev). + * Cross-app links get absolute URLs. + */ +export function resolveHref(path: string): string { + // Strip /docs prefix — we're already on the docs domain + if (path.startsWith("/docs/")) return path.slice(5); + if (path === "/docs") return "/"; + + // Cross-app links → absolute URLs + if (path.startsWith("/blog")) return `https://blog.continue.dev${path.slice(5) || ""}`; + if (path === "/login") return "https://continue.dev/login"; + if (path === "/") return "https://continue.dev"; + + // Everything else stays as-is + return path; +} diff --git a/docs-site/lib/utils.ts b/docs-site/lib/utils.ts new file mode 100644 index 0000000000..365058cebd --- /dev/null +++ b/docs-site/lib/utils.ts @@ -0,0 +1,6 @@ +import { type ClassValue, clsx } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} diff --git a/docs-site/next-env.d.ts b/docs-site/next-env.d.ts new file mode 100644 index 0000000000..9edff1c7ca --- /dev/null +++ b/docs-site/next-env.d.ts @@ -0,0 +1,6 @@ +/// +/// +import "./.next/types/routes.d.ts"; + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/docs-site/next.config.js b/docs-site/next.config.js new file mode 100644 index 0000000000..91dc0cf327 --- /dev/null +++ b/docs-site/next.config.js @@ -0,0 +1,12 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + output: "export", + typescript: { + ignoreBuildErrors: true, + }, + images: { + unoptimized: true, + }, +}; + +module.exports = nextConfig; diff --git a/docs-site/package-lock.json b/docs-site/package-lock.json new file mode 100644 index 0000000000..06c3eb2003 --- /dev/null +++ b/docs-site/package-lock.json @@ -0,0 +1,6041 @@ +{ + "name": "continue-docs", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "continue-docs", + "version": "0.1.0", + "dependencies": { + "@orama/orama": "^3.0.0", + "@radix-ui/react-accordion": "^1.2.0", + "@radix-ui/react-dialog": "^1.1.6", + "@radix-ui/react-tabs": "^1.1.0", + "@radix-ui/react-visually-hidden": "^1.1.0", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "cmdk": "1.0.4", + "geist": "^1.3.1", + "gray-matter": "^4.0.3", + "lucide-react": "^0.414.0", + "next": "^16.1.1", + "next-mdx-remote": "^6.0.0", + "next-themes": "^0.4.4", + "react": "^19.2.3", + "react-dom": "^19.2.3", + "rehype-autolink-headings": "^7.1.0", + "rehype-prism-plus": "^2.0.1", + "rehype-raw": "^7.0.0", + "rehype-sanitize": "^6.0.0", + "rehype-slug": "^6.0.0", + "remark-gfm": "^4.0.1", + "tailwind-merge": "^2.6.0" + }, + "devDependencies": { + "@tailwindcss/typography": "^0.5.19", + "@types/node": "^20", + "@types/react": "19.2.8", + "@types/react-dom": "19.2.3", + "autoprefixer": "^10.4.16", + "postcss": "^8.4.31", + "tailwindcss": "^3.3.5", + "tsx": "^4.0.0", + "typescript": "^5" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.1.tgz", + "integrity": "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.4.tgz", + "integrity": "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.4.tgz", + "integrity": "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.4.tgz", + "integrity": "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.4.tgz", + "integrity": "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.4.tgz", + "integrity": "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.4.tgz", + "integrity": "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.4.tgz", + "integrity": "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.4.tgz", + "integrity": "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.4.tgz", + "integrity": "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.4.tgz", + "integrity": "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.4.tgz", + "integrity": "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.4.tgz", + "integrity": "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.4.tgz", + "integrity": "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.4.tgz", + "integrity": "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.4.tgz", + "integrity": "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.4.tgz", + "integrity": "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.4.tgz", + "integrity": "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.4.tgz", + "integrity": "sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.4.tgz", + "integrity": "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.4.tgz", + "integrity": "sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.4.tgz", + "integrity": "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.4.tgz", + "integrity": "sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.4.tgz", + "integrity": "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.4.tgz", + "integrity": "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.4.tgz", + "integrity": "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.4.tgz", + "integrity": "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mdx-js/mdx": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.1.tgz", + "integrity": "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "acorn": "^8.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-scope": "^1.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "recma-build-jsx": "^1.0.0", + "recma-jsx": "^1.0.0", + "recma-stringify": "^1.0.0", + "rehype-recma": "^1.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/react": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", + "integrity": "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==", + "license": "MIT", + "dependencies": { + "@types/mdx": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=16", + "react": ">=16" + } + }, + "node_modules/@next/env": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.0.tgz", + "integrity": "sha512-OZIbODWWAi0epQRCRjNe1VO45LOFBzgiyqmTLzIqWq6u1wrxKnAyz1HH6tgY/Mc81YzIjRPoYsPAEr4QV4l9TA==", + "license": "MIT" + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.2.0.tgz", + "integrity": "sha512-/JZsqKzKt01IFoiLLAzlNqys7qk2F3JkcUhj50zuRhKDQkZNOz9E5N6wAQWprXdsvjRP4lTFj+/+36NSv5AwhQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.2.0.tgz", + "integrity": "sha512-/hV8erWq4SNlVgglUiW5UmQ5Hwy5EW/AbbXlJCn6zkfKxTy/E/U3V8U1Ocm2YCTUoFgQdoMxRyRMOW5jYy4ygg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.2.0.tgz", + "integrity": "sha512-GkjL/Q7MWOwqWR9zoxu1TIHzkOI2l2BHCf7FzeQG87zPgs+6WDh+oC9Sw9ARuuL/FUk6JNCgKRkA6rEQYadUaw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.2.0.tgz", + "integrity": "sha512-1ffhC6KY5qWLg5miMlKJp3dZbXelEfjuXt1qcp5WzSCQy36CV3y+JT7OC1WSFKizGQCDOcQbfkH/IjZP3cdRNA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.2.0.tgz", + "integrity": "sha512-FmbDcZQ8yJRq93EJSL6xaE0KK/Rslraf8fj1uViGxg7K4CKBCRYSubILJPEhjSgZurpcPQq12QNOJQ0DRJl6Hg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.2.0.tgz", + "integrity": "sha512-HzjIHVkmGAwRbh/vzvoBWWEbb8BBZPxBvVbDQDvzHSf3D8RP/4vjw7MNLDXFF9Q1WEzeQyEj2zdxBtVAHu5Oyw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.2.0.tgz", + "integrity": "sha512-UMiFNQf5H7+1ZsZPxEsA064WEuFbRNq/kEXyepbCnSErp4f5iut75dBA8UeerFIG3vDaQNOfCpevnERPp2V+nA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.0.tgz", + "integrity": "sha512-DRrNJKW+/eimrZgdhVN1uvkN1OI4j6Lpefwr44jKQ0YQzztlmOBUUzHuV5GxOMPK3nmodAYElUVCY8ZXo/IWeA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@orama/orama": { + "version": "3.1.18", + "resolved": "https://registry.npmjs.org/@orama/orama/-/orama-3.1.18.tgz", + "integrity": "sha512-a61ljmRVVyG5MC/698C8/FfFDw5a8LOIvyOLW5fztgUXqUpc1jOfQzOitSCbge657OgXXThmY3Tk8fpiDb4UcA==", + "license": "Apache-2.0", + "engines": { + "node": ">= 20.0.0" + } + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", + "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-accordion": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.12.tgz", + "integrity": "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collapsible": "1.1.12", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collapsible": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz", + "integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", + "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", + "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz", + "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", + "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", + "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" + }, + "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz", + "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", + "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", + "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", + "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", + "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz", + "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz", + "integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", + "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", + "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", + "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", + "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.4.tgz", + "integrity": "sha512-kaeiyGCe844dkb9AVF+rb4yTyb1LiLN/e3es3nLiRyN4dC8AduBYPMnnNlDjX2VDOcvDEiPnRNMJeWCfsX0txg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.4" + }, + "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden/node_modules/@radix-ui/react-primitive": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz", + "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.4" + }, + "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden/node_modules/@radix-ui/react-slot": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz", + "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@tailwindcss/typography": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.19.tgz", + "integrity": "sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "6.0.10" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" + } + }, + "node_modules/@types/debug": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", + "license": "MIT" + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.37.tgz", + "integrity": "sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/prismjs": { + "version": "1.26.6", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.6.tgz", + "integrity": "sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw==", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.8.tgz", + "integrity": "sha512-3MbSL37jEchWZz2p2mjntRZtPt837ij10ApxKfgmXCTuHWagYg7iA5bqPw6C8BMPfwidlvfPI/fxOc42HLhcyg==", + "license": "MIT", + "peer": true, + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "devOptional": true, + "license": "MIT", + "peer": true, + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "license": "ISC" + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "license": "MIT", + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/aria-hidden": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", + "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/astring": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", + "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", + "license": "MIT", + "bin": { + "astring": "bin/astring" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.27", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.27.tgz", + "integrity": "sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.1", + "caniuse-lite": "^1.0.30001774", + "fraction.js": "^5.3.4", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.9", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.9.tgz", + "integrity": "sha512-OZd0e2mU11ClX8+IdXe3r0dbqMEznRiT4TfbhYIbcRPZkqJ7Qwer8ij3GZAmLsRKa+II9V1v5czCkvmHH3XZBg==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001780", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001780.tgz", + "integrity": "sha512-llngX0E7nQci5BPJDqoZSbuZ5Bcs9F5db7EtgfwBerX9XGtkkiO4NwfDDIRzHTTwcYC8vC7bmeUEPGrKlR/TkQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/class-variance-authority": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", + "license": "Apache-2.0", + "dependencies": { + "clsx": "^2.1.1" + }, + "funding": { + "url": "https://polar.sh/cva" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cmdk": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.0.4.tgz", + "integrity": "sha512-AnsjfHyHpQ/EFeAnG216WY7A5LiYCoZzCSygiLvfXC3H3LFGCprErteUcszaVluGOhuOTbJS3jWHrSDYPBBygg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-dialog": "^1.1.2", + "@radix-ui/react-id": "^1.1.0", + "@radix-ui/react-primitive": "^2.0.0", + "use-sync-external-store": "^1.2.2" + }, + "peerDependencies": { + "react": "^18 || ^19 || ^19.0.0-rc", + "react-dom": "^18 || ^19 || ^19.0.0-rc" + } + }, + "node_modules/collapse-white-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "license": "MIT" + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.321", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.321.tgz", + "integrity": "sha512-L2C7Q279W2D/J4PLZLk7sebOILDSWos7bMsMNN06rK482umHUrh/3lM8G7IlHFOYip2oAg5nha1rCMxr/rs6ZQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/esast-util-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz", + "integrity": "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esast-util-from-js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz", + "integrity": "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "acorn": "^8.0.0", + "esast-util-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esbuild": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.4.tgz", + "integrity": "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.4", + "@esbuild/android-arm": "0.27.4", + "@esbuild/android-arm64": "0.27.4", + "@esbuild/android-x64": "0.27.4", + "@esbuild/darwin-arm64": "0.27.4", + "@esbuild/darwin-x64": "0.27.4", + "@esbuild/freebsd-arm64": "0.27.4", + "@esbuild/freebsd-x64": "0.27.4", + "@esbuild/linux-arm": "0.27.4", + "@esbuild/linux-arm64": "0.27.4", + "@esbuild/linux-ia32": "0.27.4", + "@esbuild/linux-loong64": "0.27.4", + "@esbuild/linux-mips64el": "0.27.4", + "@esbuild/linux-ppc64": "0.27.4", + "@esbuild/linux-riscv64": "0.27.4", + "@esbuild/linux-s390x": "0.27.4", + "@esbuild/linux-x64": "0.27.4", + "@esbuild/netbsd-arm64": "0.27.4", + "@esbuild/netbsd-x64": "0.27.4", + "@esbuild/openbsd-arm64": "0.27.4", + "@esbuild/openbsd-x64": "0.27.4", + "@esbuild/openharmony-arm64": "0.27.4", + "@esbuild/sunos-x64": "0.27.4", + "@esbuild/win32-arm64": "0.27.4", + "@esbuild/win32-ia32": "0.27.4", + "@esbuild/win32-x64": "0.27.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estree-util-attach-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", + "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-build-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", + "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-walker": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-scope": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/estree-util-scope/-/estree-util-scope-1.0.0.tgz", + "integrity": "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", + "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-visit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", + "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fraction.js": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", + "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/geist": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/geist/-/geist-1.7.0.tgz", + "integrity": "sha512-ZaoiZwkSf0DwwB1ncdLKp+ggAldqxl5L1+SXaNIBGkPAqcu+xjVJLxlf3/S8vLt9UHx1xu5fz3lbzKCj5iOVdQ==", + "license": "SIL OPEN FONT LICENSE", + "peerDependencies": { + "next": ">=13.2.0" + } + }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/get-tsconfig": { + "version": "4.13.6", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.6.tgz", + "integrity": "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "license": "ISC" + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "license": "MIT", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-from-html": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz", + "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.1.0", + "hast-util-from-parse5": "^8.0.0", + "parse5": "^7.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", + "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^7.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-heading-rank": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-heading-rank/-/hast-util-heading-rank-3.0.0.tgz", + "integrity": "sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", + "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-sanitize": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-5.0.2.tgz", + "integrity": "sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "unist-util-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-estree": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.3.tgz", + "integrity": "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-attach-comments": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", + "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.1.tgz", + "integrity": "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-string": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz", + "integrity": "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", + "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/inline-style-parser": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", + "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", + "license": "MIT" + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lucide-react": { + "version": "0.414.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.414.0.tgz", + "integrity": "sha512-Krr/MHg9AWoJc52qx8hyJ64X9++JNfS1wjaJviLM1EP/68VNB7Tv0VMldLCB1aUe6Ka9QxURPhQm/eB6cqOM3A==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/markdown-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", + "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz", + "integrity": "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", + "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", + "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-expression": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz", + "integrity": "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.2.tgz", + "integrity": "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-md": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", + "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", + "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", + "license": "MIT", + "dependencies": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "micromark-extension-mdx-expression": "^3.0.0", + "micromark-extension-mdx-jsx": "^3.0.0", + "micromark-extension-mdx-md": "^2.0.0", + "micromark-extension-mdxjs-esm": "^3.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", + "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz", + "integrity": "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-events-to-acorn": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz", + "integrity": "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/next": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/next/-/next-16.2.0.tgz", + "integrity": "sha512-NLBVrJy1pbV1Yn00L5sU4vFyAHt5XuSjzrNyFnxo6Com0M0KrL6hHM5B99dbqXb2bE9pm4Ow3Zl1xp6HVY9edQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@next/env": "16.2.0", + "@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" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=20.9.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "16.2.0", + "@next/swc-darwin-x64": "16.2.0", + "@next/swc-linux-arm64-gnu": "16.2.0", + "@next/swc-linux-arm64-musl": "16.2.0", + "@next/swc-linux-x64-gnu": "16.2.0", + "@next/swc-linux-x64-musl": "16.2.0", + "@next/swc-win32-arm64-msvc": "16.2.0", + "@next/swc-win32-x64-msvc": "16.2.0", + "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" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next-mdx-remote": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/next-mdx-remote/-/next-mdx-remote-6.0.0.tgz", + "integrity": "sha512-cJEpEZlgD6xGjB4jL8BnI8FaYdN9BzZM4NwadPe1YQr7pqoWjg9EBCMv3nXBkuHqMRfv2y33SzUsuyNh9LFAQQ==", + "license": "MPL-2.0", + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@mdx-js/mdx": "^3.0.1", + "@mdx-js/react": "^3.0.1", + "unist-util-remove": "^4.0.0", + "unist-util-visit": "^5.1.0", + "vfile": "^6.0.1", + "vfile-matter": "^5.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=7" + }, + "peerDependencies": { + "react": ">=16" + } + }, + "node_modules/next-themes": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz", + "integrity": "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" + } + }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/node-releases": { + "version": "2.0.36", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", + "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/parse-numeric-range": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", + "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==", + "license": "ISC" + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss": { + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz", + "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", + "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-nested/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/property-information": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react": { + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", + "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", + "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.4" + } + }, + "node_modules/react-remove-scroll": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz", + "integrity": "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==", + "license": "MIT", + "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" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "license": "MIT", + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "license": "MIT", + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/recma-build-jsx": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz", + "integrity": "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-build-jsx": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-jsx": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/recma-jsx/-/recma-jsx-1.0.1.tgz", + "integrity": "sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==", + "license": "MIT", + "dependencies": { + "acorn-jsx": "^5.0.0", + "estree-util-to-js": "^2.0.0", + "recma-parse": "^1.0.0", + "recma-stringify": "^1.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/recma-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-parse/-/recma-parse-1.0.0.tgz", + "integrity": "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "esast-util-from-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-stringify/-/recma-stringify-1.0.0.tgz", + "integrity": "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-to-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/refractor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/refractor/-/refractor-5.0.0.tgz", + "integrity": "sha512-QXOrHQF5jOpjjLfiNk5GFnWhRXvxjUVnlFxkeDmewR5sXkr3iM46Zo+CnRR8B+MDVqkULW4EcLVcRBNOPXHosw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/prismjs": "^1.0.0", + "hastscript": "^9.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/rehype-autolink-headings": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/rehype-autolink-headings/-/rehype-autolink-headings-7.1.0.tgz", + "integrity": "sha512-rItO/pSdvnvsP4QRB1pmPiNHUskikqtPojZKJPPPAVx9Hj8i8TwMBhofrrAYRhYOOBZH9tgmG5lPqDLuIWPWmw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-heading-rank": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unified": "^11.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.1.tgz", + "integrity": "sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-from-html": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-prism-plus": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/rehype-prism-plus/-/rehype-prism-plus-2.0.2.tgz", + "integrity": "sha512-jTHb8ZtQHd2VWAAKeCINgv/8zNEF0+LesmwJak69GemoPVN9/8fGEARTvqOpKqmN57HwaM9z8UKBVNVJe8zggw==", + "license": "MIT", + "dependencies": { + "hast-util-to-string": "^3.0.1", + "parse-numeric-range": "^1.3.0", + "refractor": "^5.0.0", + "rehype-parse": "^9.0.1", + "unist-util-filter": "^5.0.1", + "unist-util-visit": "^5.1.0" + } + }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-recma": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rehype-recma/-/rehype-recma-1.0.0.tgz", + "integrity": "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "hast-util-to-estree": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-sanitize": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/rehype-sanitize/-/rehype-sanitize-6.0.0.tgz", + "integrity": "sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-sanitize": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-slug": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/rehype-slug/-/rehype-slug-6.0.0.tgz", + "integrity": "sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "github-slugger": "^2.0.0", + "hast-util-heading-rank": "^3.0.0", + "hast-util-to-string": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-mdx": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.1.tgz", + "integrity": "sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==", + "license": "MIT", + "dependencies": { + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "license": "BSD-3-Clause" + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/style-to-js": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz", + "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==", + "license": "MIT", + "dependencies": { + "style-to-object": "1.0.14" + } + }, + "node_modules/style-to-object": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz", + "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.7" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/sucrase": { + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", + "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "tinyglobby": "^0.2.11", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwind-merge": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.1.tgz", + "integrity": "sha512-Oo6tHdpZsGpkKG88HJ8RR1rg/RdnEkQEfMoEk2x1XRI3F1AxeU+ijRXpiVUF4UbLfcxxRGw6TbUINKYdWVsQTQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz", + "integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.7", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-filter": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/unist-util-filter/-/unist-util-filter-5.0.1.tgz", + "integrity": "sha512-pHx7D4Zt6+TsfwylH9+lYhBhzyhEnCXs/lbq/Hstxno5z4gVdyc2WEW0asfjGKPyG4pEKrnBv5hdkO6+aRnQJw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", + "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove/-/unist-util-remove-4.0.0.tgz", + "integrity": "sha512-b4gokeGId57UVRX/eVKej5gXqGlc9+trkORhFJpu9raqZkZhU0zm8Doi05+HaiBsMEIJowL+2WtQ5ItjsngPXg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "license": "MIT", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-matter": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/vfile-matter/-/vfile-matter-5.0.1.tgz", + "integrity": "sha512-o6roP82AiX0XfkyTHyRCMXgHfltUNlXSEqCIS80f+mbAyiQBE2fxtDVMtseyytGx75sihiJFo/zR6r/4LTs2Cw==", + "license": "MIT", + "dependencies": { + "vfile": "^6.0.0", + "yaml": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/yaml": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", + "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/docs-site/package.json b/docs-site/package.json new file mode 100644 index 0000000000..72d0fe2f72 --- /dev/null +++ b/docs-site/package.json @@ -0,0 +1,50 @@ +{ + "name": "continue-docs", + "version": "0.1.0", + "private": true, + "scripts": { + "prebuild": "npx tsx scripts/copy-doc-images.ts && npx tsx scripts/build-search-index.ts", + "dev": "npx tsx scripts/copy-doc-images.ts && npx tsx scripts/build-search-index.ts && next dev -p 3005", + "build": "next build", + "start": "next start -p 3005", + "lint": "next lint", + "tsc:check": "tsc --noEmit", + "tsc:watch": "tsc --watch --noEmit --pretty" + }, + "dependencies": { + "@orama/orama": "^3.0.0", + "@radix-ui/react-accordion": "^1.2.0", + "@radix-ui/react-dialog": "^1.1.6", + "@radix-ui/react-tabs": "^1.1.0", + "@radix-ui/react-visually-hidden": "^1.1.0", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "cmdk": "1.0.4", + "geist": "^1.3.1", + "gray-matter": "^4.0.3", + "lucide-react": "^0.414.0", + "next": "^16.1.1", + "next-mdx-remote": "^6.0.0", + "next-themes": "^0.4.4", + "react": "^19.2.3", + "react-dom": "^19.2.3", + "rehype-autolink-headings": "^7.1.0", + "rehype-prism-plus": "^2.0.1", + "rehype-raw": "^7.0.0", + "rehype-sanitize": "^6.0.0", + "rehype-slug": "^6.0.0", + "remark-gfm": "^4.0.1", + "tailwind-merge": "^2.6.0" + }, + "devDependencies": { + "@tailwindcss/typography": "^0.5.19", + "@types/node": "^20", + "@types/react": "19.2.8", + "@types/react-dom": "19.2.3", + "autoprefixer": "^10.4.16", + "postcss": "^8.4.31", + "tailwindcss": "^3.3.5", + "tsx": "^4.0.0", + "typescript": "^5" + } +} diff --git a/docs-site/postcss.config.js b/docs-site/postcss.config.js new file mode 100644 index 0000000000..12a703d900 --- /dev/null +++ b/docs-site/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/docs-site/public/images/continue-logo-light.png b/docs-site/public/images/continue-logo-light.png new file mode 100644 index 0000000000000000000000000000000000000000..a266b35c3fb3757e0084de01fe90f6a6bd40e3d9 GIT binary patch literal 32528 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 aru;jPYEvZ2fd3c2%gDg&Dqina?0*5XGx|#a literal 0 HcmV?d00001 diff --git a/docs-site/scripts/build-search-index.ts b/docs-site/scripts/build-search-index.ts new file mode 100644 index 0000000000..38a26f3e4a --- /dev/null +++ b/docs-site/scripts/build-search-index.ts @@ -0,0 +1,107 @@ +/** + * Build-time script that generates the Orama search index as a static JSON file. + * Run via: npx tsx scripts/build-search-index.ts + */ +import fs from "fs"; +import path from "path"; +import matter from "gray-matter"; +import { create, insert, save } from "@orama/orama"; + +const DOCS_DIR = path.resolve(__dirname, "../../docs"); + +function loadDocsNav() { + const docsJsonPath = path.join(DOCS_DIR, "docs.json"); + if (!fs.existsSync(docsJsonPath)) return []; + const raw = JSON.parse(fs.readFileSync(docsJsonPath, "utf8")); + return raw.navigation?.tabs ?? []; +} + +function getAllDocSlugs(nav: any[]): string[] { + const slugs: string[] = []; + function walk(items: any[]) { + for (const item of items) { + if (typeof item === "string") slugs.push(item); + else if (item.pages) walk(item.pages); + } + } + for (const tab of nav) { + for (const group of tab.groups) { + walk(group.pages); + } + } + return Array.from(new Set(slugs)); +} + +function stripMdx(content: string): string { + return content + .replace(/<[^>]+>/g, "") + .replace(/```[\s\S]*?```/g, "") + .replace(/`[^`]+`/g, "") + .replace(/!\[.*?\]\(.*?\)/g, "") + .replace(/\[([^\]]+)\]\([^)]+\)/g, "$1") + .replace(/^#+\s+/gm, "") + .replace(/\*\*([^*]+)\*\*/g, "$1") + .replace(/\*([^*]+)\*/g, "$1") + .replace(/\n{3,}/g, "\n\n") + .trim(); +} + +function loadMdxFile(slug: string) { + const filePath = path.join(DOCS_DIR, slug + ".mdx"); + if (fs.existsSync(filePath)) { + const raw = fs.readFileSync(filePath, "utf8"); + const { data, content } = matter(raw); + return { frontmatter: data, content }; + } + const indexPath = path.join(DOCS_DIR, slug, "index.mdx"); + if (fs.existsSync(indexPath)) { + const raw = fs.readFileSync(indexPath, "utf8"); + const { data, content } = matter(raw); + return { frontmatter: data, content }; + } + return null; +} + +async function main() { + const nav = loadDocsNav(); + const slugs = getAllDocSlugs(nav); + + const db = create({ + schema: { + title: "string" as const, + path: "string" as const, + content: "string" as const, + section: "string" as const, + }, + }); + + for (const slug of slugs) { + const doc = loadMdxFile(slug); + if (!doc) continue; + + const title = + doc.frontmatter.title || + slug + .split("/") + .pop()! + .replace(/^\d+-/, "") + .replace(/-/g, " ") + .replace(/\b\w/g, (l: string) => l.toUpperCase()); + + const section = slug.split("/")[0] || "docs"; + const plainText = stripMdx(doc.content); + + insert(db, { title, path: slug, content: plainText, section }); + } + + const data = save(db); + const outDir = path.resolve(__dirname, "../public"); + if (!fs.existsSync(outDir)) fs.mkdirSync(outDir, { recursive: true }); + fs.writeFileSync(path.join(outDir, "search-index.json"), JSON.stringify(data)); + console.log(`Search index written to public/search-index.json (${slugs.length} docs)`); +} + +main().catch((err) => { + console.error(err); + process.exit(1); +}); diff --git a/docs-site/scripts/copy-doc-images.ts b/docs-site/scripts/copy-doc-images.ts new file mode 100644 index 0000000000..766050c9b0 --- /dev/null +++ b/docs-site/scripts/copy-doc-images.ts @@ -0,0 +1,62 @@ +/** + * Build-time script that copies images from the docs directory to public/images/docs/. + * Run via: npx tsx scripts/copy-doc-images.ts + */ +import fs from "fs"; +import path from "path"; + +const DOCS_DIR = path.resolve(__dirname, "../../docs"); +const OUT_DIR = path.resolve(__dirname, "../public/images/docs"); + +const IMAGE_EXTENSIONS = new Set([".png", ".jpg", ".jpeg", ".gif", ".svg", ".webp", ".ico"]); + +function copyImagesRecursive(srcDir: string, destDir: string) { + if (!fs.existsSync(srcDir)) return; + + const entries = fs.readdirSync(srcDir, { withFileTypes: true }); + for (const entry of entries) { + const srcPath = path.join(srcDir, entry.name); + const destPath = path.join(destDir, entry.name); + + if (entry.isDirectory()) { + copyImagesRecursive(srcPath, destPath); + } else if (IMAGE_EXTENSIONS.has(path.extname(entry.name).toLowerCase())) { + if (!fs.existsSync(destDir)) { + fs.mkdirSync(destDir, { recursive: true }); + } + fs.copyFileSync(srcPath, destPath); + } + } +} + +function main() { + // Clean output directory + if (fs.existsSync(OUT_DIR)) { + fs.rmSync(OUT_DIR, { recursive: true }); + } + + // Copy all images from docs/images/ to public/images/docs/ + const imagesDir = path.join(DOCS_DIR, "images"); + if (fs.existsSync(imagesDir)) { + copyImagesRecursive(imagesDir, OUT_DIR); + } + + // Also copy any images scattered in other doc subdirectories + // (for relative image references like ../some-dir/image.png) + copyImagesRecursive(DOCS_DIR, OUT_DIR); + + // Count copied files + let count = 0; + function countFiles(dir: string) { + if (!fs.existsSync(dir)) return; + for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { + if (entry.isDirectory()) countFiles(path.join(dir, entry.name)); + else count++; + } + } + countFiles(OUT_DIR); + + console.log(`Copied ${count} images to public/images/docs/`); +} + +main(); diff --git a/docs-site/tailwind.config.ts b/docs-site/tailwind.config.ts new file mode 100644 index 0000000000..375aaa087f --- /dev/null +++ b/docs-site/tailwind.config.ts @@ -0,0 +1,14 @@ +import type { Config } from "tailwindcss"; + +const config: Config = { + darkMode: "class", + content: [ + "./app/**/*.{js,ts,jsx,tsx,mdx}", + "./components/**/*.{js,ts,jsx,tsx,mdx}", + ], + theme: { + extend: {}, + }, + plugins: [], +}; +export default config; diff --git a/docs-site/tsconfig.json b/docs-site/tsconfig.json new file mode 100644 index 0000000000..b09cc802a3 --- /dev/null +++ b/docs-site/tsconfig.json @@ -0,0 +1,41 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "react-jsx", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": [ + "./*" + ] + } + }, + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + ".next/dev/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] +} From 52c32529022bf4f1dbc450192cbcebdf873523f1 Mon Sep 17 00:00:00 2001 From: Nate Date: Fri, 20 Mar 2026 14:00:02 -0700 Subject: [PATCH 3/7] fix: eliminate free trial system from continue-fork Delete freeTrialTransition.ts, FreeTrialStatus.tsx, FreeTrialTransitionUI.tsx, StarterCreditsButton.tsx, StarterCreditsPopover.tsx, and related tests/mocks. Strengthen free-trial provider filtering to hard-drop (no more warnings). Remove checkForOutOfStarterCredits from streamChat. Simplify useCredits hook to a one-time fetch (no polling). Remove freeTrialExceeded listener from Layout. Clean up navigation context and toolbar references. Co-Authored-By: Claude Opus 4.6 (1M context) --- core/config/load.ts | 22 +- core/config/yaml/loadYaml.ts | 12 +- core/llm/streamChat.ts | 25 -- extensions/cli/src/freeTrialTransition.ts | 143 -------- extensions/cli/src/ui/FreeTrialStatus.tsx | 108 ------ .../cli/src/ui/FreeTrialTransitionUI.tsx | 334 ------------------ .../cli/src/ui/__mocks__/FreeTrialStatus.tsx | 11 - .../__tests__/FreeTrialTransitionUI.test.tsx | 173 --------- ...FreeTrialTransitionUI.urlHandling.test.tsx | 65 ---- .../TUIChat.freeTrialTransition.test.tsx | 21 -- .../src/ui/__tests__/mocks/MockApiClient.ts | 7 - .../cli/src/ui/components/BottomStatusBar.tsx | 20 +- .../cli/src/ui/components/ScreenContent.tsx | 6 - .../cli/src/ui/context/NavigationContext.tsx | 1 - .../__tests__/NavigationContext.test.tsx | 35 +- gui/src/components/Layout.tsx | 16 - .../OnboardingCard/hooks/useOnboardingCard.ts | 3 +- gui/src/components/StarterCreditsButton.tsx | 38 -- gui/src/components/StarterCreditsPopover.tsx | 196 ---------- .../LumpToolbar/BlockSettingsTopToolbar.tsx | 19 - gui/src/hooks/useCredits.ts | 31 +- 21 files changed, 13 insertions(+), 1273 deletions(-) delete mode 100644 extensions/cli/src/freeTrialTransition.ts delete mode 100644 extensions/cli/src/ui/FreeTrialStatus.tsx delete mode 100644 extensions/cli/src/ui/FreeTrialTransitionUI.tsx delete mode 100644 extensions/cli/src/ui/__mocks__/FreeTrialStatus.tsx delete mode 100644 extensions/cli/src/ui/__tests__/FreeTrialTransitionUI.test.tsx delete mode 100644 extensions/cli/src/ui/__tests__/FreeTrialTransitionUI.urlHandling.test.tsx delete mode 100644 extensions/cli/src/ui/__tests__/TUIChat.freeTrialTransition.test.tsx delete mode 100644 gui/src/components/StarterCreditsButton.tsx delete mode 100644 gui/src/components/StarterCreditsPopover.tsx diff --git a/core/config/load.ts b/core/config/load.ts index e4c7e13c4f..e152cdd180 100644 --- a/core/config/load.ts +++ b/core/config/load.ts @@ -346,12 +346,8 @@ async function intermediateToFinalConfig({ "summarize", ]); // Default to chat role if not specified - // Free trial provider will be completely ignored - let warnAboutFreeTrial = false; + // Free trial provider is no longer supported — hard-drop any such models models = models.filter((model) => model.providerName !== "free-trial"); - if (models.filter((m) => m.providerName === "free-trial").length) { - warnAboutFreeTrial = true; - } // Tab autocomplete model const tabAutocompleteModels: BaseLLM[] = []; @@ -373,9 +369,7 @@ async function intermediateToFinalConfig({ config.completionOptions, ); if (llm) { - if (llm.providerName === "free-trial") { - warnAboutFreeTrial = true; - } else { + if (llm.providerName !== "free-trial") { tabAutocompleteModels.push(llm); } } @@ -419,9 +413,6 @@ async function intermediateToFinalConfig({ } const { provider, ...options } = embedConfig; if (provider === "transformers.js" || provider === "free-trial") { - if (provider === "free-trial") { - warnAboutFreeTrial = true; - } return new TransformersJsEmbeddingsProvider(); } else { const cls = LLMClasses.find((c) => c.providerName === provider); @@ -459,7 +450,6 @@ async function intermediateToFinalConfig({ } const { name, params } = config.reranker as RerankerDescription; if (name === "free-trial") { - warnAboutFreeTrial = true; return null; } if (name === "llm") { @@ -492,14 +482,6 @@ async function intermediateToFinalConfig({ } const newReranker = getRerankingILLM(config.reranker); - if (warnAboutFreeTrial) { - errors.push({ - fatal: false, - message: - "Model provider 'free-trial' is no longer supported, will be ignored", - }); - } - const continueConfig: ContinueConfig = { ...config, contextProviders, diff --git a/core/config/yaml/loadYaml.ts b/core/config/yaml/loadYaml.ts index 40278fdbe4..4634dcefb9 100644 --- a/core/config/yaml/loadYaml.ts +++ b/core/config/yaml/loadYaml.ts @@ -305,13 +305,13 @@ export async function configYamlToContinueConfig(options: { }); // Models - let warnAboutFreeTrial = false; const defaultModelRoles: ModelRole[] = ["chat", "summarize", "apply", "edit"]; for (const model of config.models ?? []) { model.roles = model.roles ?? defaultModelRoles; // Default to all 4 chat-esque roles if not specified + // Free trial provider is no longer supported — hard-drop if (model.provider === "free-trial") { - warnAboutFreeTrial = true; + continue; } try { const llms = await llmsFromModelConfig({ @@ -386,14 +386,6 @@ export async function configYamlToContinueConfig(options: { ); } - if (warnAboutFreeTrial) { - localErrors.push({ - fatal: false, - message: - "Model provider 'free-trial' is no longer supported, will be ignored.", - }); - } - const { providers, errors: contextErrors } = loadConfigContextProviders( config.context, !!config.docs?.length, diff --git a/core/llm/streamChat.ts b/core/llm/streamChat.ts index 013222ec0c..bd4aebb22e 100644 --- a/core/llm/streamChat.ts +++ b/core/llm/streamChat.ts @@ -1,12 +1,10 @@ import { fetchwithRequestOptions } from "@continuedev/fetch"; import { ChatMessage, IDE, PromptLog } from ".."; import { ConfigHandler } from "../config/ConfigHandler"; -import { usesCreditsBasedApiKey } from "../config/usesFreeTrialApiKey"; import { FromCoreProtocol, ToCoreProtocol } from "../protocol"; import { IMessenger, Message } from "../protocol/messenger"; import { TTS } from "../util/tts"; -import { isOutOfStarterCredits } from "./utils/starterCredits"; export async function* llmStreamChat( configHandler: ConfigHandler, @@ -136,8 +134,6 @@ export async function* llmStreamChat( void TTS.read(next.value?.completion); } - void checkForOutOfStarterCredits(configHandler, messenger); - if (!next.done) { throw new Error("Will never happen"); } @@ -149,24 +145,3 @@ export async function* llmStreamChat( throw error; } } - -async function checkForOutOfStarterCredits( - configHandler: ConfigHandler, - messenger: IMessenger, -) { - try { - const { config } = await configHandler.getSerializedConfig(); - const creditStatus = - await configHandler.controlPlaneClient.getCreditStatus(); - - if ( - config && - creditStatus && - isOutOfStarterCredits(usesCreditsBasedApiKey(config), creditStatus) - ) { - void messenger.request("freeTrialExceeded", undefined); - } - } catch (error) { - console.error("Error checking free trial status:", error); - } -} diff --git a/extensions/cli/src/freeTrialTransition.ts b/extensions/cli/src/freeTrialTransition.ts deleted file mode 100644 index 484b9d6720..0000000000 --- a/extensions/cli/src/freeTrialTransition.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { spawn } from "child_process"; -import * as fs from "fs"; -import * as path from "path"; - -import chalk from "chalk"; -import { setConfigFilePermissions } from "core/util/paths.js"; -import open from "open"; - -import { env } from "./env.js"; -import { - getApiKeyValidationError, - isValidAnthropicApiKey, -} from "./util/apiKeyValidation.js"; -import { gracefulExit } from "./util/exit.js"; -import { question, questionWithChoices } from "./util/prompt.js"; -import { updateAnthropicModelInYaml } from "./util/yamlConfigUpdater.js"; - -const CONFIG_PATH = path.join(env.continueHome, "config.yaml"); - -/** - * Creates or updates the local config with Anthropic API key - */ -async function createOrUpdateConfig(apiKey: string): Promise { - const configDir = path.dirname(CONFIG_PATH); - - if (!fs.existsSync(configDir)) { - fs.mkdirSync(configDir, { recursive: true }); - } - - const existingContent = fs.existsSync(CONFIG_PATH) - ? fs.readFileSync(CONFIG_PATH, "utf8") - : ""; - - const updatedContent = updateAnthropicModelInYaml(existingContent, apiKey); - fs.writeFileSync(CONFIG_PATH, updatedContent); - setConfigFilePermissions(CONFIG_PATH); -} - -/** - * Handles the free trial transition flow for users who have maxed out their free trial - * This function provides a specialized flow that: - * 1. Assumes the user is already authenticated - * 2. Provides two specific options for continuing - * 3. Returns to the chat without restarting the entire CLI - */ -export async function handleMaxedOutFreeTrial( - onReload?: () => Promise, -): Promise { - // Clear the screen but don't show ASCII art - keep it minimal since we're resuming a conversation - console.clear(); - - console.log(chalk.yellow("🚀 Free trial limit reached!\n")); - console.log("Choose how you'd like to Continue:"); - console.log(chalk.white("1. 💳 Sign up for models add-on")); - console.log(chalk.white("2. 🔑 Enter your Anthropic API key")); - - const choice = await questionWithChoices( - chalk.yellow("\nEnter choice (1): "), - ["1", "2", ""], - "1", - chalk.dim("Please enter 1 or 2"), - ); - - if (choice === "1" || choice === "") { - // Option 1: Open models setup page - const modelsUrl = new URL("setup-models", env.appUrl).toString(); - console.log(chalk.blue(`Opening ${modelsUrl}...`)); - - try { - await open(modelsUrl); - console.log(chalk.green("\n✓ Browser opened successfully!")); - console.log( - chalk.dim( - "After setting up your models subscription, restart the CLI to continue.", - ), - ); - } catch { - console.log(chalk.yellow("\n⚠ Could not open browser automatically")); - console.log(chalk.white(`Please visit: ${modelsUrl}`)); - console.log( - chalk.dim( - "After setting up your models subscription, restart the CLI to continue.", - ), - ); - } - - // Wait for user to acknowledge - await question(chalk.dim("\nPress Enter to exit...")); - await gracefulExit(0); - } else if (choice === "2") { - // Option 2: Enter Anthropic API key - const apiKey = await question( - chalk.white("\nEnter your Anthropic API key: "), - ); - - if (!isValidAnthropicApiKey(apiKey)) { - console.log(chalk.red(`❌ ${getApiKeyValidationError(apiKey)}`)); - await gracefulExit(1); - } - - try { - await createOrUpdateConfig(apiKey); - console.log(chalk.green(`✓ API key saved successfully!`)); - console.log(chalk.green("✓ Switching to local configuration...")); - - // If a reload callback is provided, use it instead of restarting - if (onReload) { - await onReload(); - return; - } - } catch (error) { - console.log(chalk.red(`❌ Error saving API key: ${error}`)); - await gracefulExit(1); - } - } - - // Fallback: restart the CLI if no reload callback was provided - console.log( - chalk.green( - "\n🔄 Restarting Continue CLI to resume your conversation...\n", - ), - ); - - // Get the path to the current script - const scriptPath = path.resolve(process.argv[1]); - - // Restart the CLI with the same arguments, except for the first two (node and script path) - // Use spawn instead of spawnSync, since we want to exit this process - const child = spawn( - process.execPath, - [scriptPath, ...process.argv.slice(2)], - { - stdio: "inherit", - detached: true, - }, - ); - - // Unref the child to allow the parent process to exit - child.unref(); - - // Exit the current process - await gracefulExit(0); -} diff --git a/extensions/cli/src/ui/FreeTrialStatus.tsx b/extensions/cli/src/ui/FreeTrialStatus.tsx deleted file mode 100644 index 5a2c7c78d0..0000000000 --- a/extensions/cli/src/ui/FreeTrialStatus.tsx +++ /dev/null @@ -1,108 +0,0 @@ -import { ModelConfig } from "@continuedev/config-yaml"; -import { - DefaultApiInterface, - GetFreeTrialStatus200Response, -} from "@continuedev/sdk/dist/api/dist/index.js"; -import { Text } from "ink"; -import React, { useEffect, useState } from "react"; - -export function isModelUsingFreeTrial(model: ModelConfig): boolean { - return ( - model.provider === "continue-proxy" && - (model as any).apiKeyLocation.startsWith("free_trial:") - ); -} - -interface FreeTrialStatusProps { - apiClient?: DefaultApiInterface; - onTransitionStateChange?: (isShowingTransition: boolean) => void; - model: ModelConfig; -} - -const FreeTrialStatus: React.FC = ({ - apiClient, - onTransitionStateChange, - model, -}) => { - const [status, setStatus] = useState( - null, - ); - const [loading, setLoading] = useState(true); - - const fetchStatus = async () => { - try { - if (!apiClient) { - setStatus(null); - setLoading(false); - return; - } - - const response = await apiClient.getFreeTrialStatus(); - setStatus(response); - setLoading(false); - } catch { - // Silently handle errors - component returns null if no status - setStatus(null); - setLoading(false); - } - }; - - useEffect(() => { - // Initial fetch - fetchStatus(); - - // Don't poll in test environment - if (process.env.NODE_ENV === "test") { - return; - } - - // Poll every 5 seconds - const interval = setInterval(fetchStatus, 5000); - - return () => clearInterval(interval); - }, []); - - // Check if user has maxed out their free trial and notify parent - useEffect(() => { - if (!status || !status.optedInToFreeTrial || loading) { - // No transition needed - if (onTransitionStateChange) { - onTransitionStateChange(false); - } - return; - } - - const chatUsed = status.chatCount ?? 0; - const chatLimit = status.chatLimit; - - // Check if user has maxed out their free trial - const shouldShowTransition = - chatUsed >= chatLimit && isModelUsingFreeTrial(model); - - if (onTransitionStateChange) { - onTransitionStateChange(shouldShowTransition); - } - }, [status, loading, onTransitionStateChange, model]); - - // Don't render anything while loading or if no status - if ( - loading || - !status || - !status.optedInToFreeTrial || - !isModelUsingFreeTrial(model) - ) { - return null; - } - - const chatUsed = status.chatCount ?? 0; - const chatLimit = status.chatLimit; - - // Only show the normal status text - transition UI is handled by parent - return ( - - {chatUsed}/{chatLimit} free trial - - ); -}; - -export { FreeTrialStatus }; diff --git a/extensions/cli/src/ui/FreeTrialTransitionUI.tsx b/extensions/cli/src/ui/FreeTrialTransitionUI.tsx deleted file mode 100644 index 4b3cbbeb74..0000000000 --- a/extensions/cli/src/ui/FreeTrialTransitionUI.tsx +++ /dev/null @@ -1,334 +0,0 @@ -import * as fs from "fs"; -import * as path from "path"; - -import { Box, Text, useInput } from "ink"; -import open from "open"; -import React, { useState } from "react"; -import useSWR from "swr"; - -import { listUserOrganizations } from "../auth/workos.js"; -import { env } from "../env.js"; -import { - getApiKeyValidationError, - isValidAnthropicApiKey, -} from "../util/apiKeyValidation.js"; -import { updateAnthropicModelInYaml } from "../util/yamlConfigUpdater.js"; - -import { useNavigation } from "./context/NavigationContext.js"; -import { defaultBoxStyles } from "./styles.js"; - -const CONFIG_PATH = path.join(env.continueHome, "config.yaml"); - -// Helper functions for input handling -interface ChoiceInputOptions { - input: string; - key: any; - selectedOption: number; - setSelectedOption: (option: number) => void; - hasOrganizations: boolean; - handleOptionSelect: () => void; -} - -function handleChoiceInput(options: ChoiceInputOptions): void { - const { - input, - key, - selectedOption, - setSelectedOption, - hasOrganizations, - handleOptionSelect, - } = options; - if (key.upArrow && selectedOption > 1) { - setSelectedOption(selectedOption - 1); - } else if (key.downArrow && selectedOption < (hasOrganizations ? 4 : 3)) { - setSelectedOption(selectedOption + 1); - } else if (input === "1") { - setSelectedOption(1); - } else if (input === "2") { - setSelectedOption(2); - } else if (input === "3") { - setSelectedOption(3); - } else if (input === "4" && hasOrganizations) { - setSelectedOption(4); - } else if (key.return) { - handleOptionSelect(); - } -} - -interface ApiKeyInputOptions { - input: string; - key: any; - apiKey: string; - setApiKey: (key: string) => void; - setErrorMessage: (msg: string) => void; - handleApiKeySubmit: () => void; -} - -function handleApiKeyInput(options: ApiKeyInputOptions): void { - const { input, key, apiKey, setApiKey, setErrorMessage, handleApiKeySubmit } = - options; - if (key.return) { - if (isValidAnthropicApiKey(apiKey)) { - handleApiKeySubmit(); - } else { - setErrorMessage(getApiKeyValidationError(apiKey)); - } - } else if (key.backspace || key.delete) { - setApiKey(apiKey.slice(0, -1)); - setErrorMessage(""); - } else if (input && !key.ctrl && !key.meta) { - setApiKey(apiKey + input); - setErrorMessage(""); - } -} - -interface FreeTrialTransitionUIProps { - onReload: () => void; -} - -/** - * Creates or updates the local config with Anthropic API key - */ -async function createOrUpdateConfig(apiKey: string): Promise { - const configDir = path.dirname(CONFIG_PATH); - - if (!fs.existsSync(configDir)) { - fs.mkdirSync(configDir, { recursive: true }); - } - - const existingContent = fs.existsSync(CONFIG_PATH) - ? fs.readFileSync(CONFIG_PATH, "utf8") - : ""; - - const updatedContent = updateAnthropicModelInYaml(existingContent, apiKey); - fs.writeFileSync(CONFIG_PATH, updatedContent); -} - -const FreeTrialTransitionUI: React.FC = ({ - onReload, -}) => { - const { navigateTo, closeCurrentScreen } = useNavigation(); - const [currentStep, setCurrentStep] = useState< - "choice" | "enterApiKey" | "processing" | "success" | "error" - >("choice"); - const [selectedOption, setSelectedOption] = useState(1); - const [apiKey, setApiKey] = useState(""); - const [errorMessage, setErrorMessage] = useState(""); - const [successMessage, setSuccessMessage] = useState(""); - const [wasModelsSetup, setWasModelsSetup] = useState(false); - - // Fetch organizations using SWR - const { data: organizations } = useSWR( - "organizations", - listUserOrganizations, - { - revalidateOnFocus: false, - revalidateOnReconnect: false, - shouldRetryOnError: false, - }, - ); - - const hasOrganizations = organizations && organizations.length > 0; - - useInput((input, key) => { - // Allow Escape to cancel immediately, but Ctrl+C uses two-stage exit - if (key.escape) { - closeCurrentScreen(); - return; - } - - // Handle Ctrl+C with two-stage exit (delegates to main process) - if (key.ctrl && input === "c") { - process.kill(process.pid, "SIGINT"); - return; - } - - if (currentStep === "choice") { - handleChoiceInput({ - input, - key, - selectedOption, - setSelectedOption, - hasOrganizations: !!hasOrganizations, - handleOptionSelect, - }); - } else if (currentStep === "enterApiKey") { - handleApiKeyInput({ - input, - key, - apiKey, - setApiKey, - setErrorMessage, - handleApiKeySubmit, - }); - } else if (currentStep === "success" || currentStep === "error") { - if (key.return) { - closeCurrentScreen(); - // If user went through models setup, do a full reload to register their purchase - if (wasModelsSetup) { - onReload(); - } - } - } - }); - - const handleOptionSelect = async () => { - if (selectedOption === 1) { - // Option 1: Open models setup page - setCurrentStep("processing"); - const modelsUrl = new URL("settings/billing", env.appUrl).toString(); - setWasModelsSetup(true); // Track that user went through models setup - - try { - await open(modelsUrl); - setSuccessMessage( - `Browser opened to ${modelsUrl}. After setting up your models subscription, press Enter to continue.`, - ); - setCurrentStep("success"); - } catch { - setErrorMessage( - `Could not open browser automatically. Please visit: ${modelsUrl}. After setting up your models subscription, press Enter to continue.`, - ); - setCurrentStep("error"); - } - } else if (selectedOption === 2) { - // Option 2: Enter API key - setCurrentStep("enterApiKey"); - setWasModelsSetup(false); // This is not models setup - } else if (selectedOption === 3) { - // Option 3: Switch to different configuration - navigateTo("config"); - } else if (selectedOption === 4 && hasOrganizations) { - // Option 4: Switch to configuration (includes organization switching) - navigateTo("config"); - } - }; - - const handleApiKeySubmit = async () => { - setCurrentStep("processing"); - - try { - await createOrUpdateConfig(apiKey); - setSuccessMessage( - "✓ API key saved successfully! Switching to local configuration...", - ); - setCurrentStep("success"); - - // After a brief delay, switch to local configuration - setTimeout(() => { - closeCurrentScreen(); - onReload(); - }, 1000); - } catch (error) { - setErrorMessage( - `❌ Error saving API key: ${error}. Press Enter to try again.`, - ); - setCurrentStep("error"); - } - }; - - if (currentStep === "choice") { - const options = [ - { num: 1, text: "💳 Sign up for models add-on (recommended)" }, - { num: 2, text: "🔑 Enter your Anthropic API key" }, - { num: 3, text: "⚙️ Switch to a different configuration" }, - ]; - - if (hasOrganizations) { - options.push({ - num: 4, - text: "🏢 Switch to organization configuration", - }); - } - - return ( - - - 🚀 Free trial limit reached! - - Choose how you'd like to continue: - - {options.map((option) => ( - - {selectedOption === option.num ? "➤ " : " "} - {option.num}. {option.text} - - ))} - - - ↑/↓ to navigate or {hasOrganizations ? "1/2/3/4" : "1/2/3"} to select, - Enter to confirm - - - ); - } - - if (currentStep === "enterApiKey") { - return ( - - - Enter your Anthropic API key - - - API Key: {"*".repeat(apiKey.length)} - - {errorMessage && {errorMessage}} - - Type your API key and press Enter (must start with 'sk-ant-') - - - ); - } - - if (currentStep === "processing") { - return ( - - - Processing... - - Please wait... - - ); - } - - if (currentStep === "success") { - return ( - - - Success! - - {successMessage} - - - {wasModelsSetup - ? "Press Enter to reload and continue with your new subscription" - : "Press Enter to continue your conversation"} - - - ); - } - - if (currentStep === "error") { - return ( - - - Error - - {errorMessage} - - - {wasModelsSetup - ? "Press Enter to reload and try again" - : "Press Enter to continue"} - - - ); - } - - return null; -}; - -export { FreeTrialTransitionUI }; diff --git a/extensions/cli/src/ui/__mocks__/FreeTrialStatus.tsx b/extensions/cli/src/ui/__mocks__/FreeTrialStatus.tsx deleted file mode 100644 index 2359e7f5d9..0000000000 --- a/extensions/cli/src/ui/__mocks__/FreeTrialStatus.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import React from "react"; - -// Mock FreeTrialStatus component that doesn't create any timers -const FreeTrialStatus: React.FC = () => { - return null; -}; - -export { FreeTrialStatus }; -export function isModelUsingFreeTrial(): boolean { - return false; -} diff --git a/extensions/cli/src/ui/__tests__/FreeTrialTransitionUI.test.tsx b/extensions/cli/src/ui/__tests__/FreeTrialTransitionUI.test.tsx deleted file mode 100644 index dfb3b59ceb..0000000000 --- a/extensions/cli/src/ui/__tests__/FreeTrialTransitionUI.test.tsx +++ /dev/null @@ -1,173 +0,0 @@ -import { render } from "ink-testing-library"; -import React from "react"; -import { vi } from "vitest"; - -import { FreeTrialTransitionUI } from "../FreeTrialTransitionUI.js"; - -// Mock the 'open' module to prevent actual URL opening during tests -vi.mock("open", () => ({ - default: vi.fn(), -})); - -// Mock the NavigationContext -vi.mock("../context/NavigationContext.js", () => ({ - useNavigation: () => ({ - navigateTo: vi.fn(), - closeCurrentScreen: vi.fn(), - isScreenActive: vi.fn(() => false), - state: { currentScreen: "free-trial", screenData: null }, - }), -})); - -describe("FreeTrialTransitionUI - Rendering and Props Tests", () => { - const mockOnReload = vi.fn(); - - beforeEach(() => { - vi.clearAllMocks(); - }); - - describe("Initial Choice Screen Rendering", () => { - it("displays all three options with proper formatting", () => { - const { lastFrame } = render( - , - ); - - const frame = lastFrame(); - expect(frame).toContain("🚀 Free trial limit reached!"); - expect(frame).toContain("1. 💳 Sign up for models add-on"); - expect(frame).toContain("2. 🔑 Enter your Anthropic API key"); - expect(frame).toContain("3. ⚙️ Switch to a different configuration"); - expect(frame).toContain("↑/↓ to navigate or 1/2/3 to select"); - }); - - it("highlights first option by default", () => { - const { lastFrame } = render( - , - ); - - const frame = lastFrame(); - expect(frame).toContain("➤ 1. 💳 Sign up for models add-on"); - expect(frame).not.toContain("➤ 2. 🔑 Enter your Anthropic API key"); - expect(frame).not.toContain( - "➤ 3. ⚙️ Switch to a different configuration", - ); - }); - - it("renders without crashing when all props are provided", () => { - const { lastFrame } = render( - , - ); - - const frame = lastFrame(); - expect(frame).toBeDefined(); - expect(frame?.length).toBeGreaterThan(0); - }); - - it("renders without crashing when onShowConfigSelector is not provided", () => { - const { lastFrame } = render( - , - ); - - const frame = lastFrame(); - expect(frame).toBeDefined(); - expect(frame?.length).toBeGreaterThan(0); - expect(frame).toContain("3. ⚙️ Switch to a different configuration"); - }); - - it("includes proper user instructions", () => { - const { lastFrame } = render( - , - ); - - const frame = lastFrame(); - expect(frame).toContain("Choose how you'd like to continue:"); - expect(frame).toContain( - "↑/↓ to navigate or 1/2/3 to select, Enter to confirm", - ); - }); - - it("shows all options with proper descriptions", () => { - const { lastFrame } = render( - , - ); - - const frame = lastFrame(); - expect(frame).toContain("Sign up for models add-on (recommended)"); - expect(frame).toContain("Enter your Anthropic API key"); - expect(frame).toContain("Switch to a different configuration"); - }); - }); - - describe("Component Props and Interface", () => { - it("accepts all required callback props", () => { - // Test that component accepts and renders with all props - expect(() => { - render(); - }).not.toThrow(); - }); - - it("accepts optional onShowConfigSelector prop", () => { - // Test that component works without onShowConfigSelector - expect(() => { - render(); - }).not.toThrow(); - }); - }); - - describe("Visual Styling and Layout", () => { - it("renders with proper border styling", () => { - const { lastFrame } = render( - , - ); - - const frame = lastFrame(); - // Check for box border characters (unicode box drawing) - expect(frame).toMatch(/[╭╮╯╰│─]/); - }); - - it("displays with proper spacing and formatting", () => { - const { lastFrame } = render( - , - ); - - const frame = lastFrame(); - // Should have proper spacing between lines - expect(frame?.split("\n").length).toBeGreaterThan(5); - }); - - it("shows selection indicator on first option by default", () => { - const { lastFrame } = render( - , - ); - - const frame = lastFrame(); - const lines = frame?.split("\n") || []; - const modelsLine = lines.find((line) => - line.includes("Sign up for models add-on"), - ); - const apiKeyLine = lines.find((line) => - line.includes("Enter your Anthropic API key"), - ); - const configLine = lines.find((line) => - line.includes("Switch to a different configuration"), - ); - - expect(modelsLine).toContain("➤"); - expect(apiKeyLine).not.toContain("➤"); - expect(configLine).not.toContain("➤"); - }); - }); - - describe("URL Opening Security", () => { - it("should use mocked open function to prevent actual URL opening", async () => { - // This test verifies that we properly mock the 'open' module - // to prevent actual URLs from being opened during test runs - const openModule = await import("open"); - expect(openModule.default).toBeDefined(); - expect(typeof openModule.default).toBe("function"); - }); - }); -}); diff --git a/extensions/cli/src/ui/__tests__/FreeTrialTransitionUI.urlHandling.test.tsx b/extensions/cli/src/ui/__tests__/FreeTrialTransitionUI.urlHandling.test.tsx deleted file mode 100644 index d1aa186f36..0000000000 --- a/extensions/cli/src/ui/__tests__/FreeTrialTransitionUI.urlHandling.test.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import { vi } from "vitest"; - -// Test URL opening behavior without complex component rendering -describe("FreeTrialTransitionUI - URL Opening Security", () => { - it("should mock URL opening to prevent actual browser launches during tests", () => { - // This test verifies that we properly mock the 'open' module - // to prevent actual URLs from being opened during test runs - - // Import and check that open is mocked - const mockOpen = vi.fn(); - vi.mock("open", () => mockOpen); - - // Verify the mock is properly set up - expect(mockOpen).toBeDefined(); - expect(typeof mockOpen).toBe("function"); - }); - - it("should verify URL format for models setup", () => { - // Test the URL construction logic without actually opening URLs - const baseUrl = "https://test.continue.dev"; - const expectedUrl = new URL("setup-models", baseUrl).toString(); - - expect(expectedUrl).toBe("https://test.continue.dev/setup-models"); - }); - - it("should handle URL construction with different base URLs", () => { - // Test URL construction with various base URLs - const testCases = [ - { - base: "https://continue.dev", - expected: "https://continue.dev/setup-models", - }, - { - base: "https://app.continue.dev", - expected: "https://app.continue.dev/setup-models", - }, - { - base: "http://localhost:3000", - expected: "http://localhost:3000/setup-models", - }, - ]; - - testCases.forEach(({ base, expected }) => { - const url = new URL("setup-models", base).toString(); - expect(url).toBe(expected); - }); - }); - - it("should validate that mocking prevents security issues in tests", () => { - // This test documents the security consideration: - // Without proper mocking, tests could open arbitrary URLs in the user's browser - // The mock ensures this doesn't happen during automated test runs - - const openFunction = vi.fn(); - - // Simulate what would happen if URL opening was called - openFunction("https://malicious-site.com"); - - // Verify the mock was called instead of actual URL opening - expect(openFunction).toHaveBeenCalledWith("https://malicious-site.com"); - expect(openFunction).toHaveBeenCalledTimes(1); - - // In real usage, this would have opened a browser tab, but with mocking it's safe - }); -}); diff --git a/extensions/cli/src/ui/__tests__/TUIChat.freeTrialTransition.test.tsx b/extensions/cli/src/ui/__tests__/TUIChat.freeTrialTransition.test.tsx deleted file mode 100644 index cf913fe792..0000000000 --- a/extensions/cli/src/ui/__tests__/TUIChat.freeTrialTransition.test.tsx +++ /dev/null @@ -1,21 +0,0 @@ -// Integration tests for free trial transition - simplified version - -describe("TUIChat - Free Trial Transition Integration", () => { - it("should integrate free trial transition with config selector", () => { - // This test verifies that the integration points exist - // More comprehensive integration tests would require complex mocking - // that is difficult to maintain and test reliably. - - // The key integration points are: - // 1. FreeTrialTransitionUI receives onShowConfigSelector callback - // 2. TUIChat provides handleFreeTrialShowConfigSelector function - // 3. Config selector is shown when option 3 is selected - - // These integration points are tested via: - // - Type checking (ensures interfaces match) - // - Manual testing during development - // - E2E tests that exercise the full flow - - expect(true).toBe(true); // Placeholder test - }); -}); diff --git a/extensions/cli/src/ui/__tests__/mocks/MockApiClient.ts b/extensions/cli/src/ui/__tests__/mocks/MockApiClient.ts index d619a6256a..f361cd6a70 100644 --- a/extensions/cli/src/ui/__tests__/mocks/MockApiClient.ts +++ b/extensions/cli/src/ui/__tests__/mocks/MockApiClient.ts @@ -1,12 +1,5 @@ // Mock API Client export class MockApiClient { - async getFreeTrialStatus() { - return { - optedInToFreeTrial: true, - chatCount: 5, - chatLimit: 100, - }; - } async listAssistants() { return []; } diff --git a/extensions/cli/src/ui/components/BottomStatusBar.tsx b/extensions/cli/src/ui/components/BottomStatusBar.tsx index e323911da0..7af52f4a53 100644 --- a/extensions/cli/src/ui/components/BottomStatusBar.tsx +++ b/extensions/cli/src/ui/components/BottomStatusBar.tsx @@ -4,7 +4,6 @@ import React, { useEffect, useState } from "react"; import { setExitMessageCallback, shouldShowExitMessage } from "../../index.js"; import type { PermissionMode } from "../../permissions/types.js"; import type { NavigationScreen } from "../context/NavigationContext.js"; -import { FreeTrialStatus } from "../FreeTrialStatus.js"; import { UpdateNotification } from "../UpdateNotification.js"; import { ContextPercentageDisplay } from "./ContextPercentageDisplay.js"; @@ -89,24 +88,7 @@ export const BottomStatusBar: React.FC = ({ )} - - {!isRemoteMode && services.model?.model && ( - { - if (shouldShow && navState.currentScreen === "chat") { - navigateTo("free-trial"); - } else if ( - !shouldShow && - navState.currentScreen === "free-trial" - ) { - closeCurrentScreen(); - } - }} - /> - )} - + diff --git a/extensions/cli/src/ui/components/ScreenContent.tsx b/extensions/cli/src/ui/components/ScreenContent.tsx index 516cb7811c..045101abc9 100644 --- a/extensions/cli/src/ui/components/ScreenContent.tsx +++ b/extensions/cli/src/ui/components/ScreenContent.tsx @@ -8,7 +8,6 @@ import { ConfigSelector } from "../ConfigSelector.js"; import type { NavigationScreen } from "../context/NavigationContext.js"; import { DiffViewer } from "../DiffViewer.js"; import { EditMessageSelector } from "../EditMessageSelector.js"; -import { FreeTrialTransitionUI } from "../FreeTrialTransitionUI.js"; import type { ActivePermissionRequest, ActiveQuizQuestion, @@ -169,11 +168,6 @@ export const ScreenContent: React.FC = ({ return ; } - // Free trial transition UI - if (isScreenActive("free-trial")) { - return ; - } - // Diff viewer overlay if (isScreenActive("diff")) { return ( diff --git a/extensions/cli/src/ui/context/NavigationContext.tsx b/extensions/cli/src/ui/context/NavigationContext.tsx index 04c1689f50..ca5ceb385c 100644 --- a/extensions/cli/src/ui/context/NavigationContext.tsx +++ b/extensions/cli/src/ui/context/NavigationContext.tsx @@ -14,7 +14,6 @@ export type NavigationScreen = | "chat" // Normal chat interface | "config" // Config selector (includes organization switching) | "model" // Model selector - | "free-trial" // Free trial transition UI | "login" // Login prompt | "mcp" // MCP selector | "session" // Session selector diff --git a/extensions/cli/src/ui/context/__tests__/NavigationContext.test.tsx b/extensions/cli/src/ui/context/__tests__/NavigationContext.test.tsx index d3da83ef75..a5508dfa85 100644 --- a/extensions/cli/src/ui/context/__tests__/NavigationContext.test.tsx +++ b/extensions/cli/src/ui/context/__tests__/NavigationContext.test.tsx @@ -78,7 +78,6 @@ describe("NavigationContext", () => { "chat", "config", "model", - "free-trial", "login", "mcp", ]; @@ -168,8 +167,8 @@ describe("NavigationContext", () => { it("closes from any screen back to chat", () => { const { result } = renderHook(() => useNavigation(), { wrapper }); const screens: Array< - "config" | "model" | "free-trial" | "login" | "mcp" - > = ["config", "model", "free-trial", "login", "mcp"]; + "config" | "model" | "login" | "mcp" + > = ["config", "model", "login", "mcp"]; screens.forEach((screen) => { act(() => { @@ -205,7 +204,6 @@ describe("NavigationContext", () => { expect(result.current.isScreenActive("config")).toBe(false); expect(result.current.isScreenActive("model")).toBe(false); expect(result.current.isScreenActive("mcp")).toBe(false); - expect(result.current.isScreenActive("free-trial")).toBe(false); expect(result.current.isScreenActive("login")).toBe(false); }); @@ -213,14 +211,14 @@ describe("NavigationContext", () => { const { result } = renderHook(() => useNavigation(), { wrapper }); act(() => { - result.current.navigateTo("free-trial"); + result.current.navigateTo("config"); }); - expect(result.current.isScreenActive("free-trial")).toBe(true); + expect(result.current.isScreenActive("config")).toBe(true); act(() => { result.current.navigateTo("model"); }); - expect(result.current.isScreenActive("free-trial")).toBe(false); + expect(result.current.isScreenActive("config")).toBe(false); expect(result.current.isScreenActive("model")).toBe(true); act(() => { @@ -308,29 +306,6 @@ describe("NavigationContext", () => { expect(result.current.isScreenActive("chat")).toBe(true); }); - it("handles free trial transition flow", () => { - const { result } = renderHook(() => useNavigation(), { wrapper }); - - // Show free trial screen - act(() => { - result.current.navigateTo("free-trial"); - }); - expect(result.current.isScreenActive("free-trial")).toBe(true); - - // User might navigate to config from free trial - act(() => { - result.current.navigateTo("config"); - }); - expect(result.current.isScreenActive("config")).toBe(true); - expect(result.current.isScreenActive("free-trial")).toBe(false); - - // Return to chat - act(() => { - result.current.closeCurrentScreen(); - }); - expect(result.current.isScreenActive("chat")).toBe(true); - }); - it("handles model switching flow", () => { const { result } = renderHook(() => useNavigation(), { wrapper }); diff --git a/gui/src/components/Layout.tsx b/gui/src/components/Layout.tsx index 440d8c2803..c82f1d60d9 100644 --- a/gui/src/components/Layout.tsx +++ b/gui/src/components/Layout.tsx @@ -145,22 +145,6 @@ const Layout = () => { [], ); - useWebviewListener( - "freeTrialExceeded", - async () => { - dispatch(setShowDialog(true)); - onboardingCard.setActiveTab(OnboardingModes.MODELS_ADD_ON); - dispatch( - setDialogMessage( -
- -
, - ), - ); - }, - [], - ); - useWebviewListener( "setupApiKey", async () => { diff --git a/gui/src/components/OnboardingCard/hooks/useOnboardingCard.ts b/gui/src/components/OnboardingCard/hooks/useOnboardingCard.ts index b3cbd644d1..12ab8582b0 100644 --- a/gui/src/components/OnboardingCard/hooks/useOnboardingCard.ts +++ b/gui/src/components/OnboardingCard/hooks/useOnboardingCard.ts @@ -30,8 +30,7 @@ export function useOnboardingCard(): UseOnboardingCard { let show: boolean; - // Always show if we explicitly want to, e.g. passing free trial - // and setting up keys + // Always show if we explicitly want to, e.g. setting up keys if (onboardingCard.show) { show = true; } else { diff --git a/gui/src/components/StarterCreditsButton.tsx b/gui/src/components/StarterCreditsButton.tsx deleted file mode 100644 index 51f58d16e1..0000000000 --- a/gui/src/components/StarterCreditsButton.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { GiftIcon } from "@heroicons/react/24/outline"; -import { CreditStatus } from "core/control-plane/client"; -import StarterCreditsPopover from "./StarterCreditsPopover"; - -interface FreeTrialButtonProps { - creditStatus?: CreditStatus | null; - refreshCreditStatus?: () => Promise; -} - -/** - * @deprecated Use StarterCreditsPopover with a custom button/icon instead. - * This component is kept for backward compatibility. - */ -export default function StarterCreditsButton({ - creditStatus, - refreshCreditStatus, -}: FreeTrialButtonProps) { - return ( - - - - - - ); -} diff --git a/gui/src/components/StarterCreditsPopover.tsx b/gui/src/components/StarterCreditsPopover.tsx deleted file mode 100644 index c80777199e..0000000000 --- a/gui/src/components/StarterCreditsPopover.tsx +++ /dev/null @@ -1,196 +0,0 @@ -import { - ArrowPathIcon, - GiftIcon, - XMarkIcon, -} from "@heroicons/react/24/outline"; -import { CreditStatus } from "core/control-plane/client"; -import { useContext, useState } from "react"; -import { Button, SecondaryButton, vscButtonBackground } from "."; -import { useAuth } from "../context/Auth"; -import { IdeMessengerContext } from "../context/IdeMessenger"; -import { cn } from "../util/cn"; -import { setLocalStorage } from "../util/localStorage"; -import { ToolbarButtonWithTooltip } from "./StyledMarkdownPreview/StepContainerPreToolbar/ToolbarButtonWithTooltip"; -import { Listbox, ListboxButton, ListboxOptions, Transition } from "./ui"; - -interface ProgressBarProps { - label: string; - current: number; - total: number; -} - -function ProgressBar({ label, current, total }: ProgressBarProps) { - const percentage = Math.min((current / total) * 100, 100); - - return ( -
-
- {label} - - ${(current / 100).toFixed(2)} / ${(total / 100).toFixed(2)} - -
-
-
-
-
- ); -} - -interface CreditStatusProgressBarsProps { - creditStatus: CreditStatus; -} - -function CreditStatusProgressBar({ - creditStatus, -}: CreditStatusProgressBarsProps) { - const total = 50; - const usage = total - (creditStatus.creditBalance ?? 0); - - return ( - - ); -} - -interface StarterCreditsPopoverProps { - creditStatus?: CreditStatus | null; - refreshCreditStatus?: () => Promise; - children: React.ReactNode; -} - -export default function StarterCreditsPopover({ - creditStatus, - refreshCreditStatus, - children, -}: StarterCreditsPopoverProps) { - const ideMessenger = useContext(IdeMessengerContext); - const { refreshProfiles } = useAuth(); - const [isRefreshing, setIsRefreshing] = useState(false); - - const onSetupApiKeys = async () => { - await ideMessenger.request("controlPlane/openUrl", { - path: "setup-models/api-keys", - orgSlug: undefined, - }); - }; - - const onPurchaseCredits = async () => { - await ideMessenger.request("controlPlane/openUrl", { - path: "settings/billing", - orgSlug: undefined, - }); - }; - - const onHideStarterCreditsUsage = async () => { - // At this point the user doesn't want to see the credit usage UI, so we make sure this is gone right away - setLocalStorage("hasExitedFreeTrial", true); - }; - - const onRefresh = async () => { - if (isRefreshing) { - return; - } - - setIsRefreshing(true); - - const refreshCalls: Promise[] = [ - refreshProfiles("Manual refresh from starter credits button"), - ]; - - if (refreshCreditStatus) { - refreshCalls.push(refreshCreditStatus()); - } - - try { - await Promise.all(refreshCalls); - } finally { - setIsRefreshing(false); - } - }; - - return ( - - - {children} - - - - -
-
- -

Starter credits

-
-
- { - void onRefresh(); - }} - tooltipContent="Refresh credit usage" - > - - - - - -
- -
- - You are currently using starter credits for Continue, which - allows you to use a variety of frontier models at cost. Read - more{" "} - { - await ideMessenger.request("controlPlane/openUrl", { - path: "pricing", - orgSlug: undefined, - }); - ``; - }} - className="cursor-pointer text-blue-400 underline hover:text-blue-300" - > - here - - . - -
- - {!creditStatus ? ( -
- - Loading credit usage... - -
- ) : ( - - )} - -
- - Setup API Keys - - -
-
-
-
-
- ); -} diff --git a/gui/src/components/mainInput/Lump/LumpToolbar/BlockSettingsTopToolbar.tsx b/gui/src/components/mainInput/Lump/LumpToolbar/BlockSettingsTopToolbar.tsx index 2f022ea5a5..e6ed1a0124 100644 --- a/gui/src/components/mainInput/Lump/LumpToolbar/BlockSettingsTopToolbar.tsx +++ b/gui/src/components/mainInput/Lump/LumpToolbar/BlockSettingsTopToolbar.tsx @@ -1,7 +1,6 @@ import { CubeIcon, ExclamationTriangleIcon, - GiftIcon, PencilIcon, WrenchScrewdriverIcon, } from "@heroicons/react/24/outline"; @@ -14,12 +13,10 @@ import { selectToolCallsByStatus, } from "../../../../redux/selectors/selectToolCalls"; import { setSelectedProfile } from "../../../../redux/slices/profilesSlice"; -import StarterCreditsPopover from "../../../StarterCreditsPopover"; import { ToolTip } from "../../../gui/Tooltip"; import HoverItem from "../../InputToolbar/HoverItem"; import { useAuth } from "../../../../context/Auth"; -import { useCreditStatus } from "../../../../hooks/useCredits"; import { CONFIG_ROUTES } from "../../../../util/navigation"; import { AssistantAndOrgListbox } from "../../../AssistantAndOrgListbox"; @@ -40,9 +37,6 @@ export function BlockSettingsTopToolbar() { const shouldShowError = configError && configError?.length > 0; - const { creditStatus, isUsingFreeTrial, refreshCreditStatus } = - useCreditStatus(); - const handleRulesClick = () => { if (selectedProfile) { dispatch(setSelectedProfile(selectedProfile.id)); @@ -101,19 +95,6 @@ export function BlockSettingsTopToolbar() { {!hasActiveContent && (
- {isUsingFreeTrial && ( - - - - - - - - )} - diff --git a/gui/src/hooks/useCredits.ts b/gui/src/hooks/useCredits.ts index 8f2a4bb45b..cd9a841ec3 100644 --- a/gui/src/hooks/useCredits.ts +++ b/gui/src/hooks/useCredits.ts @@ -1,23 +1,11 @@ -import { usesCreditsBasedApiKey } from "core/config/usesFreeTrialApiKey"; import { CreditStatus } from "core/control-plane/client"; -import { isOutOfStarterCredits } from "core/llm/utils/starterCredits"; import { useCallback, useContext, useEffect, useState } from "react"; import { IdeMessengerContext } from "../context/IdeMessenger"; -import { useAppSelector } from "../redux/hooks"; -import { getLocalStorage } from "../util/localStorage"; export function useCreditStatus() { - const config = useAppSelector((state) => state.config.config); const ideMessenger = useContext(IdeMessengerContext); const [creditStatus, setCreditStatus] = useState(null); - const hasExitedFreeTrial = getLocalStorage("hasExitedFreeTrial"); - const usingCreditsBasedApiKey = usesCreditsBasedApiKey(config); - const isUsingFreeTrial = usingCreditsBasedApiKey && !hasExitedFreeTrial; - const outOfStarterCredits = creditStatus - ? isOutOfStarterCredits(usingCreditsBasedApiKey, creditStatus) - : false; - const refreshCreditStatus = useCallback(async () => { try { const resp = await ideMessenger.request( @@ -32,28 +20,13 @@ export function useCreditStatus() { } }, [ideMessenger]); + // One-time fetch on mount — no polling useEffect(() => { void refreshCreditStatus(); - - let intervalId: NodeJS.Timeout | null = null; - - if (isUsingFreeTrial) { - intervalId = setInterval(() => { - void refreshCreditStatus(); - }, 15000); - } - - return () => { - if (intervalId) { - clearInterval(intervalId); - } - }; - }, [isUsingFreeTrial, refreshCreditStatus]); + }, [refreshCreditStatus]); return { creditStatus, - outOfStarterCredits, - isUsingFreeTrial, refreshCreditStatus, }; } From ab84469997e0d15e25caa7c85610cc80c80b82b7 Mon Sep 17 00:00:00 2001 From: Nate Date: Fri, 20 Mar 2026 14:04:06 -0700 Subject: [PATCH 4/7] style: fix prettier formatting Co-Authored-By: Claude Opus 4.6 (1M context) --- docs-site/app/[[...slug]]/page.tsx | 25 ++++- docs-site/app/components/ClientRedirect.tsx | 6 +- docs-site/app/components/NotFoundPage.tsx | 11 ++- docs-site/app/layout.tsx | 3 +- docs-site/components/docs/CopyPageButton.tsx | 2 +- docs-site/components/docs/DocsSearch.tsx | 24 +++-- docs-site/components/docs/DocsShell.tsx | 97 +++++++++++-------- docs-site/components/docs/PageNav.tsx | 6 +- docs-site/components/docs/TableOfContents.tsx | 16 ++- docs-site/components/docs/mdx/Callout.tsx | 4 +- docs-site/components/docs/mdx/CardGroup.tsx | 25 ++--- docs-site/components/docs/mdx/CodeBlock.tsx | 6 +- docs-site/components/docs/mdx/CodeGroup.tsx | 10 +- docs-site/components/docs/mdx/Columns.tsx | 9 +- .../components/docs/mdx/DocsAccordion.tsx | 20 ++-- docs-site/components/docs/mdx/DocsTabs.tsx | 2 +- .../components/docs/mdx/OSAutoDetect.tsx | 4 +- docs-site/components/ui/command.tsx | 24 +++-- docs-site/components/ui/dialog.tsx | 10 +- docs-site/lib/docs.ts | 35 +++---- docs-site/lib/resolveHref.ts | 3 +- docs-site/scripts/build-search-index.ts | 9 +- docs-site/scripts/copy-doc-images.ts | 10 +- docs-site/tsconfig.json | 14 +-- .../__tests__/NavigationContext.test.tsx | 9 +- .../RecentlyVisitedRangesService.ts | 1 - gui/src/components/Layout.tsx | 71 +++++++------- gui/src/redux/thunks/streamThunkWrapper.tsx | 3 +- gui/vite.config.ts | 5 +- package-lock.json | 4 + 30 files changed, 255 insertions(+), 213 deletions(-) diff --git a/docs-site/app/[[...slug]]/page.tsx b/docs-site/app/[[...slug]]/page.tsx index 873aa13703..94b6c05428 100644 --- a/docs-site/app/[[...slug]]/page.tsx +++ b/docs-site/app/[[...slug]]/page.tsx @@ -6,7 +6,15 @@ import remarkGfm from "remark-gfm"; import rehypeSlug from "rehype-slug"; import rehypeAutolinkHeadings from "rehype-autolink-headings"; import rehypePrismPlus from "rehype-prism-plus"; -import { loadMdxFile, getHeadings, getAllDocTitles, getAllDocSlugs, docsNav, resolveDocsRedirect, docsRedirects } from "@/lib/docs"; +import { + loadMdxFile, + getHeadings, + getAllDocTitles, + getAllDocSlugs, + docsNav, + resolveDocsRedirect, + docsRedirects, +} from "@/lib/docs"; import { getPageNavigation } from "@/config/docsNav"; import { mdxComponents } from "@/components/docs/mdx"; import { DocsShell } from "@/components/docs/DocsShell"; @@ -58,7 +66,9 @@ export default async function DocsPage({ params }: Props) { // Check redirect first const redirectTo = resolveDocsRedirect(slugPath); if (redirectTo) { - const target = redirectTo.startsWith("http") ? redirectTo : `/docs${redirectTo}`; + const target = redirectTo.startsWith("http") + ? redirectTo + : `/docs${redirectTo}`; return ; } @@ -95,9 +105,14 @@ export default async function DocsPage({ params }: Props) { const { prev, next } = getPageNavigation(docsNav, currentSlug, titleMap); return ( - + {doc.frontmatter.title && ( -
+

{doc.frontmatter.title}

@@ -105,7 +120,7 @@ export default async function DocsPage({ params }: Props) {
)} {doc.frontmatter.description && ( -

+

{doc.frontmatter.description.replace(/\*\*/g, "")}

)} diff --git a/docs-site/app/components/ClientRedirect.tsx b/docs-site/app/components/ClientRedirect.tsx index 1623c4e998..99c3f07afb 100644 --- a/docs-site/app/components/ClientRedirect.tsx +++ b/docs-site/app/components/ClientRedirect.tsx @@ -8,10 +8,8 @@ export function ClientRedirect({ to }: { to: string }) { }, [to]); return ( -
-

- Redirecting... -

+
+

Redirecting...

); } diff --git a/docs-site/app/components/NotFoundPage.tsx b/docs-site/app/components/NotFoundPage.tsx index f0bd602d5c..50e984cba0 100644 --- a/docs-site/app/components/NotFoundPage.tsx +++ b/docs-site/app/components/NotFoundPage.tsx @@ -2,9 +2,14 @@ import Link from "next/link"; export default function NotFoundPage() { return ( -
-

Page not found

- +
+

+ Page not found +

+ Back to docs
diff --git a/docs-site/app/layout.tsx b/docs-site/app/layout.tsx index ea2ca44cdc..ced9a7e340 100644 --- a/docs-site/app/layout.tsx +++ b/docs-site/app/layout.tsx @@ -7,7 +7,8 @@ import "./docs.css"; export const metadata: Metadata = { title: "Continue Docs", - description: "Documentation for Continue — the open-source AI code assistant.", + description: + "Documentation for Continue — the open-source AI code assistant.", }; export default function RootLayout({ diff --git a/docs-site/components/docs/CopyPageButton.tsx b/docs-site/components/docs/CopyPageButton.tsx index 73ec5c08a0..869cb3ee4d 100644 --- a/docs-site/components/docs/CopyPageButton.tsx +++ b/docs-site/components/docs/CopyPageButton.tsx @@ -19,7 +19,7 @@ export function CopyPageButton({ slug }: { slug: string }) { return ( - + string }) { /> {loading ? ( -
+
Loading search index...
) : ( @@ -125,7 +135,7 @@ export function DocsSearch({ resolve }: { resolve: (path: string) => string }) { >
{result.title} - + {result.content.slice(0, 120)}
diff --git a/docs-site/components/docs/DocsShell.tsx b/docs-site/components/docs/DocsShell.tsx index ec7ef01cca..b1e60180c7 100644 --- a/docs-site/components/docs/DocsShell.tsx +++ b/docs-site/components/docs/DocsShell.tsx @@ -66,13 +66,13 @@ function ThemeToggle() { useEffect(() => setMounted(true), []); if (!mounted) { - return
; + return
; } return ( {open && ( -
+
{group.pages.map((item, i) => ( {slugToLabel(item, titleMap)} @@ -188,7 +188,13 @@ function SidebarItem({ } return ( - + ); } @@ -213,19 +219,20 @@ export function DocsShell({ const [selectedTab, setSelectedTab] = useState(activeTab.tab); const [mobileOpen, setMobileOpen] = useState(false); const [mobileMenuOpen, setMobileMenuOpen] = useState(false); - const currentTab = - docsNav.find((t) => t.tab === selectedTab) ?? docsNav[0]!; + const currentTab = docsNav.find((t) => t.tab === selectedTab) ?? docsNav[0]!; const navLinks = NAV_LINKS; return ( -
+
{/* ---- Header: nav + tabs ---- */} -
+
{/* Top nav bar */}