diff --git a/.gitignore b/.gitignore index ee81e8959..a7ceeebe7 100644 --- a/.gitignore +++ b/.gitignore @@ -28,4 +28,3 @@ dist # Content Collections generated files .content-collections -test-results diff --git a/.npmrc b/.npmrc new file mode 100644 index 000000000..8cd4bdac2 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +public-hoist-pattern[]=@takumi-rs/core-* \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index f9bd95c4f..f74609922 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -40,38 +40,6 @@ const value = getValue() // Type inferred from function implementation If types need to be fixed, fix them at the source (schema, API definition, function signature) rather than casting at the point of use. -### Generic Type Parameter Naming - -**All generic type parameters must be prefixed with `T`.** - -This convention makes it immediately clear that a name refers to a type parameter rather than a concrete type or value. - -❌ **Bad:** - -```typescript -function withCapability( - handler: (user: AuthUser, ...args: Args) => R, -) { ... } -``` - -✅ **Good:** - -```typescript -function withCapability( - handler: (user: AuthUser, ...args: TArgs) => TReturn, -) { ... } -``` - -Common examples: - -- `T` for a single generic type -- `TArgs` for argument types -- `TReturn` for return types -- `TData` for data types -- `TError` for error types -- `TKey` for key types -- `TValue` for value types - ## Route Loaders ### loaderDeps Must Be Specific diff --git a/docs/mcp/config.json b/docs/mcp/config.json deleted file mode 100644 index 945453f92..000000000 --- a/docs/mcp/config.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "$schema": "https://tanstack.com/tanstack-docs-config.schema.json", - "docSearch": { - "appId": "FQ0DQ6MA3C", - "apiKey": "10c34d6a5c89f6048cf644d601e65172", - "indexName": "tanstack-test" - }, - "sections": [ - { - "label": "Getting Started", - "children": [ - { "label": "Overview", "to": "overview" }, - { "label": "Connecting", "to": "connecting" } - ] - }, - { - "label": "Reference", - "children": [{ "label": "Available Tools", "to": "tools" }] - } - ] -} diff --git a/docs/mcp/connecting.md b/docs/mcp/connecting.md deleted file mode 100644 index 5476b12b9..000000000 --- a/docs/mcp/connecting.md +++ /dev/null @@ -1,165 +0,0 @@ ---- -id: connecting -title: Connecting ---- - -The TanStack MCP Server is available at `https://tanstack.com/api/mcp` and uses the Streamable HTTP transport. Authentication via API key is required. - -## Getting an API Key - -Before connecting, you'll need to create an API key: - -1. [Sign in to your TanStack account](/login) -2. Go to [API Keys](/account/api-keys) -3. Click "New Key" and give it a descriptive name -4. Copy the key immediately (you won't see it again) - -> [!NOTE] -> Replace `YOUR_API_KEY` in the examples below with your actual API key. - -## OpenCode - -Add to your OpenCode MCP configuration in `~/.config/opencode/config.json`: - -```json -{ - "mcp": { - "servers": { - "tanstack": { - "type": "remote", - "url": "https://tanstack.com/api/mcp", - "headers": { - "Authorization": "Bearer YOUR_API_KEY" - } - } - } - } -} -``` - -## Claude Code - -```bash -claude mcp add --transport http tanstack https://tanstack.com/api/mcp --header "Authorization: Bearer YOUR_API_KEY" -``` - -## Cursor - -Add to your Cursor MCP configuration: - -```json -{ - "mcpServers": { - "tanstack": { - "command": "npx", - "args": ["mcp-remote", "https://tanstack.com/api/mcp"], - "env": { - "MCP_HEADERS": "Authorization: Bearer YOUR_API_KEY" - } - } - } -} -``` - -## VS Code - -Add to your VS Code settings or `.vscode/mcp.json`: - -```json -{ - "servers": { - "tanstack": { - "type": "http", - "url": "https://tanstack.com/api/mcp", - "headers": { - "Authorization": "Bearer YOUR_API_KEY" - } - } - } -} -``` - -## Claude Desktop - -Add the following to your Claude Desktop configuration file: - -**macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json` -**Windows:** `%APPDATA%\Claude\claude_desktop_config.json` - -```json -{ - "mcpServers": { - "tanstack": { - "command": "npx", - "args": ["mcp-remote", "https://tanstack.com/api/mcp"], - "env": { - "MCP_HEADERS": "Authorization: Bearer YOUR_API_KEY" - } - } - } -} -``` - -Restart Claude Desktop after updating the configuration. - -## Windsurf - -Add to your Windsurf MCP configuration: - -```json -{ - "mcpServers": { - "tanstack": { - "serverUrl": "https://tanstack.com/api/mcp", - "headers": { - "Authorization": "Bearer YOUR_API_KEY" - } - } - } -} -``` - -## MCP Inspector - -Use the MCP Inspector to test the server interactively: - -```bash -npx @modelcontextprotocol/inspector https://tanstack.com/api/mcp --header "Authorization: Bearer YOUR_API_KEY" -``` - -## Custom Integration - -For custom integrations, the server accepts standard MCP requests via HTTP: - -- **Endpoint:** `https://tanstack.com/api/mcp` -- **Transport:** Streamable HTTP (stateless) -- **Methods:** POST (for requests), GET (for server-sent events), DELETE (for session cleanup) -- **Authentication:** Bearer token via Authorization header - -Example request using curl: - -```bash -curl -X POST https://tanstack.com/api/mcp \ - -H "Content-Type: application/json" \ - -H "Authorization: Bearer YOUR_API_KEY" \ - -d '{ - "jsonrpc": "2.0", - "id": 1, - "method": "tools/list" - }' -``` - -## Rate Limits - -API requests are rate-limited to protect the service: - -- **Authenticated requests:** 60 requests per minute -- Rate limit headers are included in responses (`X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`) - -## Verifying Connection - -After connecting, ask your AI assistant to list TanStack libraries: - -> "Use the TanStack MCP to list all available libraries" - -You should see a list of all TanStack libraries with their versions and descriptions. diff --git a/docs/mcp/overview.md b/docs/mcp/overview.md deleted file mode 100644 index 7e8388fef..000000000 --- a/docs/mcp/overview.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -id: overview -title: Overview ---- - -TanStack MCP Server provides AI assistants with direct access to TanStack documentation through the [Model Context Protocol](https://modelcontextprotocol.io). This allows AI tools like Claude, Cursor, and others to search and retrieve up-to-date documentation for all TanStack libraries. - -## Why Use the MCP Server? - -AI assistants are trained on snapshots of documentation that become stale over time. The TanStack MCP Server solves this by giving AI tools real-time access to: - -- **Current documentation** for all TanStack libraries (Router, Query, Table, Form, Virtual, Store, and more) -- **Version-specific docs** for the exact version you're using -- **Full-text search** across all documentation - -## Quick Start - -Copy and paste the following instructions to your AI agent: - -> [!NOTE] -> Replace `YOUR_API_KEY` with an API key from [tanstack.com/account/api-keys](/account/api-keys) - -``` -Connect to the TanStack MCP server with these settings: - -URL: https://tanstack.com/api/mcp -Transport: Streamable HTTP -Authorization Header: Bearer YOUR_API_KEY -``` - -See [Connecting](./connecting) for client-specific setup instructions. - -## Available Tools - -The MCP server exposes three tools: - -| Tool | Description | -| ---------------- | ------------------------------------------------------------ | -| `list_libraries` | List all TanStack libraries with their versions and metadata | -| `get_doc` | Fetch a specific documentation page by library and path | -| `search_docs` | Full-text search across all TanStack documentation | - -See [Available Tools](./tools) for detailed parameter documentation. - -## How It Works - -The TanStack MCP Server uses the Streamable HTTP transport, making it compatible with serverless deployments and any MCP client that supports HTTP transport. When your AI assistant needs TanStack documentation, it calls the appropriate tool and receives the content directly. - -``` -AI Assistant → MCP Client → TanStack MCP Server → Documentation -``` - -All documentation is fetched directly from the TanStack GitHub repositories, ensuring you always get the most current content for your specified version. diff --git a/docs/mcp/tools.md b/docs/mcp/tools.md deleted file mode 100644 index c3399350f..000000000 --- a/docs/mcp/tools.md +++ /dev/null @@ -1,143 +0,0 @@ ---- -id: tools -title: Available Tools ---- - -The TanStack MCP Server exposes three tools for accessing documentation. Each tool is designed for a specific use case. - -## list_libraries - -List all available TanStack libraries with their metadata. - -### Parameters - -| Parameter | Type | Required | Description | -| --------- | ------ | -------- | ------------------------------------------------------------------- | -| `group` | string | No | Filter by group: `state`, `headlessUI`, `performance`, or `tooling` | - -### Response - -Returns an object containing: - -- `group` - The group name or "All Libraries" -- `count` - Number of libraries returned -- `libraries` - Array of library objects with `id`, `name`, `tagline`, `description`, `frameworks`, `latestVersion`, `docsUrl`, and `githubUrl` - -### Example - -```json -{ - "name": "list_libraries", - "arguments": { - "group": "state" - } -} -``` - ---- - -## get_doc - -Fetch a specific documentation page by library and path. - -### Parameters - -| Parameter | Type | Required | Description | -| --------- | ------ | -------- | --------------------------------------------------------------------------------------- | -| `library` | string | Yes | Library ID (e.g., `query`, `router`, `table`, `form`) | -| `path` | string | Yes | Documentation path (e.g., `framework/react/overview`, `framework/react/guides/queries`) | -| `version` | string | No | Version (e.g., `v5`, `v1`). Defaults to `latest` | - -### Response - -Returns an object containing: - -- `title` - Document title from frontmatter -- `content` - Full markdown content of the document -- `url` - Canonical URL to the documentation page -- `library` - Library name -- `version` - Resolved version - -### Example - -```json -{ - "name": "get_doc", - "arguments": { - "library": "query", - "path": "framework/react/guides/queries", - "version": "v5" - } -} -``` - -### Common Documentation Paths - -Most TanStack libraries follow this path structure: - -- `framework/{framework}/overview` - Framework-specific overview -- `framework/{framework}/installation` - Installation guide -- `framework/{framework}/guides/{topic}` - Guides for specific topics -- `framework/{framework}/reference/{api}` - API reference - -Where `{framework}` is one of: `react`, `vue`, `solid`, `svelte`, `angular` - ---- - -## search_docs - -Full-text search across all TanStack documentation. - -### Parameters - -| Parameter | Type | Required | Description | -| ----------- | ------ | -------- | ------------------------------------------------------------ | -| `query` | string | Yes | Search query | -| `library` | string | No | Filter to specific library (e.g., `query`, `router`) | -| `framework` | string | No | Filter to specific framework (e.g., `react`, `vue`, `solid`) | -| `limit` | number | No | Maximum results (default: 10, max: 50) | - -### Response - -Returns an object containing: - -- `query` - The search query -- `totalHits` - Total number of matching documents -- `results` - Array of search results with `title`, `url`, `snippet`, `library`, and `breadcrumb` - -### Example - -```json -{ - "name": "search_docs", - "arguments": { - "query": "useQuery refetch", - "library": "query", - "framework": "react", - "limit": 5 - } -} -``` - ---- - -## Usage Tips - -### Finding Documentation - -1. **Start with `list_libraries`** to discover available libraries and their IDs -2. **Use `search_docs`** to find specific topics when you don't know the exact path -3. **Use `get_doc`** to fetch the full content once you know the path - -### Version Handling - -- Use `latest` (default) to always get the current documentation -- Specify a version like `v5` or `v4` when working with a specific library version -- The `list_libraries` tool shows available versions for each library - -### Path Discovery - -Search results include URLs that reveal the documentation path structure. For example, a URL like `https://tanstack.com/query/latest/docs/framework/react/guides/queries` indicates: - -- Library: `query` -- Path: `framework/react/guides/queries` diff --git a/netlify.toml b/netlify.toml index 5359cbbca..9a9140ee6 100644 --- a/netlify.toml +++ b/netlify.toml @@ -6,18 +6,6 @@ publish = "dist/client" [functions] + node_bundler = "esbuild" directory = "netlify/functions" - -[[headers]] - for = "/*" - [headers.values] - X-Frame-Options = "DENY" - X-Content-Type-Options = "nosniff" - X-XSS-Protection = "1; mode=block" - Referrer-Policy = "strict-origin-when-cross-origin" - Permissions-Policy = "camera=(), microphone=(), geolocation=()" - -[[headers]] - for = "/*" - [headers.values] - Strict-Transport-Security = "max-age=31536000; includeSubDomains" + included_files = ["node_modules/@takumi-rs/core-linux-x64-gnu/**/*.*"] \ No newline at end of file diff --git a/package.json b/package.json index bed411060..81e662bcc 100644 --- a/package.json +++ b/package.json @@ -17,15 +17,11 @@ "db:generate": "drizzle-kit generate", "db:migrate": "drizzle-kit migrate", "db:push": "drizzle-kit push", - "db:studio": "drizzle-kit studio", - "test": "pnpm run test:smoke", - "test:smoke": "playwright test" + "db:studio": "drizzle-kit studio" }, "dependencies": { "@auth/core": "0.37.0", "@floating-ui/react": "^0.27.8", - "@hono/mcp": "^0.2.3", - "@modelcontextprotocol/sdk": "^1.25.2", "@netlify/functions": "^5.1.0", "@netlify/neon": "^0.1.0", "@netlify/vite-plugin-tanstack-start": "^1.0.2", @@ -35,12 +31,11 @@ "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.12", "@radix-ui/react-toast": "^1.2.2", - "@react-three/drei": "^10.7.7", - "@react-three/fiber": "^9.5.0", "@sentry/react": "^8.35.0", "@sentry/vite-plugin": "^2.22.6", "@tailwindcss/typography": "^0.5.13", "@tailwindcss/vite": "^4.1.11", + "@takumi-rs/image-response": "^0.62.6", "@tanstack/pacer": "^0.16.4", "@tanstack/react-pacer": "^0.17.4", "@tanstack/react-query": "^5.90.12", @@ -59,13 +54,11 @@ "cmdk": "^1.1.1", "d3": "^7.9.0", "date-fns": "^2.30.0", - "discord-interactions": "^4.4.0", "drizzle-orm": "^0.44.7", "eslint-plugin-jsx-a11y": "^6.10.2", "gray-matter": "^4.0.3", "hast-util-is-element": "^3.0.0", "hast-util-to-string": "^3.0.1", - "hono": "^4.11.3", "html-react-parser": "^5.1.10", "lru-cache": "^7.13.1", "lucide-react": "^0.561.0", @@ -89,30 +82,24 @@ "resend": "^6.6.0", "shiki": "^1.4.0", "tailwind-merge": "^1.14.0", - "three": "^0.182.0", - "troika-three-text": "^0.52.4", "unified": "^11.0.5", "unist-util-visit": "^5.0.0", "uploadthing": "^7.7.4", "valibot": "^1.2.0", "vite-bundle-analyzer": "^1.2.1", "vite-tsconfig-paths": "^5.0.1", - "zod": "^4.3.5", "zustand": "^4.5.2" }, "devDependencies": { "@content-collections/core": "^0.8.2", "@content-collections/vite": "^0.2.4", "@eslint/js": "^9.39.1", - "@playwright/test": "^1.57.0", "@shikijs/transformers": "^1.10.3", - "@types/hast": "^3.0.4", "@types/node": "^24.3.0", "@types/pg": "^8.15.6", "@types/react": "^19.2.0", "@types/react-dom": "^19.2.0", "@types/remove-markdown": "^0.3.4", - "@types/three": "^0.182.0", "autoprefixer": "^10.4.18", "dotenv-cli": "^8.0.0", "drizzle-kit": "^0.31.7", @@ -133,17 +120,6 @@ "engines": { "node": ">=18.0.0" }, - "pnpm": { - "overrides": { - "cross-spawn": ">=6.0.6", - "glob": ">=10.5.0", - "node-forge": ">=1.3.2", - "jws": ">=3.2.3", - "qs": ">=6.14.1", - "js-yaml": ">=3.14.2", - "brace-expansion": ">=1.1.12" - } - }, "_pnpm": { "overrides": { "@tanstack/react-router": "file:../router/packages/react-router", diff --git a/playwright.config.ts b/playwright.config.ts deleted file mode 100644 index d5c78a05b..000000000 --- a/playwright.config.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { defineConfig } from '@playwright/test' - -export default defineConfig({ - testDir: './tests', - fullyParallel: true, - forbidOnly: !!process.env.CI, - retries: 0, - workers: 1, - reporter: 'list', - timeout: 30000, - use: { - baseURL: 'http://localhost:3000', - trace: 'off', - video: 'off', - screenshot: 'off', - }, - webServer: { - command: 'pnpm dev', - url: 'http://localhost:3000', - reuseExistingServer: !process.env.CI, - timeout: 120000, - }, - projects: [ - { - name: 'chromium', - use: { browserName: 'chromium', headless: true }, - }, - ], -}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index deb943c3e..c51e7392c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,15 +4,6 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false -overrides: - cross-spawn: '>=6.0.6' - glob: '>=10.5.0' - node-forge: '>=1.3.2' - jws: '>=3.2.3' - qs: '>=6.14.1' - js-yaml: '>=3.14.2' - brace-expansion: '>=1.1.12' - importers: .: @@ -23,12 +14,6 @@ importers: '@floating-ui/react': specifier: ^0.27.8 version: 0.27.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@hono/mcp': - specifier: ^0.2.3 - version: 0.2.3(@modelcontextprotocol/sdk@1.25.2(hono@4.11.3)(zod@4.3.5))(hono-rate-limiter@0.4.2(hono@4.11.3))(hono@4.11.3)(zod@4.3.5) - '@modelcontextprotocol/sdk': - specifier: ^1.25.2 - version: 1.25.2(hono@4.11.3)(zod@4.3.5) '@netlify/functions': specifier: ^5.1.0 version: 5.1.0 @@ -37,7 +22,7 @@ importers: version: 0.1.0 '@netlify/vite-plugin-tanstack-start': specifier: ^1.0.2 - version: 1.0.2(@tanstack/react-start@1.141.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.1.7(@types/node@24.3.0)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1)))(babel-plugin-macros@3.1.0)(rollup@4.53.3)(uploadthing@7.7.4(express@5.2.1)(h3@1.15.4)(tailwindcss@4.1.11))(vite@7.1.7(@types/node@24.3.0)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1)) + version: 1.0.2(@tanstack/react-start@1.141.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.1.7(@types/node@24.3.0)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1)))(babel-plugin-macros@3.1.0)(rollup@4.53.3)(uploadthing@7.7.4(h3@1.15.4)(tailwindcss@4.1.11))(vite@7.1.7(@types/node@24.3.0)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1)) '@number-flow/react': specifier: ^0.4.1 version: 0.4.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -56,12 +41,6 @@ importers: '@radix-ui/react-toast': specifier: ^1.2.2 version: 1.2.15(@types/react-dom@19.2.3(@types/react@19.2.5))(@types/react@19.2.5)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@react-three/drei': - specifier: ^10.7.7 - version: 10.7.7(@react-three/fiber@9.5.0(@types/react@19.2.5)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(three@0.182.0))(@types/react@19.2.5)(@types/three@0.182.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(three@0.182.0) - '@react-three/fiber': - specifier: ^9.5.0 - version: 9.5.0(@types/react@19.2.5)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(three@0.182.0) '@sentry/react': specifier: ^8.35.0 version: 8.35.0(react@19.2.0) @@ -74,6 +53,9 @@ importers: '@tailwindcss/vite': specifier: ^4.1.11 version: 4.1.11(vite@7.1.7(@types/node@24.3.0)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1)) + '@takumi-rs/image-response': + specifier: ^0.62.6 + version: 0.62.6 '@tanstack/pacer': specifier: ^0.16.4 version: 0.16.4 @@ -103,7 +85,7 @@ importers: version: 7.4.3 '@uploadthing/react': specifier: ^7.3.3 - version: 7.3.3(react@19.2.0)(uploadthing@7.7.4(express@5.2.1)(h3@1.15.4)(tailwindcss@4.1.11)) + version: 7.3.3(react@19.2.0)(uploadthing@7.7.4(h3@1.15.4)(tailwindcss@4.1.11)) '@visx/hierarchy': specifier: ^2.10.0 version: 2.17.0(react@19.2.0) @@ -128,9 +110,6 @@ importers: date-fns: specifier: ^2.30.0 version: 2.30.0 - discord-interactions: - specifier: ^4.4.0 - version: 4.4.0 drizzle-orm: specifier: ^0.44.7 version: 0.44.7(@neondatabase/serverless@0.10.4)(@types/pg@8.15.6)(kysely@0.28.5)(postgres@3.4.7) @@ -146,9 +125,6 @@ importers: hast-util-to-string: specifier: ^3.0.1 version: 3.0.1 - hono: - specifier: ^4.11.3 - version: 4.11.3 html-react-parser: specifier: ^5.1.10 version: 5.1.10(@types/react@19.2.5)(react@19.2.0) @@ -218,12 +194,6 @@ importers: tailwind-merge: specifier: ^1.14.0 version: 1.14.0 - three: - specifier: ^0.182.0 - version: 0.182.0 - troika-three-text: - specifier: ^0.52.4 - version: 0.52.4(three@0.182.0) unified: specifier: ^11.0.5 version: 11.0.5 @@ -232,7 +202,7 @@ importers: version: 5.0.0 uploadthing: specifier: ^7.7.4 - version: 7.7.4(express@5.2.1)(h3@1.15.4)(tailwindcss@4.1.11) + version: 7.7.4(h3@1.15.4)(tailwindcss@4.1.11) valibot: specifier: ^1.2.0 version: 1.2.0(typescript@5.9.2) @@ -242,9 +212,6 @@ importers: vite-tsconfig-paths: specifier: ^5.0.1 version: 5.0.1(typescript@5.9.2)(vite@7.1.7(@types/node@24.3.0)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1)) - zod: - specifier: ^4.3.5 - version: 4.3.5 zustand: specifier: ^4.5.2 version: 4.5.2(@types/react@19.2.5)(react@19.2.0) @@ -258,15 +225,9 @@ importers: '@eslint/js': specifier: ^9.39.1 version: 9.39.1 - '@playwright/test': - specifier: ^1.57.0 - version: 1.57.0 '@shikijs/transformers': specifier: ^1.10.3 version: 1.10.3 - '@types/hast': - specifier: ^3.0.4 - version: 3.0.4 '@types/node': specifier: ^24.3.0 version: 24.3.0 @@ -282,9 +243,6 @@ importers: '@types/remove-markdown': specifier: ^0.3.4 version: 0.3.4 - '@types/three': - specifier: ^0.182.0 - version: 0.182.0 autoprefixer: specifier: ^10.4.18 version: 10.4.18(postcss@8.5.6) @@ -570,10 +528,6 @@ packages: resolution: {integrity: sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==} engines: {node: '>=6.9.0'} - '@babel/runtime@7.28.4': - resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} - engines: {node: '>=6.9.0'} - '@babel/template@7.27.2': resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} @@ -643,9 +597,6 @@ packages: resolution: {integrity: sha512-Y6+WUMsTFWE5jb20IFP4YGa5IrGY/+a/FbOSjDF/wz9gepU2hwCYSXRHP/vPwBvwcY3SVMASt4yXxbXNXigmZQ==} engines: {node: '>=18'} - '@dimforge/rapier3d-compat@0.12.0': - resolution: {integrity: sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==} - '@drizzle-team/brocli@0.10.2': resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==} @@ -1334,20 +1285,6 @@ packages: '@floating-ui/utils@0.2.9': resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} - '@hono/mcp@0.2.3': - resolution: {integrity: sha512-wrYKVQSjnBg4/ZinnnP/1t3jlvP3Z9fqZv8OzuhLXV4gVTLOHOHDhnXsIwD0nFVKk2pMOvA+sDfrKyRzw4yUPg==} - peerDependencies: - '@modelcontextprotocol/sdk': ^1.25.1 - hono: '*' - hono-rate-limiter: ^0.4.2 - zod: ^3.25.0 || ^4.0.0 - - '@hono/node-server@1.19.8': - resolution: {integrity: sha512-0/g2lIOPzX8f3vzW1ggQgvG5mjtFBDBHFAzI5SFAi2DzSqS9luJwqg9T6O/gKYLi+inS7eNxBeIFkkghIPvrMA==} - engines: {node: '>=18.14.1'} - peerDependencies: - hono: ^4 - '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -1506,13 +1443,9 @@ packages: '@import-maps/resolve@2.0.0': resolution: {integrity: sha512-RwzRTpmrrS6Q1ZhQExwuxJGK1Wqhv4stt+OF2JzS+uawewpwNyU7EJL1WpBex7aDiiGLs4FsXGkfUBdYuX7xiQ==} - '@isaacs/balanced-match@4.0.1': - resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} - engines: {node: 20 || >=22} - - '@isaacs/brace-expansion@5.0.0': - resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} - engines: {node: 20 || >=22} + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} '@isaacs/fs-minipass@4.0.1': resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} @@ -1548,27 +1481,9 @@ packages: engines: {node: '>=18'} hasBin: true - '@mediapipe/tasks-vision@0.10.17': - resolution: {integrity: sha512-CZWV/q6TTe8ta61cZXjfnnHsfWIdFhms03M9T7Cnd5y2mdpylJM0rF1qRq+wsQVRMLz1OYPVEBU9ph2Bx8cxrg==} - '@mermaid-js/parser@0.6.2': resolution: {integrity: sha512-+PO02uGF6L6Cs0Bw8RpGhikVvMWEysfAyl27qTlroUB8jSWr1lL0Sf6zi78ZxlSnmgSY2AMMKVgghnN9jTtwkQ==} - '@modelcontextprotocol/sdk@1.25.2': - resolution: {integrity: sha512-LZFeo4F9M5qOhC/Uc1aQSrBHxMrvxett+9KLHt7OhcExtoiRN9DKgbZffMP/nxjutWDQpfMDfP3nkHI4X9ijww==} - engines: {node: '>=18'} - peerDependencies: - '@cfworker/json-schema': ^4.1.1 - zod: ^3.25 || ^4.0 - peerDependenciesMeta: - '@cfworker/json-schema': - optional: true - - '@monogrid/gainmap-js@3.4.0': - resolution: {integrity: sha512-2Z0FATFHaoYJ8b+Y4y4Hgfn3FRFwuU5zRrk+9dFWp4uGAdHGqVEdP7HP+gLA3X469KXHmfupJaUbKo1b/aDKIg==} - peerDependencies: - three: '>= 0.159.0' - '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': resolution: {integrity: sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==} cpu: [arm64] @@ -1879,10 +1794,9 @@ packages: resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} engines: {node: '>= 10.0.0'} - '@playwright/test@1.57.0': - resolution: {integrity: sha512-6TyEnHgd6SArQO8UO2OMTxshln3QMWBtPGrOCgs3wVEmQmwyuNtB10IZMfmYDE0riwNR1cu4q+pPcxMVtaG3TA==} - engines: {node: '>=18'} - hasBin: true + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} '@radix-ui/primitive@1.1.2': resolution: {integrity: sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==} @@ -2288,42 +2202,6 @@ packages: '@radix-ui/rect@1.1.1': resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} - '@react-three/drei@10.7.7': - resolution: {integrity: sha512-ff+J5iloR0k4tC++QtD/j9u3w5fzfgFAWDtAGQah9pF2B1YgOq/5JxqY0/aVoQG5r3xSZz0cv5tk2YuBob4xEQ==} - peerDependencies: - '@react-three/fiber': ^9.0.0 - react: ^19 - react-dom: ^19 - three: '>=0.159' - peerDependenciesMeta: - react-dom: - optional: true - - '@react-three/fiber@9.5.0': - resolution: {integrity: sha512-FiUzfYW4wB1+PpmsE47UM+mCads7j2+giRBltfwH7SNhah95rqJs3ltEs9V3pP8rYdS0QlNne+9Aj8dS/SiaIA==} - peerDependencies: - expo: '>=43.0' - expo-asset: '>=8.4' - expo-file-system: '>=11.0' - expo-gl: '>=11.0' - react: '>=19 <19.3' - react-dom: '>=19 <19.3' - react-native: '>=0.78' - three: '>=0.156' - peerDependenciesMeta: - expo: - optional: true - expo-asset: - optional: true - expo-file-system: - optional: true - expo-gl: - optional: true - react-dom: - optional: true - react-native: - optional: true - '@rolldown/pluginutils@1.0.0-beta.40': resolution: {integrity: sha512-s3GeJKSQOwBlzdUrj4ISjJj5SfSh+aqn0wjOar4Bx95iV1ETI7F6S/5hLcfAxZ9kXDcyrAkxPlqmd1ZITttf+w==} @@ -2655,6 +2533,67 @@ packages: peerDependencies: vite: ^5.2.0 || ^6 || ^7 + '@takumi-rs/core-darwin-arm64@0.62.6': + resolution: {integrity: sha512-nRz8WT7dphyhRB1QBpCJkxzpDj/0dT9xv6rAPrHK4yV9Tk01+zFW9iVgLtu8hDzLDZszmkbZzbTJ8QaZCve6Xg==} + engines: {node: '>= 12.22.0 < 13 || >= 14.17.0 < 15 || >= 15.12.0 < 16 || >= 16.0.0'} + cpu: [arm64] + os: [darwin] + + '@takumi-rs/core-darwin-x64@0.62.6': + resolution: {integrity: sha512-uhq7dBMPP7cqsx+igXjsPFGmWlPb8wrFJNNrIzjno0Ly/X2RHn6ViZV+uE3NZsX/s3mFeOmNN1h4Mvy4k4oB2Q==} + engines: {node: '>= 12.22.0 < 13 || >= 14.17.0 < 15 || >= 15.12.0 < 16 || >= 16.0.0'} + cpu: [x64] + os: [darwin] + + '@takumi-rs/core-linux-arm64-gnu@0.62.6': + resolution: {integrity: sha512-tFiSTF+mkrXtzmuDUgpi2JAgumw9/okaFCMoUfKtEEPZXD6DFT65LEufmZDkHfBzKZTtqUvtM1WUc8X8Cp4oBQ==} + engines: {node: '>= 12.22.0 < 13 || >= 14.17.0 < 15 || >= 15.12.0 < 16 || >= 16.0.0'} + cpu: [arm64] + os: [linux] + + '@takumi-rs/core-linux-arm64-musl@0.62.6': + resolution: {integrity: sha512-EbgNVGMsvkYenDBiNOi61Yz3xoSt0vlWeFOgOPQp3jrMu8936fIagb9UmDMDZjL4JWsI7Wozxp8RL8y3Tw6gkw==} + engines: {node: '>= 12.22.0 < 13 || >= 14.17.0 < 15 || >= 15.12.0 < 16 || >= 16.0.0'} + cpu: [arm64] + os: [linux] + + '@takumi-rs/core-linux-x64-gnu@0.62.6': + resolution: {integrity: sha512-tWqCpIrDY4IccFk6Dp4wRlIWhc2Vtj5WTwxRjrPLqsEW/6uV4Oc8OUBY4tCmhll523BWxwSRAsqXyk4IR1D6uA==} + engines: {node: '>= 12.22.0 < 13 || >= 14.17.0 < 15 || >= 15.12.0 < 16 || >= 16.0.0'} + cpu: [x64] + os: [linux] + + '@takumi-rs/core-linux-x64-musl@0.62.6': + resolution: {integrity: sha512-Q4L2NyxynlrUqKDNWys81lgIunH2BBc10g13iIYiKlpliXwZccGBcrsl2QwcjdyVcGXPc8fqL28LOwaVdOcqkA==} + engines: {node: '>= 12.22.0 < 13 || >= 14.17.0 < 15 || >= 15.12.0 < 16 || >= 16.0.0'} + cpu: [x64] + os: [linux] + + '@takumi-rs/core-win32-arm64-msvc@0.62.6': + resolution: {integrity: sha512-HYF6ES0SYaJ0ZSUGeVI4zrc1wvUOqtEkXJQb/DgwGcZlbQSkEVDzdKC119orBCqpVDsxTwAEeDu7eg/m135x3A==} + engines: {node: '>= 12.22.0 < 13 || >= 14.17.0 < 15 || >= 15.12.0 < 16 || >= 16.0.0'} + cpu: [arm64] + os: [win32] + + '@takumi-rs/core-win32-x64-msvc@0.62.6': + resolution: {integrity: sha512-Sl19GuKovAxxsSh/23q4RZhh/zdRUAwwOdLRb0VgEG+TCJmIewBBMlxMyppUBXB5xm/9N8jtVbXetxEyU5tHUQ==} + engines: {node: '>= 12.22.0 < 13 || >= 14.17.0 < 15 || >= 15.12.0 < 16 || >= 16.0.0'} + cpu: [x64] + os: [win32] + + '@takumi-rs/core@0.62.6': + resolution: {integrity: sha512-EsThHYARwTJyrl2Yq40GCjwvpfmuh0jWkHsx8i+EcL5UM3j1WfrTU8hGAewJFwiISdSlMgyDh87EH8ywfUJ4mQ==} + engines: {node: '>= 12.22.0 < 13 || >= 14.17.0 < 15 || >= 15.12.0 < 16 || >= 16.0.0'} + + '@takumi-rs/helpers@0.62.6': + resolution: {integrity: sha512-sQ7gBgdY7HeCH+lsSheapCUYJnBkZ4kPbqKBaD6LwD1ejX2gNGlDLbkvMDPRdCZzEWXkYU48+5YokADJys2J6w==} + + '@takumi-rs/image-response@0.62.6': + resolution: {integrity: sha512-g+soCdxo6BRInb+vsiNyP6aZJT4D+9hlCd0xRCviUFTLVmweLoIK4mGxLJzgl0mEc+gr8QVIHnV+uBCJTkusjw==} + + '@takumi-rs/wasm@0.62.6': + resolution: {integrity: sha512-txQkgHMT1jLvbqbH+xlztKeL8jyIe09BEyh+rZcaXhjtym0wl0OqgKO7v0m4JxBV4a2gkWxOmthzLLODRE7C9g==} + '@tanstack/devtools-event-client@0.3.5': resolution: {integrity: sha512-RL1f5ZlfZMpghrCIdzl6mLOFLTuhqmPNblZgBaeKfdtk5rfbjykurv+VfYydOFXj0vxVIoA2d/zT7xfD7Ph8fw==} engines: {node: '>=18'} @@ -2847,9 +2786,6 @@ packages: resolution: {integrity: sha512-CJrWtr6L9TVzEImm9S7dQINx+xJcYP/aDkIi6gnaWtIgbZs1pnzsE0yJc2noqXZ+yAOqLx3TBGpBEs9tS0P9/A==} engines: {node: '>=12'} - '@tweenjs/tween.js@23.1.3': - resolution: {integrity: sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==} - '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -2964,9 +2900,6 @@ packages: '@types/dom-speech-recognition@0.0.1': resolution: {integrity: sha512-udCxb8DvjcDKfk1WTBzDsxFbLgYxmQGKrE/ricoMqHRNjSlSUCcamVTA5lIQqzY10mY5qCY0QDwBfFEwhfoDPw==} - '@types/draco3d@1.4.10': - resolution: {integrity: sha512-AX22jp8Y7wwaBgAixaSvkoG4M/+PlAcm3Qs4OW8yT9DM4xUpWKeFhLueTAyZF39pviAdcDdeJoACapiAceqNcw==} - '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} @@ -3003,9 +2936,6 @@ packages: '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} - '@types/offscreencanvas@2019.7.3': - resolution: {integrity: sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A==} - '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} @@ -3023,11 +2953,6 @@ packages: peerDependencies: '@types/react': ^19.2.0 - '@types/react-reconciler@0.28.9': - resolution: {integrity: sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg==} - peerDependencies: - '@types/react': '*' - '@types/react@19.2.5': resolution: {integrity: sha512-keKxkZMqnDicuvFoJbzrhbtdLSPhj/rZThDlKWCDbgXmUg0rEUFtRssDXKYmtXluZlIqiC5VqkCgRwzuyLHKHw==} @@ -3037,12 +2962,6 @@ packages: '@types/retry@0.12.2': resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==} - '@types/stats.js@0.17.4': - resolution: {integrity: sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==} - - '@types/three@0.182.0': - resolution: {integrity: sha512-WByN9V3Sbwbe2OkWuSGyoqQO8Du6yhYaXtXLoA5FkKTUJorZ+yOHBZ35zUUPQXlAKABZmbYp5oAqpA4RBjtJ/Q==} - '@types/triple-beam@1.3.5': resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==} @@ -3052,9 +2971,6 @@ packages: '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} - '@types/webxr@0.5.24': - resolution: {integrity: sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==} - '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} @@ -3136,14 +3052,6 @@ packages: '@uploadthing/shared@7.1.10': resolution: {integrity: sha512-R/XSA3SfCVnLIzFpXyGaKPfbwlYlWYSTuGjTFHuJhdAomuBuhopAHLh2Ois5fJibAHzi02uP1QCKbgTAdmArqg==} - '@use-gesture/core@10.3.1': - resolution: {integrity: sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw==} - - '@use-gesture/react@10.3.1': - resolution: {integrity: sha512-Yy19y6O2GJq8f7CHf7L0nxL8bf4PZCPaVOCgJrusOeFHY1LvHgYXnmnXg6N5iwAnbgbZCDjo60SiM6IPJi9C5g==} - peerDependencies: - react: '>= 16.8.0' - '@vercel/nft@0.29.4': resolution: {integrity: sha512-6lLqMNX3TuycBPABycx7A9F1bHQR7kiQln6abjFbPrf5C/05qHM9M5E4PeTE59c7z8g6vHnx1Ioihb2AQl7BTA==} engines: {node: '>=18'} @@ -3185,9 +3093,6 @@ packages: '@vue/shared@3.5.22': resolution: {integrity: sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w==} - '@webgpu/types@0.1.68': - resolution: {integrity: sha512-3ab1B59Ojb6RwjOspYLsTpCzbNB3ZaamIAxBMmvnNkiDoLTZUOBXZ9p5nAYVEkQlDdf6qAZWi1pqj9+ypiqznA==} - '@whatwg-node/disposablestack@0.0.6': resolution: {integrity: sha512-LOtTn+JgJvX8WfBVJtF08TGrdjuFzGJc4mkP8EdDI8ADbvO7kiexYep1o8dwnt0okb0jYclCDXF13xU7Ge4zSw==} engines: {node: '>=18.0.0'} @@ -3219,10 +3124,6 @@ packages: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} - accepts@2.0.0: - resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} - engines: {node: '>= 0.6'} - acorn-import-attributes@1.9.5: resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} peerDependencies: @@ -3251,14 +3152,6 @@ packages: peerDependencies: ajv: ^8.0.1 - ajv-formats@3.0.1: - resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} - peerDependencies: - ajv: ^8.0.0 - peerDependenciesMeta: - ajv: - optional: true - ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} @@ -3278,6 +3171,10 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -3286,6 +3183,10 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + ansis@4.1.0: resolution: {integrity: sha512-BGcItUBWSMRgOCe+SVZJ+S7yTRG0eGt9cXAHev72yuGcY23hnLA7Bky5L/xLyPINoSN95geovfBkqoTlNZYa7w==} engines: {node: '>=14'} @@ -3302,6 +3203,9 @@ packages: resolution: {integrity: sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==} engines: {node: '>= 14'} + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -3418,9 +3322,6 @@ packages: peerDependencies: ajv: 4.11.8 - 8 - bidi-js@1.0.3: - resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} - binary-extensions@2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} @@ -3431,13 +3332,12 @@ packages: bindings@1.5.0: resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - body-parser@2.2.2: - resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} - engines: {node: '>=18'} - boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + brace-expansion@2.0.2: resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} @@ -3471,10 +3371,6 @@ packages: buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} - call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} @@ -3502,12 +3398,6 @@ packages: resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} engines: {node: '>=16'} - camera-controls@3.1.2: - resolution: {integrity: sha512-xkxfpG2ECZ6Ww5/9+kf4mfg1VEYAoe9aDSY+IwF0UEs7qEzwy0aVRfs2grImIECs/PoBtWFrh7RXsQkwG922JA==} - engines: {node: '>=22.0.0', npm: '>=10.5.1'} - peerDependencies: - three: '>=0.126.1' - caniuse-lite@1.0.30001692: resolution: {integrity: sha512-A95VKan0kdtrsnMubMKxEKUKImOPSuCpYgxSQBo036P5YYgVIcOYJEgt/txJWqObiRQeISNCfef9nvlQ0vbV7A==} @@ -3651,6 +3541,9 @@ packages: resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==} engines: {node: '>= 14'} + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} @@ -3661,14 +3554,6 @@ packages: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} - content-disposition@1.0.1: - resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==} - engines: {node: '>=18'} - - content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} - convert-source-map@1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} @@ -3681,10 +3566,6 @@ packages: cookie-es@2.0.0: resolution: {integrity: sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg==} - cookie-signature@1.2.2: - resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} - engines: {node: '>=6.6.0'} - cookie@0.7.1: resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} engines: {node: '>= 0.6'} @@ -3700,10 +3581,6 @@ packages: core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - cors@2.8.5: - resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} - engines: {node: '>= 0.10'} - cose-base@1.0.3: resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} @@ -3727,10 +3604,9 @@ packages: resolution: {integrity: sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==} engines: {node: '>=12.0.0'} - cross-env@7.0.3: - resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} - engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} - hasBin: true + cross-spawn@6.0.5: + resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} + engines: {node: '>=4.8'} cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} @@ -4007,10 +3883,6 @@ packages: delaunator@5.0.1: resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} - depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - deprecation@2.3.1: resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} @@ -4021,9 +3893,6 @@ packages: destr@2.0.5: resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} - detect-gpu@5.0.70: - resolution: {integrity: sha512-bqerEP1Ese6nt3rFkwPnGbsUF9a4q+gMmpTVVOEzoCyeCc+y7/RvJnQZJx1JwhgQI5Ntg0Kgat8Uu7XpBqnz1w==} - detect-libc@1.0.3: resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} engines: {node: '>=0.10'} @@ -4093,10 +3962,6 @@ packages: resolution: {integrity: sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==} engines: {node: '>=0.3.1'} - discord-interactions@4.4.0: - resolution: {integrity: sha512-jjJx8iwAeJcj8oEauV43fue9lNqkf38fy60aSs2+G8D1nJmDxUIrk08o3h0F3wgwuBWWJUZO+X/VgfXsxpCiJA==} - engines: {node: '>=18.4.0'} - doctrine@2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} @@ -4133,9 +3998,6 @@ packages: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} - draco3d@1.5.7: - resolution: {integrity: sha512-m6WCKt/erDXcw+70IJXnG7M3awwQPAsZvJGX5zY7beBqpELw6RDGkYVU0W43AFxye4pDZ5i2Lbyc/NNGqwjUVQ==} - drizzle-kit@0.31.7: resolution: {integrity: sha512-hOzRGSdyKIU4FcTSFYGKdXEjFsncVwHZ43gY3WU5Bz9j5Iadp6Rh6hxLSQ1IWXpKLBKt/d5y1cpSPcV+FcoQ1A==} hasBin: true @@ -4239,12 +4101,12 @@ packages: duplexer@0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + ecdsa-sig-formatter@1.0.11: resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} - ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - effect@3.17.7: resolution: {integrity: sha512-dpt0ONUn3zzAuul6k4nC/coTTw27AL5nhkORXgTi6NfMPzqWYa1M05oKmOMTxpVSTKepqXVcW9vIwkuaaqx9zA==} @@ -4269,10 +4131,6 @@ packages: enabled@2.0.0: resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==} - encodeurl@2.0.0: - resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} - engines: {node: '>= 0.8'} - encoding-sniffer@0.2.1: resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==} @@ -4482,28 +4340,10 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} - eventsource-parser@3.0.6: - resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} - engines: {node: '>=18.0.0'} - - eventsource@3.0.7: - resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} - engines: {node: '>=18.0.0'} - execa@8.0.1: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} - express-rate-limit@7.5.1: - resolution: {integrity: sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==} - engines: {node: '>= 16'} - peerDependencies: - express: '>= 4.11' - - express@5.2.1: - resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} - engines: {node: '>= 18'} - exsolve@1.0.7: resolution: {integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==} @@ -4573,12 +4413,6 @@ packages: fetchdts@0.1.7: resolution: {integrity: sha512-YoZjBdafyLIop9lSxXVI33oLD5kN31q4Td+CasofLLYeLXRFeOsuOw0Uo+XNRi9PZlbfdlN2GmRtm4tCEQ9/KA==} - fflate@0.6.10: - resolution: {integrity: sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==} - - fflate@0.8.2: - resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} - figures@6.1.0: resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} engines: {node: '>=18'} @@ -4605,10 +4439,6 @@ packages: resolution: {integrity: sha512-xdMtCAODmPloU9qtmPcdBV9Kd27NtMse+4ayThxqIHUES5Z2S6bGpap5PpdmNM56ub7y3i1eyr+vJJIIgWGKmA==} engines: {node: '>=18'} - finalhandler@2.1.1: - resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} - engines: {node: '>= 18.0.0'} - find-my-way-ts@0.1.6: resolution: {integrity: sha512-a85L9ZoXtNAey3Y6Z+eBWW658kO/MwR7zIafkIUPUMf3isZG0NCs2pjW2wtjxAKuJPxMAsHUIP4ZPGv0o5gyTA==} @@ -4641,25 +4471,19 @@ packages: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + formdata-polyfill@4.0.10: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} - forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} - fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} - fresh@2.0.0: - resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} - engines: {node: '>= 0.8'} - - fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} @@ -4741,9 +4565,17 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} - glob@13.0.0: - resolution: {integrity: sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==} - engines: {node: 20 || >=22} + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + glob@9.3.5: + resolution: {integrity: sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==} + engines: {node: '>=16 || 14 >=14.17'} globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} @@ -4764,9 +4596,6 @@ packages: globrex@0.1.2: resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} - glsl-noise@0.0.0: - resolution: {integrity: sha512-b/ZCF6amfAUb7dJM/MxRs7AetQEahYzJ8PtgfrmEdtw6uyGOr+ZSGtgjFm6mfsBkxJ4d2W7kg+Nlqzqvn3Bc0w==} - gonzales-pe@4.3.0: resolution: {integrity: sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==} engines: {node: '>=0.6.0'} @@ -4883,9 +4712,6 @@ packages: hermes-parser@0.25.1: resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} - hls.js@1.6.15: - resolution: {integrity: sha512-E3a5VwgXimGHwpRGV+WxRTKeSp2DW5DI5MWv34ulL3t5UNmyJWCQ1KmLEHbYzcfThfXG8amBL+fCYPneGHC4VA==} - hogan.js@3.0.2: resolution: {integrity: sha512-RqGs4wavGYJWE07t35JQccByczmNUXQT0E12ZYV1VKYu5UiAU9lsos/yBAcf840+zrUQQxgVduCR5/B8nNtibg==} hasBin: true @@ -4893,15 +4719,6 @@ packages: hoist-non-react-statics@3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} - hono-rate-limiter@0.4.2: - resolution: {integrity: sha512-AAtFqgADyrmbDijcRTT/HJfwqfvhalya2Zo+MgfdrMPas3zSMD8SU03cv+ZsYwRU1swv7zgVt0shwN059yzhjw==} - peerDependencies: - hono: ^4.1.1 - - hono@4.11.3: - resolution: {integrity: sha512-PmQi306+M/ct/m5s66Hrg+adPnkD5jiO6IjA7WhWw0gSBSo1EcRegwuI1deZ+wd5pzCGynCcn2DprnE4/yEV4w==} - engines: {node: '>=16.9.0'} - hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} @@ -4933,10 +4750,6 @@ packages: htmlparser2@9.1.0: resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==} - http-errors@2.0.1: - resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} - engines: {node: '>= 0.8'} - http-shutdown@1.2.2: resolution: {integrity: sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw==} engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} @@ -4957,10 +4770,6 @@ packages: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} - iconv-lite@0.7.2: - resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} - engines: {node: '>=0.10.0'} - ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -4980,9 +4789,6 @@ packages: engines: {node: '>=16.x'} hasBin: true - immediate@3.0.6: - resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} - import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} @@ -4999,6 +4805,10 @@ packages: resolution: {integrity: sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==} engines: {node: '>=18'} + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -5031,10 +4841,6 @@ packages: interval-tree-1d@1.0.4: resolution: {integrity: sha512-wY8QJH+6wNI0uh4pDQzMvl+478Qh7Rl4qLmqiluxALlNvl+I+o5x38Pw3/z7mDPTPS1dQalZJXsmbvxx5gclhQ==} - ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} - ipx@3.1.1: resolution: {integrity: sha512-7Xnt54Dco7uYkfdAw0r2vCly3z0rSaVhEXMzPvl3FndsTVm5p26j+PO+gyinkYmcsEUvX2Rh7OGK7KzYWRu6BA==} hasBin: true @@ -5175,12 +4981,6 @@ packages: resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} engines: {node: '>=0.10.0'} - is-promise@2.2.2: - resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} - - is-promise@4.0.0: - resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} - is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} @@ -5295,10 +5095,8 @@ packages: resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} engines: {node: '>= 0.4'} - its-fine@2.0.0: - resolution: {integrity: sha512-KLViCmWx94zOvpLwSlsx6yOCeMhZYaxrJV87Po5k/FoZzcPSahvK5qJ7fYhS61sZi5ikmh2S3Hz55A2l3U69ng==} - peerDependencies: - react: ^19.0.0 + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} jake@10.9.4: resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} @@ -5316,9 +5114,6 @@ packages: jose@5.10.0: resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==} - jose@6.1.3: - resolution: {integrity: sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==} - jpeg-js@0.4.4: resolution: {integrity: sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==} @@ -5328,6 +5123,10 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + js-yaml@4.1.1: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true @@ -5352,9 +5151,6 @@ packages: json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - json-schema-typed@8.0.2: - resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} - json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} @@ -5379,11 +5175,11 @@ packages: resolution: {integrity: sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ==} engines: {node: '>=12.20'} - jwa@2.0.1: - resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} + jwa@1.4.2: + resolution: {integrity: sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==} - jws@4.0.1: - resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} + jws@3.2.2: + resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} jwt-decode@4.0.0: resolution: {integrity: sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==} @@ -5447,9 +5243,6 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - lie@3.3.0: - resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} - lightningcss-darwin-arm64@1.30.1: resolution: {integrity: sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==} engines: {node: '>= 12.0.0'} @@ -5584,10 +5377,6 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.2.4: - resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==} - engines: {node: 20 || >=22} - lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -5604,12 +5393,6 @@ packages: resolution: {integrity: sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==} engines: {node: '>=12'} - maath@0.10.8: - resolution: {integrity: sha512-tRvbDF0Pgqz+9XUa4jjfgAQ8/aPKmQdWXilFu2tMy4GWj4NOsx99HlULO4IeREfbO3a0sA145DZYyvXPkybm0g==} - peerDependencies: - '@types/three': '>=0.134.0' - three: '>=0.134.0' - magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} @@ -5678,18 +5461,10 @@ packages: mdn-data@2.12.2: resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} - media-typer@1.1.0: - resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} - engines: {node: '>= 0.8'} - memorystream@0.3.1: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} engines: {node: '>= 0.10.0'} - merge-descriptors@2.0.0: - resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} - engines: {node: '>=18'} - merge-options@3.0.4: resolution: {integrity: sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==} engines: {node: '>=10'} @@ -5704,14 +5479,6 @@ packages: mermaid@11.11.0: resolution: {integrity: sha512-9lb/VNkZqWTRjVgCV+l1N+t4kyi94y+l5xrmBmbbxZYkfRl5hEDaTPMOcaWKCl1McG8nBEaMlWwkcAEEgjhBgg==} - meshline@3.3.1: - resolution: {integrity: sha512-/TQj+JdZkeSUOl5Mk2J7eLcYTLiQm2IDzmlSvYm7ov15anEcDJ92GHqqazxTSreeNgfnYu24kiEvvv0WlbCdFQ==} - peerDependencies: - three: '>=0.137' - - meshoptimizer@0.22.0: - resolution: {integrity: sha512-IebiK79sqIy+E4EgOr+CAw+Ke8hAspXKzBd0JdgEmPHiAwmvEj2S4h1rfvo+o/BnfEYd/jAOg5IeeIjzlzSnDg==} - micromark-core-commonmark@2.0.3: resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} @@ -5808,18 +5575,10 @@ packages: resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} engines: {node: '>= 0.6'} - mime-types@3.0.2: - resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} - engines: {node: '>=18'} - mimic-fn@4.0.0: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} - minimatch@10.1.1: - resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} - engines: {node: 20 || >=22} - minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -5827,6 +5586,10 @@ packages: resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} engines: {node: '>=10'} + minimatch@8.0.4: + resolution: {integrity: sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==} + engines: {node: '>=16 || 14 >=14.17'} + minimatch@9.0.5: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} @@ -5834,6 +5597,10 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minipass@4.2.8: + resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} + engines: {node: '>=8'} + minipass@7.1.2: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} @@ -5884,13 +5651,12 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - negotiator@1.0.0: - resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} - engines: {node: '>= 0.6'} - netlify-redirector@0.5.0: resolution: {integrity: sha512-4zdzIP+6muqPCuE8avnrgDJ6KW/2+UpHTRcTbMXCIRxiRmyrX+IZ4WSJGZdHPWF3WmQpXpy603XxecZ9iygN7w==} + nice-try@1.0.5: + resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} + node-addon-api@7.1.1: resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} @@ -5915,8 +5681,8 @@ packages: resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - node-forge@1.3.3: - resolution: {integrity: sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==} + node-forge@1.3.1: + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} node-gyp-build-optional-packages@5.2.2: @@ -6031,10 +5797,6 @@ packages: omit.js@2.0.2: resolution: {integrity: sha512-hJmu9D+bNB40YpL9jYebQl4lsTW6yEHRTroJzNLqQJYHm7c+NQnJGfZmIWh8S3q3KoaxV1aLhV6B3+0N0/kyJg==} - on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} - once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -6097,6 +5859,9 @@ packages: resolution: {integrity: sha512-lwx6u1CotQYPVju77R+D0vFomni/AqRfqLmqQ8hekklqZ6gAY9rONh7lBQ0uxWMkC2AuX9b2DVAl8To0NyP1JA==} engines: {node: '>=12'} + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + package-manager-detector@1.3.0: resolution: {integrity: sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==} @@ -6133,10 +5898,6 @@ packages: parse5@7.3.0: resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} - parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - path-data-parser@0.1.0: resolution: {integrity: sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==} @@ -6148,6 +5909,14 @@ packages: resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@2.0.1: + resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} + engines: {node: '>=4'} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -6159,12 +5928,9 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-scurry@2.0.1: - resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} - engines: {node: 20 || >=22} - - path-to-regexp@8.3.0: - resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} path-type@3.0.0: resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} @@ -6229,26 +5995,12 @@ packages: resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} engines: {node: '>=4'} - pkce-challenge@5.0.1: - resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} - engines: {node: '>=16.20.0'} - pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} pkg-types@2.3.0: resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} - playwright-core@1.57.0: - resolution: {integrity: sha512-agTcKlMw/mjBWOnD6kFZttAAGHgi/Nw0CZ2o6JqWSbMlI219lAFLZZCyqByTsvVAJq5XA5H8cA6PrvBRpBWEuQ==} - engines: {node: '>=18'} - hasBin: true - - playwright@1.57.0: - resolution: {integrity: sha512-ilYQj1s8sr2ppEJ2YVadYBN0Mb3mdo9J0wQ+UuDhzYqURwSoW4n1Xs5vs7ORwgDGmyEh33tRMeS8KhdkMoLXQw==} - engines: {node: '>=18'} - hasBin: true - pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} @@ -6319,9 +6071,6 @@ packages: resolution: {integrity: sha512-Jtc2612XINuBjIl/QTWsV5UvE8UHuNblcO3vVADSrKsrc6RqGX6lOW1cEo3CM2v0XG4Nat8nI+YM7/f26VxXLw==} engines: {node: '>=12'} - potpack@1.0.2: - resolution: {integrity: sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==} - preact-render-to-string@5.2.3: resolution: {integrity: sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==} peerDependencies: @@ -6361,9 +6110,6 @@ packages: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} - promise-worker-transferable@1.0.4: - resolution: {integrity: sha512-bN+0ehEnrXfxV2ZQvU2PetO0n4gqBD4ulq3MI1WOPLgr7/Mg9yRQkX5+0v1vagr74ZTsl7XtzlaYDo2EuCeYJw==} - prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -6373,10 +6119,6 @@ packages: property-information@7.1.0: resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} - proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} - proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} @@ -6390,8 +6132,8 @@ packages: pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} - qs@6.14.1: - resolution: {integrity: sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==} + qs@6.9.7: + resolution: {integrity: sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==} engines: {node: '>=0.6'} quansync@0.2.11: @@ -6412,14 +6154,6 @@ packages: randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} - range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} - - raw-body@3.0.2: - resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} - engines: {node: '>= 0.10'} - react-colorful@5.6.1: resolution: {integrity: sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==} peerDependencies: @@ -6490,15 +6224,6 @@ packages: '@types/react': optional: true - react-use-measure@2.1.7: - resolution: {integrity: sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==} - peerDependencies: - react: '>=16.13' - react-dom: '>=16.13' - peerDependenciesMeta: - react-dom: - optional: true - react@19.2.0: resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==} engines: {node: '>=0.10.0'} @@ -6663,10 +6388,6 @@ packages: roughjs@4.6.6: resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==} - router@2.2.0: - resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} - engines: {node: '>= 18'} - run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -6737,10 +6458,6 @@ packages: engines: {node: '>=10'} hasBin: true - send@1.2.1: - resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} - engines: {node: '>= 18'} - serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} @@ -6768,10 +6485,6 @@ packages: resolution: {integrity: sha512-9GOc+8T6LN4aByLN75uRvMbrwY5RDBW6lSlknsY4LEa9ZmWcxKcRe1G/Q3HZXjltxMHTrStnvrwAICxZrhldtg==} engines: {node: '>=10'} - serve-static@2.2.1: - resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} - engines: {node: '>= 18'} - set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -6788,17 +6501,22 @@ packages: resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} engines: {node: '>= 0.4'} - setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - sharp@0.34.4: resolution: {integrity: sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shebang-command@1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} + shebang-regex@1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} @@ -6870,6 +6588,9 @@ packages: spdx-license-ids@3.0.16: resolution: {integrity: sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==} + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + sqids@0.3.0: resolution: {integrity: sha512-lOQK1ucVg+W6n3FhRwwSeUijxe93b51Bfz5PMRMihVf1iVkl82ePQG7V5vwrhzB11v0NtsR25PSZRGiSomJaJw==} @@ -6886,19 +6607,6 @@ packages: stack-trace@0.0.10: resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} - stats-gl@2.4.2: - resolution: {integrity: sha512-g5O9B0hm9CvnM36+v7SFl39T7hmAlv541tU81ME8YeSb3i1CIP5/QdDeSB3A0la0bKNHpxpwxOVRo2wFTYEosQ==} - peerDependencies: - '@types/three': '*' - three: '*' - - stats.js@0.17.0: - resolution: {integrity: sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==} - - statuses@2.0.2: - resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} - engines: {node: '>= 0.8'} - std-env@3.9.0: resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} @@ -6913,6 +6621,10 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + string.prototype.includes@2.0.1: resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} engines: {node: '>= 0.4'} @@ -6963,6 +6675,10 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} + strip-ansi@7.1.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} + engines: {node: '>=12'} + strip-bom-string@1.0.0: resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} engines: {node: '>=0.10.0'} @@ -7000,11 +6716,6 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - suspend-react@0.1.3: - resolution: {integrity: sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ==} - peerDependencies: - react: '>=17.0' - svgo@4.0.0: resolution: {integrity: sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==} engines: {node: '>=16'} @@ -7052,19 +6763,6 @@ packages: text-hex@1.0.0: resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==} - three-mesh-bvh@0.8.3: - resolution: {integrity: sha512-4G5lBaF+g2auKX3P0yqx+MJC6oVt6sB5k+CchS6Ob0qvH0YIhuUk1eYr7ktsIpY+albCqE80/FVQGV190PmiAg==} - peerDependencies: - three: '>= 0.159.0' - - three-stdlib@2.36.1: - resolution: {integrity: sha512-XyGQrFmNQ5O/IoKm556ftwKsBg11TIb301MB5dWNicziQBEs2g3gtOYIf7pFiLa0zI2gUwhtCjv9fmjnxKZ1Cg==} - peerDependencies: - three: '>=0.128.0' - - three@0.182.0: - resolution: {integrity: sha512-GbHabT+Irv+ihI1/f5kIIsZ+Ef9Sl5A1Y7imvS5RQjWgtTPfPnZ43JmlYI7NtCRDK9zir20lQpfg8/9Yd02OvQ==} - tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} @@ -7093,10 +6791,6 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - toml@3.0.0: resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} @@ -7113,19 +6807,6 @@ packages: resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==} engines: {node: '>= 14.0.0'} - troika-three-text@0.52.4: - resolution: {integrity: sha512-V50EwcYGruV5rUZ9F4aNsrytGdKcXKALjEtQXIOBfhVoZU9VAqZNIoGQ3TMiooVqFAbR1w15T+f+8gkzoFzawg==} - peerDependencies: - three: '>=0.125.0' - - troika-three-utils@0.52.4: - resolution: {integrity: sha512-NORAStSVa/BDiG52Mfudk4j1FG4jC4ILutB3foPnfGbOeIs9+G5vZLa0pnmnaftZUGm4UwSoqEpWdqvC7zms3A==} - peerDependencies: - three: '>=0.125.0' - - troika-worker-utils@0.52.0: - resolution: {integrity: sha512-W1CpvTHykaPH5brv5VHLfQo9D1OYuo0cSBEUQFFT/nBUzM8iD6Lq2/tgG/f1OelbAS1WtaTPQzE5uM49egnngw==} - trough@2.2.0: resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} @@ -7157,9 +6838,6 @@ packages: engines: {node: '>=18.0.0'} hasBin: true - tunnel-rat@0.1.2: - resolution: {integrity: sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ==} - type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -7168,10 +6846,6 @@ packages: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} - type-is@2.0.1: - resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} - engines: {node: '>= 0.6'} - typed-array-buffer@1.0.2: resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} engines: {node: '>= 0.4'} @@ -7272,10 +6946,6 @@ packages: resolution: {integrity: sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg==} engines: {node: '>=0.10.0'} - unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - unplugin@1.0.1: resolution: {integrity: sha512-aqrHaVBWW1JVKBHmGo33T5TxeL0qWzfvjWokObHA9bYmN7eNDkwOxmLjhioHl9878qDFMAaT51XNroRyuz7WxA==} @@ -7424,10 +7094,6 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - utility-types@3.11.0: - resolution: {integrity: sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==} - engines: {node: '>= 4'} - uuid@10.0.0: resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} hasBin: true @@ -7451,10 +7117,6 @@ packages: resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} - vfile-location@5.0.3: resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} @@ -7551,12 +7213,6 @@ packages: resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} engines: {node: '>= 8'} - webgl-constants@1.1.1: - resolution: {integrity: sha512-LkBXKjU5r9vAW7Gcu3T5u+5cvSvh5WwINdr0C+9jpzVB41cjQAP5ePArDtk/WHYdVj0GefCgM73BA7FlIiNtdg==} - - webgl-sdf-generator@1.1.1: - resolution: {integrity: sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA==} - webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} @@ -7573,7 +7229,6 @@ packages: whatwg-encoding@3.1.1: resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} engines: {node: '>=18'} - deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation whatwg-mimetype@4.0.0: resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} @@ -7605,6 +7260,10 @@ packages: resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} engines: {node: '>= 0.4'} + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -7622,6 +7281,10 @@ packages: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -7693,11 +7356,6 @@ packages: resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} engines: {node: '>= 14'} - zod-to-json-schema@3.25.1: - resolution: {integrity: sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==} - peerDependencies: - zod: ^3.25 || ^4 - zod-validation-error@4.0.2: resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==} engines: {node: '>=18.0.0'} @@ -7707,8 +7365,8 @@ packages: zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} - zod@4.3.5: - resolution: {integrity: sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==} + zod@4.1.9: + resolution: {integrity: sha512-HI32jTq0AUAC125z30E8bQNz0RQ+9Uc+4J7V97gLYjZVKRjeydPgGt6dvQzFrav7MYOUGFqqOGiHpA/fdbd0cQ==} zustand@4.5.2: resolution: {integrity: sha512-2cN1tPkDVkwCy5ickKrI7vijSjPksFRfqS6237NzT0vqSsztTNnQdHw9mmN7uBdk3gceVXU0a+21jFzFzAc9+g==} @@ -7725,24 +7383,6 @@ packages: react: optional: true - zustand@5.0.9: - resolution: {integrity: sha512-ALBtUj0AfjJt3uNRQoL1tL2tMvj6Gp/6e39dnfT6uzpelGru8v1tPOGBzayOWbPJvujM8JojDk3E1LxeFisBNg==} - engines: {node: '>=12.20.0'} - peerDependencies: - '@types/react': '>=18.0.0' - immer: '>=9.0.6' - react: '>=18.0.0' - use-sync-external-store: '>=1.2.0' - peerDependenciesMeta: - '@types/react': - optional: true - immer: - optional: true - react: - optional: true - use-sync-external-store: - optional: true - zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} @@ -8074,8 +7714,6 @@ snapshots: dependencies: regenerator-runtime: 0.14.1 - '@babel/runtime@7.28.4': {} - '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 @@ -8090,7 +7728,7 @@ snapshots: '@babel/parser': 7.28.3 '@babel/template': 7.27.2 '@babel/types': 7.28.2 - debug: 4.4.3 + debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -8178,8 +7816,6 @@ snapshots: gonzales-pe: 4.3.0 node-source-walk: 7.0.1 - '@dimforge/rapier3d-compat@0.12.0': {} - '@drizzle-team/brocli@0.10.2': {} '@effect/platform@0.90.3(effect@3.17.7)': @@ -8585,18 +8221,6 @@ snapshots: '@floating-ui/utils@0.2.9': {} - '@hono/mcp@0.2.3(@modelcontextprotocol/sdk@1.25.2(hono@4.11.3)(zod@4.3.5))(hono-rate-limiter@0.4.2(hono@4.11.3))(hono@4.11.3)(zod@4.3.5)': - dependencies: - '@modelcontextprotocol/sdk': 1.25.2(hono@4.11.3)(zod@4.3.5) - hono: 4.11.3 - hono-rate-limiter: 0.4.2(hono@4.11.3) - pkce-challenge: 5.0.1 - zod: 4.3.5 - - '@hono/node-server@1.19.8(hono@4.11.3)': - dependencies: - hono: 4.11.3 - '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.7': @@ -8717,11 +8341,14 @@ snapshots: '@import-maps/resolve@2.0.0': {} - '@isaacs/balanced-match@4.0.1': {} - - '@isaacs/brace-expansion@5.0.0': + '@isaacs/cliui@8.0.2': dependencies: - '@isaacs/balanced-match': 4.0.1 + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.2 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 '@isaacs/fs-minipass@4.0.1': dependencies: @@ -8772,39 +8399,10 @@ snapshots: - encoding - supports-color - '@mediapipe/tasks-vision@0.10.17': {} - '@mermaid-js/parser@0.6.2': dependencies: langium: 3.3.1 - '@modelcontextprotocol/sdk@1.25.2(hono@4.11.3)(zod@4.3.5)': - dependencies: - '@hono/node-server': 1.19.8(hono@4.11.3) - ajv: 8.17.1 - ajv-formats: 3.0.1(ajv@8.17.1) - content-type: 1.0.5 - cors: 2.8.5 - cross-spawn: 7.0.6 - eventsource: 3.0.7 - eventsource-parser: 3.0.6 - express: 5.2.1 - express-rate-limit: 7.5.1(express@5.2.1) - jose: 6.1.3 - json-schema-typed: 8.0.2 - pkce-challenge: 5.0.1 - raw-body: 3.0.2 - zod: 4.3.5 - zod-to-json-schema: 3.25.1(zod@4.3.5) - transitivePeerDependencies: - - hono - - supports-color - - '@monogrid/gainmap-js@3.4.0(three@0.182.0)': - dependencies: - promise-worker-transferable: 1.0.4 - three: 0.182.0 - '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': optional: true @@ -8890,7 +8488,7 @@ snapshots: uuid: 11.1.0 write-file-atomic: 5.0.1 - '@netlify/dev@4.5.12(rollup@4.53.3)(uploadthing@7.7.4(express@5.2.1)(h3@1.15.4)(tailwindcss@4.1.11))': + '@netlify/dev@4.5.12(rollup@4.53.3)(uploadthing@7.7.4(h3@1.15.4)(tailwindcss@4.1.11))': dependencies: '@netlify/blobs': 10.0.11 '@netlify/config': 23.2.0 @@ -8898,7 +8496,7 @@ snapshots: '@netlify/edge-functions': 2.18.2 '@netlify/functions': 4.2.7(rollup@4.53.3) '@netlify/headers': 2.0.12 - '@netlify/images': 1.2.8(@netlify/blobs@10.0.11)(uploadthing@7.7.4(express@5.2.1)(h3@1.15.4)(tailwindcss@4.1.11)) + '@netlify/images': 1.2.8(@netlify/blobs@10.0.11)(uploadthing@7.7.4(h3@1.15.4)(tailwindcss@4.1.11)) '@netlify/redirects': 3.0.13 '@netlify/runtime': 4.0.16 '@netlify/static': 3.0.11 @@ -8998,9 +8596,9 @@ snapshots: dependencies: '@netlify/headers-parser': 9.0.2 - '@netlify/images@1.2.8(@netlify/blobs@10.0.11)(uploadthing@7.7.4(express@5.2.1)(h3@1.15.4)(tailwindcss@4.1.11))': + '@netlify/images@1.2.8(@netlify/blobs@10.0.11)(uploadthing@7.7.4(h3@1.15.4)(tailwindcss@4.1.11))': dependencies: - ipx: 3.1.1(@netlify/blobs@10.0.11)(uploadthing@7.7.4(express@5.2.1)(h3@1.15.4)(tailwindcss@4.1.11)) + ipx: 3.1.1(@netlify/blobs@10.0.11)(uploadthing@7.7.4(h3@1.15.4)(tailwindcss@4.1.11)) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -9062,9 +8660,9 @@ snapshots: '@netlify/types@2.2.0': {} - '@netlify/vite-plugin-tanstack-start@1.0.2(@tanstack/react-start@1.141.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.1.7(@types/node@24.3.0)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1)))(babel-plugin-macros@3.1.0)(rollup@4.53.3)(uploadthing@7.7.4(express@5.2.1)(h3@1.15.4)(tailwindcss@4.1.11))(vite@7.1.7(@types/node@24.3.0)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1))': + '@netlify/vite-plugin-tanstack-start@1.0.2(@tanstack/react-start@1.141.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.1.7(@types/node@24.3.0)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1)))(babel-plugin-macros@3.1.0)(rollup@4.53.3)(uploadthing@7.7.4(h3@1.15.4)(tailwindcss@4.1.11))(vite@7.1.7(@types/node@24.3.0)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1))': dependencies: - '@netlify/vite-plugin': 2.6.1(babel-plugin-macros@3.1.0)(rollup@4.53.3)(uploadthing@7.7.4(express@5.2.1)(h3@1.15.4)(tailwindcss@4.1.11))(vite@7.1.7(@types/node@24.3.0)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1)) + '@netlify/vite-plugin': 2.6.1(babel-plugin-macros@3.1.0)(rollup@4.53.3)(uploadthing@7.7.4(h3@1.15.4)(tailwindcss@4.1.11))(vite@7.1.7(@types/node@24.3.0)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1)) vite: 7.1.7(@types/node@24.3.0)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1) optionalDependencies: '@tanstack/react-start': 1.141.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.1.7(@types/node@24.3.0)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1)) @@ -9093,9 +8691,9 @@ snapshots: - supports-color - uploadthing - '@netlify/vite-plugin@2.6.1(babel-plugin-macros@3.1.0)(rollup@4.53.3)(uploadthing@7.7.4(express@5.2.1)(h3@1.15.4)(tailwindcss@4.1.11))(vite@7.1.7(@types/node@24.3.0)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1))': + '@netlify/vite-plugin@2.6.1(babel-plugin-macros@3.1.0)(rollup@4.53.3)(uploadthing@7.7.4(h3@1.15.4)(tailwindcss@4.1.11))(vite@7.1.7(@types/node@24.3.0)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1))': dependencies: - '@netlify/dev': 4.5.12(rollup@4.53.3)(uploadthing@7.7.4(express@5.2.1)(h3@1.15.4)(tailwindcss@4.1.11)) + '@netlify/dev': 4.5.12(rollup@4.53.3)(uploadthing@7.7.4(h3@1.15.4)(tailwindcss@4.1.11)) '@netlify/dev-utils': 4.2.0 dedent: 1.7.0(babel-plugin-macros@3.1.0) vite: 7.1.7(@types/node@24.3.0)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1) @@ -9307,9 +8905,8 @@ snapshots: '@parcel/watcher-win32-ia32': 2.5.1 '@parcel/watcher-win32-x64': 2.5.1 - '@playwright/test@1.57.0': - dependencies: - playwright: 1.57.0 + '@pkgjs/parseargs@0.11.0': + optional: true '@radix-ui/primitive@1.1.2': {} @@ -9682,59 +9279,6 @@ snapshots: '@radix-ui/rect@1.1.1': {} - '@react-three/drei@10.7.7(@react-three/fiber@9.5.0(@types/react@19.2.5)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(three@0.182.0))(@types/react@19.2.5)(@types/three@0.182.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(three@0.182.0)': - dependencies: - '@babel/runtime': 7.28.4 - '@mediapipe/tasks-vision': 0.10.17 - '@monogrid/gainmap-js': 3.4.0(three@0.182.0) - '@react-three/fiber': 9.5.0(@types/react@19.2.5)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(three@0.182.0) - '@use-gesture/react': 10.3.1(react@19.2.0) - camera-controls: 3.1.2(three@0.182.0) - cross-env: 7.0.3 - detect-gpu: 5.0.70 - glsl-noise: 0.0.0 - hls.js: 1.6.15 - maath: 0.10.8(@types/three@0.182.0)(three@0.182.0) - meshline: 3.3.1(three@0.182.0) - react: 19.2.0 - stats-gl: 2.4.2(@types/three@0.182.0)(three@0.182.0) - stats.js: 0.17.0 - suspend-react: 0.1.3(react@19.2.0) - three: 0.182.0 - three-mesh-bvh: 0.8.3(three@0.182.0) - three-stdlib: 2.36.1(three@0.182.0) - troika-three-text: 0.52.4(three@0.182.0) - tunnel-rat: 0.1.2(@types/react@19.2.5)(react@19.2.0) - use-sync-external-store: 1.6.0(react@19.2.0) - utility-types: 3.11.0 - zustand: 5.0.9(@types/react@19.2.5)(react@19.2.0)(use-sync-external-store@1.6.0(react@19.2.0)) - optionalDependencies: - react-dom: 19.2.0(react@19.2.0) - transitivePeerDependencies: - - '@types/react' - - '@types/three' - - immer - - '@react-three/fiber@9.5.0(@types/react@19.2.5)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(three@0.182.0)': - dependencies: - '@babel/runtime': 7.24.5 - '@types/webxr': 0.5.24 - base64-js: 1.5.1 - buffer: 6.0.3 - its-fine: 2.0.0(@types/react@19.2.5)(react@19.2.0) - react: 19.2.0 - react-use-measure: 2.1.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - scheduler: 0.27.0 - suspend-react: 0.1.3(react@19.2.0) - three: 0.182.0 - use-sync-external-store: 1.6.0(react@19.2.0) - zustand: 5.0.9(@types/react@19.2.5)(react@19.2.0)(use-sync-external-store@1.6.0(react@19.2.0)) - optionalDependencies: - react-dom: 19.2.0(react@19.2.0) - transitivePeerDependencies: - - '@types/react' - - immer - '@rolldown/pluginutils@1.0.0-beta.40': {} '@rollup/pluginutils@5.3.0(rollup@4.53.3)': @@ -9856,7 +9400,7 @@ snapshots: '@sentry/cli': 2.38.1 dotenv: 16.6.1 find-up: 5.0.0 - glob: 13.0.0 + glob: 9.3.5 magic-string: 0.30.8 unplugin: 1.0.1 transitivePeerDependencies: @@ -10029,6 +9573,51 @@ snapshots: tailwindcss: 4.1.11 vite: 7.1.7(@types/node@24.3.0)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1) + '@takumi-rs/core-darwin-arm64@0.62.6': + optional: true + + '@takumi-rs/core-darwin-x64@0.62.6': + optional: true + + '@takumi-rs/core-linux-arm64-gnu@0.62.6': + optional: true + + '@takumi-rs/core-linux-arm64-musl@0.62.6': + optional: true + + '@takumi-rs/core-linux-x64-gnu@0.62.6': + optional: true + + '@takumi-rs/core-linux-x64-musl@0.62.6': + optional: true + + '@takumi-rs/core-win32-arm64-msvc@0.62.6': + optional: true + + '@takumi-rs/core-win32-x64-msvc@0.62.6': + optional: true + + '@takumi-rs/core@0.62.6': + optionalDependencies: + '@takumi-rs/core-darwin-arm64': 0.62.6 + '@takumi-rs/core-darwin-x64': 0.62.6 + '@takumi-rs/core-linux-arm64-gnu': 0.62.6 + '@takumi-rs/core-linux-arm64-musl': 0.62.6 + '@takumi-rs/core-linux-x64-gnu': 0.62.6 + '@takumi-rs/core-linux-x64-musl': 0.62.6 + '@takumi-rs/core-win32-arm64-msvc': 0.62.6 + '@takumi-rs/core-win32-x64-msvc': 0.62.6 + + '@takumi-rs/helpers@0.62.6': {} + + '@takumi-rs/image-response@0.62.6': + dependencies: + '@takumi-rs/core': 0.62.6 + '@takumi-rs/helpers': 0.62.6 + '@takumi-rs/wasm': 0.62.6 + + '@takumi-rs/wasm@0.62.6': {} + '@tanstack/devtools-event-client@0.3.5': {} '@tanstack/directive-functions-plugin@1.141.0(vite@7.1.7(@types/node@24.3.0)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1))': @@ -10327,8 +9916,6 @@ snapshots: '@tanstack/virtual-file-routes@1.141.0': {} - '@tweenjs/tween.js@23.1.3': {} - '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.28.4 @@ -10475,8 +10062,6 @@ snapshots: '@types/dom-speech-recognition@0.0.1': {} - '@types/draco3d@1.4.10': {} - '@types/estree@1.0.8': {} '@types/geojson@7946.0.16': {} @@ -10509,8 +10094,6 @@ snapshots: '@types/normalize-package-data@2.4.4': {} - '@types/offscreencanvas@2019.7.3': {} - '@types/parse-json@4.0.2': optional: true @@ -10532,10 +10115,6 @@ snapshots: dependencies: '@types/react': 19.2.5 - '@types/react-reconciler@0.28.9(@types/react@19.2.5)': - dependencies: - '@types/react': 19.2.5 - '@types/react@19.2.5': dependencies: csstype: 3.1.3 @@ -10544,18 +10123,6 @@ snapshots: '@types/retry@0.12.2': {} - '@types/stats.js@0.17.4': {} - - '@types/three@0.182.0': - dependencies: - '@dimforge/rapier3d-compat': 0.12.0 - '@tweenjs/tween.js': 23.1.3 - '@types/stats.js': 0.17.4 - '@types/webxr': 0.5.24 - '@webgpu/types': 0.1.68 - fflate: 0.8.2 - meshoptimizer: 0.22.0 - '@types/triple-beam@1.3.5': {} '@types/trusted-types@2.0.7': @@ -10563,8 +10130,6 @@ snapshots: '@types/unist@3.0.3': {} - '@types/webxr@0.5.24': {} - '@types/yauzl@2.10.3': dependencies: '@types/node': 24.3.0 @@ -10666,12 +10231,12 @@ snapshots: '@uploadthing/mime-types@0.3.6': {} - '@uploadthing/react@7.3.3(react@19.2.0)(uploadthing@7.7.4(express@5.2.1)(h3@1.15.4)(tailwindcss@4.1.11))': + '@uploadthing/react@7.3.3(react@19.2.0)(uploadthing@7.7.4(h3@1.15.4)(tailwindcss@4.1.11))': dependencies: '@uploadthing/shared': 7.1.10 file-selector: 0.6.0 react: 19.2.0 - uploadthing: 7.7.4(express@5.2.1)(h3@1.15.4)(tailwindcss@4.1.11) + uploadthing: 7.7.4(h3@1.15.4)(tailwindcss@4.1.11) '@uploadthing/shared@7.1.10': dependencies: @@ -10679,13 +10244,6 @@ snapshots: effect: 3.17.7 sqids: 0.3.0 - '@use-gesture/core@10.3.1': {} - - '@use-gesture/react@10.3.1(react@19.2.0)': - dependencies: - '@use-gesture/core': 10.3.1 - react: 19.2.0 - '@vercel/nft@0.29.4(rollup@4.53.3)': dependencies: '@mapbox/node-pre-gyp': 2.0.0 @@ -10695,7 +10253,7 @@ snapshots: async-sema: 3.1.1 bindings: 1.5.0 estree-walker: 2.0.2 - glob: 13.0.0 + glob: 10.4.5 graceful-fs: 4.2.11 node-gyp-build: 4.8.4 picomatch: 4.0.3 @@ -10774,8 +10332,6 @@ snapshots: '@vue/shared@3.5.22': {} - '@webgpu/types@0.1.68': {} - '@whatwg-node/disposablestack@0.0.6': dependencies: '@whatwg-node/promise-helpers': 1.3.2 @@ -10813,11 +10369,6 @@ snapshots: dependencies: event-target-shim: 5.0.1 - accepts@2.0.0: - dependencies: - mime-types: 3.0.1 - negotiator: 1.0.0 - acorn-import-attributes@1.9.5(acorn@8.15.0): dependencies: acorn: 8.15.0 @@ -10840,10 +10391,6 @@ snapshots: dependencies: ajv: 8.17.1 - ajv-formats@3.0.1(ajv@8.17.1): - optionalDependencies: - ajv: 8.17.1 - ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -10881,6 +10428,8 @@ snapshots: ansi-regex@5.0.1: {} + ansi-regex@6.2.2: {} + ansi-styles@3.2.1: dependencies: color-convert: 1.9.3 @@ -10889,6 +10438,8 @@ snapshots: dependencies: color-convert: 2.0.1 + ansi-styles@6.2.3: {} + ansis@4.1.0: {} anymatch@3.1.3: @@ -10898,7 +10449,7 @@ snapshots: archiver-utils@5.0.2: dependencies: - glob: 13.0.0 + glob: 10.4.5 graceful-fs: 4.2.11 is-stream: 2.0.1 lazystream: 1.0.1 @@ -10918,6 +10469,10 @@ snapshots: transitivePeerDependencies: - react-native-b4a + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + argparse@2.0.1: {} aria-hidden@1.2.4: @@ -11042,7 +10597,7 @@ snapshots: babel-plugin-macros@3.1.0: dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.24.5 cosmiconfig: 7.1.0 resolve: 1.22.10 optional: true @@ -11064,10 +10619,6 @@ snapshots: jsonpointer: 5.0.1 leven: 3.1.0 - bidi-js@1.0.3: - dependencies: - require-from-string: 2.0.2 - binary-extensions@2.2.0: {} binary-search-bounds@2.0.5: {} @@ -11076,22 +10627,13 @@ snapshots: dependencies: file-uri-to-path: 1.0.0 - body-parser@2.2.2: - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 4.4.3 - http-errors: 2.0.1 - iconv-lite: 0.7.2 - on-finished: 2.4.1 - qs: 6.14.1 - raw-body: 3.0.2 - type-is: 2.0.1 - transitivePeerDependencies: - - supports-color - boolbase@1.0.0: {} + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + brace-expansion@2.0.2: dependencies: balanced-match: 1.0.2 @@ -11122,8 +10664,6 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 - bytes@3.1.2: {} - call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 @@ -11155,10 +10695,6 @@ snapshots: camelcase@8.0.0: {} - camera-controls@3.1.2(three@0.182.0): - dependencies: - three: 0.182.0 - caniuse-lite@1.0.30001692: {} ccount@2.0.1: {} @@ -11326,16 +10862,14 @@ snapshots: normalize-path: 3.0.0 readable-stream: 4.7.0 + concat-map@0.0.1: {} + confbox@0.1.8: {} confbox@0.2.2: {} consola@3.4.2: {} - content-disposition@1.0.1: {} - - content-type@1.0.5: {} - convert-source-map@1.9.0: {} convert-source-map@2.0.0: {} @@ -11344,8 +10878,6 @@ snapshots: cookie-es@2.0.0: {} - cookie-signature@1.2.2: {} - cookie@0.7.1: {} cookie@1.0.2: {} @@ -11357,11 +10889,6 @@ snapshots: core-util-is@1.0.3: {} - cors@2.8.5: - dependencies: - object-assign: 4.1.1 - vary: 1.1.2 - cose-base@1.0.3: dependencies: layout-base: 1.0.2 @@ -11390,9 +10917,13 @@ snapshots: dependencies: luxon: 3.5.0 - cross-env@7.0.3: + cross-spawn@6.0.5: dependencies: - cross-spawn: 7.0.6 + nice-try: 1.0.5 + path-key: 2.0.1 + semver: 5.7.2 + shebang-command: 1.2.0 + which: 1.3.1 cross-spawn@7.0.6: dependencies: @@ -11690,18 +11221,12 @@ snapshots: dependencies: robust-predicates: 3.0.2 - depd@2.0.0: {} - deprecation@2.3.1: {} dequal@2.0.3: {} destr@2.0.5: {} - detect-gpu@5.0.70: - dependencies: - webgl-constants: 1.1.1 - detect-libc@1.0.3: {} detect-libc@2.0.4: {} @@ -11774,8 +11299,6 @@ snapshots: diff@8.0.2: {} - discord-interactions@4.4.0: {} - doctrine@2.1.0: dependencies: esutils: 2.0.3 @@ -11817,8 +11340,6 @@ snapshots: dotenv@16.6.1: {} - draco3d@1.5.7: {} - drizzle-kit@0.31.7: dependencies: '@drizzle-team/brocli': 0.10.2 @@ -11843,12 +11364,12 @@ snapshots: duplexer@0.1.2: {} + eastasianwidth@0.2.0: {} + ecdsa-sig-formatter@1.0.11: dependencies: safe-buffer: 5.2.1 - ee-first@1.1.1: {} - effect@3.17.7: dependencies: '@standard-schema/spec': 1.1.0 @@ -11868,8 +11389,6 @@ snapshots: enabled@2.0.0: {} - encodeurl@2.0.0: {} - encoding-sniffer@0.2.1: dependencies: iconv-lite: 0.6.3 @@ -12217,8 +11736,8 @@ snapshots: '@babel/parser': 7.28.4 eslint: 9.39.1(jiti@2.6.0) hermes-parser: 0.25.1 - zod: 4.3.5 - zod-validation-error: 4.0.2(zod@4.3.5) + zod: 4.1.9 + zod-validation-error: 4.0.2(zod@4.1.9) transitivePeerDependencies: - supports-color @@ -12328,12 +11847,6 @@ snapshots: events@3.3.0: {} - eventsource-parser@3.0.6: {} - - eventsource@3.0.7: - dependencies: - eventsource-parser: 3.0.6 - execa@8.0.1: dependencies: cross-spawn: 7.0.6 @@ -12346,43 +11859,6 @@ snapshots: signal-exit: 4.1.0 strip-final-newline: 3.0.0 - express-rate-limit@7.5.1(express@5.2.1): - dependencies: - express: 5.2.1 - - express@5.2.1: - dependencies: - accepts: 2.0.0 - body-parser: 2.2.2 - content-disposition: 1.0.1 - content-type: 1.0.5 - cookie: 0.7.1 - cookie-signature: 1.2.2 - debug: 4.4.3 - depd: 2.0.0 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 2.1.1 - fresh: 2.0.0 - http-errors: 2.0.1 - merge-descriptors: 2.0.0 - mime-types: 3.0.1 - on-finished: 2.4.1 - once: 1.4.0 - parseurl: 1.3.3 - proxy-addr: 2.0.7 - qs: 6.14.1 - range-parser: 1.2.1 - router: 2.2.0 - send: 1.2.1 - serve-static: 2.2.1 - statuses: 2.0.2 - type-is: 2.0.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - exsolve@1.0.7: {} extend-shallow@2.0.1: @@ -12448,10 +11924,6 @@ snapshots: fetchdts@0.1.7: {} - fflate@0.6.10: {} - - fflate@0.8.2: {} - figures@6.1.0: dependencies: is-unicode-supported: 2.1.0 @@ -12476,17 +11948,6 @@ snapshots: filter-obj@6.1.0: {} - finalhandler@2.1.1: - dependencies: - debug: 4.4.3 - encodeurl: 2.0.0 - escape-html: 1.0.3 - on-finished: 2.4.1 - parseurl: 1.3.3 - statuses: 2.0.2 - transitivePeerDependencies: - - supports-color - find-my-way-ts@0.1.6: {} find-up-simple@1.0.1: {} @@ -12519,18 +11980,18 @@ snapshots: dependencies: is-callable: 1.2.7 + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + formdata-polyfill@4.0.10: dependencies: fetch-blob: 3.2.0 - forwarded@0.2.0: {} - fraction.js@4.3.7: {} - fresh@2.0.0: {} - - fsevents@2.3.2: - optional: true + fs.realpath@1.0.0: {} fsevents@2.3.3: optional: true @@ -12620,11 +12081,30 @@ snapshots: dependencies: is-glob: 4.0.3 - glob@13.0.0: + glob@10.4.5: dependencies: - minimatch: 10.1.1 + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 minipass: 7.1.2 - path-scurry: 2.0.1 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@9.3.5: + dependencies: + fs.realpath: 1.0.0 + minimatch: 8.0.4 + minipass: 4.2.8 + path-scurry: 1.11.1 globals@14.0.0: {} @@ -12641,8 +12121,6 @@ snapshots: globrex@0.1.2: {} - glsl-noise@0.0.0: {} - gonzales-pe@4.3.0: dependencies: minimist: 1.2.8 @@ -12659,7 +12137,7 @@ snapshots: gray-matter@4.0.3: dependencies: - js-yaml: 4.1.1 + js-yaml: 3.14.1 kind-of: 6.0.3 section-matter: 1.0.0 strip-bom-string: 1.0.0 @@ -12809,8 +12287,6 @@ snapshots: dependencies: hermes-estree: 0.25.1 - hls.js@1.6.15: {} - hogan.js@3.0.2: dependencies: mkdirp: 0.3.0 @@ -12820,12 +12296,6 @@ snapshots: dependencies: react-is: 16.13.1 - hono-rate-limiter@0.4.2(hono@4.11.3): - dependencies: - hono: 4.11.3 - - hono@4.11.3: {} - hosted-git-info@2.8.9: {} hosted-git-info@7.0.2: @@ -12865,14 +12335,6 @@ snapshots: domutils: 3.2.2 entities: 4.5.0 - http-errors@2.0.1: - dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.2 - toidentifier: 1.0.1 - http-shutdown@1.2.2: {} https-proxy-agent@5.0.1: @@ -12895,10 +12357,6 @@ snapshots: dependencies: safer-buffer: 2.1.2 - iconv-lite@0.7.2: - dependencies: - safer-buffer: 2.1.2 - ieee754@1.2.1: {} ignore@5.3.2: {} @@ -12909,8 +12367,6 @@ snapshots: image-size@2.0.2: {} - immediate@3.0.6: {} - import-fresh@3.3.0: dependencies: parent-module: 1.0.1 @@ -12922,6 +12378,11 @@ snapshots: index-to-position@1.2.0: {} + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + inherits@2.0.4: {} inline-style-parser@0.2.3: {} @@ -12943,7 +12404,7 @@ snapshots: htm: 3.1.1 instantsearch-ui-components: 0.11.1 preact: 10.26.5 - qs: 6.14.1 + qs: 6.9.7 search-insights: 2.17.3 internal-slot@1.0.7: @@ -12966,9 +12427,7 @@ snapshots: dependencies: binary-search-bounds: 2.0.5 - ipaddr.js@1.9.1: {} - - ipx@3.1.1(@netlify/blobs@10.0.11)(uploadthing@7.7.4(express@5.2.1)(h3@1.15.4)(tailwindcss@4.1.11)): + ipx@3.1.1(@netlify/blobs@10.0.11)(uploadthing@7.7.4(h3@1.15.4)(tailwindcss@4.1.11)): dependencies: '@fastify/accept-negotiator': 2.0.1 citty: 0.1.6 @@ -12984,7 +12443,7 @@ snapshots: sharp: 0.34.4 svgo: 4.0.0 ufo: 1.6.1 - unstorage: 1.17.1(@netlify/blobs@10.0.11)(uploadthing@7.7.4(express@5.2.1)(h3@1.15.4)(tailwindcss@4.1.11)) + unstorage: 1.17.1(@netlify/blobs@10.0.11)(uploadthing@7.7.4(h3@1.15.4)(tailwindcss@4.1.11)) xss: 1.0.15 transitivePeerDependencies: - '@azure/app-configuration' @@ -13120,10 +12579,6 @@ snapshots: is-plain-object@5.0.0: {} - is-promise@2.2.2: {} - - is-promise@4.0.0: {} - is-regex@1.1.4: dependencies: call-bind: 1.0.7 @@ -13231,12 +12686,11 @@ snapshots: has-symbols: 1.1.0 set-function-name: 2.0.2 - its-fine@2.0.0(@types/react@19.2.5)(react@19.2.0): + jackspeak@3.4.3: dependencies: - '@types/react-reconciler': 0.28.9(@types/react@19.2.5) - react: 19.2.0 - transitivePeerDependencies: - - '@types/react' + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 jake@10.9.4: dependencies: @@ -13250,8 +12704,6 @@ snapshots: jose@5.10.0: {} - jose@6.1.3: {} - jpeg-js@0.4.4: {} js-image-generator@1.0.4: @@ -13260,6 +12712,11 @@ snapshots: js-tokens@4.0.0: {} + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + js-yaml@4.1.1: dependencies: argparse: 2.0.1 @@ -13277,8 +12734,6 @@ snapshots: json-schema-traverse@1.0.0: {} - json-schema-typed@8.0.2: {} - json-stable-stringify-without-jsonify@1.0.1: {} json5@2.2.3: {} @@ -13287,7 +12742,7 @@ snapshots: jsonwebtoken@9.0.2: dependencies: - jws: 4.0.1 + jws: 3.2.2 lodash.includes: 4.3.0 lodash.isboolean: 3.0.3 lodash.isinteger: 4.0.4 @@ -13307,15 +12762,15 @@ snapshots: junk@4.0.1: {} - jwa@2.0.1: + jwa@1.4.2: dependencies: buffer-equal-constant-time: 1.0.1 ecdsa-sig-formatter: 1.0.11 safe-buffer: 5.2.1 - jws@4.0.1: + jws@3.2.2: dependencies: - jwa: 2.0.1 + jwa: 1.4.2 safe-buffer: 5.2.1 jwt-decode@4.0.0: {} @@ -13374,10 +12829,6 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - lie@3.3.0: - dependencies: - immediate: 3.0.6 - lightningcss-darwin-arm64@1.30.1: optional: true @@ -13440,7 +12891,7 @@ snapshots: http-shutdown: 1.2.2 jiti: 2.6.0 mlly: 1.7.4 - node-forge: 1.3.3 + node-forge: 1.3.1 pathe: 1.1.2 std-env: 3.9.0 ufo: 1.6.1 @@ -13507,8 +12958,6 @@ snapshots: lru-cache@10.4.3: {} - lru-cache@11.2.4: {} - lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -13521,11 +12970,6 @@ snapshots: luxon@3.5.0: {} - maath@0.10.8(@types/three@0.182.0)(three@0.182.0): - dependencies: - '@types/three': 0.182.0 - three: 0.182.0 - magic-string@0.30.17: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -13664,12 +13108,8 @@ snapshots: mdn-data@2.12.2: {} - media-typer@1.1.0: {} - memorystream@0.3.1: {} - merge-descriptors@2.0.0: {} - merge-options@3.0.4: dependencies: is-plain-obj: 2.1.0 @@ -13703,12 +13143,6 @@ snapshots: transitivePeerDependencies: - supports-color - meshline@3.3.1(three@0.182.0): - dependencies: - three: 0.182.0 - - meshoptimizer@0.22.0: {} - micromark-core-commonmark@2.0.3: dependencies: decode-named-character-reference: 1.2.0 @@ -13911,21 +13345,17 @@ snapshots: dependencies: mime-db: 1.54.0 - mime-types@3.0.2: - dependencies: - mime-db: 1.54.0 - mimic-fn@4.0.0: {} - minimatch@10.1.1: + minimatch@3.1.2: dependencies: - '@isaacs/brace-expansion': 5.0.0 + brace-expansion: 1.1.11 - minimatch@3.1.2: + minimatch@5.1.6: dependencies: brace-expansion: 2.0.2 - minimatch@5.1.6: + minimatch@8.0.4: dependencies: brace-expansion: 2.0.2 @@ -13935,6 +13365,8 @@ snapshots: minimist@1.2.8: {} + minipass@4.2.8: {} + minipass@7.1.2: {} minizlib@3.0.2: @@ -13985,10 +13417,10 @@ snapshots: natural-compare@1.4.0: {} - negotiator@1.0.0: {} - netlify-redirector@0.5.0: {} + nice-try@1.0.5: {} + node-addon-api@7.1.1: {} node-domexception@1.0.0: {} @@ -14005,7 +13437,7 @@ snapshots: fetch-blob: 3.2.0 formdata-polyfill: 4.0.10 - node-forge@1.3.3: {} + node-forge@1.3.1: {} node-gyp-build-optional-packages@5.2.2: dependencies: @@ -14059,7 +13491,7 @@ snapshots: dependencies: ansi-styles: 3.2.1 chalk: 2.4.2 - cross-spawn: 7.0.6 + cross-spawn: 6.0.5 memorystream: 0.3.1 minimatch: 3.1.2 pidtree: 0.3.1 @@ -14134,10 +13566,6 @@ snapshots: omit.js@2.0.2: {} - on-finished@2.4.1: - dependencies: - ee-first: 1.1.1 - once@1.4.0: dependencies: wrappy: 1.0.2 @@ -14208,6 +13636,8 @@ snapshots: dependencies: p-timeout: 6.1.4 + package-json-from-dist@1.0.1: {} + package-manager-detector@1.3.0: {} parent-module@1.0.1: @@ -14253,27 +13683,27 @@ snapshots: dependencies: entities: 6.0.1 - parseurl@1.3.3: {} - path-data-parser@0.1.0: {} path-exists@4.0.0: {} path-exists@5.0.0: {} + path-is-absolute@1.0.1: {} + + path-key@2.0.1: {} + path-key@3.1.1: {} path-key@4.0.0: {} path-parse@1.0.7: {} - path-scurry@2.0.1: + path-scurry@1.11.1: dependencies: - lru-cache: 11.2.4 + lru-cache: 10.4.3 minipass: 7.1.2 - path-to-regexp@8.3.0: {} - path-type@3.0.0: dependencies: pify: 3.0.0 @@ -14325,8 +13755,6 @@ snapshots: pify@3.0.0: {} - pkce-challenge@5.0.1: {} - pkg-types@1.3.1: dependencies: confbox: 0.1.8 @@ -14339,14 +13767,6 @@ snapshots: exsolve: 1.0.7 pathe: 2.0.3 - playwright-core@1.57.0: {} - - playwright@1.57.0: - dependencies: - playwright-core: 1.57.0 - optionalDependencies: - fsevents: 2.3.2 - pluralize@8.0.0: {} points-on-curve@0.2.0: {} @@ -14402,8 +13822,6 @@ snapshots: postgres@3.4.7: {} - potpack@1.0.2: {} - preact-render-to-string@5.2.3(preact@10.11.3): dependencies: preact: 10.11.3 @@ -14445,11 +13863,6 @@ snapshots: progress@2.0.3: {} - promise-worker-transferable@1.0.4: - dependencies: - is-promise: 2.2.2 - lie: 3.3.0 - prop-types@15.8.1: dependencies: loose-envify: 1.4.0 @@ -14460,11 +13873,6 @@ snapshots: property-information@7.1.0: {} - proxy-addr@2.0.7: - dependencies: - forwarded: 0.2.0 - ipaddr.js: 1.9.1 - proxy-from-env@1.1.0: {} pump@3.0.3: @@ -14476,9 +13884,7 @@ snapshots: pure-rand@6.1.0: {} - qs@6.14.1: - dependencies: - side-channel: 1.1.0 + qs@6.9.7: {} quansync@0.2.11: {} @@ -14494,15 +13900,6 @@ snapshots: dependencies: safe-buffer: 5.2.1 - range-parser@1.2.1: {} - - raw-body@3.0.2: - dependencies: - bytes: 3.1.2 - http-errors: 2.0.1 - iconv-lite: 0.7.2 - unpipe: 1.0.0 - react-colorful@5.6.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: react: 19.2.0 @@ -14572,12 +13969,6 @@ snapshots: optionalDependencies: '@types/react': 19.2.5 - react-use-measure@2.1.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0): - dependencies: - react: 19.2.0 - optionalDependencies: - react-dom: 19.2.0(react@19.2.0) - react@19.2.0: {} read-package-up@11.0.0: @@ -14788,7 +14179,7 @@ snapshots: rimraf@2.6.3: dependencies: - glob: 13.0.0 + glob: 7.2.3 robust-predicates@3.0.2: {} @@ -14829,16 +14220,6 @@ snapshots: points-on-curve: 0.2.0 points-on-path: 0.2.1 - router@2.2.0: - dependencies: - debug: 4.4.3 - depd: 2.0.0 - is-promise: 4.0.0 - parseurl: 1.3.3 - path-to-regexp: 8.3.0 - transitivePeerDependencies: - - supports-color - run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -14904,22 +14285,6 @@ snapshots: semver@7.7.3: {} - send@1.2.1: - dependencies: - debug: 4.4.3 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 2.0.0 - http-errors: 2.0.1 - mime-types: 3.0.2 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.2 - transitivePeerDependencies: - - supports-color - serialize-javascript@6.0.2: dependencies: randombytes: 2.1.0 @@ -14942,15 +14307,6 @@ snapshots: seroval@1.4.1: {} - serve-static@2.2.1: - dependencies: - encodeurl: 2.0.0 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 1.2.1 - transitivePeerDependencies: - - supports-color - set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -14979,8 +14335,6 @@ snapshots: es-errors: 1.3.0 es-object-atoms: 1.1.1 - setprototypeof@1.2.0: {} - sharp@0.34.4: dependencies: '@img/colour': 1.0.0 @@ -15010,10 +14364,16 @@ snapshots: '@img/sharp-win32-ia32': 0.34.4 '@img/sharp-win32-x64': 0.34.4 + shebang-command@1.2.0: + dependencies: + shebang-regex: 1.0.0 + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 + shebang-regex@1.0.0: {} + shebang-regex@3.0.0: {} shell-quote@1.8.1: {} @@ -15068,7 +14428,7 @@ snapshots: convert-source-map: 1.9.0 ejs: 3.1.10 escape-html: 1.0.3 - glob: 13.0.0 + glob: 7.2.3 gzip-size: 6.0.0 lodash: 4.17.21 open: 7.4.2 @@ -15103,6 +14463,8 @@ snapshots: spdx-license-ids@3.0.16: {} + sprintf-js@1.0.3: {} + sqids@0.3.0: {} srvx@0.8.16: {} @@ -15111,15 +14473,6 @@ snapshots: stack-trace@0.0.10: {} - stats-gl@2.4.2(@types/three@0.182.0)(three@0.182.0): - dependencies: - '@types/three': 0.182.0 - three: 0.182.0 - - stats.js@0.17.0: {} - - statuses@2.0.2: {} - std-env@3.9.0: {} stop-iteration-iterator@1.1.0: @@ -15141,6 +14494,12 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.2 + string.prototype.includes@2.0.1: dependencies: call-bind: 1.0.8 @@ -15232,6 +14591,10 @@ snapshots: dependencies: ansi-regex: 5.0.1 + strip-ansi@7.1.2: + dependencies: + ansi-regex: 6.2.2 + strip-bom-string@1.0.0: {} strip-bom@3.0.0: {} @@ -15260,10 +14623,6 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - suspend-react@0.1.3(react@19.2.0): - dependencies: - react: 19.2.0 - svgo@4.0.0: dependencies: commander: 11.1.0 @@ -15331,22 +14690,6 @@ snapshots: text-hex@1.0.0: {} - three-mesh-bvh@0.8.3(three@0.182.0): - dependencies: - three: 0.182.0 - - three-stdlib@2.36.1(three@0.182.0): - dependencies: - '@types/draco3d': 1.4.10 - '@types/offscreencanvas': 2019.7.3 - '@types/webxr': 0.5.24 - draco3d: 1.5.7 - fflate: 0.6.10 - potpack: 1.0.2 - three: 0.182.0 - - three@0.182.0: {} - tiny-invariant@1.3.3: {} tiny-warning@1.0.3: {} @@ -15373,8 +14716,6 @@ snapshots: dependencies: is-number: 7.0.0 - toidentifier@1.0.1: {} - toml@3.0.0: {} tomlify-j0.4@3.0.0: {} @@ -15385,20 +14726,6 @@ snapshots: triple-beam@1.4.1: {} - troika-three-text@0.52.4(three@0.182.0): - dependencies: - bidi-js: 1.0.3 - three: 0.182.0 - troika-three-utils: 0.52.4(three@0.182.0) - troika-worker-utils: 0.52.0 - webgl-sdf-generator: 1.1.1 - - troika-three-utils@0.52.4(three@0.182.0): - dependencies: - three: 0.182.0 - - troika-worker-utils@0.52.0: {} - trough@2.2.0: {} ts-api-utils@2.1.0(typescript@5.9.2): @@ -15420,26 +14747,12 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - tunnel-rat@0.1.2(@types/react@19.2.5)(react@19.2.0): - dependencies: - zustand: 4.5.2(@types/react@19.2.5)(react@19.2.0) - transitivePeerDependencies: - - '@types/react' - - immer - - react - type-check@0.4.0: dependencies: prelude-ls: 1.2.1 type-fest@4.41.0: {} - type-is@2.0.1: - dependencies: - content-type: 1.0.5 - media-typer: 1.1.0 - mime-types: 3.0.1 - typed-array-buffer@1.0.2: dependencies: call-bind: 1.0.7 @@ -15585,8 +14898,6 @@ snapshots: dependencies: normalize-path: 2.1.1 - unpipe@1.0.0: {} - unplugin@1.0.1: dependencies: acorn: 8.15.0 @@ -15601,7 +14912,7 @@ snapshots: picomatch: 4.0.3 webpack-virtual-modules: 0.6.2 - unstorage@1.17.1(@netlify/blobs@10.0.11)(uploadthing@7.7.4(express@5.2.1)(h3@1.15.4)(tailwindcss@4.1.11)): + unstorage@1.17.1(@netlify/blobs@10.0.11)(uploadthing@7.7.4(h3@1.15.4)(tailwindcss@4.1.11)): dependencies: anymatch: 3.1.3 chokidar: 4.0.3 @@ -15613,7 +14924,7 @@ snapshots: ufo: 1.6.1 optionalDependencies: '@netlify/blobs': 10.0.11 - uploadthing: 7.7.4(express@5.2.1)(h3@1.15.4)(tailwindcss@4.1.11) + uploadthing: 7.7.4(h3@1.15.4)(tailwindcss@4.1.11) untun@0.1.3: dependencies: @@ -15627,7 +14938,7 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 - uploadthing@7.7.4(express@5.2.1)(h3@1.15.4)(tailwindcss@4.1.11): + uploadthing@7.7.4(h3@1.15.4)(tailwindcss@4.1.11): dependencies: '@effect/platform': 0.90.3(effect@3.17.7) '@standard-schema/spec': 1.0.0-beta.4 @@ -15635,7 +14946,6 @@ snapshots: '@uploadthing/shared': 7.1.10 effect: 3.17.7 optionalDependencies: - express: 5.2.1 h3: 1.15.4 tailwindcss: 4.1.11 @@ -15679,8 +14989,6 @@ snapshots: util-deprecate@1.0.2: {} - utility-types@3.11.0: {} - uuid@10.0.0: {} uuid@11.1.0: {} @@ -15696,8 +15004,6 @@ snapshots: validate-npm-package-name@5.0.1: {} - vary@1.1.2: {} - vfile-location@5.0.3: dependencies: '@types/unist': 3.0.3 @@ -15768,10 +15074,6 @@ snapshots: web-streams-polyfill@3.3.3: {} - webgl-constants@1.1.1: {} - - webgl-sdf-generator@1.1.1: {} - webidl-conversions@3.0.1: {} webpack-sources@3.2.3: {} @@ -15848,6 +15150,10 @@ snapshots: gopd: 1.2.0 has-tostringtag: 1.0.2 + which@1.3.1: + dependencies: + isexe: 2.0.0 + which@2.0.2: dependencies: isexe: 2.0.0 @@ -15878,6 +15184,12 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.1.2 + wrappy@1.0.2: {} write-file-atomic@5.0.1: @@ -15949,17 +15261,13 @@ snapshots: compress-commons: 6.0.2 readable-stream: 4.7.0 - zod-to-json-schema@3.25.1(zod@4.3.5): + zod-validation-error@4.0.2(zod@4.1.9): dependencies: - zod: 4.3.5 - - zod-validation-error@4.0.2(zod@4.3.5): - dependencies: - zod: 4.3.5 + zod: 4.1.9 zod@3.25.76: {} - zod@4.3.5: {} + zod@4.1.9: {} zustand@4.5.2(@types/react@19.2.5)(react@19.2.0): dependencies: @@ -15968,10 +15276,4 @@ snapshots: '@types/react': 19.2.5 react: 19.2.0 - zustand@5.0.9(@types/react@19.2.5)(react@19.2.0)(use-sync-external-store@1.6.0(react@19.2.0)): - optionalDependencies: - '@types/react': 19.2.5 - react: 19.2.0 - use-sync-external-store: 1.6.0(react@19.2.0) - zwitch@2.0.4: {} diff --git a/public/Algolia-logo-blue.svg b/public/Algolia-logo-blue.svg deleted file mode 100644 index 44e9942d1..000000000 --- a/public/Algolia-logo-blue.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/Algolia-logo-white.svg b/public/Algolia-logo-white.svg deleted file mode 100644 index f2cb9d3c5..000000000 --- a/public/Algolia-logo-white.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/blog-assets/tanstack-ai-why-we-split-the-adapters/header.jpeg b/public/blog-assets/tanstack-ai-why-we-split-the-adapters/header.jpeg deleted file mode 100644 index d21ad6a90..000000000 Binary files a/public/blog-assets/tanstack-ai-why-we-split-the-adapters/header.jpeg and /dev/null differ diff --git a/public/images/ship.png b/public/images/ship.png deleted file mode 100644 index 1e3188cde..000000000 Binary files a/public/images/ship.png and /dev/null differ diff --git a/public/models/Textures/colormap.png b/public/models/Textures/colormap.png deleted file mode 100644 index d070357c2..000000000 Binary files a/public/models/Textures/colormap.png and /dev/null differ diff --git a/public/models/beach-chair.glb b/public/models/beach-chair.glb deleted file mode 100644 index 10f4ac366..000000000 Binary files a/public/models/beach-chair.glb and /dev/null differ diff --git a/public/models/boat.glb b/public/models/boat.glb deleted file mode 100644 index 08282c980..000000000 Binary files a/public/models/boat.glb and /dev/null differ diff --git a/public/models/colormap.png b/public/models/colormap.png deleted file mode 100644 index d070357c2..000000000 Binary files a/public/models/colormap.png and /dev/null differ diff --git a/public/models/palm-tree.glb b/public/models/palm-tree.glb deleted file mode 100644 index 454429375..000000000 Binary files a/public/models/palm-tree.glb and /dev/null differ diff --git a/public/models/palm-trees.glb b/public/models/palm-trees.glb deleted file mode 100644 index d3e903eeb..000000000 Binary files a/public/models/palm-trees.glb and /dev/null differ diff --git a/public/models/rowboat.glb b/public/models/rowboat.glb deleted file mode 100644 index e301aaf2f..000000000 Binary files a/public/models/rowboat.glb and /dev/null differ diff --git a/public/models/sailboat.glb b/public/models/sailboat.glb deleted file mode 100644 index 4401373de..000000000 Binary files a/public/models/sailboat.glb and /dev/null differ diff --git a/public/models/ship.glb b/public/models/ship.glb deleted file mode 100644 index e8e190edf..000000000 Binary files a/public/models/ship.glb and /dev/null differ diff --git a/scripts/mcp-eval/README.md b/scripts/mcp-eval/README.md deleted file mode 100644 index d0e8e0401..000000000 --- a/scripts/mcp-eval/README.md +++ /dev/null @@ -1,103 +0,0 @@ -# MCP Documentation Discoverability Evaluation - -This tool tests how well AI assistants can find the right TanStack documentation using the MCP server. - -## Why This Exists - -When an AI uses the TanStack MCP to answer questions, it needs to: - -1. Search for relevant docs -2. Find the RIGHT docs (not just related ones) -3. Do so efficiently (fewer searches = better) - -This evaluation suite helps us "train" our docs to be more discoverable by: - -- Identifying search queries that fail to surface important docs -- Finding gaps in doc titles, descriptions, and content -- Measuring improvement over time - -## Running the Tests - -```bash -# Run all tests (requires dev server running on port 3001) -pnpm dev # in another terminal -npx tsx scripts/mcp-eval/run-eval.ts - -# Run a specific test -npx tsx scripts/mcp-eval/run-eval.ts --test router-query-ssr-integration - -# Run tests by tag -npx tsx scripts/mcp-eval/run-eval.ts --tag start -npx tsx scripts/mcp-eval/run-eval.ts --tag query - -# Use a different MCP endpoint -MCP_URL=https://tanstack.com/api/mcp npx tsx scripts/mcp-eval/run-eval.ts -``` - -## Test Case Structure - -Each test case in `test-cases.json` includes: - -```json -{ - "id": "unique-id", - "question": "The question an AI might receive", - "difficulty": "easy | medium | hard", - "tags": ["library", "topic"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/guide/data-loading", - "required": true, - "reason": "Why this doc should be found" - } - ], - "idealSearchQueries": ["queries that SHOULD find the doc"], - "badSearchQueries": ["queries that surprisingly DON'T work"], - "correctAnswerMustInclude": ["key terms the answer needs"], - "notes": "Any additional context" -} -``` - -## Scoring - -Each test is scored 0-100: - -- **50%** - Finding required docs -- **30%** - Search efficiency (fewer searches = better) -- **20%** - Doc appearing in top 3 results - -A test passes if: - -- All required docs are found -- Score >= 70 - -## Adding New Tests - -1. Think of a question users/AIs commonly ask -2. Search for it yourself using the MCP tools -3. Document which docs SHOULD be found -4. Add the test case to `test-cases.json` -5. Run the eval to see if it passes -6. If it fails, either: - - Fix the test (wrong expectations) - - Fix the docs (improve discoverability) - -## Improving Doc Discoverability - -When a test fails, consider: - -1. **Doc titles** - Does the title include key search terms? -2. **Doc descriptions** - Is there frontmatter that Algolia indexes? -3. **Cross-references** - Do related docs link to each other? -4. **Canonical terms** - Are you using the terms users search for? - -Example: The "useQuery" search returns API reference, not the guide. -Solution: Either rename the guide or add "useQuery" prominently to it. - -## CI Integration - -```bash -# Exit code is 0 if all tests pass, 1 otherwise -npx tsx scripts/mcp-eval/run-eval.ts || echo "Some tests failed" -``` diff --git a/scripts/mcp-eval/mine-questions.ts b/scripts/mcp-eval/mine-questions.ts deleted file mode 100644 index f478d2409..000000000 --- a/scripts/mcp-eval/mine-questions.ts +++ /dev/null @@ -1,407 +0,0 @@ -/** - * Question Mining Script for MCP Eval Test Cases - * - * This script helps systematically gather real user questions from various sources - * to improve our test coverage. - * - * Sources: - * 1. Stack Overflow - API for tagged questions - * 2. GitHub Issues/Discussions - GraphQL API - * 3. Reddit - API for subreddit search - * - * Usage: - * npx tsx scripts/mcp-eval/mine-questions.ts --source stackoverflow --library query - * npx tsx scripts/mcp-eval/mine-questions.ts --source github --library router - * npx tsx scripts/mcp-eval/mine-questions.ts --all - */ - -const STACK_OVERFLOW_TAGS: Record = { - query: ['tanstackreact-query', 'react-query'], - router: ['tanstack-router'], - table: ['tanstack-table', 'react-table'], - form: ['tanstack-form', 'react-hook-form'], // react-hook-form for comparison - virtual: ['tanstack-virtual', 'react-virtual'], -} - -const GITHUB_REPOS: Record = { - query: 'TanStack/query', - router: 'TanStack/router', - table: 'TanStack/table', - form: 'TanStack/form', - virtual: 'TanStack/virtual', - start: 'TanStack/start', - store: 'TanStack/store', -} - -interface QuestionCandidate { - source: 'stackoverflow' | 'github' | 'reddit' - title: string - url: string - score: number - tags: string[] - library: string - createdAt: string -} - -async function fetchStackOverflowQuestions( - tags: string[], - library: string, -): Promise { - const questions: QuestionCandidate[] = [] - - for (const tag of tags) { - try { - // Stack Overflow API - get questions sorted by votes - const url = `https://api.stackexchange.com/2.3/questions?order=desc&sort=votes&tagged=${tag}&site=stackoverflow&pagesize=50&filter=withbody` - const response = await fetch(url) - const data = await response.json() - - if (data.items) { - for (const item of data.items) { - questions.push({ - source: 'stackoverflow', - title: item.title, - url: item.link, - score: item.score, - tags: item.tags, - library, - createdAt: new Date(item.creation_date * 1000).toISOString(), - }) - } - } - } catch (error) { - console.error(`Error fetching SO questions for ${tag}:`, error) - } - } - - return questions -} - -async function fetchGitHubDiscussions( - repo: string, - library: string, -): Promise { - const questions: QuestionCandidate[] = [] - - // GitHub GraphQL API for discussions - // Note: Requires GITHUB_TOKEN env var - const token = process.env.GITHUB_TOKEN - if (!token) { - console.warn('GITHUB_TOKEN not set, skipping GitHub discussions') - return questions - } - - const query = ` - query($repo: String!, $owner: String!) { - repository(name: $repo, owner: $owner) { - discussions(first: 50, orderBy: {field: CREATED_AT, direction: DESC}, categoryId: null) { - nodes { - title - url - upvoteCount - createdAt - category { - name - } - } - } - } - } - ` - - const [owner, repoName] = repo.split('/') - - try { - const response = await fetch('https://api.github.com/graphql', { - method: 'POST', - headers: { - Authorization: `Bearer ${token}`, - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - query, - variables: { repo: repoName, owner }, - }), - }) - - const data = await response.json() - - if (data.data?.repository?.discussions?.nodes) { - for (const node of data.data.repository.discussions.nodes) { - // Filter to Q&A category - if ( - node.category?.name?.toLowerCase().includes('q&a') || - node.category?.name?.toLowerCase().includes('help') - ) { - questions.push({ - source: 'github', - title: node.title, - url: node.url, - score: node.upvoteCount, - tags: [node.category?.name || 'discussion'], - library, - createdAt: node.createdAt, - }) - } - } - } - } catch (error) { - console.error(`Error fetching GitHub discussions for ${repo}:`, error) - } - - return questions -} - -async function fetchGitHubIssues( - repo: string, - library: string, -): Promise { - const questions: QuestionCandidate[] = [] - - const token = process.env.GITHUB_TOKEN - const headers: Record = { - Accept: 'application/vnd.github.v3+json', - } - if (token) { - headers.Authorization = `Bearer ${token}` - } - - try { - // Get issues labeled as questions or with "how" in title - const url = `https://api.github.com/repos/${repo}/issues?state=all&per_page=100&sort=comments&direction=desc` - const response = await fetch(url, { headers }) - const issues = await response.json() - - if (Array.isArray(issues)) { - for (const issue of issues) { - // Filter to question-like issues - const isQuestion = - issue.title.toLowerCase().includes('how') || - issue.title.toLowerCase().includes('?') || - issue.labels?.some( - (l: { name: string }) => - l.name.toLowerCase().includes('question') || - l.name.toLowerCase().includes('help'), - ) - - if (isQuestion && !issue.pull_request) { - questions.push({ - source: 'github', - title: issue.title, - url: issue.html_url, - score: issue.comments + (issue.reactions?.['+1'] || 0), - tags: issue.labels?.map((l: { name: string }) => l.name) || [], - library, - createdAt: issue.created_at, - }) - } - } - } - } catch (error) { - console.error(`Error fetching GitHub issues for ${repo}:`, error) - } - - return questions -} - -function categorizeQuestion(title: string): string[] { - const categories: string[] = [] - const lower = title.toLowerCase() - - // Topic detection - if (lower.includes('mutation') || lower.includes('mutate')) - categories.push('mutations') - if (lower.includes('cache') || lower.includes('invalidat')) - categories.push('cache') - if (lower.includes('infinite') || lower.includes('pagination')) - categories.push('pagination') - if (lower.includes('ssr') || lower.includes('server')) categories.push('ssr') - if (lower.includes('typescript') || lower.includes('type')) - categories.push('typescript') - if (lower.includes('test')) categories.push('testing') - if (lower.includes('error') || lower.includes('retry')) - categories.push('error-handling') - if (lower.includes('prefetch') || lower.includes('preload')) - categories.push('prefetching') - if (lower.includes('suspense')) categories.push('suspense') - if (lower.includes('devtools')) categories.push('devtools') - if (lower.includes('optimistic')) categories.push('optimistic') - if (lower.includes('dependent') || lower.includes('serial')) - categories.push('dependent') - if (lower.includes('parallel')) categories.push('parallel') - if (lower.includes('refetch') || lower.includes('stale')) - categories.push('refetching') - if (lower.includes('auth')) categories.push('auth') - if (lower.includes('loading') || lower.includes('pending')) - categories.push('loading-states') - if (lower.includes('route') || lower.includes('navigation')) - categories.push('routing') - if (lower.includes('param')) categories.push('params') - if (lower.includes('search')) categories.push('search-params') - if (lower.includes('loader')) categories.push('loaders') - if (lower.includes('sort')) categories.push('sorting') - if (lower.includes('filter')) categories.push('filtering') - if (lower.includes('select')) categories.push('selection') - if (lower.includes('virtual')) categories.push('virtualization') - if (lower.includes('form') || lower.includes('submit')) - categories.push('forms') - if (lower.includes('valid')) categories.push('validation') - - return categories.length > 0 ? categories : ['general'] -} - -function convertToTestCase(q: QuestionCandidate): object { - const categories = categorizeQuestion(q.title) - - return { - id: `mined-${q.library}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`, - question: q.title.replace(/'/g, "'").replace(/"/g, '"'), - difficulty: 'medium', - tags: [q.library, ...categories], - source: { - type: q.source, - url: q.url, - score: q.score, - }, - expectedDocs: [ - { - library: q.library, - path: 'TODO: Fill in the correct doc path', - required: true, - reason: 'TODO: Explain why this doc answers the question', - }, - ], - idealSearchQueries: ['TODO: Add ideal search queries'], - correctAnswerMustInclude: ['TODO: Add key terms'], - notes: `Mined from ${q.source} on ${new Date().toISOString()}. Original score: ${q.score}`, - } -} - -async function main() { - const args = process.argv.slice(2) - let source = 'all' as string - let library: string | null = null - - for (let i = 0; i < args.length; i++) { - if (args[i] === '--source' && args[i + 1]) { - source = args[i + 1] - } - if (args[i] === '--library' && args[i + 1]) { - library = args[i + 1] - } - } - - console.log(`\n🔍 Mining questions from ${source}...`) - if (library) console.log(` Filtering to library: ${library}`) - console.log('') - - const allQuestions: QuestionCandidate[] = [] - - const libraries = library ? [library] : Object.keys(GITHUB_REPOS) - - for (const lib of libraries) { - console.log(`\n📚 Processing ${lib}...`) - - if (source === 'stackoverflow' || source === 'all') { - const tags = STACK_OVERFLOW_TAGS[lib] - if (tags) { - console.log(` Stack Overflow tags: ${tags.join(', ')}`) - const soQuestions = await fetchStackOverflowQuestions(tags, lib) - console.log(` Found ${soQuestions.length} SO questions`) - allQuestions.push(...soQuestions) - } - } - - if (source === 'github' || source === 'all') { - const repo = GITHUB_REPOS[lib] - if (repo) { - console.log(` GitHub repo: ${repo}`) - const ghDiscussions = await fetchGitHubDiscussions(repo, lib) - const ghIssues = await fetchGitHubIssues(repo, lib) - console.log( - ` Found ${ghDiscussions.length} discussions, ${ghIssues.length} issues`, - ) - allQuestions.push(...ghDiscussions, ...ghIssues) - } - } - - // Rate limiting - await new Promise((r) => setTimeout(r, 1000)) - } - - // Sort by score and dedupe - const sortedQuestions = allQuestions - .sort((a, b) => b.score - a.score) - .filter( - (q, i, arr) => - arr.findIndex( - (x) => x.title.toLowerCase() === q.title.toLowerCase(), - ) === i, - ) - - console.log(`\n\n📊 Results Summary`) - console.log(` Total unique questions: ${sortedQuestions.length}`) - - // Group by library - const byLibrary: Record = {} - for (const q of sortedQuestions) { - byLibrary[q.library] = (byLibrary[q.library] || 0) + 1 - } - console.log(` By library:`) - for (const [lib, count] of Object.entries(byLibrary)) { - console.log(` ${lib}: ${count}`) - } - - // Group by category - const byCategory: Record = {} - for (const q of sortedQuestions) { - for (const cat of categorizeQuestion(q.title)) { - byCategory[cat] = (byCategory[cat] || 0) + 1 - } - } - console.log(` By category:`) - const sortedCategories = Object.entries(byCategory).sort( - (a, b) => b[1] - a[1], - ) - for (const [cat, count] of sortedCategories.slice(0, 15)) { - console.log(` ${cat}: ${count}`) - } - - // Output top questions as potential test cases - console.log(`\n\n🎯 Top 20 Questions (by score):`) - console.log('='.repeat(80)) - - const testCaseCandidates = sortedQuestions.slice(0, 20).map(convertToTestCase) - - for (const q of sortedQuestions.slice(0, 20)) { - console.log(`\n[${q.library}] ${q.title}`) - console.log(` Score: ${q.score} | Source: ${q.source}`) - console.log(` Categories: ${categorizeQuestion(q.title).join(', ')}`) - console.log(` URL: ${q.url}`) - } - - // Save candidates to file - const outputPath = './scripts/mcp-eval/mined-questions.json' - const fs = await import('fs') - fs.writeFileSync( - outputPath, - JSON.stringify( - { - minedAt: new Date().toISOString(), - totalQuestions: sortedQuestions.length, - topCandidates: testCaseCandidates, - allQuestions: sortedQuestions, - }, - null, - 2, - ), - ) - console.log( - `\n\n💾 Saved ${sortedQuestions.length} questions to ${outputPath}`, - ) - console.log( - ` Review the file and add promising questions to test-cases.json`, - ) -} - -main().catch(console.error) diff --git a/scripts/mcp-eval/run-eval.ts b/scripts/mcp-eval/run-eval.ts deleted file mode 100644 index 57854c560..000000000 --- a/scripts/mcp-eval/run-eval.ts +++ /dev/null @@ -1,347 +0,0 @@ -/** - * MCP Documentation Discoverability Evaluation Runner - * - * This script tests how well the TanStack MCP server helps AI assistants - * find the right documentation to answer questions. - * - * Usage: - * npx tsx scripts/mcp-eval/run-eval.ts - * npx tsx scripts/mcp-eval/run-eval.ts --test router-query-ssr-integration - * npx tsx scripts/mcp-eval/run-eval.ts --tag start - */ - -import testCases from './test-cases.json' - -const MCP_URL = process.env.MCP_URL || 'http://localhost:3001/api/mcp' - -interface SearchResult { - title: string - url: string - library: string - breadcrumb: string[] -} - -interface McpResponse { - result?: { - content: Array<{ type: string; text: string }> - } - error?: { - code: number - message: string - } -} - -interface TestResult { - testId: string - question: string - difficulty: string - searchesPerformed: Array<{ - query: string - resultsCount: number - foundExpectedDoc: boolean - topResults: string[] - }> - expectedDocsFound: string[] - expectedDocsMissed: string[] - totalSearches: number - passed: boolean - score: number - notes: string[] -} - -async function callMcp(method: string, params: object): Promise { - // First initialize - await fetch(MCP_URL, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - Accept: 'application/json, text/event-stream', - }, - body: JSON.stringify({ - jsonrpc: '2.0', - id: 0, - method: 'initialize', - params: { - protocolVersion: '2024-11-05', - capabilities: {}, - clientInfo: { name: 'mcp-eval', version: '1.0.0' }, - }, - }), - }) - - // Then call the tool - const response = await fetch(MCP_URL, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - Accept: 'application/json, text/event-stream', - }, - body: JSON.stringify({ - jsonrpc: '2.0', - id: 1, - method: 'tools/call', - params: { - name: method, - arguments: params, - }, - }), - }) - - return response.json() -} - -async function searchDocs( - query: string, - library?: string, -): Promise<{ results: SearchResult[]; totalHits: number }> { - const response = await callMcp('search_docs', { - query, - library, - limit: 10, - }) - - if (response.error) { - throw new Error(response.error.message) - } - - const text = response.result?.content[0]?.text || '{}' - return JSON.parse(text) -} - -async function getDoc( - library: string, - path: string, -): Promise<{ title: string; content: string } | null> { - try { - const response = await callMcp('get_doc', { library, path }) - if (response.error) return null - - const metaText = response.result?.content[0]?.text || '{}' - const contentText = response.result?.content[1]?.text || '' - - return { - ...JSON.parse(metaText), - content: contentText, - } - } catch { - return null - } -} - -function extractPathFromUrl(url: string): string { - // Extract path from URL like https://tanstack.com/router/latest/docs/integrations/query - // Also handle anchors like #some-section - const match = url.match(/\/docs\/([^#]+)/) - return match ? match[1] : '' -} - -async function runTestCase( - testCase: (typeof testCases.testCases)[0], -): Promise { - const result: TestResult = { - testId: testCase.id, - question: testCase.question, - difficulty: testCase.difficulty, - searchesPerformed: [], - expectedDocsFound: [], - expectedDocsMissed: [], - totalSearches: 0, - passed: false, - score: 0, - notes: [], - } - - const expectedPaths = new Set( - testCase.expectedDocs.map((d) => `${d.library}:${d.path}`), - ) - const foundPaths = new Set() - - // Try ideal search queries first - for (const query of testCase.idealSearchQueries || []) { - result.totalSearches++ - - try { - const searchResult = await searchDocs(query) - const topResults = searchResult.results.slice(0, 5).map((r) => r.url) - - let foundExpected = false - for (const r of searchResult.results) { - const path = extractPathFromUrl(r.url) - const key = `${r.library}:${path}` - - if (expectedPaths.has(key)) { - foundPaths.add(key) - foundExpected = true - } - } - - result.searchesPerformed.push({ - query, - resultsCount: searchResult.totalHits, - foundExpectedDoc: foundExpected, - topResults, - }) - - // If we found all expected docs, stop searching - if (foundPaths.size === expectedPaths.size) { - break - } - } catch (error) { - result.notes.push(`Search failed for "${query}": ${error}`) - } - } - - // Record which docs were found vs missed - for (const doc of testCase.expectedDocs) { - const key = `${doc.library}:${doc.path}` - if (foundPaths.has(key)) { - result.expectedDocsFound.push(key) - } else { - result.expectedDocsMissed.push(key) - } - } - - // Calculate score - const requiredDocs = testCase.expectedDocs.filter((d) => d.required) - const requiredFound = requiredDocs.filter((d) => - foundPaths.has(`${d.library}:${d.path}`), - ) - - // Score breakdown: - // - 50% for finding required docs - // - 30% for finding them in fewer searches - // - 20% for finding them in top results - - const requiredScore = - requiredDocs.length > 0 ? requiredFound.length / requiredDocs.length : 1 - - const searchEfficiency = Math.max( - 0, - 1 - (result.totalSearches - 1) / (testCase.idealSearchQueries?.length || 3), - ) - - // Check if expected doc appeared in top 3 results - const topResultScore = result.searchesPerformed.some((s) => { - return testCase.expectedDocs.some((doc) => - s.topResults - .slice(0, 3) - .some((url) => url.includes(doc.path.replace(/\//g, '/'))), - ) - }) - ? 1 - : 0 - - result.score = Math.round( - (requiredScore * 0.5 + searchEfficiency * 0.3 + topResultScore * 0.2) * 100, - ) - - result.passed = - requiredFound.length === requiredDocs.length && result.score >= 70 - - return result -} - -async function main() { - const args = process.argv.slice(2) - let testFilter: string | undefined - let tagFilter: string | undefined - - for (let i = 0; i < args.length; i++) { - if (args[i] === '--test' && args[i + 1]) { - testFilter = args[i + 1] - } - if (args[i] === '--tag' && args[i + 1]) { - tagFilter = args[i + 1] - } - } - - let cases = testCases.testCases - - if (testFilter) { - cases = cases.filter((c) => c.id === testFilter) - } - - if (tagFilter) { - cases = cases.filter((c) => c.tags.includes(tagFilter)) - } - - console.log(`\n🧪 Running ${cases.length} MCP evaluation test(s)...\n`) - console.log('='.repeat(60)) - - const results: TestResult[] = [] - - for (const testCase of cases) { - console.log(`\n📋 Test: ${testCase.id}`) - console.log(` Question: ${testCase.question.slice(0, 60)}...`) - - try { - const result = await runTestCase(testCase) - results.push(result) - - const status = result.passed ? '✅ PASS' : '❌ FAIL' - console.log(` ${status} (Score: ${result.score}/100)`) - console.log(` Searches: ${result.totalSearches}`) - - if (result.expectedDocsMissed.length > 0) { - console.log(` ⚠️ Missed: ${result.expectedDocsMissed.join(', ')}`) - } - - if (result.notes.length > 0) { - result.notes.forEach((n) => console.log(` 📝 ${n}`)) - } - } catch (error) { - console.log(` ❌ ERROR: ${error}`) - } - } - - console.log('\n' + '='.repeat(60)) - console.log('\n📊 Summary\n') - - const passed = results.filter((r) => r.passed).length - const total = results.length - const avgScore = Math.round( - results.reduce((sum, r) => sum + r.score, 0) / total, - ) - - console.log(` Passed: ${passed}/${total}`) - console.log(` Average Score: ${avgScore}/100`) - - // Group by difficulty - const byDifficulty = { - easy: results.filter((r) => r.difficulty === 'easy'), - medium: results.filter((r) => r.difficulty === 'medium'), - hard: results.filter((r) => r.difficulty === 'hard'), - } - - for (const [diff, tests] of Object.entries(byDifficulty)) { - if (tests.length > 0) { - const p = tests.filter((t) => t.passed).length - const avg = Math.round( - tests.reduce((s, t) => s + t.score, 0) / tests.length, - ) - console.log(` ${diff}: ${p}/${tests.length} passed (avg: ${avg})`) - } - } - - // Output detailed results as JSON - const outputPath = './scripts/mcp-eval/results.json' - const fs = await import('fs') - fs.writeFileSync( - outputPath, - JSON.stringify( - { - timestamp: new Date().toISOString(), - summary: { passed, total, avgScore }, - results, - }, - null, - 2, - ), - ) - console.log(`\n Detailed results: ${outputPath}`) - - // Exit with error if any tests failed - process.exit(passed === total ? 0 : 1) -} - -main().catch(console.error) diff --git a/scripts/mcp-eval/test-cases.json b/scripts/mcp-eval/test-cases.json deleted file mode 100644 index 58472b6e5..000000000 --- a/scripts/mcp-eval/test-cases.json +++ /dev/null @@ -1,1666 +0,0 @@ -{ - "$schema": "./test-cases.schema.json", - "version": "1.0.0", - "description": "MCP documentation discoverability test cases", - "testCases": [ - { - "id": "router-query-ssr-integration", - "question": "In TanStack Start, how do I prefetch data for a route that uses both a loader and TanStack Query, ensuring the data is dehydrated to the client without double-fetching?", - "difficulty": "hard", - "tags": ["start", "router", "query", "ssr", "integration"], - "expectedDocs": [ - { - "library": "router", - "path": "integrations/query", - "required": true, - "reason": "This is THE official integration guide" - } - ], - "idealSearchQueries": [ - "query integration", - "router query ssr", - "react-router-ssr-query" - ], - "badSearchQueries": [ - "prefetch dehydrate SSR", - "loader prefetch dehydrate" - ], - "correctAnswerMustInclude": [ - "@tanstack/react-router-ssr-query", - "setupRouterSsrQueryIntegration" - ], - "notes": "The integration package handles all dehydration/hydration automatically. Manual setup is possible but not recommended." - }, - { - "id": "createfileroute-basic", - "question": "How do I create a file-based route in TanStack Router?", - "difficulty": "easy", - "tags": ["router", "basics"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/api/router/createFileRouteFunction", - "required": true, - "reason": "Primary API reference" - } - ], - "idealSearchQueries": ["createFileRoute"], - "correctAnswerMustInclude": ["createFileRoute", "export const Route"] - }, - { - "id": "query-usequery-basic", - "question": "How do I fetch data with TanStack Query in React?", - "difficulty": "easy", - "tags": ["query", "basics", "react"], - "expectedDocs": [ - { - "library": "query", - "path": "framework/react/guides/queries", - "required": true, - "reason": "Primary guide for queries" - } - ], - "idealSearchQueries": ["queries guide", "query basics"], - "badSearchQueries": ["useQuery"], - "correctAnswerMustInclude": ["useQuery", "queryKey", "queryFn"], - "notes": "Searching 'useQuery' returns the API reference, not the guide. Search for 'queries guide' instead." - }, - { - "id": "start-server-functions", - "question": "How do I create a server function in TanStack Start that can be called from the client?", - "difficulty": "medium", - "tags": ["start", "server-functions"], - "expectedDocs": [ - { - "library": "start", - "path": "framework/react/guide/server-functions", - "required": true, - "reason": "Primary server functions guide" - } - ], - "idealSearchQueries": ["server function", "createServerFn"], - "correctAnswerMustInclude": ["createServerFn"] - }, - { - "id": "router-search-params-validation", - "question": "How do I validate and type search params in TanStack Router?", - "difficulty": "medium", - "tags": ["router", "search-params", "validation", "typescript"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/guide/search-params", - "required": true, - "reason": "Primary search params guide" - } - ], - "idealSearchQueries": ["search params validation", "validateSearch"], - "correctAnswerMustInclude": ["validateSearch"] - }, - { - "id": "table-column-definitions", - "question": "How do I define columns for TanStack Table?", - "difficulty": "easy", - "tags": ["table", "basics"], - "expectedDocs": [ - { - "library": "table", - "path": "guide/column-defs", - "required": true, - "reason": "Primary column definitions guide" - } - ], - "idealSearchQueries": ["column definitions", "createColumnHelper"], - "correctAnswerMustInclude": ["columnHelper", "accessorKey"] - }, - { - "id": "form-validation-zod", - "question": "How do I use Zod validation with TanStack Form?", - "difficulty": "medium", - "tags": ["form", "validation", "zod"], - "expectedDocs": [ - { - "library": "form", - "path": "framework/react/guides/validation", - "required": true, - "reason": "Validation guide covering Zod" - } - ], - "idealSearchQueries": ["form zod validation", "form validation"], - "correctAnswerMustInclude": ["zod", "validators"] - }, - { - "id": "virtual-dynamic-row-heights", - "question": "How do I handle dynamic/variable row heights in TanStack Virtual?", - "difficulty": "medium", - "tags": ["virtual", "dynamic-sizing"], - "expectedDocs": [ - { - "library": "virtual", - "path": "api/virtualizer", - "required": true, - "reason": "API docs for measureElement and estimateSize" - }, - { - "library": "virtual", - "path": "framework/react/examples/dynamic", - "required": false, - "reason": "Example showing dynamic sizing" - } - ], - "idealSearchQueries": ["dynamic size virtualizer", "measureElement"], - "correctAnswerMustInclude": ["estimateSize", "measureElement"] - }, - { - "id": "query-mutations", - "question": "How do I update data on the server with TanStack Query?", - "difficulty": "easy", - "tags": ["query", "mutations"], - "expectedDocs": [ - { - "library": "query", - "path": "framework/react/guides/mutations", - "required": true, - "reason": "Primary mutations guide" - } - ], - "idealSearchQueries": ["mutation", "useMutation"], - "correctAnswerMustInclude": ["useMutation", "mutate"] - }, - { - "id": "router-loaderDeps", - "question": "How do I make a TanStack Router loader depend on search params so it reloads when they change?", - "difficulty": "medium", - "tags": ["router", "loaders", "search-params"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/guide/data-loading", - "required": true, - "reason": "Data loading guide covers loaderDeps" - } - ], - "idealSearchQueries": ["loaderDeps", "loader search params"], - "correctAnswerMustInclude": ["loaderDeps"] - }, - - { - "id": "query-optimistic-updates", - "question": "How do I implement optimistic updates with TanStack Query so the UI updates immediately before the server responds?", - "difficulty": "medium", - "tags": ["query", "mutations", "optimistic"], - "expectedDocs": [ - { - "library": "query", - "path": "framework/react/guides/optimistic-updates", - "required": true, - "reason": "Dedicated optimistic updates guide" - } - ], - "idealSearchQueries": ["optimistic updates", "optimistic mutation"], - "correctAnswerMustInclude": ["onMutate", "onError", "onSettled"] - }, - { - "id": "query-infinite-scroll", - "question": "How do I implement infinite scrolling with TanStack Query?", - "difficulty": "medium", - "tags": ["query", "pagination", "infinite"], - "expectedDocs": [ - { - "library": "query", - "path": "framework/react/guides/infinite-queries", - "required": true, - "reason": "Infinite queries guide" - } - ], - "idealSearchQueries": ["infinite query", "useInfiniteQuery"], - "correctAnswerMustInclude": [ - "useInfiniteQuery", - "getNextPageParam", - "fetchNextPage" - ] - }, - { - "id": "query-cache-invalidation", - "question": "How do I invalidate and refetch queries after a mutation in TanStack Query?", - "difficulty": "easy", - "tags": ["query", "cache", "invalidation"], - "expectedDocs": [ - { - "library": "query", - "path": "framework/react/guides/invalidations-from-mutations", - "required": true, - "reason": "Guide on invalidating queries from mutations" - } - ], - "idealSearchQueries": [ - "invalidate queries", - "invalidateQueries mutation" - ], - "correctAnswerMustInclude": ["invalidateQueries", "queryClient"] - }, - { - "id": "query-dependent-queries", - "question": "How do I make one query depend on the result of another query in TanStack Query?", - "difficulty": "medium", - "tags": ["query", "dependent", "serial"], - "expectedDocs": [ - { - "library": "query", - "path": "framework/react/guides/dependent-queries", - "required": true, - "reason": "Dependent queries guide" - } - ], - "idealSearchQueries": ["dependent queries", "enabled option"], - "correctAnswerMustInclude": ["enabled"] - }, - { - "id": "query-prefetching", - "question": "How do I prefetch data before a user navigates to a page with TanStack Query?", - "difficulty": "medium", - "tags": ["query", "prefetch", "performance"], - "expectedDocs": [ - { - "library": "query", - "path": "framework/react/guides/prefetching", - "required": true, - "reason": "Prefetching guide" - } - ], - "idealSearchQueries": ["prefetch query", "prefetchQuery"], - "correctAnswerMustInclude": ["prefetchQuery"] - }, - { - "id": "query-suspense", - "question": "How do I use TanStack Query with React Suspense?", - "difficulty": "medium", - "tags": ["query", "suspense", "react"], - "expectedDocs": [ - { - "library": "query", - "path": "framework/react/guides/suspense", - "required": true, - "reason": "Suspense guide" - } - ], - "idealSearchQueries": ["suspense guide", "suspense query guide"], - "badSearchQueries": ["useSuspenseQuery"], - "correctAnswerMustInclude": ["useSuspenseQuery"], - "notes": "Searching 'useSuspenseQuery' returns API reference first. Once Algolia pageRank fix is deployed, guide should rank higher." - }, - { - "id": "query-devtools", - "question": "How do I set up TanStack Query DevTools to debug my queries?", - "difficulty": "easy", - "tags": ["query", "devtools", "debugging"], - "expectedDocs": [ - { - "library": "query", - "path": "framework/react/devtools", - "required": true, - "reason": "DevTools setup guide" - } - ], - "idealSearchQueries": ["query devtools", "ReactQueryDevtools"], - "correctAnswerMustInclude": ["ReactQueryDevtools"] - }, - - { - "id": "router-code-splitting", - "question": "How do I implement code splitting and lazy loading routes in TanStack Router?", - "difficulty": "medium", - "tags": ["router", "code-splitting", "lazy", "performance"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/guide/code-splitting", - "required": true, - "reason": "Code splitting guide" - } - ], - "idealSearchQueries": ["code splitting", "lazy route"], - "correctAnswerMustInclude": ["lazyRouteComponent", "lazy"] - }, - { - "id": "router-navigation-blocking", - "question": "How do I prevent navigation when a form has unsaved changes in TanStack Router?", - "difficulty": "medium", - "tags": ["router", "navigation", "blocking", "forms"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/guide/navigation-blocking", - "required": true, - "reason": "Navigation blocking guide" - } - ], - "idealSearchQueries": ["navigation blocking", "useBlocker"], - "correctAnswerMustInclude": ["useBlocker"] - }, - { - "id": "router-authenticated-routes", - "question": "How do I protect routes that require authentication in TanStack Router?", - "difficulty": "medium", - "tags": ["router", "auth", "protected-routes"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/guide/authenticated-routes", - "required": true, - "reason": "Authenticated routes guide" - } - ], - "idealSearchQueries": [ - "authenticated routes", - "protected routes", - "auth redirect" - ], - "correctAnswerMustInclude": ["beforeLoad", "redirect"] - }, - { - "id": "router-not-found", - "question": "How do I handle 404 not found pages in TanStack Router?", - "difficulty": "easy", - "tags": ["router", "404", "not-found"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/guide/not-found-errors", - "required": true, - "reason": "Not found errors guide" - } - ], - "idealSearchQueries": ["not found", "404", "notFoundComponent"], - "correctAnswerMustInclude": ["notFoundComponent"] - }, - { - "id": "router-path-params", - "question": "How do I access dynamic path parameters like /posts/$postId in TanStack Router?", - "difficulty": "easy", - "tags": ["router", "params", "dynamic-routes"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/guide/path-params", - "required": true, - "reason": "Path params guide" - } - ], - "idealSearchQueries": ["path params", "useParams", "route params"], - "correctAnswerMustInclude": ["useParams", "$"] - }, - { - "id": "router-preloading", - "question": "How do I preload route data on hover in TanStack Router?", - "difficulty": "easy", - "tags": ["router", "preload", "performance"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/guide/preloading", - "required": true, - "reason": "Preloading guide" - } - ], - "idealSearchQueries": ["preload route", "preloading"], - "correctAnswerMustInclude": ["preload"] - }, - { - "id": "router-devtools", - "question": "How do I set up TanStack Router DevTools?", - "difficulty": "easy", - "tags": ["router", "devtools", "debugging"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/devtools", - "required": true, - "reason": "DevTools guide" - } - ], - "idealSearchQueries": ["router devtools", "TanStackRouterDevtools"], - "correctAnswerMustInclude": ["TanStackRouterDevtools"] - }, - - { - "id": "table-sorting", - "question": "How do I implement column sorting in TanStack Table?", - "difficulty": "easy", - "tags": ["table", "sorting"], - "expectedDocs": [ - { - "library": "table", - "path": "guide/sorting", - "required": true, - "reason": "Sorting guide" - } - ], - "idealSearchQueries": ["table sorting", "getSortedRowModel"], - "correctAnswerMustInclude": ["getSortedRowModel", "sorting"] - }, - { - "id": "table-filtering", - "question": "How do I add filtering to TanStack Table?", - "difficulty": "medium", - "tags": ["table", "filtering"], - "expectedDocs": [ - { - "library": "table", - "path": "guide/column-filtering", - "required": true, - "reason": "Column filtering guide" - } - ], - "idealSearchQueries": ["table filtering", "getFilteredRowModel"], - "correctAnswerMustInclude": ["getFilteredRowModel", "columnFilters"] - }, - { - "id": "table-pagination", - "question": "How do I implement pagination in TanStack Table?", - "difficulty": "easy", - "tags": ["table", "pagination"], - "expectedDocs": [ - { - "library": "table", - "path": "guide/pagination", - "required": true, - "reason": "Pagination guide" - } - ], - "idealSearchQueries": ["table pagination", "getPaginationRowModel"], - "correctAnswerMustInclude": [ - "getPaginationRowModel", - "pageIndex", - "pageSize" - ] - }, - { - "id": "table-row-selection", - "question": "How do I enable row selection with checkboxes in TanStack Table?", - "difficulty": "medium", - "tags": ["table", "selection"], - "expectedDocs": [ - { - "library": "table", - "path": "guide/row-selection", - "required": true, - "reason": "Row selection guide" - } - ], - "idealSearchQueries": ["row selection", "table checkbox"], - "correctAnswerMustInclude": ["rowSelection", "enableRowSelection"] - }, - { - "id": "table-virtualization", - "question": "How do I virtualize a large table with TanStack Table and TanStack Virtual?", - "difficulty": "hard", - "tags": ["table", "virtual", "performance"], - "expectedDocs": [ - { - "library": "table", - "path": "framework/react/examples/virtualized-rows", - "required": true, - "reason": "Virtualized rows example" - } - ], - "idealSearchQueries": ["table virtualization", "virtualized rows"], - "correctAnswerMustInclude": ["useVirtualizer", "virtualRows"] - }, - { - "id": "table-server-side", - "question": "How do I implement server-side pagination and sorting with TanStack Table?", - "difficulty": "hard", - "tags": ["table", "server-side", "pagination"], - "expectedDocs": [ - { - "library": "table", - "path": "guide/pagination", - "required": true, - "reason": "Pagination guide covers manual mode" - } - ], - "idealSearchQueries": ["server side table", "manual pagination"], - "correctAnswerMustInclude": ["manualPagination", "pageCount"] - }, - - { - "id": "form-field-arrays", - "question": "How do I handle dynamic arrays of fields in TanStack Form?", - "difficulty": "medium", - "tags": ["form", "arrays", "dynamic"], - "expectedDocs": [ - { - "library": "form", - "path": "framework/react/guides/arrays", - "required": true, - "reason": "Array fields guide" - } - ], - "idealSearchQueries": ["form arrays", "field array"], - "correctAnswerMustInclude": ["pushValue", "removeValue"] - }, - { - "id": "form-async-validation", - "question": "How do I implement async validation that checks the server in TanStack Form?", - "difficulty": "medium", - "tags": ["form", "validation", "async"], - "expectedDocs": [ - { - "library": "form", - "path": "framework/react/guides/dynamic-validation", - "required": true, - "reason": "Dynamic validation guide covers async validation" - } - ], - "idealSearchQueries": ["async validation", "async form validation"], - "correctAnswerMustInclude": ["async"] - }, - { - "id": "form-submission", - "question": "How do I handle form submission with TanStack Form?", - "difficulty": "easy", - "tags": ["form", "submit"], - "expectedDocs": [ - { - "library": "form", - "path": "framework/react/guides/basic-concepts", - "required": true, - "reason": "Basic concepts covers submission" - } - ], - "idealSearchQueries": ["form submit", "handleSubmit form"], - "correctAnswerMustInclude": ["onSubmit", "handleSubmit"] - }, - - { - "id": "virtual-horizontal-scroll", - "question": "How do I create a horizontal virtualized list with TanStack Virtual?", - "difficulty": "easy", - "tags": ["virtual", "horizontal"], - "expectedDocs": [ - { - "library": "virtual", - "path": "api/virtualizer", - "required": true, - "reason": "API docs cover horizontal option" - } - ], - "idealSearchQueries": ["horizontal virtual", "horizontal virtualizer"], - "correctAnswerMustInclude": ["horizontal"] - }, - { - "id": "virtual-window-scroll", - "question": "How do I virtualize a list that uses window scrolling instead of a container?", - "difficulty": "medium", - "tags": ["virtual", "window-scroll"], - "expectedDocs": [ - { - "library": "virtual", - "path": "framework/react/react-virtual", - "required": true, - "reason": "React Virtual docs cover useWindowVirtualizer" - } - ], - "idealSearchQueries": ["useWindowVirtualizer", "window virtualizer"], - "correctAnswerMustInclude": ["useWindowVirtualizer"] - }, - { - "id": "virtual-grid", - "question": "How do I create a virtualized grid with TanStack Virtual?", - "difficulty": "medium", - "tags": ["virtual", "grid"], - "expectedDocs": [ - { - "library": "virtual", - "path": "api/virtualizer", - "required": true, - "reason": "Virtualizer API covers grid setup" - } - ], - "idealSearchQueries": ["virtualizer grid", "virtual rows columns"], - "correctAnswerMustInclude": ["virtualizer"] - }, - - { - "id": "start-deployment-vercel", - "question": "How do I deploy a TanStack Start app to Vercel?", - "difficulty": "easy", - "tags": ["start", "deployment", "vercel"], - "expectedDocs": [ - { - "library": "start", - "path": "framework/react/guide/hosting", - "required": true, - "reason": "Hosting guide contains Vercel section" - } - ], - "idealSearchQueries": ["hosting vercel", "deploy start"], - "correctAnswerMustInclude": ["vercel"] - }, - { - "id": "start-deployment-netlify", - "question": "How do I deploy a TanStack Start app to Netlify?", - "difficulty": "easy", - "tags": ["start", "deployment", "netlify"], - "expectedDocs": [ - { - "library": "start", - "path": "framework/react/guide/hosting", - "required": true, - "reason": "Hosting guide contains Netlify section" - } - ], - "idealSearchQueries": ["hosting netlify", "deploy start"], - "correctAnswerMustInclude": ["netlify"] - }, - { - "id": "start-middleware", - "question": "How do I add middleware to TanStack Start for things like authentication?", - "difficulty": "medium", - "tags": ["start", "middleware", "auth"], - "expectedDocs": [ - { - "library": "start", - "path": "framework/react/guide/middleware", - "required": true, - "reason": "Middleware guide" - } - ], - "idealSearchQueries": ["start middleware", "createMiddleware"], - "correctAnswerMustInclude": ["middleware"] - }, - { - "id": "start-api-routes", - "question": "How do I create API routes in TanStack Start?", - "difficulty": "medium", - "tags": ["start", "api", "routes"], - "expectedDocs": [ - { - "library": "start", - "path": "framework/react/guide/server-routes", - "required": true, - "reason": "Server routes guide covers API routes" - } - ], - "idealSearchQueries": ["server routes", "api routes"], - "correctAnswerMustInclude": ["server", "routes"] - }, - { - "id": "start-static-prerendering", - "question": "How do I statically prerender pages at build time in TanStack Start?", - "difficulty": "medium", - "tags": ["start", "static", "prerender", "ssg"], - "expectedDocs": [ - { - "library": "start", - "path": "framework/react/guide/static-prerendering", - "required": true, - "reason": "Static prerendering guide" - } - ], - "idealSearchQueries": ["static prerender", "prerender start"], - "correctAnswerMustInclude": ["prerender"] - }, - - { - "id": "store-basics", - "question": "How do I create and use a store with TanStack Store?", - "difficulty": "easy", - "tags": ["store", "basics"], - "expectedDocs": [ - { - "library": "store", - "path": "framework/react/quick-start", - "required": true, - "reason": "Quick start guide" - } - ], - "idealSearchQueries": ["store quick start", "useStore"], - "correctAnswerMustInclude": ["Store", "useStore"] - }, - { - "id": "store-derived", - "question": "How do I create derived state from a TanStack Store?", - "difficulty": "medium", - "tags": ["store", "derived", "computed"], - "expectedDocs": [ - { - "library": "store", - "path": "reference/classes/Derived", - "required": true, - "reason": "Derived class reference" - } - ], - "idealSearchQueries": ["derived", "Derived store"], - "correctAnswerMustInclude": ["Derived"] - }, - - { - "id": "query-vue-basics", - "question": "How do I use TanStack Query with Vue?", - "difficulty": "easy", - "tags": ["query", "vue", "basics"], - "expectedDocs": [ - { - "library": "query", - "path": "framework/vue/overview", - "required": true, - "reason": "Vue overview" - } - ], - "idealSearchQueries": ["vue query", "tanstack query vue"], - "correctAnswerMustInclude": ["useQuery", "VueQueryPlugin"] - }, - { - "id": "query-solid-basics", - "question": "How do I use TanStack Query with SolidJS?", - "difficulty": "easy", - "tags": ["query", "solid", "basics"], - "expectedDocs": [ - { - "library": "query", - "path": "framework/solid/overview", - "required": true, - "reason": "Solid overview" - } - ], - "idealSearchQueries": ["solid query", "tanstack query solid"], - "correctAnswerMustInclude": ["createQuery", "QueryClientProvider"] - }, - { - "id": "router-vue-basics", - "question": "How do I use TanStack Router with Vue?", - "difficulty": "easy", - "tags": ["router", "vue", "basics"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/overview", - "required": true, - "reason": "Router overview (Vue support is experimental)" - } - ], - "idealSearchQueries": ["router overview", "tanstack router"], - "correctAnswerMustInclude": ["router"], - "notes": "Vue support for Router is experimental and docs may be limited" - }, - - { - "id": "query-testing", - "question": "How do I test components that use TanStack Query?", - "difficulty": "medium", - "tags": ["query", "testing"], - "expectedDocs": [ - { - "library": "query", - "path": "framework/react/guides/testing", - "required": true, - "reason": "Testing guide" - } - ], - "idealSearchQueries": ["testing query", "test useQuery"], - "correctAnswerMustInclude": ["QueryClientProvider", "test"] - }, - { - "id": "query-typescript", - "question": "How do I properly type TanStack Query hooks with TypeScript?", - "difficulty": "medium", - "tags": ["query", "typescript"], - "expectedDocs": [ - { - "library": "query", - "path": "framework/react/typescript", - "required": true, - "reason": "TypeScript guide" - } - ], - "idealSearchQueries": ["query typescript", "type useQuery"], - "correctAnswerMustInclude": ["TypeScript", "TData", "TError"] - }, - - { - "id": "router-scroll-restoration", - "question": "How do I handle scroll position restoration in TanStack Router?", - "difficulty": "medium", - "tags": ["router", "scroll"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/guide/scroll-restoration", - "required": true, - "reason": "Scroll restoration guide" - } - ], - "idealSearchQueries": ["scroll restoration", "ScrollRestoration"], - "correctAnswerMustInclude": ["ScrollRestoration", "scroll"] - }, - { - "id": "router-error-handling", - "question": "How do I handle route errors and show error boundaries in TanStack Router?", - "difficulty": "medium", - "tags": ["router", "errors"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/guide/data-loading", - "required": true, - "reason": "Data loading covers error handling" - } - ], - "idealSearchQueries": ["router error boundary", "errorComponent"], - "correctAnswerMustInclude": ["errorComponent", "onError"] - }, - { - "id": "router-pending-ui", - "question": "How do I show loading states during navigation in TanStack Router?", - "difficulty": "easy", - "tags": ["router", "loading", "pending"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/guide/data-loading", - "required": true, - "reason": "Data loading covers pending states" - } - ], - "idealSearchQueries": ["pending component", "loading navigation"], - "correctAnswerMustInclude": ["pendingComponent"] - }, - - { - "id": "start-forms", - "question": "How do I handle form submissions with server actions in TanStack Start?", - "difficulty": "medium", - "tags": ["start", "forms", "server-actions"], - "expectedDocs": [ - { - "library": "start", - "path": "framework/react/guide/server-functions", - "required": true, - "reason": "Server functions cover form handling" - } - ], - "idealSearchQueries": ["server functions", "createServerFn"], - "correctAnswerMustInclude": ["createServerFn"] - }, - { - "id": "start-head-meta", - "question": "How do I set page titles and meta tags in TanStack Start?", - "difficulty": "easy", - "tags": ["start", "meta", "seo"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/guide/document-head-management", - "required": true, - "reason": "Document head management guide" - } - ], - "idealSearchQueries": ["document head", "meta title"], - "correctAnswerMustInclude": ["head"] - }, - - { - "id": "query-enabled-button-click", - "question": "How do I trigger a query only when a button is clicked instead of on component mount?", - "difficulty": "medium", - "tags": ["query", "enabled", "manual-fetch"], - "expectedDocs": [ - { - "library": "query", - "path": "framework/react/guides/disabling-queries", - "required": true, - "reason": "Disabling queries guide covers enabled option and refetch" - } - ], - "idealSearchQueries": ["disable query", "enabled false", "manual query"], - "correctAnswerMustInclude": ["enabled", "refetch"], - "notes": "Mined from Stack Overflow - score 227. Very common question about lazy/on-demand queries." - }, - { - "id": "query-stale-cache-time", - "question": "What is the difference between staleTime and gcTime (cacheTime) in TanStack Query?", - "difficulty": "medium", - "tags": ["query", "cache", "stale"], - "expectedDocs": [ - { - "library": "query", - "path": "framework/react/guides/caching", - "required": true, - "reason": "Caching guide explains staleTime and gcTime" - } - ], - "idealSearchQueries": ["staleTime gcTime", "caching query", "cache time"], - "correctAnswerMustInclude": ["staleTime", "gcTime"], - "notes": "Mined from Stack Overflow - score 71. Common confusion about cache timing options." - }, - { - "id": "query-conditional-enabled", - "question": "How do I conditionally run a query based on some state or prop in TanStack Query?", - "difficulty": "easy", - "tags": ["query", "enabled", "conditional"], - "expectedDocs": [ - { - "library": "query", - "path": "framework/react/guides/dependent-queries", - "required": true, - "reason": "Dependent queries guide covers enabled option" - } - ], - "idealSearchQueries": [ - "dependent queries", - "enabled query", - "conditional query" - ], - "correctAnswerMustInclude": ["enabled"], - "notes": "Mined from Stack Overflow - score 68. Very common pattern for conditional fetching." - }, - { - "id": "query-callbacks-deprecated", - "question": "The onSuccess, onError, and onSettled callbacks are deprecated in TanStack Query. What should I use instead?", - "difficulty": "medium", - "tags": ["query", "callbacks", "migration"], - "expectedDocs": [ - { - "library": "query", - "path": "framework/react/guides/migrating-to-v5", - "required": true, - "reason": "Migration guide covers callback changes" - } - ], - "idealSearchQueries": [ - "migrate v5", - "onSuccess deprecated", - "query callbacks" - ], - "correctAnswerMustInclude": ["useEffect"], - "notes": "Mined from Stack Overflow - score 54. Important migration question for v5 users." - }, - { - "id": "query-provider-error", - "question": "I'm getting 'No QueryClient set, use QueryClientProvider to set one'. How do I fix this?", - "difficulty": "easy", - "tags": ["query", "setup", "error"], - "expectedDocs": [ - { - "library": "query", - "path": "framework/react/quick-start", - "required": true, - "reason": "Quick start shows proper QueryClientProvider setup" - } - ], - "idealSearchQueries": ["QueryClientProvider", "quick start query"], - "correctAnswerMustInclude": ["QueryClientProvider", "QueryClient"], - "notes": "Mined from Stack Overflow - score 113. Common setup error for new users." - }, - { - "id": "table-default-sorting", - "question": "How do I set a default/initial sort order when the table first loads in TanStack Table?", - "difficulty": "easy", - "tags": ["table", "sorting", "initial-state"], - "expectedDocs": [ - { - "library": "table", - "path": "guide/sorting", - "required": true, - "reason": "Sorting guide covers initial sorting state" - } - ], - "idealSearchQueries": ["initial sorting", "default sort table"], - "correctAnswerMustInclude": ["sorting", "initialState"], - "notes": "Mined from Stack Overflow - score 50. Common question about initial table state." - }, - { - "id": "table-column-visibility", - "question": "How do I hide or show columns dynamically in TanStack Table?", - "difficulty": "easy", - "tags": ["table", "columns", "visibility"], - "expectedDocs": [ - { - "library": "table", - "path": "guide/column-visibility", - "required": true, - "reason": "Column visibility guide" - } - ], - "idealSearchQueries": ["column visibility", "hide column table"], - "correctAnswerMustInclude": ["columnVisibility"], - "notes": "Mined from GitHub - score 54. Users often confused about show/hide columns." - }, - { - "id": "table-row-click-handler", - "question": "How do I handle row click events and select a row when clicked in TanStack Table?", - "difficulty": "medium", - "tags": ["table", "selection", "events"], - "expectedDocs": [ - { - "library": "table", - "path": "guide/row-selection", - "required": true, - "reason": "Row selection guide" - } - ], - "idealSearchQueries": ["row selection", "row click table"], - "correctAnswerMustInclude": ["rowSelection", "onClick"], - "notes": "Mined from Stack Overflow - score 65. Common interaction pattern." - }, - { - "id": "virtual-scroll-to-index", - "question": "How do I programmatically scroll to a specific item/index in TanStack Virtual?", - "difficulty": "medium", - "tags": ["virtual", "scroll", "navigation"], - "expectedDocs": [ - { - "library": "virtual", - "path": "api/virtualizer", - "required": true, - "reason": "Virtualizer API covers scrollToIndex" - } - ], - "idealSearchQueries": ["scrollToIndex", "scroll to item virtual"], - "correctAnswerMustInclude": ["scrollToIndex"], - "notes": "Common need for navigating virtualized lists programmatically." - }, - { - "id": "query-parallel-queries", - "question": "How do I run multiple queries in parallel with TanStack Query?", - "difficulty": "medium", - "tags": ["query", "parallel", "multiple"], - "expectedDocs": [ - { - "library": "query", - "path": "framework/react/guides/parallel-queries", - "required": true, - "reason": "Parallel queries guide" - } - ], - "idealSearchQueries": ["parallel queries", "useQueries"], - "correctAnswerMustInclude": ["useQueries"], - "notes": "Common pattern for fetching multiple resources at once." - }, - { - "id": "query-placeholder-data", - "question": "How do I show placeholder or initial data while my query is loading in TanStack Query?", - "difficulty": "medium", - "tags": ["query", "placeholder", "loading"], - "expectedDocs": [ - { - "library": "query", - "path": "framework/react/guides/placeholder-query-data", - "required": true, - "reason": "Placeholder query data guide" - } - ], - "idealSearchQueries": ["placeholder data", "initialData query"], - "correctAnswerMustInclude": ["placeholderData"], - "notes": "Important UX pattern for perceived performance." - }, - { - "id": "router-link-active-state", - "question": "How do I style the active link differently when on that route in TanStack Router?", - "difficulty": "easy", - "tags": ["router", "link", "active", "styling"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/api/router/ActiveLinkOptionsType", - "required": true, - "reason": "ActiveLinkOptionsType API covers activeProps and inactiveProps" - } - ], - "idealSearchQueries": ["Link active", "activeProps router"], - "correctAnswerMustInclude": ["activeProps", "Link"], - "notes": "Common navigation styling pattern." - }, - - { - "id": "router-layout-routes", - "question": "How do I create layout routes that wrap child routes with shared UI in TanStack Router?", - "difficulty": "medium", - "tags": ["router", "layout", "nested"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/routing/routing-concepts", - "required": true, - "reason": "Routing concepts covers layout routes and Outlet" - } - ], - "idealSearchQueries": ["layout routes", "Outlet router"], - "correctAnswerMustInclude": ["Outlet", "layout"] - }, - { - "id": "router-pathless-layout", - "question": "How do I create a pathless layout route that groups routes without adding to the URL path?", - "difficulty": "medium", - "tags": ["router", "layout", "pathless"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/routing/routing-concepts", - "required": true, - "reason": "Routing concepts covers pathless layout routes with underscore prefix" - } - ], - "idealSearchQueries": ["pathless layout", "route grouping"], - "correctAnswerMustInclude": ["_"] - }, - { - "id": "router-route-context", - "question": "How do I pass data through route context to child routes in TanStack Router?", - "difficulty": "medium", - "tags": ["router", "context", "data"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/api/router/createRootRouteWithContextFunction", - "required": true, - "reason": "createRootRouteWithContext for typed context" - } - ], - "idealSearchQueries": ["route context", "createRootRouteWithContext"], - "correctAnswerMustInclude": ["context"] - }, - { - "id": "router-use-navigate", - "question": "How do I programmatically navigate to a route in TanStack Router?", - "difficulty": "easy", - "tags": ["router", "navigation", "programmatic"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/api/router/useNavigateHook", - "required": true, - "reason": "useNavigate hook API" - } - ], - "idealSearchQueries": ["useNavigate", "programmatic navigation"], - "correctAnswerMustInclude": ["useNavigate"] - }, - { - "id": "router-catch-all-splat", - "question": "How do I create a catch-all or splat route that matches any path in TanStack Router?", - "difficulty": "easy", - "tags": ["router", "splat", "catch-all"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/routing/routing-concepts", - "required": true, - "reason": "Routing concepts covers splat routes" - } - ], - "idealSearchQueries": ["splat route", "catch all route"], - "correctAnswerMustInclude": ["$"] - }, - { - "id": "router-file-based-routing", - "question": "How does file-based routing work in TanStack Router?", - "difficulty": "easy", - "tags": ["router", "file-based", "basics"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/routing/file-based-routing", - "required": true, - "reason": "File-based routing guide" - } - ], - "idealSearchQueries": ["file based routing", "route file"], - "correctAnswerMustInclude": ["routes", "file"] - }, - { - "id": "router-navigate-search-params", - "question": "How do I navigate while preserving or modifying search params in TanStack Router?", - "difficulty": "medium", - "tags": ["router", "navigation", "search-params"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/guide/search-params", - "required": true, - "reason": "Search params guide covers navigation with search" - } - ], - "idealSearchQueries": ["search params navigation", "navigate search"], - "correctAnswerMustInclude": ["search"] - }, - { - "id": "router-redirect-beforeload", - "question": "How do I redirect users in TanStack Router before the route loads?", - "difficulty": "medium", - "tags": ["router", "redirect", "beforeLoad"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/guide/authenticated-routes", - "required": true, - "reason": "Authenticated routes guide shows redirect pattern" - } - ], - "idealSearchQueries": ["redirect beforeLoad", "redirect router"], - "correctAnswerMustInclude": ["redirect", "beforeLoad"] - }, - { - "id": "router-route-masking", - "question": "How do I show a different URL in the browser than the actual route in TanStack Router?", - "difficulty": "hard", - "tags": ["router", "masking", "url"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/guide/route-masking", - "required": true, - "reason": "Route masking guide" - } - ], - "idealSearchQueries": ["route masking", "mask url"], - "correctAnswerMustInclude": ["mask"] - }, - { - "id": "router-ssr-streaming", - "question": "How does SSR and streaming work in TanStack Router?", - "difficulty": "hard", - "tags": ["router", "ssr", "streaming"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/guide/ssr", - "required": true, - "reason": "SSR guide covers streaming" - } - ], - "idealSearchQueries": ["ssr router guide", "server side rendering"], - "correctAnswerMustInclude": ["SSR", "streaming"] - }, - { - "id": "router-external-data-loading", - "question": "How do I use TanStack Router with an external data fetching library like TanStack Query?", - "difficulty": "medium", - "tags": ["router", "query", "integration", "data"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/guide/external-data-loading", - "required": true, - "reason": "External data loading guide" - } - ], - "idealSearchQueries": [ - "external data loading", - "router query integration" - ], - "correctAnswerMustInclude": ["external", "data"] - }, - - { - "id": "start-execution-model", - "question": "How do I understand where my code runs in TanStack Start (server vs client)?", - "difficulty": "medium", - "tags": ["start", "ssr", "execution"], - "expectedDocs": [ - { - "library": "start", - "path": "framework/react/guide/execution-model", - "required": true, - "reason": "Execution model guide explains server/client code" - } - ], - "idealSearchQueries": ["execution model", "server client start"], - "correctAnswerMustInclude": ["server", "client"] - }, - { - "id": "start-server-only-code", - "question": "How do I ensure code only runs on the server in TanStack Start?", - "difficulty": "medium", - "tags": ["start", "server", "code-patterns"], - "expectedDocs": [ - { - "library": "start", - "path": "framework/react/guide/code-execution-patterns", - "required": true, - "reason": "Code execution patterns guide" - } - ], - "idealSearchQueries": ["server only code", "code execution patterns"], - "correctAnswerMustInclude": ["server"] - }, - { - "id": "start-authentication", - "question": "How do I implement authentication in TanStack Start?", - "difficulty": "hard", - "tags": ["start", "auth", "security"], - "expectedDocs": [ - { - "library": "start", - "path": "framework/react/guide/authentication", - "required": true, - "reason": "Authentication guide" - } - ], - "idealSearchQueries": ["authentication start", "auth tanstack start"], - "correctAnswerMustInclude": ["auth"] - }, - { - "id": "start-auth-overview", - "question": "What authentication options are available for TanStack Start?", - "difficulty": "easy", - "tags": ["start", "auth", "overview"], - "expectedDocs": [ - { - "library": "start", - "path": "framework/react/guide/authentication-overview", - "required": true, - "reason": "Authentication overview with partner solutions" - } - ], - "idealSearchQueries": ["authentication overview", "clerk workos start"], - "correctAnswerMustInclude": ["Clerk", "WorkOS"] - }, - { - "id": "start-streaming-server-functions", - "question": "How do I stream data from a server function in TanStack Start?", - "difficulty": "hard", - "tags": ["start", "streaming", "server-functions"], - "expectedDocs": [ - { - "library": "start", - "path": "framework/react/guide/server-functions", - "required": true, - "reason": "Server functions guide covers streaming" - } - ], - "idealSearchQueries": ["streaming server function", "stream data start"], - "correctAnswerMustInclude": ["stream"] - }, - { - "id": "start-tailwind", - "question": "How do I set up Tailwind CSS with TanStack Start?", - "difficulty": "easy", - "tags": ["start", "tailwind", "css"], - "expectedDocs": [ - { - "library": "start", - "path": "framework/react/guide/tailwind-integration", - "required": true, - "reason": "Tailwind CSS integration guide" - } - ], - "idealSearchQueries": ["tailwind start", "css tailwind tanstack"], - "correctAnswerMustInclude": ["tailwind"] - }, - { - "id": "start-database", - "question": "How do I connect to a database in TanStack Start?", - "difficulty": "medium", - "tags": ["start", "database", "data"], - "expectedDocs": [ - { - "library": "start", - "path": "framework/react/guide/databases", - "required": true, - "reason": "Databases guide" - } - ], - "idealSearchQueries": ["database start", "drizzle prisma start"], - "correctAnswerMustInclude": ["database"] - }, - { - "id": "start-migrate-nextjs", - "question": "How do I migrate from Next.js to TanStack Start?", - "difficulty": "hard", - "tags": ["start", "migration", "nextjs"], - "expectedDocs": [ - { - "library": "start", - "path": "framework/react/migrate-from-next-js", - "required": true, - "reason": "Next.js migration guide" - } - ], - "idealSearchQueries": ["migrate nextjs", "next.js to start"], - "correctAnswerMustInclude": ["migrate", "Next"] - }, - { - "id": "start-build-from-scratch", - "question": "How do I build a TanStack Start project from scratch without using a template?", - "difficulty": "medium", - "tags": ["start", "setup", "manual"], - "expectedDocs": [ - { - "library": "start", - "path": "framework/react/build-from-scratch", - "required": true, - "reason": "Build from scratch guide" - } - ], - "idealSearchQueries": ["build from scratch", "manual setup start"], - "correctAnswerMustInclude": ["scratch"] - }, - { - "id": "start-rendering-markdown", - "question": "How do I render markdown content in TanStack Start?", - "difficulty": "medium", - "tags": ["start", "markdown", "content"], - "expectedDocs": [ - { - "library": "start", - "path": "framework/react/guide/rendering-markdown", - "required": true, - "reason": "Rendering markdown guide" - } - ], - "idealSearchQueries": ["render markdown", "markdown start"], - "correctAnswerMustInclude": ["markdown"] - }, - { - "id": "start-cloudflare-workers", - "question": "How do I deploy TanStack Start to Cloudflare Workers?", - "difficulty": "medium", - "tags": ["start", "deployment", "cloudflare"], - "expectedDocs": [ - { - "library": "start", - "path": "framework/react/guide/hosting", - "required": true, - "reason": "Hosting guide covers Cloudflare Workers" - } - ], - "idealSearchQueries": ["cloudflare workers", "deploy cloudflare start"], - "correctAnswerMustInclude": ["cloudflare"] - }, - { - "id": "start-vs-nextjs", - "question": "How does TanStack Start compare to Next.js?", - "difficulty": "easy", - "tags": ["start", "comparison", "nextjs"], - "expectedDocs": [ - { - "library": "start", - "path": "framework/react/comparison", - "required": true, - "reason": "Comparison guide" - } - ], - "idealSearchQueries": ["start vs nextjs", "comparison next"], - "correctAnswerMustInclude": ["Next"] - }, - { - "id": "router-providers-location", - "question": "Where do I put providers like QueryClientProvider in TanStack Start?", - "difficulty": "medium", - "tags": ["start", "router", "providers", "setup"], - "expectedDocs": [ - { - "library": "router", - "path": "integrations/query", - "required": true, - "reason": "Query integration guide shows provider setup" - } - ], - "idealSearchQueries": [ - "query integration setup", - "QueryClientProvider router" - ], - "correctAnswerMustInclude": ["provider"], - "notes": "Mined from Stack Overflow. Common setup question." - }, - { - "id": "router-routetree-gen-error", - "question": "I'm getting 'Cannot find module routeTree.gen' error. How do I fix it?", - "difficulty": "easy", - "tags": ["router", "setup", "error"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/faq", - "required": true, - "reason": "FAQ covers routeTree.gen questions" - } - ], - "idealSearchQueries": ["routeTree.gen", "route tree faq"], - "correctAnswerMustInclude": ["routeTree"], - "notes": "Mined from Stack Overflow. Common setup error." - }, - { - "id": "router-exclude-layout", - "question": "How do I exclude specific routes from a parent layout in TanStack Router?", - "difficulty": "medium", - "tags": ["router", "layout", "nested"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/routing/routing-concepts", - "required": true, - "reason": "Routing concepts covers non-nested routes" - } - ], - "idealSearchQueries": ["non-nested routes", "exclude layout"], - "correctAnswerMustInclude": ["_"], - "notes": "Mined from Stack Overflow. Users want to break out of layouts." - }, - { - "id": "router-dynamic-nested-routes", - "question": "How do I create dynamic nested routes like /users/$userId/posts/$postId in TanStack Router?", - "difficulty": "medium", - "tags": ["router", "dynamic", "nested", "params"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/routing/routing-concepts", - "required": true, - "reason": "Routing concepts covers dynamic route segments" - } - ], - "idealSearchQueries": ["dynamic route segments", "routing concepts"], - "correctAnswerMustInclude": ["$"] - }, - { - "id": "router-search-params-no-rerender", - "question": "How do I update search params without causing a full page re-render in TanStack Router?", - "difficulty": "medium", - "tags": ["router", "search-params", "performance"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/guide/search-params", - "required": true, - "reason": "Search params guide covers shallow navigation" - } - ], - "idealSearchQueries": [ - "search params shallow", - "update search no rerender" - ], - "correctAnswerMustInclude": ["search"], - "notes": "Mined from Stack Overflow. Common performance concern." - }, - { - "id": "router-link-typesafe-wrapper", - "question": "How do I wrap TanStack Router's Link component while keeping type safety?", - "difficulty": "hard", - "tags": ["router", "typescript", "link"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/guide/custom-link", - "required": true, - "reason": "Custom link guide covers createLink" - } - ], - "idealSearchQueries": ["custom link", "createLink wrapper"], - "correctAnswerMustInclude": ["createLink"], - "notes": "Mined from Stack Overflow. TypeScript users want custom Link components." - }, - { - "id": "router-error-boundary-disable", - "question": "How do I disable or customize the error boundary in TanStack Router?", - "difficulty": "medium", - "tags": ["router", "errors", "error-boundary"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/guide/data-loading", - "required": true, - "reason": "Data loading covers error handling" - } - ], - "idealSearchQueries": ["error boundary router", "errorComponent"], - "correctAnswerMustInclude": ["errorComponent"], - "notes": "Mined from Stack Overflow. Users want custom error handling." - }, - { - "id": "router-generate-href", - "question": "How do I generate a URL/href string for a route without navigating in TanStack Router?", - "difficulty": "medium", - "tags": ["router", "url", "href"], - "expectedDocs": [ - { - "library": "router", - "path": "framework/react/api/router/RouterType", - "required": true, - "reason": "Router API covers buildLocation" - } - ], - "idealSearchQueries": ["buildLocation", "generate href router"], - "correctAnswerMustInclude": ["buildLocation"], - "notes": "Mined from Stack Overflow. Need URLs for sharing/copying." - }, - { - "id": "start-server-fn-validation", - "question": "How do I validate input data in a TanStack Start server function?", - "difficulty": "medium", - "tags": ["start", "server-functions", "validation"], - "expectedDocs": [ - { - "library": "start", - "path": "framework/react/guide/server-functions", - "required": true, - "reason": "Server functions guide covers validation" - } - ], - "idealSearchQueries": [ - "server function validation", - "validate server fn" - ], - "correctAnswerMustInclude": ["validator", "zod"] - }, - { - "id": "start-env-variables", - "question": "How do I use environment variables in TanStack Start?", - "difficulty": "easy", - "tags": ["start", "env", "config"], - "expectedDocs": [ - { - "library": "start", - "path": "framework/react/guide/environment-variables", - "required": true, - "reason": "Environment variables guide" - } - ], - "idealSearchQueries": ["environment variables", "env tanstack start"], - "correctAnswerMustInclude": ["env", "VITE"] - } - ] -} diff --git a/scripts/register-discord-commands.ts b/scripts/register-discord-commands.ts deleted file mode 100644 index 6ce9d0d22..000000000 --- a/scripts/register-discord-commands.ts +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Register Discord slash commands with the Discord API. - * - * Run this script after adding new commands or modifying existing ones: - * pnpm tsx scripts/register-discord-commands.ts - * - * Required environment variables: - * DISCORD_APPLICATION_ID - Your Discord application ID - * DISCORD_BOT_TOKEN - Your Discord bot token - */ - -const DISCORD_APPLICATION_ID = process.env.DISCORD_APPLICATION_ID -const DISCORD_BOT_TOKEN = process.env.DISCORD_BOT_TOKEN - -if (!DISCORD_APPLICATION_ID || !DISCORD_BOT_TOKEN) { - console.error('Missing required environment variables:') - if (!DISCORD_APPLICATION_ID) console.error(' - DISCORD_APPLICATION_ID') - if (!DISCORD_BOT_TOKEN) console.error(' - DISCORD_BOT_TOKEN') - process.exit(1) -} - -const commands = [ - { - name: 'tanstack', - description: 'Check TanStack Bot status', - type: 1, // CHAT_INPUT - }, -] - -async function registerCommands() { - const url = `https://discord.com/api/v10/applications/${DISCORD_APPLICATION_ID}/commands` - - console.log('Registering commands with Discord API...') - console.log(`Application ID: ${DISCORD_APPLICATION_ID}`) - console.log(`Commands to register: ${commands.map((c) => c.name).join(', ')}`) - - const response = await fetch(url, { - method: 'PUT', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bot ${DISCORD_BOT_TOKEN}`, - }, - body: JSON.stringify(commands), - }) - - if (!response.ok) { - const error = await response.text() - console.error(`Failed to register commands: ${response.status}`) - console.error(error) - process.exit(1) - } - - const registered = await response.json() - console.log('\nSuccessfully registered commands:') - for (const cmd of registered) { - console.log(` - /${cmd.name} (ID: ${cmd.id})`) - } -} - -registerCommands().catch((error) => { - console.error('Failed to register commands:', error) - process.exit(1) -}) diff --git a/src/auth/client.ts b/src/auth/client.ts index 9b79ed9e0..9e5097697 100644 --- a/src/auth/client.ts +++ b/src/auth/client.ts @@ -17,26 +17,11 @@ import type { OAuthProvider } from './types' export const authClient = { signIn: { /** - * Initiate OAuth sign-in with a social provider (full page redirect) + * Initiate OAuth sign-in with a social provider */ social: ({ provider }: { provider: OAuthProvider }) => { window.location.href = `/auth/${provider}/start` }, - - /** - * Initiate OAuth sign-in in a popup window (for modal-based login) - */ - socialPopup: ({ provider }: { provider: OAuthProvider }) => { - const width = 500 - const height = 600 - const left = window.screenX + (window.outerWidth - width) / 2 - const top = window.screenY + (window.outerHeight - height) / 2 - window.open( - `/auth/${provider}/start?popup=true`, - 'tanstack-oauth', - `width=${width},height=${height},left=${left},top=${top},popup=yes`, - ) - }, }, /** diff --git a/src/auth/context.server.ts b/src/auth/context.server.ts index b107bbadb..e05f84fb5 100644 --- a/src/auth/context.server.ts +++ b/src/auth/context.server.ts @@ -21,19 +21,7 @@ import { // ============================================================================ function getSessionSecret(): string { - const secret = process.env.SESSION_SECRET - if (!secret) { - if (process.env.NODE_ENV === 'production') { - throw new Error( - 'SESSION_SECRET environment variable is required in production', - ) - } - console.warn( - '[Auth] SESSION_SECRET not set, using insecure default for development only', - ) - return 'dev-secret-key-change-in-production' - } - return secret + return process.env.SESSION_SECRET || 'dev-secret-key-change-in-production' } function isProduction(): boolean { diff --git a/src/auth/guards.server.ts b/src/auth/guards.server.ts index 1824c8b55..81f5061b8 100644 --- a/src/auth/guards.server.ts +++ b/src/auth/guards.server.ts @@ -117,30 +117,30 @@ export type AuthGuards = ReturnType /** * Create a guard that wraps a handler with capability check */ -export function withCapability( +export function withCapability unknown>( guards: AuthGuards, capability: Capability, getRequest: () => Request, - handler: (user: AuthUser, ...args: TArgs) => TReturn, -) { - return async (...args: TArgs): Promise> => { + handler: (user: AuthUser, ...args: Parameters) => ReturnType, +): (...args: Parameters) => Promise>> { + return async (...args: Parameters) => { const request = getRequest() const user = await guards.requireCapability(request, capability) - return (await handler(user, ...args)) as Awaited + return handler(user, ...args) as Awaited> } } /** * Create a guard that wraps a handler with auth check */ -export function withAuth( +export function withAuth unknown>( guards: AuthGuards, getRequest: () => Request, - handler: (user: AuthUser, ...args: TArgs) => TReturn, -) { - return async (...args: TArgs): Promise> => { + handler: (user: AuthUser, ...args: Parameters) => ReturnType, +): (...args: Parameters) => Promise>> { + return async (...args: Parameters) => { const request = getRequest() const user = await guards.requireAuth(request) - return (await handler(user, ...args)) as Awaited + return handler(user, ...args) as Awaited> } } diff --git a/src/auth/index.server.ts b/src/auth/index.server.ts index d8ffb81e1..e0ca0da7f 100644 --- a/src/auth/index.server.ts +++ b/src/auth/index.server.ts @@ -64,9 +64,6 @@ export { createOAuthStateCookie, clearOAuthStateCookie, getOAuthStateCookie, - createOAuthPopupCookie, - clearOAuthPopupCookie, - isOAuthPopupMode, SESSION_DURATION_MS, SESSION_MAX_AGE_SECONDS, } from './session.server' diff --git a/src/auth/oauth.server.ts b/src/auth/oauth.server.ts index f218d1d45..6803c9884 100644 --- a/src/auth/oauth.server.ts +++ b/src/auth/oauth.server.ts @@ -186,7 +186,7 @@ export function buildGitHubAuthUrl( clientId, )}&redirect_uri=${encodeURIComponent( redirectUri, - )}&scope=user:email&state=${encodeURIComponent(state)}` + )}&scope=user:email&state=${state}` } /** @@ -201,7 +201,7 @@ export function buildGoogleAuthUrl( clientId, )}&redirect_uri=${encodeURIComponent( redirectUri, - )}&response_type=code&scope=openid email profile&state=${encodeURIComponent(state)}` + )}&response_type=code&scope=openid email profile&state=${state}` } /** diff --git a/src/auth/session.server.ts b/src/auth/session.server.ts index 9b08e8f8e..4f23d3970 100644 --- a/src/auth/session.server.ts +++ b/src/auth/session.server.ts @@ -264,19 +264,6 @@ export function getOAuthStateCookie(request: Request): string | null { return decodeURIComponent(stateCookie.split('=').slice(1).join('=').trim()) } -export function createOAuthPopupCookie(isProduction: boolean): string { - return `oauth_popup=1; HttpOnly; Path=/; Max-Age=${10 * 60}; SameSite=Lax${isProduction ? '; Secure' : ''}` -} - -export function clearOAuthPopupCookie(isProduction: boolean): string { - return `oauth_popup=; HttpOnly; Path=/; Max-Age=0; SameSite=Lax${isProduction ? '; Secure' : ''}` -} - -export function isOAuthPopupMode(request: Request): boolean { - const cookies = request.headers.get('cookie') || '' - return cookies.split(';').some((c) => c.trim().startsWith('oauth_popup=1')) -} - // ============================================================================ // Session Constants // ============================================================================ diff --git a/src/auth/types.ts b/src/auth/types.ts index 5a30cee43..d31112c2c 100644 --- a/src/auth/types.ts +++ b/src/auth/types.ts @@ -6,11 +6,32 @@ * server and client code. */ -// Re-export shared types from db/types.ts (single source of truth) -export type { Capability, OAuthProvider } from '~/db/types' -export { CAPABILITIES as VALID_CAPABILITIES } from '~/db/types' +// ============================================================================ +// Capability Types +// ============================================================================ + +export type Capability = + | 'admin' + | 'disableAds' + | 'builder' + | 'feed' + | 'moderate-feedback' + | 'moderate-showcases' + +export const VALID_CAPABILITIES: readonly Capability[] = [ + 'admin', + 'disableAds', + 'builder', + 'feed', + 'moderate-feedback', + 'moderate-showcases', +] as const + +// ============================================================================ +// OAuth Types +// ============================================================================ -import type { Capability, OAuthProvider } from '~/db/types' +export type OAuthProvider = 'github' | 'google' export interface OAuthProfile { id: string diff --git a/src/blog/composite-components.md b/src/blog/composite-components.md index 697d313a7..470f6204f 100644 --- a/src/blog/composite-components.md +++ b/src/blog/composite-components.md @@ -1,7 +1,6 @@ --- title: 'Composite Components: Server Components with Client-Led Composition' -published: 2026-01-15 -draft: true +published: 2025-01-15 authors: - Manuel Schiller - Tanner Linsley diff --git a/src/blog/tanstack-ai-why-we-split-the-adapters.md b/src/blog/tanstack-ai-why-we-split-the-adapters.md index af2180fc6..97da550d7 100644 --- a/src/blog/tanstack-ai-why-we-split-the-adapters.md +++ b/src/blog/tanstack-ai-why-we-split-the-adapters.md @@ -1,12 +1,10 @@ --- -title: 'TanStack AI: Why We Split the Adapters' +title: 'Why We Split the Adapters' published: 2026-01-02 authors: - Alem Tuzlak --- -![TanStack AI: Why We Split the Adapters](/blog-assets/tanstack-ai-why-we-split-the-adapters/header.jpeg) - With the latest release we brought a major architectural change to how we do adapters. Instead of one monolithic adapter that does everything, we split into smaller adapters. Each in charge of a single functionality. Here's why. diff --git a/src/components/AILibraryHero.tsx b/src/components/AILibraryHero.tsx index db151ad53..60a1b2fb6 100644 --- a/src/components/AILibraryHero.tsx +++ b/src/components/AILibraryHero.tsx @@ -1,9 +1,12 @@ import * as React from 'react' import { LinkProps } from '@tanstack/react-router' import type { Library } from '~/libraries' +import { useIsDark } from '~/hooks/useIsDark' import { ChatPanel } from './ChatPanel' -import { AnimationPhase } from '~/stores/aiLibraryHeroAnimation' -import { useAILibraryHeroAnimation } from '~/hooks/useAILibraryHeroAnimation' +import { + useAILibraryHeroAnimationStore, + AnimationPhase, +} from '~/stores/aiLibraryHeroAnimation' import { AILibraryHeroCard } from './AILibraryHeroCard' import { AILibraryHeroBox } from './AILibraryHeroBox' import { AILibraryHeroServiceCard } from './AILibraryHeroServiceCard' @@ -27,6 +30,7 @@ import { BOX_FONT_SIZE, BOX_FONT_WEIGHT, SERVICE_WIDTH, + SERVICE_GUTTER, SERVICE_LOCATIONS, SERVICE_Y_OFFSET, SERVICE_Y_CENTER, @@ -40,6 +44,9 @@ import { SERVER_CARD_HEIGHT, } from '~/stores/aiLibraryHeroAnimation' +// Get the store instance for accessing getState in closures +const getStoreState = () => useAILibraryHeroAnimationStore.getState() + type AILibraryHeroProps = { project: Library cta?: { @@ -50,15 +57,47 @@ type AILibraryHeroProps = { actions?: React.ReactNode } -const HIGHLIGHT_COLOR = 'rgba(255, 255, 240, 0.95)' +const FRAMEWORKS = ['vanilla', 'react', 'solid', '?'] as const +const SERVICES = ['ollama', 'openai', 'anthropic', 'gemini'] as const +const SERVERS = ['typescript', 'php', 'python', '?'] as const + +const MESSAGES = [ + { + user: 'What makes TanStack AI different?', + assistant: + 'TanStack AI is completely agnostic - server agnostic, client agnostic, and service agnostic. Use any backend (TypeScript, PHP, Python), any client (vanilla JS, React, Solid), and any AI service (OpenAI, Anthropic, Gemini, Ollama). We provide the libraries and standards, you choose your stack.', + }, + { + user: 'Do you support tools?', + assistant: + 'Yes! We have full support for both client and server tooling, including tool approvals. You can execute tools on either side with complete type safety and control.', + }, + { + user: 'What about thinking models?', + assistant: + "We fully support thinking and reasoning models. All thinking and reasoning tokens are sent to the client, giving you complete visibility into the model's reasoning process.", + }, + { + user: 'How type-safe is it?', + assistant: + 'We have total type safety across providers, models, and model options. Every interaction is fully typed from end to end, catching errors at compile time.', + }, + { + user: 'What about developer experience?', + assistant: + 'We have next-generation dev tools that show you everything happening with your AI connection in real-time. Debug, inspect, and optimize with complete visibility.', + }, + { + user: 'Is this a service I have to pay for?', + assistant: + "No! TanStack AI is pure open source software. We don't have a service to promote or charge for. This is an ecosystem of libraries and standards connecting you with the services you choose - completely community supported.", + }, +] export function AILibraryHero({}: AILibraryHeroProps) { - const strokeColor = 'var(--hero-stroke)' - const textColor = 'var(--hero-text)' - const glassGradientStart = 'var(--hero-glass-start)' - const glassGradientEnd = 'var(--hero-glass-end)' - // Use the animation hook - handles all animation state and orchestration - const { store } = useAILibraryHeroAnimation() + const isDark = useIsDark() + const strokeColor = isDark ? 'rgba(255, 255, 255, 0.8)' : 'rgba(0, 0, 0, 0.6)' + const textColor = isDark ? '#ffffff' : '#000000' const { phase, @@ -72,7 +111,258 @@ export function AILibraryHero({}: AILibraryHeroProps) { messages, typingUserMessage, connectionPulseDirection, - } = store + setPhase, + setSelectedFramework, + setSelectedService, + setSelectedServer, + setRotatingFramework, + setRotatingServer, + setRotatingService, + setServiceOffset, + addMessage, + updateCurrentAssistantMessage, + setCurrentMessageStreaming, + clearMessages, + setTypingUserMessage, + clearTypingUserMessage, + setConnectionPulseDirection, + addTimeout, + clearTimeouts, + } = useAILibraryHeroAnimationStore() + + React.useEffect(() => { + const addTimeoutHelper = (fn: () => void, delay: number) => { + const timeout = setTimeout(fn, delay) + addTimeout(timeout) + return timeout + } + + const getRandomIndex = (length: number, exclude?: number) => { + let index + do { + index = Math.floor(Math.random() * length) + } while (exclude !== undefined && index === exclude) + return index + } + + const selectFrameworkServiceServer = (onComplete: () => void) => { + // Phase 2: DESELECTING + setPhase(AnimationPhase.DESELECTING) + addTimeoutHelper(() => { + // Phase 3: SELECTING_FRAMEWORK + setPhase(AnimationPhase.SELECTING_FRAMEWORK) + const targetFramework = getRandomIndex(FRAMEWORKS.length) + let currentIndex = Math.floor(Math.random() * FRAMEWORKS.length) + const rotationCount = 8 + Math.floor(Math.random() * 4) // 8-11 rotations + + const rotateFramework = (iteration: number) => { + if (iteration < rotationCount - 1) { + setRotatingFramework(currentIndex) + currentIndex = (currentIndex + 1) % FRAMEWORKS.length + const delay = + iteration < rotationCount - 4 + ? 100 + : 150 + (iteration - (rotationCount - 4)) * 50 + addTimeoutHelper(() => rotateFramework(iteration + 1), delay) + } else { + // Final iteration - ensure we land on target + setRotatingFramework(targetFramework) + addTimeoutHelper(() => { + setSelectedFramework(targetFramework) + setRotatingFramework(null) + addTimeoutHelper(() => { + // Phase 4: SELECTING_SERVICE + setPhase(AnimationPhase.SELECTING_SERVICE) + // Always pick a different service so it has to scroll + const currentSelectedService = getStoreState().selectedService + const targetService = getRandomIndex( + SERVICES.length, + currentSelectedService ?? undefined, + ) + let currentServiceIndex = Math.floor( + Math.random() * SERVICES.length, + ) + const serviceRotationCount = 6 + Math.floor(Math.random() * 3) + + const rotateService = (iteration: number) => { + if (iteration < serviceRotationCount - 1) { + setRotatingService(currentServiceIndex) + currentServiceIndex = + (currentServiceIndex + 1) % SERVICES.length + const delay = + iteration < serviceRotationCount - 3 + ? 120 + : 180 + (iteration - (serviceRotationCount - 3)) * 60 + addTimeoutHelper(() => rotateService(iteration + 1), delay) + } else { + // Final iteration - ensure we land on target + setRotatingService(targetService) + addTimeoutHelper(() => { + setSelectedService(targetService) + setRotatingService(null) + const targetX = + 0 - + SERVICE_WIDTH / 2 - + SERVICE_GUTTER / 2 - + targetService * (SERVICE_WIDTH + SERVICE_GUTTER) + setServiceOffset(targetX) + + addTimeoutHelper(() => { + // Phase 5: SELECTING_SERVER + setPhase(AnimationPhase.SELECTING_SERVER) + const targetServer = getRandomIndex(SERVERS.length) + let currentServerIndex = Math.floor( + Math.random() * SERVERS.length, + ) + const serverRotationCount = + 8 + Math.floor(Math.random() * 4) + + const rotateServer = (iteration: number) => { + if (iteration < serverRotationCount - 1) { + setRotatingServer(currentServerIndex) + currentServerIndex = + (currentServerIndex + 1) % SERVERS.length + const delay = + iteration < serverRotationCount - 4 + ? 100 + : 150 + + (iteration - (serverRotationCount - 4)) * 50 + addTimeoutHelper( + () => rotateServer(iteration + 1), + delay, + ) + } else { + // Final iteration - ensure we land on target + setRotatingServer(targetServer) + addTimeoutHelper(() => { + setSelectedServer(targetServer) + setRotatingServer(null) + addTimeoutHelper(() => { + // Selection complete, call callback + onComplete() + }, 800) + }, 1000) + } + } + rotateServer(0) + }, 1000) + }, 800) + } + } + rotateService(0) + }, 800) + }, 500) + } + } + rotateFramework(0) + }, 500) + } + + const processNextMessage = (messageIndex: number) => { + if (messageIndex >= MESSAGES.length) { + // All messages shown, clear and restart + clearMessages() + addTimeoutHelper(() => { + // Phase 1: STARTING (initial state) + setPhase(AnimationPhase.STARTING) + addTimeoutHelper(() => { + // Start first message with selection + selectFrameworkServiceServer(() => { + processNextMessage(0) + }) + }, 1000) + }, 1000) + return + } + + const message = MESSAGES[messageIndex] + + // Phase 6: SHOWING_CHAT - Type user message in input field first + setPhase(AnimationPhase.SHOWING_CHAT) + clearTypingUserMessage() + + // Type the user message character by character in the input field + let typingIndex = 0 + const typeUserMessage = () => { + if (typingIndex < message.user.length) { + setTypingUserMessage(message.user.slice(0, typingIndex + 1)) + typingIndex++ + const delay = 30 + Math.floor(Math.random() * 40) // 30-70ms per character + addTimeoutHelper(typeUserMessage, delay) + } else { + // Typing complete, wait a moment then clear input and show as bubble + addTimeoutHelper(() => { + clearTypingUserMessage() + addMessage(message.user) + addTimeoutHelper(() => { + // Phase 7: PULSING_CONNECTIONS + setPhase(AnimationPhase.PULSING_CONNECTIONS) + setConnectionPulseDirection('down') + addTimeoutHelper(() => { + // Phase 8: STREAMING_RESPONSE + setPhase(AnimationPhase.STREAMING_RESPONSE) + setConnectionPulseDirection('up') + const fullMessage = message.assistant + setCurrentMessageStreaming(true) + let currentIndex = 0 + + const streamChunk = () => { + if (currentIndex < fullMessage.length) { + // Random chunk size between 2 and 8 characters + const chunkSize = 2 + Math.floor(Math.random() * 7) + const nextIndex = Math.min( + currentIndex + chunkSize, + fullMessage.length, + ) + updateCurrentAssistantMessage( + fullMessage.slice(0, nextIndex), + ) + currentIndex = nextIndex + // Random delay between 20ms and 80ms + const delay = 20 + Math.floor(Math.random() * 60) + addTimeoutHelper(streamChunk, delay) + } else { + setCurrentMessageStreaming(false) + addTimeoutHelper(() => { + // Phase 9: HOLDING - brief pause before next message + setPhase(AnimationPhase.HOLDING) + addTimeoutHelper(() => { + // Select new combination for next message + selectFrameworkServiceServer(() => { + // Move to next message + processNextMessage(messageIndex + 1) + }) + }, 2000) + }, 500) + } + } + streamChunk() + }, 2000) + }, 500) + }, 300) + } + } + typeUserMessage() + } + + const startAnimationSequence = () => { + // Phase 1: STARTING (initial state) + setPhase(AnimationPhase.STARTING) + addTimeoutHelper(() => { + // Start first message with selection + selectFrameworkServiceServer(() => { + processNextMessage(0) + }) + }, 1000) + } + + startAnimationSequence() + + return () => { + clearTimeouts() + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) const getOpacity = ( index: number, @@ -146,7 +436,8 @@ export function AILibraryHero({}: AILibraryHeroProps) { // Active path: selected framework -> client -> ai -> selected server // Only return off-white if we're in a highlighting phase AND this is the active path if (isFrameworkSelected && isServerSelected) { - return HIGHLIGHT_COLOR + // Off-white color when active + return isDark ? 'rgba(255, 255, 240, 0.95)' : 'rgba(255, 255, 240, 0.95)' } // Not the active path, return original color @@ -180,18 +471,6 @@ export function AILibraryHero({}: AILibraryHeroProps) {