From cb0771b43ab0ee51b28e0114c2168f89112da918 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 20 Jun 2026 18:19:53 +0000 Subject: [PATCH] feat(worker): fix broken import, harden + test + CI-gate the registry API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wave 1 of the production-grade roadmap: make the only running software (the Cloudflare Worker) actually load, and surround it with hardening, tests and CI. Worker (CC-A / CC-B): - Fix dead import: index.js imported ./verisimdb.js but the file is verisim.js, so the Worker never loaded. Now imports ./verisim.js. - Add top-level try/catch (controlled 500), input validation (clade whitelist, NaN/oversized pagination clamps, safe URI decode, bounded query length), security headers (CSP/nosniff/HSTS/frame-deny), structured JSON logging with request ids, optional native rate limiting (fails open), and a /v1/ready readiness probe (reports "degraded" on KV fallback). - Add scheduled() cron handler + refreshFromSource() to re-seed from the canonical snapshot. - Split helpers into http/log/validate/ratelimit modules. Toolchain + tests (CC-A / CC-F): - Add worker/package.json with Vitest, ESLint (flat) and Prettier; configs and package-lock for reproducible `npm ci`. - 30 tests: routing, validation, headers, pagination, search, 405/404/503/500 paths, KV-fallback queries, a fuzz sweep (no uncontrolled 5xx), and a contract test enforcing the 12-clade invariant + snapshot count consistency. Data fix (Phase 0 reconcile): - Regenerate worker/data/index.json: it claimed total_repos=202 while carrying 203 repos, and game-server-admin (ix) was missing from clade membership. Now internally consistent (203 / 203 / member-sum 203). CI/CD (CC-E): - Add worker-ci.yml (lint, format, test, wrangler dry-run) and worker-deploy.yml (staging on main; production via dispatch; skips cleanly until CLOUDFLARE_API_TOKEN is set). - Fix malformed JSON quoting in boj-build.yml curl trigger. Hygiene: - Fix /var$REPOS_DIR path bug in sync/deploy-clade-a2ml.sh and parse-repos.sh (now derive paths from script location; REPOS_DIR overridable). - Add .well-known/groove/manifest.json (service discovery). - wrangler.toml: VERISIMDB_URL/DATA_SOURCE_URL vars, observability, hourly cron, rate-limiter binding, staging environment. - Stop tracking local .wrangler/ dev state. - STATE.a2ml: honest status (Phase 3 → 60%, external blockers recorded). Verified locally: eslint clean, prettier clean, 30/30 tests pass, and both the top-level and staging configs pass `wrangler deploy --dry-run`. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01UCnxjXkN6uDj9YSANuGEgR --- .github/workflows/boj-build.yml | 2 +- .github/workflows/worker-ci.yml | 53 + .github/workflows/worker-deploy.yml | 76 + .machine_readable/6a2/STATE.a2ml | 16 +- .well-known/groove/manifest.json | 31 + sync/deploy-clade-a2ml.sh | 16 +- sync/parse-repos.sh | 4 +- worker/.gitignore | 7 + worker/.prettierignore | 5 + worker/.prettierrc.json | 5 + worker/.wrangler/cache/wrangler-account.json | 0 ...4a0929a736ef843b9a687ee7ad0000019cf71de97a | 2773 ------------- ...55d6ec1b194b1752354760cca8df9171e72.sqlite | Bin 4096 -> 0 bytes ...ec1b194b1752354760cca8df9171e72.sqlite-shm | Bin 32768 -> 0 bytes ...ec1b194b1752354760cca8df9171e72.sqlite-wal | Bin 28872 -> 0 bytes worker/data/index.json | 208 +- worker/eslint.config.js | 23 + worker/package-lock.json | 3611 +++++++++++++++++ worker/package.json | 27 + worker/src/http.js | 69 + worker/src/index.js | 493 +-- worker/src/log.js | 32 + worker/src/ratelimit.js | 29 + worker/src/validate.js | 79 + worker/src/verisim.js | 329 +- worker/test/data.test.js | 58 + worker/test/worker.test.js | 267 ++ worker/vitest.config.js | 9 + worker/wrangler.toml | 46 + 29 files changed, 5004 insertions(+), 3264 deletions(-) create mode 100644 .github/workflows/worker-ci.yml create mode 100644 .github/workflows/worker-deploy.yml create mode 100644 .well-known/groove/manifest.json create mode 100644 worker/.gitignore create mode 100644 worker/.prettierignore create mode 100644 worker/.prettierrc.json delete mode 100644 worker/.wrangler/cache/wrangler-account.json delete mode 100644 worker/.wrangler/state/v3/kv/e34a9970a5684c3fb8bc2f1fa5a6ca77/blobs/d67d5fa364c193566d960a842fdcb7cbe982934a0929a736ef843b9a687ee7ad0000019cf71de97a delete mode 100644 worker/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/249e5f66be2e7bbeb362e83e0af0b55d6ec1b194b1752354760cca8df9171e72.sqlite delete mode 100644 worker/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/249e5f66be2e7bbeb362e83e0af0b55d6ec1b194b1752354760cca8df9171e72.sqlite-shm delete mode 100644 worker/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/249e5f66be2e7bbeb362e83e0af0b55d6ec1b194b1752354760cca8df9171e72.sqlite-wal create mode 100644 worker/eslint.config.js create mode 100644 worker/package-lock.json create mode 100644 worker/package.json create mode 100644 worker/src/http.js create mode 100644 worker/src/log.js create mode 100644 worker/src/ratelimit.js create mode 100644 worker/src/validate.js create mode 100644 worker/test/data.test.js create mode 100644 worker/test/worker.test.js create mode 100644 worker/vitest.config.js diff --git a/.github/workflows/boj-build.yml b/.github/workflows/boj-build.yml index 2d3ca0d..1cfc569 100644 --- a/.github/workflows/boj-build.yml +++ b/.github/workflows/boj-build.yml @@ -13,7 +13,7 @@ jobs: - name: Trigger BoJ Server (Casket/ssg-mcp) run: | # Send a secure trigger to boj-server to build this repository - curl -X POST "http://boj-server.local:7700/cartridges/ssg-mcp/invoke" -H "Content-Type: application/json" -d "{\"repo\": \"${{ github.repository }}\", \"branch\": \"${{ github.ref_name }}\", \"engine\": \"casket\\"}"} + curl -X POST "http://boj-server.local:7700/cartridges/ssg-mcp/invoke" -H "Content-Type: application/json" -d "{\"repo\": \"${{ github.repository }}\", \"branch\": \"${{ github.ref_name }}\", \"engine\": \"casket\"}" continue-on-error: true permissions: contents: read diff --git a/.github/workflows/worker-ci.yml b/.github/workflows/worker-ci.yml new file mode 100644 index 0000000..384e41a --- /dev/null +++ b/.github/workflows/worker-ci.yml @@ -0,0 +1,53 @@ +# SPDX-License-Identifier: MPL-2.0 +# Worker CI — lint, format, test and bundle the Cloudflare Worker. +# This is the gate that actually exercises the deliverable (the read API). +name: Worker CI + +on: + pull_request: + branches: ['**'] + paths: + - 'worker/**' + - '.github/workflows/worker-ci.yml' + push: + branches: [main, master] + paths: + - 'worker/**' + - '.github/workflows/worker-ci.yml' + +permissions: + contents: read + +defaults: + run: + working-directory: worker + +jobs: + build-test: + name: Lint, format, test, bundle + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Setup Node.js + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + with: + node-version: '22' + cache: npm + cache-dependency-path: worker/package-lock.json + + - name: Install dependencies + run: npm ci + + - name: Lint (eslint) + run: npm run lint + + - name: Format check (prettier) + run: npm run format:check + + - name: Unit + contract tests (vitest) + run: npm test + + - name: Bundle check (wrangler dry-run) + run: npx wrangler deploy --dry-run diff --git a/.github/workflows/worker-deploy.yml b/.github/workflows/worker-deploy.yml new file mode 100644 index 0000000..30b707d --- /dev/null +++ b/.github/workflows/worker-deploy.yml @@ -0,0 +1,76 @@ +# SPDX-License-Identifier: MPL-2.0 +# Worker Deploy — push the Cloudflare Worker to staging on merge to main, and +# to production via manual dispatch (gated by the "production" GitHub Environment). +# +# Required repository secret: CLOUDFLARE_API_TOKEN (Workers Scripts:Edit). +# Optional: CLOUDFLARE_ACCOUNT_ID (if the token spans multiple accounts). +# Until CLOUDFLARE_API_TOKEN is set, the deploy step is skipped (workflow stays green). +name: Worker Deploy + +on: + push: + branches: [main, master] + paths: + - 'worker/**' + - '.github/workflows/worker-deploy.yml' + workflow_dispatch: + inputs: + environment: + description: Target environment + type: choice + options: + - staging + - production + default: staging + +permissions: + contents: read + +defaults: + run: + working-directory: worker + +jobs: + deploy: + name: Deploy + runs-on: ubuntu-latest + # Manual dispatch picks the env (production requires approval if the + # "production" GitHub Environment has protection rules); push → staging. + environment: ${{ github.event_name == 'workflow_dispatch' && inputs.environment || 'staging' }} + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Setup Node.js + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + with: + node-version: '22' + cache: npm + cache-dependency-path: worker/package-lock.json + + - name: Install dependencies + run: npm ci + + - name: Test before deploy + run: npm test + + - name: Check deploy credentials + id: gate + run: echo "have_token=${{ secrets.CLOUDFLARE_API_TOKEN != '' }}" >> "$GITHUB_OUTPUT" + + - name: Deploy (wrangler) + if: steps.gate.outputs.have_token == 'true' + env: + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + TARGET_ENV: ${{ github.event_name == 'workflow_dispatch' && inputs.environment || 'staging' }} + run: | + if [ "$TARGET_ENV" = "production" ]; then + npx wrangler deploy + else + npx wrangler deploy --env staging + fi + + - name: Skipped (no credentials) + if: steps.gate.outputs.have_token != 'true' + run: echo "::notice::CLOUDFLARE_API_TOKEN not set — skipping deploy. Add the secret to enable automated deploys." diff --git a/.machine_readable/6a2/STATE.a2ml b/.machine_readable/6a2/STATE.a2ml index 636880b..4f64da5 100644 --- a/.machine_readable/6a2/STATE.a2ml +++ b/.machine_readable/6a2/STATE.a2ml @@ -6,13 +6,13 @@ [metadata] project = "gv-clade-index" version = "0.1.0" -last-updated = "2026-03-16" +last-updated = "2026-06-20" status = "active" [project-context] name = "gv-clade-index" purpose = "VeriSimDB-backed clade taxonomy and central registry for the hyperpolymath ecosystem (200+ repos)" -completion-percentage = 10 +completion-percentage = 18 [position] phase = "implementation" @@ -23,7 +23,7 @@ milestones = [ { name = "Phase 0: Clade taxonomy, repo seed, VQL schema, queries", completion = 100 }, { name = "Phase 1: Deploy CLADE.a2ml to all 200 repos", completion = 0 }, { name = "Phase 2: VeriSimDB instance on VPS, ingest data", completion = 0 }, - { name = "Phase 3: Cloudflare Worker API endpoints", completion = 0 }, + { name = "Phase 3: Cloudflare Worker API endpoints", completion = 60 }, { name = "Phase 4: ReScript/WASM portal on github.io", completion = 0 }, { name = "Phase 5: LLM query endpoint", completion = 0 }, { name = "Phase 6: Bot write endpoints + TODO octads", completion = 0 }, @@ -32,11 +32,15 @@ milestones = [ ] [blockers-and-issues] -# None at Phase 0 +blockers = [ + "Phase 3 deploy: CLOUDFLARE_API_TOKEN repo secret required to enable automated Worker deploys", + "Phase 3 live data + Phases 5-8: VeriSimDB instance (Phase 2) not yet stood up on a VPS", +] [critical-next-actions] actions = [ - "Deploy CLADE.a2ml to all 200 repos (batch script)", - "Stand up VeriSimDB instance on Verpex VPS", + "Add CLOUDFLARE_API_TOKEN secret to enable Worker auto-deploy to staging/production", + "Stand up VeriSimDB instance on Verpex VPS (Phase 2) so the Worker reads live data", + "Deploy CLADE.a2ml to all 200 repos (sync/deploy-clade-a2ml.sh)", "Write sync/ingest tooling in Rust", ] diff --git a/.well-known/groove/manifest.json b/.well-known/groove/manifest.json new file mode 100644 index 0000000..b1f38b3 --- /dev/null +++ b/.well-known/groove/manifest.json @@ -0,0 +1,31 @@ +{ + "groove_version": "1.0.0", + "service_id": "gv-clade-index", + "name": "Hyperpolymath Clade Registry API", + "description": "Read-only API and central registry — the map of the hyperpolymath ecosystem (12 clades, 200+ repos).", + "clade": "gv", + "repository": "https://github.com/hyperpolymath/gv-clade-index", + "license": "MPL-2.0", + "maintainer": "hyperpolymath", + "protocol": "https", + "api": { + "base_path": "/v1", + "health": "/v1/health", + "readiness": "/v1/ready", + "endpoints": [ + { "method": "GET", "path": "/v1/dashboard", "description": "Ecosystem overview with clade stats" }, + { "method": "GET", "path": "/v1/clades", "description": "List all 12 clades" }, + { "method": "GET", "path": "/v1/clade/:code", "description": "Single clade with member repos" }, + { "method": "GET", "path": "/v1/repo/:name", "description": "Single repo detail" }, + { "method": "GET", "path": "/v1/repos", "description": "All repos (params: clade, page, limit)" }, + { "method": "GET", "path": "/v1/search", "description": "Full-text search across repos" }, + { "method": "GET", "path": "/v1/llm", "description": "Structured output for LLM consumption" }, + { "method": "GET", "path": "/v1/query/language", "description": "Query repos by language keyword" }, + { "method": "GET", "path": "/v1/query/tag", "description": "Query repos by tag" } + ] + }, + "auth": { + "public_read": true, + "tiers": ["public-read", "llm-key", "bot-jwt", "contributor-oauth"] + } +} diff --git a/sync/deploy-clade-a2ml.sh b/sync/deploy-clade-a2ml.sh index 5779d28..8da43b5 100755 --- a/sync/deploy-clade-a2ml.sh +++ b/sync/deploy-clade-a2ml.sh @@ -9,15 +9,23 @@ set -uo pipefail -REPOS_DIR="/var$REPOS_DIR" +# REPOS_DIR is the directory that contains all hyperpolymath repo clones, +# including gv-clade-index itself. Defaults to the parent of this checkout +# (repos checked out as siblings); override by exporting REPOS_DIR. +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPOS_DIR="${REPOS_DIR:-$(cd "$SCRIPT_DIR/../.." && pwd)}" SEED_FILE="$REPOS_DIR/gv-clade-index/verisim/seed/repos.a2ml" DRY_RUN="${1:-}" + +if [[ ! -d "$REPOS_DIR" ]]; then + echo "ERROR: REPOS_DIR '$REPOS_DIR' is not a directory." >&2 + echo "Export REPOS_DIR to the folder containing your repo clones." >&2 + exit 1 +fi COMMIT_MSG="feat: add CLADE.a2ml — clade taxonomy declaration Part of gv-clade-index Phase 1: every repo declares its identity, -primary clade, and forge mappings for the VeriSimDB central registry. - -Co-Authored-By: Claude Opus 4.6 (1M context) " +primary clade, and forge mappings for the VeriSimDB central registry." SUCCESS=0 SKIPPED=0 diff --git a/sync/parse-repos.sh b/sync/parse-repos.sh index 1eef88c..d2588e5 100755 --- a/sync/parse-repos.sh +++ b/sync/parse-repos.sh @@ -2,7 +2,9 @@ # SPDX-License-Identifier: MPL-2.0 # Parse repos.a2ml and emit TSV: name\tprimary\tsecondary\tlineage\tparent\tdescription -SEED_FILE="${1:-/var$REPOS_DIR/gv-clade-index/verisim/seed/repos.a2ml}" +# Default to this repo's seed file (script lives in sync/, seed in verisim/seed/). +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SEED_FILE="${1:-$SCRIPT_DIR/../verisim/seed/repos.a2ml}" awk ' BEGIN { FS="=" } diff --git a/worker/.gitignore b/worker/.gitignore new file mode 100644 index 0000000..bd0641c --- /dev/null +++ b/worker/.gitignore @@ -0,0 +1,7 @@ +# Node toolchain (dev-only; not part of the deployed Worker) +node_modules/ +# Wrangler local dev / Miniflare state +.wrangler/ +# Test coverage +coverage/ +*.log diff --git a/worker/.prettierignore b/worker/.prettierignore new file mode 100644 index 0000000..0ace565 --- /dev/null +++ b/worker/.prettierignore @@ -0,0 +1,5 @@ +node_modules/ +.wrangler/ +coverage/ +data/ +package-lock.json diff --git a/worker/.prettierrc.json b/worker/.prettierrc.json new file mode 100644 index 0000000..ebb4af5 --- /dev/null +++ b/worker/.prettierrc.json @@ -0,0 +1,5 @@ +{ + "singleQuote": true, + "printWidth": 100, + "trailingComma": "all" +} diff --git a/worker/.wrangler/cache/wrangler-account.json b/worker/.wrangler/cache/wrangler-account.json deleted file mode 100644 index e69de29..0000000 diff --git a/worker/.wrangler/state/v3/kv/e34a9970a5684c3fb8bc2f1fa5a6ca77/blobs/d67d5fa364c193566d960a842fdcb7cbe982934a0929a736ef843b9a687ee7ad0000019cf71de97a b/worker/.wrangler/state/v3/kv/e34a9970a5684c3fb8bc2f1fa5a6ca77/blobs/d67d5fa364c193566d960a842fdcb7cbe982934a0929a736ef843b9a687ee7ad0000019cf71de97a deleted file mode 100644 index b4b2874..0000000 --- a/worker/.wrangler/state/v3/kv/e34a9970a5684c3fb8bc2f1fa5a6ca77/blobs/d67d5fa364c193566d960a842fdcb7cbe982934a0929a736ef843b9a687ee7ad0000019cf71de97a +++ /dev/null @@ -1,2773 +0,0 @@ -{ - "total_repos": 202, - "total_clades": 12, - "generated": "2026-03-16T14:45:43Z", - "clades": [ - { - "code": "fv", - "name": "Formal Verification & Proofs", - "description": "Provable correctness, reversibility, dependent types, theorem proving", - "colour": "#7c3aed", - "icon": "shield-check", - "keywords": [ - "idris2", - "lean4", - "coq", - "agda", - "reversible", - "proven", - "verified", - "proofs" - ], - "member_count": 15, - "members": [ - "proven", - "proven-servers", - "januskey", - "valence-shell", - "ochrance", - "ochrance-framework", - "echidna", - "polyglot-formalisms-elixir", - "polyglot-formalisms-gleam", - "proof-of-work", - "HOL", - "PolyglotFormalisms.jl", - "ProvenCrypto.jl", - "Skein.jl", - "SMTLib.jl" - ] - }, - { - "code": "nl", - "name": "Nextgen Languages", - "description": "Programming language implementations, compilers, runtimes", - "colour": "#f59e0b", - "icon": "code", - "keywords": [ - "compiler", - "parser", - "runtime", - "grammar", - "ast", - "language" - ], - "member_count": 8, - "members": [ - "nextgen-languages", - "ephapax", - "anvomidav", - "wokelang", - "typell", - "panll", - "metadata-grammar", - "modshells" - ] - }, - { - "code": "rm", - "name": "Repo Management & Tooling", - "description": "Repository scaffolding, graph analysis, bot orchestration, templates", - "colour": "#06b6d4", - "icon": "git-branch", - "keywords": [ - "repo", - "scaffold", - "template", - "bot", - "graph", - "git", - "rsr" - ], - "member_count": 12, - "members": [ - "reposystem", - "grim-repo", - "rsr-template-repo", - "gitbot-fleet", - "robot-vacuum-cleaner", - "polysafe-gitfixer", - "tree-navigator", - "empty-linter", - "mtpc-template-repo", - "v3-templater", - "megadog", - "robodog-ecm" - ] - }, - { - "code": "gv", - "name": "Governance & Standards", - "description": "Licensing, compliance, architectural boundaries, policy enforcement", - "colour": "#10b981", - "icon": "scale", - "keywords": [ - "license", - "policy", - "compliance", - "standard", - "governance", - "seam" - ], - "member_count": 15, - "members": [ - "gv-clade-index", - "palimpsest-license", - "palimpsest-plasma", - "standards", - "seamstress", - "ensaid-spec", - "explicit-trust-plane", - "manifesto", - "hyperpolymath-sovereign-registry", - "pandoc-a2ml", - "hyperpolymath.github.io", - "SoftwareSovereign.jl", - "accessibility-everywhere", - "hyperpolymath", - "supernorma" - ] - }, - { - "code": "db", - "name": "Databases", - "description": "Database engines, query languages, data storage systems", - "colour": "#ec4899", - "icon": "database", - "keywords": [ - "database", - "query", - "storage", - "vql", - "drift", - "modality" - ], - "member_count": 4, - "members": [ - "nextgen-databases", - "verisimdb-data", - "statistease", - "Lithoglyph.jl" - ] - }, - { - "code": "ap", - "name": "Applications", - "description": "End-user applications, web apps, desktop apps, services", - "colour": "#3b82f6", - "icon": "layout", - "keywords": [ - "app", - "web", - "desktop", - "service", - "ui", - "frontend" - ], - "member_count": 28, - "members": [ - "nexia-list", - "boj-server", - "boj-server-gemini", - "burble", - "branch-newspaper", - "civic-connect", - "lcb-website", - "nafa-app", - "docmatrix", - "docudactyl", - "dictask", - "blocky-writer", - "raze-tui", - "double-track-browser", - "universal-chat-extractor", - "voyage-enterprise-decision-system", - "feedback-o-tron", - "excel-economic-numbers-tool", - "dotmatrix-fileprinter", - "live-files", - "flat-mate", - "preference-injector", - "presswerk", - "snapcreate", - "misinformation-defence-platform", - "InvestigativeJournalist.jl", - "anamnesis", - "refugia" - ] - }, - { - "code": "ix", - "name": "Infrastructure & Cloud", - "description": "Cloud management, containers, deployment, system administration", - "colour": "#6366f1", - "icon": "cloud", - "keywords": [ - "cloud", - "container", - "deploy", - "infra", - "ops", - "dns", - "k8s" - ], - "member_count": 24, - "members": [ - "ambientops", - "cloudflare-dns-terraform", - "cloudguard-cli", - "cloudguard-server", - "stapeln", - "infrastructure-automation", - "twingate-helm-deploy", - "zerotier-k8s-link", - "cloud-sync-tuner", - "sdp-hkdf-deployment", - "hesiod-dns-map", - "ipfs-overlay", - "ipv6-tools", - "ssg-collection", - "scripts", - "HardwareResilience.jl", - "boinc-boinc", - "cccp", - "heterogenous-mobile-computing", - "hybrid-automation-router", - "kaldor-iiot", - "laminar", - "laniakea", - "ubicity" - ] - }, - { - "code": "dx", - "name": "Developer Ecosystem", - "description": "Developer tools, package managers, editor integrations, bindings", - "colour": "#8b5cf6", - "icon": "wrench", - "keywords": [ - "tool", - "plugin", - "editor", - "binding", - "sdk", - "ecosystem" - ], - "member_count": 61, - "members": [ - "developer-ecosystem", - "asdf-tool-plugins", - "nickel-augmentation", - "rescript", - "rescript-dom-mounter", - "rescript-tea", - "rescript-vite", - "bunsenite", - "mcp-servers", - "elixir-mcp-server", - "universal-language-server-plugin", - "universal-extension-format", - "universal-project-manager", - "ffmpeg-ffi", - "filesoup", - "formatrix-docs", - "thunderbird-template-reloaded", - "zotero-tools", - "wordpress-tools", - "odds-and-sods-package-manager", - "patallm-gallery", - "im-docs", - "polyglot-i18n", - "vexometer", - "AcceleratorGate.jl", - "Axiology.jl", - "Axiom.jl", - "BowtieRisk.jl", - "Causals.jl", - "Cladistics.jl", - "Cliodynamics.jl", - "Cliometrics.jl", - "Exnovation.jl", - "Hyperpolymath.jl", - "HyperpolymathRegistry", - "JuliaKids.jl", - "JuliaPackage-Reuse-Audit.jl", - "KnotTheory.jl", - "LowLevel.jl", - "MacroPower.jl", - "MinixSDK.jl", - "PostDisciplinary.jl", - "PRComms.jl", - "QuantumCircuit.jl", - "ShellIntegration.jl", - "SiliconCore.jl", - "TradeUnionist.jl", - "ViableSystems.jl", - "ZeroProb.jl", - "academic-workflow-suite", - "aerie", - "amethe", - "aspasia", - "bofig", - "flatracoon", - "kea", - "polystack", - "rpa-elysium", - "social-media-tools", - "tma-mark2", - "zerostep" - ] - }, - { - "code": "pt", - "name": "Protocols & Interop", - "description": "Internet standards, protocol implementations, interoperability", - "colour": "#14b8a6", - "icon": "globe", - "keywords": [ - "protocol", - "http", - "rfc", - "ietf", - "interop", - "consent", - "standard" - ], - "member_count": 12, - "members": [ - "intsoc-transactor", - "maa-framework", - "http-capability-gateway", - "protocol-squisher", - "squisher-corpus", - "resource-record-fluctuator", - "rrecord-verity", - "no-nonsense-nntps", - "unified-dataset-vocab", - "v-graphql", - "v-grpc", - "v-rest" - ] - }, - { - "code": "ax", - "name": "AI & Neurosymbolic", - "description": "Machine learning, neural proof synthesis, AI governance", - "colour": "#f43f5e", - "icon": "brain", - "keywords": [ - "ai", - "neural", - "neurosymbolic", - "llm", - "proof-synthesis" - ], - "member_count": 6, - "members": [ - "neural-foundations", - "hypatia", - "conative-gating", - "conflow", - "neurophone", - "i-human" - ] - }, - { - "code": "gm", - "name": "Games & Interactive", - "description": "Game engines, interactive experiences, gamified tools", - "colour": "#eab308", - "icon": "gamepad", - "keywords": [ - "game", - "interactive", - "player", - "level", - "escape" - ], - "member_count": 6, - "members": [ - "idaptik", - "idaptik-rescript13-staging", - "games & trivia", - "checky-monkey", - "chimichanga", - "HackenbushGames.jl" - ] - }, - { - "code": "sc", - "name": "Security", - "description": "Security scanning, vulnerability management, access control", - "colour": "#ef4444", - "icon": "lock", - "keywords": [ - "security", - "scan", - "vulnerability", - "auth", - "vault", - "sentinel" - ], - "member_count": 11, - "members": [ - "panic-attacker", - "svalinn", - "session-sentinel", - "reasonably-good-token-vault", - "sanctify-php", - "php-aegis", - "pimcore-fortress", - "project-wharf", - "fireflag", - "FirmwareAudit.jl", - "defiant" - ] - } - ], - "by_name": { - "proven": { - "name": "proven", - "uuid": "ffa8e1f5-5c79-5515-8043-e10eb21d5f4f", - "clade": "fv", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Formally verified safety library \u2014 Idris2 dependent types + Zig FFI + 120+ bindings", - "prefixed": "fv-proven", - "github": "hyperpolymath/proven" - }, - "proven-servers": { - "name": "proven-servers", - "uuid": "8d19c5fb-15a7-5962-bf93-0c7c2ca2bc6d", - "clade": "fv", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "MCP servers exposing proven library operations", - "prefixed": "fv-proven-servers", - "github": "hyperpolymath/proven-servers" - }, - "januskey": { - "name": "januskey", - "uuid": "e216170e-ff47-5a5c-bbdd-15e61c8190c8", - "clade": "fv", - "secondary": [ - "sc" - ], - "lineage": "standalone", - "parent": "", - "description": "Provably reversible file operations via Maximal Principle Reduction", - "prefixed": "fv-januskey", - "github": "hyperpolymath/januskey" - }, - "valence-shell": { - "name": "valence-shell", - "uuid": "908167d5-10d7-59ce-a11f-50dac264b765", - "clade": "fv", - "secondary": [ - "ix" - ], - "lineage": "standalone", - "parent": "", - "description": "Formally verified shell \u2014 250+ theorems across 6 proof systems", - "prefixed": "fv-valence-shell", - "github": "hyperpolymath/valence-shell" - }, - "ochrance": { - "name": "ochrance", - "uuid": "389cf52e-ffff-5005-8e54-22e9d9c788ca", - "clade": "fv", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Neurosymbolic filesystem verification \u2014 Idris2 dependent types", - "prefixed": "fv-ochrance", - "github": "hyperpolymath/ochrance" - }, - "ochrance-framework": { - "name": "ochrance-framework", - "uuid": "4aa8d27d-f778-556c-9f60-672169d5808b", - "clade": "fv", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Modular verification framework for subsystem integrity \u2014 Idris2", - "prefixed": "fv-ochrance-framework", - "github": "hyperpolymath/ochrance-framework" - }, - "echidna": { - "name": "echidna", - "uuid": "6bab4e6b-e028-5e31-a5d8-d46c9359669b", - "clade": "fv", - "secondary": [ - "ax" - ], - "lineage": "standalone", - "parent": "", - "description": "Neurosymbolic theorem proving \u2014 neural proof synthesis", - "prefixed": "fv-echidna", - "github": "hyperpolymath/echidna" - }, - "polyglot-formalisms-elixir": { - "name": "polyglot-formalisms-elixir", - "uuid": "ef3e3f44-fdd5-58f6-b55c-5b8940a8f7ea", - "clade": "fv", - "secondary": [ - "dx" - ], - "lineage": "standalone", - "parent": "", - "description": "Formal methods bindings for Elixir", - "prefixed": "fv-polyglot-formalisms-elixir", - "github": "hyperpolymath/polyglot-formalisms-elixir" - }, - "polyglot-formalisms-gleam": { - "name": "polyglot-formalisms-gleam", - "uuid": "2aa7d364-2062-5ee5-8eec-211c2321a286", - "clade": "fv", - "secondary": [ - "dx" - ], - "lineage": "standalone", - "parent": "", - "description": "Formal methods bindings for Gleam", - "prefixed": "fv-polyglot-formalisms-gleam", - "github": "hyperpolymath/polyglot-formalisms-gleam" - }, - "proof-of-work": { - "name": "proof-of-work", - "uuid": "8512bde0-7023-5704-a7d7-592e5a222672", - "clade": "fv", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Proof-of-work verification tooling", - "prefixed": "fv-proof-of-work", - "github": "hyperpolymath/proof-of-work" - }, - "HOL": { - "name": "HOL", - "uuid": "4af60d78-3492-5e51-8ad4-03fdbc15bdbb", - "clade": "fv", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Higher-Order Logic proof assistant integration", - "prefixed": "fv-HOL", - "github": "hyperpolymath/HOL" - }, - "nextgen-languages": { - "name": "nextgen-languages", - "uuid": "0b39d160-9cf6-52ae-9cbf-317580c5b5b1", - "clade": "nl", - "secondary": [], - "lineage": "monorepo", - "parent": "", - "description": "Monorepo \u2014 anvomidav, ephapax, wokelang, eclexia, affinescript, betlang, etc.", - "prefixed": "nl-nextgen-languages", - "github": "hyperpolymath/nextgen-languages" - }, - "ephapax": { - "name": "ephapax", - "uuid": "5fdbc410-eacd-54b6-b4e3-b352b4cb4868", - "clade": "nl", - "secondary": [ - "fv" - ], - "lineage": "standalone", - "parent": "", - "description": "Linear type language with uniqueness types", - "prefixed": "nl-ephapax", - "github": "hyperpolymath/ephapax" - }, - "anvomidav": { - "name": "anvomidav", - "uuid": "7c159f0f-c836-5fad-9a40-c9105a75bab5", - "clade": "nl", - "secondary": [], - "lineage": "monorepo-child", - "parent": "nextgen-languages", - "description": "Nextgen language \u2014 anvomidav", - "prefixed": "nl-anvomidav", - "github": "hyperpolymath/anvomidav" - }, - "wokelang": { - "name": "wokelang", - "uuid": "e460af5f-1cfb-58bf-9c5a-70bf458ea2af", - "clade": "nl", - "secondary": [], - "lineage": "monorepo-child", - "parent": "nextgen-languages", - "description": "Social-justice-aware programming language", - "prefixed": "nl-wokelang", - "github": "hyperpolymath/wokelang" - }, - "typell": { - "name": "typell", - "uuid": "e54e1b0d-2f85-5d05-9b12-e01d726bfd65", - "clade": "nl", - "secondary": [ - "fv" - ], - "lineage": "standalone", - "parent": "", - "description": "Type-level programming language \u2014 PanLL integration", - "prefixed": "nl-typell", - "github": "hyperpolymath/typell" - }, - "panll": { - "name": "panll", - "uuid": "6c8a8b70-77a6-598c-980d-46e3713d2a1a", - "clade": "nl", - "secondary": [ - "ap" - ], - "lineage": "standalone", - "parent": "", - "description": "Panel-based UI framework \u2014 TEA architecture, workspace layer", - "prefixed": "nl-panll", - "github": "hyperpolymath/panll" - }, - "metadata-grammar": { - "name": "metadata-grammar", - "uuid": "e7ba1ab4-3f37-502b-87aa-0d538d298932", - "clade": "nl", - "secondary": [ - "gv" - ], - "lineage": "standalone", - "parent": "", - "description": "Grammar definitions for metadata formats", - "prefixed": "nl-metadata-grammar", - "github": "hyperpolymath/metadata-grammar" - }, - "modshells": { - "name": "modshells", - "uuid": "15105645-61bc-559b-9e88-c11916719ac0", - "clade": "nl", - "secondary": [ - "ix" - ], - "lineage": "standalone", - "parent": "", - "description": "Modular shell framework", - "prefixed": "nl-modshells", - "github": "hyperpolymath/modshells" - }, - "reposystem": { - "name": "reposystem", - "uuid": "e96fb1bc-2796-5a0b-b1ea-c6d0a3a6fea1", - "clade": "rm", - "secondary": [], - "lineage": "monorepo", - "parent": "", - "description": "Monorepo \u2014 graph engine for repository ecosystem management", - "prefixed": "rm-reposystem", - "github": "hyperpolymath/reposystem" - }, - "grim-repo": { - "name": "grim-repo", - "uuid": "777666bc-1913-5507-89e9-b829cf4a7e99", - "clade": "rm", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Repo standards toolkit \u2014 GrimRepo Scripts (ReScript)", - "prefixed": "rm-grim-repo", - "github": "hyperpolymath/grim-repo" - }, - "rsr-template-repo": { - "name": "rsr-template-repo", - "uuid": "a5ea1382-a34c-5334-8a46-a2ebe904c810", - "clade": "rm", - "secondary": [ - "gv" - ], - "lineage": "standalone", - "parent": "", - "description": "RSR template \u2014 scaffold for new repos", - "prefixed": "rm-rsr-template-repo", - "github": "hyperpolymath/rsr-template-repo" - }, - "gitbot-fleet": { - "name": "gitbot-fleet", - "uuid": "f8cdb015-c230-50f2-b09c-f9e8d37646dd", - "clade": "rm", - "secondary": [ - "ax" - ], - "lineage": "standalone", - "parent": "", - "description": "Bot orchestration \u2014 rhodibot, echidnabot, sustainabot, glambot, seambot, finishbot", - "prefixed": "rm-gitbot-fleet", - "github": "hyperpolymath/gitbot-fleet" - }, - "robot-vacuum-cleaner": { - "name": "robot-vacuum-cleaner", - "uuid": "014b4ddb-41b2-5384-ba28-f01e970864ee", - "clade": "rm", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Automated repo cleanup tool", - "prefixed": "rm-robot-vacuum-cleaner", - "github": "hyperpolymath/robot-vacuum-cleaner" - }, - "polysafe-gitfixer": { - "name": "polysafe-gitfixer", - "uuid": "e16445ab-6938-5931-aff8-0cd023086843", - "clade": "rm", - "secondary": [ - "sc" - ], - "lineage": "standalone", - "parent": "", - "description": "Safe git fix operations across repos", - "prefixed": "rm-polysafe-gitfixer", - "github": "hyperpolymath/polysafe-gitfixer" - }, - "tree-navigator": { - "name": "tree-navigator", - "uuid": "c798e1bf-9ea8-5ceb-8f80-ae3a1b5cd761", - "clade": "rm", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Repository tree navigation tool", - "prefixed": "rm-tree-navigator", - "github": "hyperpolymath/tree-navigator" - }, - "empty-linter": { - "name": "empty-linter", - "uuid": "40ad8b7a-db85-5a43-9ac3-7b2cf303d7a4", - "clade": "rm", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Lint for empty or placeholder files", - "prefixed": "rm-empty-linter", - "github": "hyperpolymath/empty-linter" - }, - "mtpc-template-repo": { - "name": "mtpc-template-repo", - "uuid": "a7feab15-3c46-5173-b3b8-f296409bd738", - "clade": "rm", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "MTPC template repository", - "prefixed": "rm-mtpc-template-repo", - "github": "hyperpolymath/mtpc-template-repo" - }, - "v3-templater": { - "name": "v3-templater", - "uuid": "e1db84dc-2090-544d-ab6c-2396096bddf9", - "clade": "rm", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "V3 template generation tool", - "prefixed": "rm-v3-templater", - "github": "hyperpolymath/v3-templater" - }, - "gv-clade-index": { - "name": "gv-clade-index", - "uuid": "c88e9ff3-9aac-5de8-b891-19b5de64aedd", - "clade": "gv", - "secondary": [ - "db" - ], - "lineage": "standalone", - "parent": "", - "description": "THIS REPO \u2014 clade taxonomy + VeriSimDB portal registry", - "prefixed": "gv-gv-clade-index", - "github": "hyperpolymath/gv-clade-index" - }, - "palimpsest-license": { - "name": "palimpsest-license", - "uuid": "e254831b-01e0-553a-8372-ea8fa24e9a17", - "clade": "gv", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "PMPL-1.0 license text, exhibits, governance model, Rust tooling", - "prefixed": "gv-palimpsest-license", - "github": "hyperpolymath/palimpsest-license" - }, - "palimpsest-plasma": { - "name": "palimpsest-plasma", - "uuid": "6175bd82-b27e-5e6b-a887-1cf625cb690e", - "clade": "gv", - "secondary": [ - "rm" - ], - "lineage": "standalone", - "parent": "", - "description": "Governance automation engine \u2014 OCaml policy AST", - "prefixed": "gv-palimpsest-plasma", - "github": "hyperpolymath/palimpsest-plasma" - }, - "standards": { - "name": "standards", - "uuid": "d9e987dc-bb7b-51aa-839b-3d8bbfe774c3", - "clade": "gv", - "secondary": [], - "lineage": "monorepo", - "parent": "", - "description": "Monorepo \u2014 axel-protocol, a2ml, rhodium-standard-repositories, etc.", - "prefixed": "gv-standards", - "github": "hyperpolymath/standards" - }, - "seamstress": { - "name": "seamstress", - "uuid": "b7be2c04-99e5-5510-8e4c-9551b3805949", - "clade": "gv", - "secondary": [ - "rm" - ], - "lineage": "standalone", - "parent": "", - "description": "Architectural seams as first-class artifacts", - "prefixed": "gv-seamstress", - "github": "hyperpolymath/seamstress" - }, - "ensaid-spec": { - "name": "ensaid-spec", - "uuid": "052b60ae-8596-538f-833c-3bdd478b1bfb", - "clade": "gv", - "secondary": [ - "pt" - ], - "lineage": "standalone", - "parent": "", - "description": "ENSAID specification", - "prefixed": "gv-ensaid-spec", - "github": "hyperpolymath/ensaid-spec" - }, - "explicit-trust-plane": { - "name": "explicit-trust-plane", - "uuid": "536fcd4c-64d3-5c38-baf4-11c028826d97", - "clade": "gv", - "secondary": [ - "sc" - ], - "lineage": "standalone", - "parent": "", - "description": "Explicit trust plane framework", - "prefixed": "gv-explicit-trust-plane", - "github": "hyperpolymath/explicit-trust-plane" - }, - "manifesto": { - "name": "manifesto", - "uuid": "21c43c63-1190-5e94-a7fa-3b130190ab39", - "clade": "gv", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Project manifesto and principles", - "prefixed": "gv-manifesto", - "github": "hyperpolymath/manifesto" - }, - "hyperpolymath-sovereign-registry": { - "name": "hyperpolymath-sovereign-registry", - "uuid": "06e13b15-6618-55de-a808-62c3300c6729", - "clade": "gv", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Sovereign registry for hyperpolymath ecosystem", - "prefixed": "gv-hyperpolymath-sovereign-registry", - "github": "hyperpolymath/hyperpolymath-sovereign-registry" - }, - "pandoc-a2ml": { - "name": "pandoc-a2ml", - "uuid": "525eba99-adb8-5c61-af1b-90cbb1e83ec5", - "clade": "gv", - "secondary": [ - "dx" - ], - "lineage": "standalone", - "parent": "", - "description": "Pandoc readers/writers for A2ML and K9 formats", - "prefixed": "gv-pandoc-a2ml", - "github": "hyperpolymath/pandoc-a2ml" - }, - "hyperpolymath.github.io": { - "name": "hyperpolymath.github.io", - "uuid": "b6147e77-ec99-5674-b0e2-88639066508e", - "clade": "gv", - "secondary": [ - "ap" - ], - "lineage": "standalone", - "parent": "", - "description": "Public portfolio \u2014 will become ReScript/WASM portal", - "prefixed": "gv-hyperpolymath.github.io", - "github": "hyperpolymath/hyperpolymath.github.io" - }, - "nextgen-databases": { - "name": "nextgen-databases", - "uuid": "8bd9122f-61e7-5829-8755-55b276c0f53f", - "clade": "db", - "secondary": [], - "lineage": "monorepo", - "parent": "", - "description": "Monorepo \u2014 verisimdb, quandledb, lithoglyph", - "prefixed": "db-nextgen-databases", - "github": "hyperpolymath/nextgen-databases" - }, - "verisimdb-data": { - "name": "verisimdb-data", - "uuid": "22772417-fc00-5263-a78a-7567aee04984", - "clade": "db", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "VeriSimDB data repository \u2014 scan results, patterns, recipes", - "prefixed": "db-verisimdb-data", - "github": "hyperpolymath/verisimdb-data" - }, - "statistease": { - "name": "statistease", - "uuid": "a4cd8055-f92e-511b-9c0c-84a8214da79c", - "clade": "db", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Statistical analysis tool", - "prefixed": "db-statistease", - "github": "hyperpolymath/statistease" - }, - "nexia-list": { - "name": "nexia-list", - "uuid": "631b3774-30f7-59d9-b3a5-72b540677f82", - "clade": "ap", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Personal knowledge management \u2014 ReScript TEA + Tauri 2.0", - "prefixed": "ap-nexia-list", - "github": "hyperpolymath/nexia-list" - }, - "boj-server": { - "name": "boj-server", - "uuid": "5f5df93b-789d-5ff6-8a44-9dc6ed90a7b1", - "clade": "ap", - "secondary": [ - "ax" - ], - "lineage": "standalone", - "parent": "", - "description": "BoJ MCP server \u2014 cartridge system, multi-cloud", - "prefixed": "ap-boj-server", - "github": "hyperpolymath/boj-server" - }, - "boj-server-gemini": { - "name": "boj-server-gemini", - "uuid": "b30d2606-a4af-5d68-b9d7-d48e8eea950f", - "clade": "ap", - "secondary": [ - "ax" - ], - "lineage": "standalone", - "parent": "", - "description": "BoJ server Gemini variant", - "prefixed": "ap-boj-server-gemini", - "github": "hyperpolymath/boj-server-gemini" - }, - "burble": { - "name": "burble", - "uuid": "0a37e17d-8ee5-5c30-9daf-571315a88a84", - "clade": "ap", - "secondary": [ - "pt" - ], - "lineage": "standalone", - "parent": "", - "description": "Voice platform \u2014 Elixir control plane, WebRTC media", - "prefixed": "ap-burble", - "github": "hyperpolymath/burble" - }, - "branch-newspaper": { - "name": "branch-newspaper", - "uuid": "889b8a0d-8c43-5828-a4b5-836409ddd4f6", - "clade": "ap", - "secondary": [ - "pt" - ], - "lineage": "standalone", - "parent": "", - "description": "Citizen journalism \u2014 Phoenix LiveView + IPFS", - "prefixed": "ap-branch-newspaper", - "github": "hyperpolymath/branch-newspaper" - }, - "civic-connect": { - "name": "civic-connect", - "uuid": "7c4439ce-bdf6-522f-9096-5312c0650efb", - "clade": "ap", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Civic engagement platform", - "prefixed": "ap-civic-connect", - "github": "hyperpolymath/civic-connect" - }, - "lcb-website": { - "name": "lcb-website", - "uuid": "c576c71b-4b13-53c2-9086-2efb23c2d272", - "clade": "ap", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "LCB union website", - "prefixed": "ap-lcb-website", - "github": "hyperpolymath/lcb-website" - }, - "nafa-app": { - "name": "nafa-app", - "uuid": "16384433-175a-5cb0-ae69-ac079756e0e0", - "clade": "ap", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "NAFA application", - "prefixed": "ap-nafa-app", - "github": "hyperpolymath/nafa-app" - }, - "docmatrix": { - "name": "docmatrix", - "uuid": "d7466904-3d92-5663-a780-9438eba87b47", - "clade": "ap", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Document matrix tool", - "prefixed": "ap-docmatrix", - "github": "hyperpolymath/docmatrix" - }, - "docudactyl": { - "name": "docudactyl", - "uuid": "e7e383de-3984-57d6-b4e0-68642c41b9ac", - "clade": "ap", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Documentation tool", - "prefixed": "ap-docudactyl", - "github": "hyperpolymath/docudactyl" - }, - "dictask": { - "name": "dictask", - "uuid": "6bfce34f-f90d-56e2-ba72-a81d6fd6199e", - "clade": "ap", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Dictionary-based task management", - "prefixed": "ap-dictask", - "github": "hyperpolymath/dictask" - }, - "blocky-writer": { - "name": "blocky-writer", - "uuid": "3cece854-4969-5646-8d3a-bfbed895867b", - "clade": "ap", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Block-based writing tool", - "prefixed": "ap-blocky-writer", - "github": "hyperpolymath/blocky-writer" - }, - "raze-tui": { - "name": "raze-tui", - "uuid": "44ee6af8-2055-5838-9ad8-eca06b312d28", - "clade": "ap", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "TUI application framework", - "prefixed": "ap-raze-tui", - "github": "hyperpolymath/raze-tui" - }, - "double-track-browser": { - "name": "double-track-browser", - "uuid": "6978520c-1dc8-55b7-bf6c-11a071a2449a", - "clade": "ap", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Dual-pane browser", - "prefixed": "ap-double-track-browser", - "github": "hyperpolymath/double-track-browser" - }, - "universal-chat-extractor": { - "name": "universal-chat-extractor", - "uuid": "84a06742-9413-5581-835c-db6f807c1c4e", - "clade": "ap", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Chat export/extraction tool", - "prefixed": "ap-universal-chat-extractor", - "github": "hyperpolymath/universal-chat-extractor" - }, - "voyage-enterprise-decision-system": { - "name": "voyage-enterprise-decision-system", - "uuid": "dc4a3d93-61b1-56cc-80cf-3574085a3ad3", - "clade": "ap", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Enterprise decision support system", - "prefixed": "ap-voyage-enterprise-decision-system", - "github": "hyperpolymath/voyage-enterprise-decision-system" - }, - "feedback-o-tron": { - "name": "feedback-o-tron", - "uuid": "9f11b233-d506-5c01-8c50-15cd0a4df7c8", - "clade": "ap", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Feedback collection and management", - "prefixed": "ap-feedback-o-tron", - "github": "hyperpolymath/feedback-o-tron" - }, - "excel-economic-numbers-tool": { - "name": "excel-economic-numbers-tool", - "uuid": "5ad0e827-5c87-5a60-85d7-32884b0fcb80", - "clade": "ap", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Economic data analysis in Excel", - "prefixed": "ap-excel-economic-numbers-tool", - "github": "hyperpolymath/excel-economic-numbers-tool" - }, - "dotmatrix-fileprinter": { - "name": "dotmatrix-fileprinter", - "uuid": "a91d512e-6537-5988-8332-517ef0bf28ca", - "clade": "ap", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Dot-matrix style file printer", - "prefixed": "ap-dotmatrix-fileprinter", - "github": "hyperpolymath/dotmatrix-fileprinter" - }, - "live-files": { - "name": "live-files", - "uuid": "72af6322-e2bc-5fe0-a43d-5356fae10ab5", - "clade": "ap", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Live file synchronisation tool", - "prefixed": "ap-live-files", - "github": "hyperpolymath/live-files" - }, - "flat-mate": { - "name": "flat-mate", - "uuid": "c7c1258a-2caa-57a8-b5a6-72271de3127f", - "clade": "ap", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Flat/apartment sharing management", - "prefixed": "ap-flat-mate", - "github": "hyperpolymath/flat-mate" - }, - "preference-injector": { - "name": "preference-injector", - "uuid": "acdc2b57-dc57-5df8-a4f0-a36d4e1fbff9", - "clade": "ap", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "User preference injection tool", - "prefixed": "ap-preference-injector", - "github": "hyperpolymath/preference-injector" - }, - "presswerk": { - "name": "presswerk", - "uuid": "307171ac-7835-5d99-aff3-f746a860a610", - "clade": "ap", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Publishing/press tool", - "prefixed": "ap-presswerk", - "github": "hyperpolymath/presswerk" - }, - "snapcreate": { - "name": "snapcreate", - "uuid": "a88e859c-fb4a-5d06-8053-b3a3722a63d2", - "clade": "ap", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Snapshot creation tool", - "prefixed": "ap-snapcreate", - "github": "hyperpolymath/snapcreate" - }, - "misinformation-defence-platform": { - "name": "misinformation-defence-platform", - "uuid": "81c73b9a-7138-56f6-8dc3-c94aff4fe330", - "clade": "ap", - "secondary": [ - "sc" - ], - "lineage": "standalone", - "parent": "", - "description": "Counter-misinformation platform", - "prefixed": "ap-misinformation-defence-platform", - "github": "hyperpolymath/misinformation-defence-platform" - }, - "ambientops": { - "name": "ambientops", - "uuid": "86361920-1939-5421-aefd-02c93da249ed", - "clade": "ix", - "secondary": [], - "lineage": "monorepo", - "parent": "", - "description": "Monorepo \u2014 volumod, personal-sysadmin, displace, etc.", - "prefixed": "ix-ambientops", - "github": "hyperpolymath/ambientops" - }, - "cloudflare-dns-terraform": { - "name": "cloudflare-dns-terraform", - "uuid": "65764618-4ae3-58d2-b55c-d6fb268524b9", - "clade": "ix", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Cloudflare DNS management via Terraform", - "prefixed": "ix-cloudflare-dns-terraform", - "github": "hyperpolymath/cloudflare-dns-terraform" - }, - "cloudguard-cli": { - "name": "cloudguard-cli", - "uuid": "3003e0df-aff6-5b54-8eea-f530ef829767", - "clade": "ix", - "secondary": [ - "sc" - ], - "lineage": "standalone", - "parent": "", - "description": "Cloud security guard CLI", - "prefixed": "ix-cloudguard-cli", - "github": "hyperpolymath/cloudguard-cli" - }, - "cloudguard-server": { - "name": "cloudguard-server", - "uuid": "3944fe8f-d133-5bff-b02d-05b07038035f", - "clade": "ix", - "secondary": [ - "sc" - ], - "lineage": "standalone", - "parent": "", - "description": "Cloud security guard server", - "prefixed": "ix-cloudguard-server", - "github": "hyperpolymath/cloudguard-server" - }, - "stapeln": { - "name": "stapeln", - "uuid": "a6bd9705-f4d2-5bfb-8975-5fc5be8a56da", - "clade": "ix", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Container layer management \u2014 verified builds", - "prefixed": "ix-stapeln", - "github": "hyperpolymath/stapeln" - }, - "infrastructure-automation": { - "name": "infrastructure-automation", - "uuid": "5b5c69bc-7700-536c-8210-4c54f81f6ce3", - "clade": "ix", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Infrastructure automation scripts and tools", - "prefixed": "ix-infrastructure-automation", - "github": "hyperpolymath/infrastructure-automation" - }, - "twingate-helm-deploy": { - "name": "twingate-helm-deploy", - "uuid": "de81579c-9116-5484-b48b-b6e32f30aba8", - "clade": "ix", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Twingate deployment via Helm", - "prefixed": "ix-twingate-helm-deploy", - "github": "hyperpolymath/twingate-helm-deploy" - }, - "zerotier-k8s-link": { - "name": "zerotier-k8s-link", - "uuid": "ac25b1d9-d2d5-5eab-bd6c-e20c33e66633", - "clade": "ix", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "ZeroTier integration with Kubernetes", - "prefixed": "ix-zerotier-k8s-link", - "github": "hyperpolymath/zerotier-k8s-link" - }, - "cloud-sync-tuner": { - "name": "cloud-sync-tuner", - "uuid": "385cba2f-5949-55fb-a1cb-76f608fdbcc8", - "clade": "ix", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Cloud synchronisation tuning", - "prefixed": "ix-cloud-sync-tuner", - "github": "hyperpolymath/cloud-sync-tuner" - }, - "sdp-hkdf-deployment": { - "name": "sdp-hkdf-deployment", - "uuid": "3be5d7e2-1dd3-531a-a2f8-393cac5aad6e", - "clade": "ix", - "secondary": [ - "sc" - ], - "lineage": "standalone", - "parent": "", - "description": "SDP HKDF deployment tooling", - "prefixed": "ix-sdp-hkdf-deployment", - "github": "hyperpolymath/sdp-hkdf-deployment" - }, - "hesiod-dns-map": { - "name": "hesiod-dns-map", - "uuid": "7fd5917b-aeb9-5ca8-aeaf-d9319e70fc6a", - "clade": "ix", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "DNS mapping via Hesiod", - "prefixed": "ix-hesiod-dns-map", - "github": "hyperpolymath/hesiod-dns-map" - }, - "ipfs-overlay": { - "name": "ipfs-overlay", - "uuid": "0869b745-17d0-563b-931d-7f49082d7b52", - "clade": "ix", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "IPFS overlay network tool", - "prefixed": "ix-ipfs-overlay", - "github": "hyperpolymath/ipfs-overlay" - }, - "ipv6-tools": { - "name": "ipv6-tools", - "uuid": "75a311de-579c-5063-85a6-63b8c5b8014e", - "clade": "ix", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "IPv6 networking tools", - "prefixed": "ix-ipv6-tools", - "github": "hyperpolymath/ipv6-tools" - }, - "ssg-collection": { - "name": "ssg-collection", - "uuid": "1b38190c-4f1f-52a9-9455-2fb2bfa9679b", - "clade": "ix", - "secondary": [ - "ap" - ], - "lineage": "standalone", - "parent": "", - "description": "Static site generator collection", - "prefixed": "ix-ssg-collection", - "github": "hyperpolymath/ssg-collection" - }, - "scripts": { - "name": "scripts", - "uuid": "1df0b387-36cc-518e-aba0-09fb8d9c779f", - "clade": "ix", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "General automation scripts", - "prefixed": "ix-scripts", - "github": "hyperpolymath/scripts" - }, - "developer-ecosystem": { - "name": "developer-ecosystem", - "uuid": "d47185fd-2d65-537f-859d-02a295530153", - "clade": "dx", - "secondary": [], - "lineage": "monorepo", - "parent": "", - "description": "Monorepo \u2014 julia/deno/zig/rescript/elixir/idris2/v-ecosystem, etc.", - "prefixed": "dx-developer-ecosystem", - "github": "hyperpolymath/developer-ecosystem" - }, - "asdf-tool-plugins": { - "name": "asdf-tool-plugins", - "uuid": "0980150d-c75d-50e0-a371-05bc30d6ccfe", - "clade": "dx", - "secondary": [], - "lineage": "monorepo", - "parent": "", - "description": "Monorepo \u2014 74 asdf plugin dirs + asdf-augmenters", - "prefixed": "dx-asdf-tool-plugins", - "github": "hyperpolymath/asdf-tool-plugins" - }, - "nickel-augmentation": { - "name": "nickel-augmentation", - "uuid": "a01c5c73-1d20-546f-96f7-26581da08255", - "clade": "dx", - "secondary": [], - "lineage": "monorepo", - "parent": "", - "description": "Monorepo \u2014 Nickel language augmentation tools", - "prefixed": "dx-nickel-augmentation", - "github": "hyperpolymath/nickel-augmentation" - }, - "rescript": { - "name": "rescript", - "uuid": "98c14840-abac-51da-aa27-76a4751ada2d", - "clade": "dx", - "secondary": [ - "nl" - ], - "lineage": "standalone", - "parent": "", - "description": "ReScript tooling and contributions", - "prefixed": "dx-rescript", - "github": "hyperpolymath/rescript" - }, - "rescript-dom-mounter": { - "name": "rescript-dom-mounter", - "uuid": "49a4c2c0-6c7e-5752-afd2-0da3dccae515", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "ReScript DOM mounting utility", - "prefixed": "dx-rescript-dom-mounter", - "github": "hyperpolymath/rescript-dom-mounter" - }, - "rescript-tea": { - "name": "rescript-tea", - "uuid": "9e48d3c2-7f98-5647-9e67-2f734dc4630a", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "ReScript TEA (The Elm Architecture) framework", - "prefixed": "dx-rescript-tea", - "github": "hyperpolymath/rescript-tea" - }, - "rescript-vite": { - "name": "rescript-vite", - "uuid": "a6dd2a26-0834-5d8d-a568-4d6de4d9ccd2", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "ReScript + Vite integration", - "prefixed": "dx-rescript-vite", - "github": "hyperpolymath/rescript-vite" - }, - "bunsenite": { - "name": "bunsenite", - "uuid": "ef2c8003-70e4-5fee-9b95-9a5fb2f508a9", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Nickel configuration tool", - "prefixed": "dx-bunsenite", - "github": "hyperpolymath/bunsenite" - }, - "mcp-servers": { - "name": "mcp-servers", - "uuid": "535f5c97-0403-5d7b-b6d7-1d7974298af7", - "clade": "dx", - "secondary": [ - "ap" - ], - "lineage": "standalone", - "parent": "", - "description": "MCP server collection", - "prefixed": "dx-mcp-servers", - "github": "hyperpolymath/mcp-servers" - }, - "elixir-mcp-server": { - "name": "elixir-mcp-server", - "uuid": "94b5058d-40cd-5eaf-a768-adc0bae18920", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "MCP server for Elixir \u2014 BEAM layer for BoJ", - "prefixed": "dx-elixir-mcp-server", - "github": "hyperpolymath/elixir-mcp-server" - }, - "universal-language-server-plugin": { - "name": "universal-language-server-plugin", - "uuid": "7c29b884-00a0-52bb-b9e1-35a288f1e38f", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Universal LSP plugin", - "prefixed": "dx-universal-language-server-plugin", - "github": "hyperpolymath/universal-language-server-plugin" - }, - "universal-extension-format": { - "name": "universal-extension-format", - "uuid": "99fa4c1b-e625-573d-b384-3bc71865f721", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Universal browser extension format", - "prefixed": "dx-universal-extension-format", - "github": "hyperpolymath/universal-extension-format" - }, - "universal-project-manager": { - "name": "universal-project-manager", - "uuid": "0fff48d8-92fa-5464-a5df-8e34e96ef0df", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Universal project management tool", - "prefixed": "dx-universal-project-manager", - "github": "hyperpolymath/universal-project-manager" - }, - "ffmpeg-ffi": { - "name": "ffmpeg-ffi", - "uuid": "e9ae1bef-073a-51aa-a87a-ecd91565e6c1", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "FFI bindings for FFmpeg", - "prefixed": "dx-ffmpeg-ffi", - "github": "hyperpolymath/ffmpeg-ffi" - }, - "filesoup": { - "name": "filesoup", - "uuid": "f3198bf9-43a9-53ae-b372-3efefc0d8c48", - "clade": "dx", - "secondary": [], - "lineage": "monorepo", - "parent": "", - "description": "Monorepo \u2014 fslint plugin API + SDK", - "prefixed": "dx-filesoup", - "github": "hyperpolymath/filesoup" - }, - "formatrix-docs": { - "name": "formatrix-docs", - "uuid": "b2b4b7a9-cc35-5fd9-9014-19ea3377a8fc", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Formatrix documentation", - "prefixed": "dx-formatrix-docs", - "github": "hyperpolymath/formatrix-docs" - }, - "thunderbird-template-reloaded": { - "name": "thunderbird-template-reloaded", - "uuid": "33f3f717-92f6-5684-91e8-92eba0e282f2", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Thunderbird email template extension", - "prefixed": "dx-thunderbird-template-reloaded", - "github": "hyperpolymath/thunderbird-template-reloaded" - }, - "zotero-tools": { - "name": "zotero-tools", - "uuid": "99d011d5-b0b4-5411-90b9-560b5a5c46a8", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Zotero reference management tools", - "prefixed": "dx-zotero-tools", - "github": "hyperpolymath/zotero-tools" - }, - "wordpress-tools": { - "name": "wordpress-tools", - "uuid": "acfe8316-9ed7-5734-b81a-7289672a7dbe", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "WordPress development tools", - "prefixed": "dx-wordpress-tools", - "github": "hyperpolymath/wordpress-tools" - }, - "odds-and-sods-package-manager": { - "name": "odds-and-sods-package-manager", - "uuid": "8d0e4d70-0d5d-58c4-a0eb-ff46b91b7de2", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Miscellaneous package manager", - "prefixed": "dx-odds-and-sods-package-manager", - "github": "hyperpolymath/odds-and-sods-package-manager" - }, - "patallm-gallery": { - "name": "patallm-gallery", - "uuid": "dde6385a-25f4-5464-8e51-6028d5b9998c", - "clade": "dx", - "secondary": [ - "ax" - ], - "lineage": "monorepo", - "parent": "", - "description": "Monorepo \u2014 echomesh, elegant-state, claude-integrations, etc.", - "prefixed": "dx-patallm-gallery", - "github": "hyperpolymath/patallm-gallery" - }, - "im-docs": { - "name": "im-docs", - "uuid": "e2a80628-f1d7-5e30-9e6d-9c0e0c004e9f", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Instant messaging documentation", - "prefixed": "dx-im-docs", - "github": "hyperpolymath/im-docs" - }, - "polyglot-i18n": { - "name": "polyglot-i18n", - "uuid": "84f86ea3-d824-5c82-8683-73201fe1dbd2", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Polyglot internationalisation library", - "prefixed": "dx-polyglot-i18n", - "github": "hyperpolymath/polyglot-i18n" - }, - "vexometer": { - "name": "vexometer", - "uuid": "bde141bc-31eb-5e71-a634-772142968fa2", - "clade": "dx", - "secondary": [ - "rm" - ], - "lineage": "standalone", - "parent": "", - "description": "Vexation measurement tool", - "prefixed": "dx-vexometer", - "github": "hyperpolymath/vexometer" - }, - "intsoc-transactor": { - "name": "intsoc-transactor", - "uuid": "9bcd259d-1827-5327-80f7-9bac11d45449", - "clade": "pt", - "secondary": [ - "gv" - ], - "lineage": "standalone", - "parent": "", - "description": "Internet Society Transactor \u2014 IETF/IRTF/IANA draft management", - "prefixed": "pt-intsoc-transactor", - "github": "hyperpolymath/intsoc-transactor" - }, - "maa-framework": { - "name": "maa-framework", - "uuid": "e22e99d9-cd00-5764-95de-5e49d7151ea3", - "clade": "pt", - "secondary": [ - "gv" - ], - "lineage": "standalone", - "parent": "", - "description": "Mutually Assured Accountability Framework", - "prefixed": "pt-maa-framework", - "github": "hyperpolymath/maa-framework" - }, - "http-capability-gateway": { - "name": "http-capability-gateway", - "uuid": "e9b23afb-7071-5639-8ed9-7a0d162fc790", - "clade": "pt", - "secondary": [ - "sc" - ], - "lineage": "standalone", - "parent": "", - "description": "HTTP capability-based gateway", - "prefixed": "pt-http-capability-gateway", - "github": "hyperpolymath/http-capability-gateway" - }, - "protocol-squisher": { - "name": "protocol-squisher", - "uuid": "30f04d66-254a-596a-b597-400e60c0c831", - "clade": "pt", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Protocol compression and squishing", - "prefixed": "pt-protocol-squisher", - "github": "hyperpolymath/protocol-squisher" - }, - "squisher-corpus": { - "name": "squisher-corpus", - "uuid": "e8bfbb2c-d734-534c-bad6-b32d663c33e5", - "clade": "pt", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Test corpus for protocol-squisher", - "prefixed": "pt-squisher-corpus", - "github": "hyperpolymath/squisher-corpus" - }, - "resource-record-fluctuator": { - "name": "resource-record-fluctuator", - "uuid": "89522bb3-9016-529c-a6de-8783f1a0389c", - "clade": "pt", - "secondary": [ - "ix" - ], - "lineage": "standalone", - "parent": "", - "description": "DNS resource record management", - "prefixed": "pt-resource-record-fluctuator", - "github": "hyperpolymath/resource-record-fluctuator" - }, - "rrecord-verity": { - "name": "rrecord-verity", - "uuid": "82633fac-461f-591e-b3f0-6a085f902067", - "clade": "pt", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Resource record verification", - "prefixed": "pt-rrecord-verity", - "github": "hyperpolymath/rrecord-verity" - }, - "no-nonsense-nntps": { - "name": "no-nonsense-nntps", - "uuid": "4320a160-e91b-5205-a561-4a51391ef269", - "clade": "pt", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Usenet/NNTP tooling", - "prefixed": "pt-no-nonsense-nntps", - "github": "hyperpolymath/no-nonsense-nntps" - }, - "unified-dataset-vocab": { - "name": "unified-dataset-vocab", - "uuid": "0ce048b2-7653-5647-adb1-a4a16b274e6d", - "clade": "pt", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Unified dataset vocabulary standard", - "prefixed": "pt-unified-dataset-vocab", - "github": "hyperpolymath/unified-dataset-vocab" - }, - "v-graphql": { - "name": "v-graphql", - "uuid": "7e140093-a0ef-514c-bdbb-eea0b3551cc3", - "clade": "pt", - "secondary": [ - "dx" - ], - "lineage": "standalone", - "parent": "", - "description": "zig GraphQL implementation", - "prefixed": "pt-v-graphql", - "github": "hyperpolymath/v-graphql" - }, - "v-grpc": { - "name": "v-grpc", - "uuid": "e96d9947-17b6-5d39-9aca-d75bad9cf5d6", - "clade": "pt", - "secondary": [ - "dx" - ], - "lineage": "standalone", - "parent": "", - "description": "zig gRPC implementation", - "prefixed": "pt-v-grpc", - "github": "hyperpolymath/v-grpc" - }, - "v-rest": { - "name": "v-rest", - "uuid": "8de5b316-1efb-550a-8edd-699799b49146", - "clade": "pt", - "secondary": [ - "dx" - ], - "lineage": "standalone", - "parent": "", - "description": "zig REST implementation", - "prefixed": "pt-v-rest", - "github": "hyperpolymath/v-rest" - }, - "neural-foundations": { - "name": "neural-foundations", - "uuid": "8050327a-070f-5372-8901-060f79fe62ac", - "clade": "ax", - "secondary": [ - "fv" - ], - "lineage": "standalone", - "parent": "", - "description": "Neural foundations \u2014 neurosymbolic infrastructure", - "prefixed": "ax-neural-foundations", - "github": "hyperpolymath/neural-foundations" - }, - "hypatia": { - "name": "hypatia", - "uuid": "32793824-07a1-5c4d-8518-19e0981c4f57", - "clade": "ax", - "secondary": [ - "sc" - ], - "lineage": "standalone", - "parent": "", - "description": "Neurosymbolic CI/CD intelligence \u2014 rule-based scanning", - "prefixed": "ax-hypatia", - "github": "hyperpolymath/hypatia" - }, - "conative-gating": { - "name": "conative-gating", - "uuid": "ff849040-5acf-56e4-97c4-346bf2289290", - "clade": "ax", - "secondary": [ - "gv" - ], - "lineage": "standalone", - "parent": "", - "description": "SLM-as-Cerebellum for LLM policy enforcement", - "prefixed": "ax-conative-gating", - "github": "hyperpolymath/conative-gating" - }, - "conflow": { - "name": "conflow", - "uuid": "20b927fb-6fea-5215-9c57-ac4b5102dfe0", - "clade": "ax", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Conversational flow engine", - "prefixed": "ax-conflow", - "github": "hyperpolymath/conflow" - }, - "neurophone": { - "name": "neurophone", - "uuid": "4205251f-09a4-59e4-9496-ae20888b8ffa", - "clade": "ax", - "secondary": [ - "ap" - ], - "lineage": "standalone", - "parent": "", - "description": "Neural phone interface", - "prefixed": "ax-neurophone", - "github": "hyperpolymath/neurophone" - }, - "i-human": { - "name": "i-human", - "uuid": "584ee6e8-c000-5ee9-8212-cc0d00ac8b81", - "clade": "ax", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Human-AI interaction framework", - "prefixed": "ax-i-human", - "github": "hyperpolymath/i-human" - }, - "idaptik": { - "name": "idaptik", - "uuid": "01e40f52-2ed6-57ac-a3e7-1e4cb7f65d01", - "clade": "gm", - "secondary": [], - "lineage": "monorepo", - "parent": "", - "description": "Main game \u2014 asymmetric co-op, Jessica + Q, escape rooms", - "prefixed": "gm-idaptik", - "github": "hyperpolymath/idaptik" - }, - "idaptik-rescript13-staging": { - "name": "idaptik-rescript13-staging", - "uuid": "51fd8017-aa55-5ab9-a4b1-b16c3522f540", - "clade": "gm", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "IDApTIK ReScript 13 staging environment", - "prefixed": "gm-idaptik-rescript13-staging", - "github": "hyperpolymath/idaptik-rescript13-staging" - }, - "games & trivia": { - "name": "games & trivia", - "uuid": "5837ed8f-a975-5cff-a02b-1cc2184f0915", - "clade": "gm", - "secondary": [], - "lineage": "monorepo", - "parent": "", - "description": "Monorepo \u2014 phantom-metal-taste, dicti0nary-attack, candy-crash, etc.", - "prefixed": "gm-games & trivia", - "github": "hyperpolymath/games & trivia" - }, - "checky-monkey": { - "name": "checky-monkey", - "uuid": "a1df4542-91f8-5ae5-a75d-b6a545898d91", - "clade": "gm", - "secondary": [ - "sc", - "rm" - ], - "lineage": "standalone", - "parent": "", - "description": "Userscript/userstyle validation platform (Haskell)", - "prefixed": "gm-checky-monkey", - "github": "hyperpolymath/checky-monkey" - }, - "chimichanga": { - "name": "chimichanga", - "uuid": "ff29afc3-b7f3-5b88-ba26-5af1d946863b", - "clade": "gm", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Game project", - "prefixed": "gm-chimichanga", - "github": "hyperpolymath/chimichanga" - }, - "panic-attacker": { - "name": "panic-attacker", - "uuid": "7f831e69-87a5-50b5-a814-a652c38b4df2", - "clade": "sc", - "secondary": [ - "rm" - ], - "lineage": "standalone", - "parent": "", - "description": "Security scanning tool \u2014 static analysis", - "prefixed": "sc-panic-attacker", - "github": "hyperpolymath/panic-attacker" - }, - "svalinn": { - "name": "svalinn", - "uuid": "0d0a968f-314d-57e1-a395-9b84bc1994d1", - "clade": "sc", - "secondary": [ - "ix" - ], - "lineage": "standalone", - "parent": "", - "description": "Edge security gateway", - "prefixed": "sc-svalinn", - "github": "hyperpolymath/svalinn" - }, - "session-sentinel": { - "name": "session-sentinel", - "uuid": "6db869e4-738b-5cef-9893-0c0de99ae71f", - "clade": "sc", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Session security monitoring", - "prefixed": "sc-session-sentinel", - "github": "hyperpolymath/session-sentinel" - }, - "reasonably-good-token-vault": { - "name": "reasonably-good-token-vault", - "uuid": "b4db4006-f93d-5651-a2ef-b38cddcb5281", - "clade": "sc", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Token/secret management vault", - "prefixed": "sc-reasonably-good-token-vault", - "github": "hyperpolymath/reasonably-good-token-vault" - }, - "sanctify-php": { - "name": "sanctify-php", - "uuid": "29f21f71-597f-51ed-802b-1ee06ac3d093", - "clade": "sc", - "secondary": [ - "dx" - ], - "lineage": "standalone", - "parent": "", - "description": "PHP security hardening", - "prefixed": "sc-sanctify-php", - "github": "hyperpolymath/sanctify-php" - }, - "php-aegis": { - "name": "php-aegis", - "uuid": "1b7e06bd-c68e-5ab2-8cfe-f4047fec27fd", - "clade": "sc", - "secondary": [ - "dx" - ], - "lineage": "standalone", - "parent": "", - "description": "PHP security framework", - "prefixed": "sc-php-aegis", - "github": "hyperpolymath/php-aegis" - }, - "pimcore-fortress": { - "name": "pimcore-fortress", - "uuid": "6b10f9a1-8c82-540e-ab31-cb2ece0aad96", - "clade": "sc", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Pimcore security hardening", - "prefixed": "sc-pimcore-fortress", - "github": "hyperpolymath/pimcore-fortress" - }, - "project-wharf": { - "name": "project-wharf", - "uuid": "db4cb596-d2e5-5d2f-9786-222624488b01", - "clade": "sc", - "secondary": [ - "ix" - ], - "lineage": "standalone", - "parent": "", - "description": "Secure project deployment", - "prefixed": "sc-project-wharf", - "github": "hyperpolymath/project-wharf" - }, - "fireflag": { - "name": "fireflag", - "uuid": "035e19ce-0c49-5b86-b62d-135819aaa9ba", - "clade": "sc", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Feature flag security tool", - "prefixed": "sc-fireflag", - "github": "hyperpolymath/fireflag" - }, - "AcceleratorGate.jl": { - "name": "AcceleratorGate.jl", - "uuid": "b567df91-0bb8-56ea-a10c-2c0c5557fe3c", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 accelerator gate", - "prefixed": "dx-AcceleratorGate.jl", - "github": "hyperpolymath/AcceleratorGate.jl" - }, - "Axiology.jl": { - "name": "Axiology.jl", - "uuid": "8213c365-de9a-5f4d-a45f-f4daa663b7c4", - "clade": "dx", - "secondary": [ - "gv" - ], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 value theory", - "prefixed": "dx-Axiology.jl", - "github": "hyperpolymath/Axiology.jl" - }, - "Axiom.jl": { - "name": "Axiom.jl", - "uuid": "0dc4455a-08c8-57ed-9fdb-f7931c23526f", - "clade": "dx", - "secondary": [ - "fv" - ], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 axiom systems", - "prefixed": "dx-Axiom.jl", - "github": "hyperpolymath/Axiom.jl" - }, - "BowtieRisk.jl": { - "name": "BowtieRisk.jl", - "uuid": "02cba5a9-9ee2-56ca-9e60-9901778360a9", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 bowtie risk analysis", - "prefixed": "dx-BowtieRisk.jl", - "github": "hyperpolymath/BowtieRisk.jl" - }, - "Causals.jl": { - "name": "Causals.jl", - "uuid": "cad6d243-455a-59a1-bb37-08c382bff533", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 causal inference", - "prefixed": "dx-Causals.jl", - "github": "hyperpolymath/Causals.jl" - }, - "Cladistics.jl": { - "name": "Cladistics.jl", - "uuid": "501c9648-e345-5b88-b40b-c2647fc4cea7", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 phylogenetic analysis", - "prefixed": "dx-Cladistics.jl", - "github": "hyperpolymath/Cladistics.jl" - }, - "Cliodynamics.jl": { - "name": "Cliodynamics.jl", - "uuid": "963dd833-9895-5f04-9c7b-62a834b76e1c", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 mathematical history", - "prefixed": "dx-Cliodynamics.jl", - "github": "hyperpolymath/Cliodynamics.jl" - }, - "Cliometrics.jl": { - "name": "Cliometrics.jl", - "uuid": "1c0e400c-ac2f-5a80-9b06-4fc03a671509", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 quantitative economic history", - "prefixed": "dx-Cliometrics.jl", - "github": "hyperpolymath/Cliometrics.jl" - }, - "Exnovation.jl": { - "name": "Exnovation.jl", - "uuid": "349a68f3-f163-5096-b2ee-bf114326014a", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 technology phase-out analysis", - "prefixed": "dx-Exnovation.jl", - "github": "hyperpolymath/Exnovation.jl" - }, - "FirmwareAudit.jl": { - "name": "FirmwareAudit.jl", - "uuid": "e660863e-9021-59db-8b63-1ee640b227fb", - "clade": "sc", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 firmware security auditing", - "prefixed": "sc-FirmwareAudit.jl", - "github": "hyperpolymath/FirmwareAudit.jl" - }, - "HackenbushGames.jl": { - "name": "HackenbushGames.jl", - "uuid": "6aea3153-aea9-5142-9c92-30bf6fbdc49f", - "clade": "gm", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 combinatorial game theory", - "prefixed": "gm-HackenbushGames.jl", - "github": "hyperpolymath/HackenbushGames.jl" - }, - "HardwareResilience.jl": { - "name": "HardwareResilience.jl", - "uuid": "ef2eb132-93b1-5dec-be9d-d18619a595c6", - "clade": "ix", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 hardware resilience testing", - "prefixed": "ix-HardwareResilience.jl", - "github": "hyperpolymath/HardwareResilience.jl" - }, - "Hyperpolymath.jl": { - "name": "Hyperpolymath.jl", - "uuid": "8bc58e42-e39c-5c52-a60b-8ce36fd12000", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 hyperpolymath core library", - "prefixed": "dx-Hyperpolymath.jl", - "github": "hyperpolymath/Hyperpolymath.jl" - }, - "HyperpolymathRegistry": { - "name": "HyperpolymathRegistry", - "uuid": "c9cbb683-68e1-53ce-ab59-26f9bc2962f2", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package registry", - "prefixed": "dx-HyperpolymathRegistry", - "github": "hyperpolymath/HyperpolymathRegistry" - }, - "InvestigativeJournalist.jl": { - "name": "InvestigativeJournalist.jl", - "uuid": "0913d39a-bde3-50d0-a124-4c4e17c347d9", - "clade": "ap", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 investigative journalism tools", - "prefixed": "ap-InvestigativeJournalist.jl", - "github": "hyperpolymath/InvestigativeJournalist.jl" - }, - "JuliaKids.jl": { - "name": "JuliaKids.jl", - "uuid": "a5fe1198-d318-59f8-bde8-650cbb733a4f", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 educational Julia for children", - "prefixed": "dx-JuliaKids.jl", - "github": "hyperpolymath/JuliaKids.jl" - }, - "JuliaPackage-Reuse-Audit.jl": { - "name": "JuliaPackage-Reuse-Audit.jl", - "uuid": "ae643ba8-1fab-5f76-9c7c-5a4909094ce8", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 dependency reuse auditing", - "prefixed": "dx-JuliaPackage-Reuse-Audit.jl", - "github": "hyperpolymath/JuliaPackage-Reuse-Audit.jl" - }, - "KnotTheory.jl": { - "name": "KnotTheory.jl", - "uuid": "d9852dbe-4c1e-5666-83f2-57f929201526", - "clade": "dx", - "secondary": [ - "db" - ], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 knot theory (relates to QuandleDB)", - "prefixed": "dx-KnotTheory.jl", - "github": "hyperpolymath/KnotTheory.jl" - }, - "Lithoglyph.jl": { - "name": "Lithoglyph.jl", - "uuid": "8731f9e3-66d2-54a3-a6aa-523fda63ceac", - "clade": "db", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 graph database", - "prefixed": "db-Lithoglyph.jl", - "github": "hyperpolymath/Lithoglyph.jl" - }, - "LowLevel.jl": { - "name": "LowLevel.jl", - "uuid": "18bb5da5-f503-5b10-89cf-e3e536c6ab9b", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 low-level systems", - "prefixed": "dx-LowLevel.jl", - "github": "hyperpolymath/LowLevel.jl" - }, - "MacroPower.jl": { - "name": "MacroPower.jl", - "uuid": "c88fdfb4-f139-5a9b-bc63-b512383036e4", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 macro metaprogramming", - "prefixed": "dx-MacroPower.jl", - "github": "hyperpolymath/MacroPower.jl" - }, - "MinixSDK.jl": { - "name": "MinixSDK.jl", - "uuid": "812c9554-d027-59ba-ad89-abd5f7f2f1c6", - "clade": "dx", - "secondary": [ - "ix" - ], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 Minix SDK bindings", - "prefixed": "dx-MinixSDK.jl", - "github": "hyperpolymath/MinixSDK.jl" - }, - "PolyglotFormalisms.jl": { - "name": "PolyglotFormalisms.jl", - "uuid": "4b581a8f-1889-504e-b389-a8e0f86a8050", - "clade": "fv", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 formal methods", - "prefixed": "fv-PolyglotFormalisms.jl", - "github": "hyperpolymath/PolyglotFormalisms.jl" - }, - "PostDisciplinary.jl": { - "name": "PostDisciplinary.jl", - "uuid": "6f7cc69b-2432-592c-80ee-ba06c6bb6b12", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 post-disciplinary research tools", - "prefixed": "dx-PostDisciplinary.jl", - "github": "hyperpolymath/PostDisciplinary.jl" - }, - "PRComms.jl": { - "name": "PRComms.jl", - "uuid": "16260b97-06b7-5399-9277-840e7159d61d", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 PR/communications analysis", - "prefixed": "dx-PRComms.jl", - "github": "hyperpolymath/PRComms.jl" - }, - "ProvenCrypto.jl": { - "name": "ProvenCrypto.jl", - "uuid": "8cf1aac9-c110-5044-b43d-cd5e9b9ed471", - "clade": "fv", - "secondary": [ - "sc" - ], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 verified cryptography", - "prefixed": "fv-ProvenCrypto.jl", - "github": "hyperpolymath/ProvenCrypto.jl" - }, - "QuantumCircuit.jl": { - "name": "QuantumCircuit.jl", - "uuid": "1984f880-21f3-5d89-a429-9a498430585c", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 quantum circuit simulation", - "prefixed": "dx-QuantumCircuit.jl", - "github": "hyperpolymath/QuantumCircuit.jl" - }, - "ShellIntegration.jl": { - "name": "ShellIntegration.jl", - "uuid": "48a73b24-91c6-5945-bc8b-561221859939", - "clade": "dx", - "secondary": [ - "ix" - ], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 shell integration", - "prefixed": "dx-ShellIntegration.jl", - "github": "hyperpolymath/ShellIntegration.jl" - }, - "SiliconCore.jl": { - "name": "SiliconCore.jl", - "uuid": "bd4e3437-a1c1-595a-9dbb-bf4ecc6dd4d9", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 hardware abstraction", - "prefixed": "dx-SiliconCore.jl", - "github": "hyperpolymath/SiliconCore.jl" - }, - "Skein.jl": { - "name": "Skein.jl", - "uuid": "60c9c02e-fd17-508f-bdc2-485b719087c5", - "clade": "fv", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 Skein hash function", - "prefixed": "fv-Skein.jl", - "github": "hyperpolymath/Skein.jl" - }, - "SMTLib.jl": { - "name": "SMTLib.jl", - "uuid": "7a79773e-651b-5331-9904-90fa7d6de4df", - "clade": "fv", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 SMT-LIB interface", - "prefixed": "fv-SMTLib.jl", - "github": "hyperpolymath/SMTLib.jl" - }, - "SoftwareSovereign.jl": { - "name": "SoftwareSovereign.jl", - "uuid": "cb6ca3cd-3823-5981-a236-ae86f9be9d0d", - "clade": "gv", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 software sovereignty analysis", - "prefixed": "gv-SoftwareSovereign.jl", - "github": "hyperpolymath/SoftwareSovereign.jl" - }, - "TradeUnionist.jl": { - "name": "TradeUnionist.jl", - "uuid": "f28895eb-673c-5376-930c-8aab9f69b6a6", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 trade union data analysis", - "prefixed": "dx-TradeUnionist.jl", - "github": "hyperpolymath/TradeUnionist.jl" - }, - "ViableSystems.jl": { - "name": "ViableSystems.jl", - "uuid": "67460914-612c-5e0f-9412-2d9a2109b018", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 viable systems model", - "prefixed": "dx-ViableSystems.jl", - "github": "hyperpolymath/ViableSystems.jl" - }, - "ZeroProb.jl": { - "name": "ZeroProb.jl", - "uuid": "07676e66-fb11-54d4-97b2-1e90b9624571", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Julia package \u2014 zero-probability analysis", - "prefixed": "dx-ZeroProb.jl", - "github": "hyperpolymath/ZeroProb.jl" - }, - "academic-workflow-suite": { - "name": "academic-workflow-suite", - "uuid": "6eb2b24e-802c-5a2b-9900-71469664961b", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Academic workflow tools", - "prefixed": "dx-academic-workflow-suite", - "github": "hyperpolymath/academic-workflow-suite" - }, - "accessibility-everywhere": { - "name": "accessibility-everywhere", - "uuid": "97e58fb2-9134-5a48-ac0a-96c8cfc42d5e", - "clade": "gv", - "secondary": [ - "ap" - ], - "lineage": "standalone", - "parent": "", - "description": "Accessibility standards and tooling", - "prefixed": "gv-accessibility-everywhere", - "github": "hyperpolymath/accessibility-everywhere" - }, - "aerie": { - "name": "aerie", - "uuid": "94866033-010f-56eb-9b92-c9802fa8b2de", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Development environment tool", - "prefixed": "dx-aerie", - "github": "hyperpolymath/aerie" - }, - "amethe": { - "name": "amethe", - "uuid": "d0798fe7-cea5-52fc-bae5-796ed1fbe43a", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Developer tool", - "prefixed": "dx-amethe", - "github": "hyperpolymath/amethe" - }, - "anamnesis": { - "name": "anamnesis", - "uuid": "a8f9138e-228e-50c9-9f0c-36a37a4e185e", - "clade": "ap", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Memory/recall application", - "prefixed": "ap-anamnesis", - "github": "hyperpolymath/anamnesis" - }, - "aspasia": { - "name": "aspasia", - "uuid": "f4ed948f-44db-54cf-a230-09ae84402927", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Developer tool", - "prefixed": "dx-aspasia", - "github": "hyperpolymath/aspasia" - }, - "bofig": { - "name": "bofig", - "uuid": "22b86e25-80b5-514e-b839-d167ca7adf31", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Configuration tool", - "prefixed": "dx-bofig", - "github": "hyperpolymath/bofig" - }, - "boinc-boinc": { - "name": "boinc-boinc", - "uuid": "8b665738-e5cb-57be-abf8-b8385eff1986", - "clade": "ix", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "BOINC distributed computing integration", - "prefixed": "ix-boinc-boinc", - "github": "hyperpolymath/boinc-boinc" - }, - "cccp": { - "name": "cccp", - "uuid": "7e3f6173-efac-54df-b675-e9c868b32ced", - "clade": "ix", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Cloud/container coordination", - "prefixed": "ix-cccp", - "github": "hyperpolymath/cccp" - }, - "defiant": { - "name": "defiant", - "uuid": "0d5de5f7-6615-5f92-ad0b-5bdd693bde42", - "clade": "sc", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Defiance/resistance security tool", - "prefixed": "sc-defiant", - "github": "hyperpolymath/defiant" - }, - "flatracoon": { - "name": "flatracoon", - "uuid": "57da3aa7-dcd9-554e-8278-810e0f99edaf", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Flatpak tool", - "prefixed": "dx-flatracoon", - "github": "hyperpolymath/flatracoon" - }, - "heterogenous-mobile-computing": { - "name": "heterogenous-mobile-computing", - "uuid": "1ba1c30c-93d2-5521-91cf-571cbb77a210", - "clade": "ix", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Heterogeneous mobile computing research", - "prefixed": "ix-heterogenous-mobile-computing", - "github": "hyperpolymath/heterogenous-mobile-computing" - }, - "hybrid-automation-router": { - "name": "hybrid-automation-router", - "uuid": "8c1c4b84-1603-5303-bbd4-9f1f047f2dd2", - "clade": "ix", - "secondary": [ - "ax" - ], - "lineage": "standalone", - "parent": "", - "description": "Hybrid automation routing", - "prefixed": "ix-hybrid-automation-router", - "github": "hyperpolymath/hybrid-automation-router" - }, - "hyperpolymath": { - "name": "hyperpolymath", - "uuid": "b9289198-69a2-5fe4-a08c-ddf032653a25", - "clade": "gv", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Organisation profile repository", - "prefixed": "gv-hyperpolymath", - "github": "hyperpolymath/hyperpolymath" - }, - "kaldor-iiot": { - "name": "kaldor-iiot", - "uuid": "a6c5b766-2ee7-5350-9d87-2daece5fceb1", - "clade": "ix", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Industrial IoT tooling", - "prefixed": "ix-kaldor-iiot", - "github": "hyperpolymath/kaldor-iiot" - }, - "kea": { - "name": "kea", - "uuid": "eec3e85a-490a-54fe-b956-02ff48bed367", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Developer tool", - "prefixed": "dx-kea", - "github": "hyperpolymath/kea" - }, - "laminar": { - "name": "laminar", - "uuid": "769d09ef-e870-5e11-b1f5-f63b144da0a7", - "clade": "ix", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Laminar flow/pipeline tool", - "prefixed": "ix-laminar", - "github": "hyperpolymath/laminar" - }, - "laniakea": { - "name": "laniakea", - "uuid": "3b7b0de8-efa6-5b4f-be3d-492a5d459b38", - "clade": "ix", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Large-scale infrastructure", - "prefixed": "ix-laniakea", - "github": "hyperpolymath/laniakea" - }, - "megadog": { - "name": "megadog", - "uuid": "82d6362e-1a6f-5fbc-959b-f992cc5b9a43", - "clade": "rm", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Large-scale repo management", - "prefixed": "rm-megadog", - "github": "hyperpolymath/megadog" - }, - "polystack": { - "name": "polystack", - "uuid": "e4be0420-1076-5b1f-8b1e-1b621021769a", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "DELETED from GitHub \u2014 superseded by boj-server. Archived to OneDrive.", - "prefixed": "dx-polystack", - "github": "hyperpolymath/polystack" - }, - "refugia": { - "name": "refugia", - "uuid": "511e79b6-4632-5ed3-8194-ad87be1e1177", - "clade": "ap", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Refuge/safe-space platform", - "prefixed": "ap-refugia", - "github": "hyperpolymath/refugia" - }, - "robodog-ecm": { - "name": "robodog-ecm", - "uuid": "c4f57728-061a-51dc-b65f-7238aa6945d0", - "clade": "rm", - "secondary": [ - "ax" - ], - "lineage": "standalone", - "parent": "", - "description": "Robot dog enterprise content management", - "prefixed": "rm-robodog-ecm", - "github": "hyperpolymath/robodog-ecm" - }, - "rpa-elysium": { - "name": "rpa-elysium", - "uuid": "8ea59509-ffc3-5ceb-8faf-09b62827d40d", - "clade": "dx", - "secondary": [ - "ax" - ], - "lineage": "standalone", - "parent": "", - "description": "Robotic Process Automation framework", - "prefixed": "dx-rpa-elysium", - "github": "hyperpolymath/rpa-elysium" - }, - "social-media-tools": { - "name": "social-media-tools", - "uuid": "ed005160-24df-50ec-8bd0-6415de77538c", - "clade": "dx", - "secondary": [], - "lineage": "monorepo", - "parent": "", - "description": "Monorepo \u2014 social media integrations", - "prefixed": "dx-social-media-tools", - "github": "hyperpolymath/social-media-tools" - }, - "supernorma": { - "name": "supernorma", - "uuid": "34ae62e5-8224-5264-ad0a-17a8d7c4788a", - "clade": "gv", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Normalisation/standards tool", - "prefixed": "gv-supernorma", - "github": "hyperpolymath/supernorma" - }, - "tma-mark2": { - "name": "tma-mark2", - "uuid": "60c10dfb-4ba2-5d36-9dd1-9a38329e1b96", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "TMA mark 2 tool", - "prefixed": "dx-tma-mark2", - "github": "hyperpolymath/tma-mark2" - }, - "ubicity": { - "name": "ubicity", - "uuid": "500896b6-edc4-5449-823c-810603b786fe", - "clade": "ix", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Ubiquitous computing tool", - "prefixed": "ix-ubicity", - "github": "hyperpolymath/ubicity" - }, - "zerostep": { - "name": "zerostep", - "uuid": "0f6e4a31-3064-578b-bbcf-2ed96ce64846", - "clade": "dx", - "secondary": [], - "lineage": "standalone", - "parent": "", - "description": "Zero-step automation", - "prefixed": "dx-zerostep", - "github": "hyperpolymath/zerostep" - } - } -} \ No newline at end of file diff --git a/worker/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/249e5f66be2e7bbeb362e83e0af0b55d6ec1b194b1752354760cca8df9171e72.sqlite b/worker/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/249e5f66be2e7bbeb362e83e0af0b55d6ec1b194b1752354760cca8df9171e72.sqlite deleted file mode 100644 index 0b58f0dca7d6ce95907cb0b322dc4802f04688c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmWFz^vNtqRY=P(%1ta$FlG>7U}9o$P*7lCU|@t|AVoG{WYDXN;00+HAlr;ljiVtj n8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*O6ovo**AfQj diff --git a/worker/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/249e5f66be2e7bbeb362e83e0af0b55d6ec1b194b1752354760cca8df9171e72.sqlite-shm b/worker/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/249e5f66be2e7bbeb362e83e0af0b55d6ec1b194b1752354760cca8df9171e72.sqlite-shm deleted file mode 100644 index 061baa23cc26fa6217e69a412c9b29847c04d491..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeI)I}SlX6b9gNUC$7=)QJVyg+^>et5Ykqc4i6Kgo-mah*l@=_a~DxnM~&KE#OSg ziJn02dTf^?1tmp^vnHmRGob0{UguicZs{}H?*VX zz4<+_c}#@>0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAVA zMU8@kj;?MFQo+Fvij(*+xHt$Mw7XQq7wF*gByDpQ3T{I9{RB0V8*KEF;ua@$><}}K@ndhsw$_?g}>$QB@cGvi(vQ{!@(Nt#I zTA+tFp>r8`ZMfUvSZi464~>dpn+_{fxVw+;3_QEzfkfWEg zsY}W1BAvAs&xrCurCtyd?$l-Gax`-_ot72d;l<2z){K>vrB&`Qn>nm~e_(9F(-%sO zDx|H^T&{?x`8>Pr)H^!vc}86qUI9I@i!Gn)_wxnA<0HYXl@q6fvapj%klzpxfB*y_ z009U<00Izz00bZa0SNS_fXor>=LOybr(Vu%+?x!@LgWRc0s;aMfB*y_009U<00Izz z00bb=%K~ywfNyVq!Mn}P>tE-OUqD`=22.0.0" + } + }, + "node_modules/@cloudflare/unenv-preset": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.16.1.tgz", + "integrity": "sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw==", + "dev": true, + "license": "MIT OR Apache-2.0", + "peerDependencies": { + "unenv": "2.0.0-rc.24", + "workerd": ">1.20260305.0 <2.0.0-0" + }, + "peerDependenciesMeta": { + "workerd": { + "optional": true + } + } + }, + "node_modules/@cloudflare/workerd-darwin-64": { + "version": "1.20260617.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260617.1.tgz", + "integrity": "sha512-jWwmgEVVWbsHNrLSNXzwjJaH90VzRxq1cWkQFUidxyeUPnMxemeNE8I9qFAfrpzGgE11e9sKDcE3ettJW08swQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-darwin-arm64": { + "version": "1.20260617.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260617.1.tgz", + "integrity": "sha512-LHH7b565g9znfCUOkwbec6FG2rmRbsgCy6aJiU9KN662mNheWl5sw/iKleiFSiljPKQQP3HkjnC/NSkdgi/aSA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-linux-64": { + "version": "1.20260617.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260617.1.tgz", + "integrity": "sha512-FMnaAKXe4Cfd8TQurCVd9fs2XQVBFRCsP+Id/SRdUv89MlwYu9zXfoyx6BxM+brPTIUK38SHbo8iaxiwzLi9JQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-linux-arm64": { + "version": "1.20260617.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260617.1.tgz", + "integrity": "sha512-MRoifFYcqbxxIIQy7PqO5tFY/qPFSnjXzakWl0sO93l+HLyG35jRAgOi6jfqa4kBxc7gKKtH861DcewjxUfkjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-windows-64": { + "version": "1.20260617.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260617.1.tgz", + "integrity": "sha512-rgBV9wQrv0OSKgCTTbhFUFY3sLGNANZ88aqaLvtmEn2gmbFVb1J4PDGochVUdB7NSEp4D/ghHva6/8SZmbONpw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.23.5", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz", + "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^3.0.5", + "debug": "^4.3.1", + "minimatch": "^10.2.4" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.6.0.tgz", + "integrity": "sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/core": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", + "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/js": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", + "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "eslint": "^10.0.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/@eslint/object-schema": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz", + "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz", + "integrity": "sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1", + "levn": "^0.4.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.5.tgz", + "integrity": "sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.133.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz", + "integrity": "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@poppinss/colors": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@poppinss/colors/-/colors-4.1.6.tgz", + "integrity": "sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^4.1.5" + } + }, + "node_modules/@poppinss/dumper": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@poppinss/dumper/-/dumper-0.6.5.tgz", + "integrity": "sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@poppinss/colors": "^4.1.5", + "@sindresorhus/is": "^7.0.2", + "supports-color": "^10.0.0" + } + }, + "node_modules/@poppinss/exception": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@poppinss/exception/-/exception-1.2.3.tgz", + "integrity": "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz", + "integrity": "sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz", + "integrity": "sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz", + "integrity": "sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz", + "integrity": "sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz", + "integrity": "sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz", + "integrity": "sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz", + "integrity": "sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz", + "integrity": "sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz", + "integrity": "sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz", + "integrity": "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz", + "integrity": "sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz", + "integrity": "sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz", + "integrity": "sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz", + "integrity": "sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz", + "integrity": "sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sindresorhus/is": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.2.0.tgz", + "integrity": "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@speed-highlight/core": { + "version": "1.2.17", + "resolved": "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.17.tgz", + "integrity": "sha512-Z92FwKpCtfaW1V0jTU/fh3QzYEZN8wDwrzRIBoADCJfn4mJCNcJN/XegifX7BDrQ8/h9Xh/JnbyMchL0FqXrkg==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", + "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitest/expect": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.9.tgz", + "integrity": "sha512-vl/rYsUKcBr3SnQn166+XR5ZQcgMx3DQhFWdfli/cWpLnLUmbxZvyrJZotLFUryib+LtArYMSTJ5RbQ57ZqrlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.1.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.1.9", + "@vitest/utils": "4.1.9", + "chai": "^6.2.2", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.9.tgz", + "integrity": "sha512-EVkXzBjrPGM+cK8/ANWgBrkUCfJfb38/EfTSO8h7pWvKkyPkpWxvR7BkD2MyItMF62C97zAEoqdpUixwR/e+Rw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.1.9", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.9.tgz", + "integrity": "sha512-s0iufns3iIFitdgm+YR7g1whCAaGtXz459VS9/PqyKDEEFgYIhsHOQmXgIgDuYCt7DeQmiZT0Qe2OA2p4ZPu5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.9.tgz", + "integrity": "sha512-KXLMDtc7oe70+3mJfGrPUWPesswH+3sTxAMAMl8DG7I8IUQT4XW718dY5ID3vPUcmlu27CcKfY4P3h3I29SLJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.1.9", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.9.tgz", + "integrity": "sha512-Jc7RKGNBo8Z28WYIm0Niej4xdSPByRf6mU58VpHQkd6Zh05rlnA+twjbK5HyeIGHxrzsc3mJgS43uM0CZKzaIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.9", + "@vitest/utils": "4.1.9", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.9.tgz", + "integrity": "sha512-fHpsS6mIi+PiEW+vcRVOMkX1oSaPKne3VOclSFICPcGOmfKgXPU5iAah+wcNcj2xPrCCmfq99IDGf+EojhhvhA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.9.tgz", + "integrity": "sha512-A51o8ymO5PpqlWNnBP9ZHPXDIpuMtTLlGSjN7la4US+LJzoUMyhwjA5QXlm39JexgwHKW4Xjs8Z2d3dLCXOeuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.9", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/acorn": { + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", + "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/blake3-wasm": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/blake3-wasm/-/blake3-wasm-2.1.5.tgz", + "integrity": "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/error-stack-parser-es": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz", + "integrity": "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/es-module-lexer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz", + "integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.5.0.tgz", + "integrity": "sha512-1y+7C+vi12bUK1IpZeaV3gsH9fHLBmPvYmPx42pvT/E9yG0IC8g3PUZZgp0+JLJl7ZDK0flc2gc+Aw9dpCvIsQ==", + "dev": true, + "license": "MIT", + "workspaces": [ + "packages/*" + ], + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.5", + "@eslint/config-helpers": "^0.6.0", + "@eslint/core": "^1.2.1", + "@eslint/plugin-kit": "^0.7.2", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "minimatch": "^10.2.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "17.6.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.6.0.tgz", + "integrity": "sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/miniflare": { + "version": "4.20260617.1", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20260617.1.tgz", + "integrity": "sha512-Go3/gzStm99QHptsSgU+q1S+xDfLoRgwjJNY80kaTVi0ENhTyqKq+sc4xZiWBSbM7uUcJwmzm8+QFKtcYLJ9nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "0.8.1", + "sharp": "0.34.5", + "undici": "7.28.0", + "workerd": "1.20260617.1", + "ws": "8.21.0", + "youch": "4.1.0-beta.10" + }, + "bin": { + "miniflare": "bootstrap.js" + }, + "engines": { + "node": ">=22.0.0" + } + }, + "node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.14", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.14.tgz", + "integrity": "sha512-U9kYi5bpVMEI31yC8iw4bJJp0avcHXA0W8/wNfLfnvJYzihQo2ZRPYPvpAAd570HAcCBjCTN7vnr+v4StKl1IQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/obug": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.3.tgz", + "integrity": "sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.15", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", + "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.8.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.4.tgz", + "integrity": "sha512-N2MylSdi48+5N/6S5j+maeHbUSIzzZ5uOcX5Hm4QpV8Dkb1HFjfAKTKX6yNPJQD9AhcT3ifHNB66tWTTJDi11Q==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/rolldown": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz", + "integrity": "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.133.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.3", + "@rolldown/binding-darwin-arm64": "1.0.3", + "@rolldown/binding-darwin-x64": "1.0.3", + "@rolldown/binding-freebsd-x64": "1.0.3", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.3", + "@rolldown/binding-linux-arm64-gnu": "1.0.3", + "@rolldown/binding-linux-arm64-musl": "1.0.3", + "@rolldown/binding-linux-ppc64-gnu": "1.0.3", + "@rolldown/binding-linux-s390x-gnu": "1.0.3", + "@rolldown/binding-linux-x64-gnu": "1.0.3", + "@rolldown/binding-linux-x64-musl": "1.0.3", + "@rolldown/binding-openharmony-arm64": "1.0.3", + "@rolldown/binding-wasm32-wasi": "1.0.3", + "@rolldown/binding-win32-arm64-msvc": "1.0.3", + "@rolldown/binding-win32-x64-msvc": "1.0.3" + } + }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz", + "integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", + "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz", + "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyrainbow": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", + "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/undici": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.28.0.tgz", + "integrity": "sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/unenv": { + "version": "2.0.0-rc.24", + "resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.24.tgz", + "integrity": "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pathe": "^2.0.3" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/vite": { + "version": "8.0.16", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.16.tgz", + "integrity": "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.32.0", + "picomatch": "^4.0.4", + "postcss": "^8.5.15", + "rolldown": "1.0.3", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.1.18", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.9.tgz", + "integrity": "sha512-nE3/LEyc0z87uHYLZebqCUOaJr2hdtuPp7BQ4BosVFnfltxgAvMG08NyrSGlPpOUWvR27c5flSmYFTNr78L9GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.1.9", + "@vitest/mocker": "4.1.9", + "@vitest/pretty-format": "4.1.9", + "@vitest/runner": "4.1.9", + "@vitest/snapshot": "4.1.9", + "@vitest/spy": "4.1.9", + "@vitest/utils": "4.1.9", + "es-module-lexer": "^2.0.0", + "expect-type": "^1.3.0", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^4.0.0-rc.1", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.1.0", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.1.9", + "@vitest/browser-preview": "4.1.9", + "@vitest/browser-webdriverio": "4.1.9", + "@vitest/coverage-istanbul": "4.1.9", + "@vitest/coverage-v8": "4.1.9", + "@vitest/ui": "4.1.9", + "happy-dom": "*", + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/coverage-istanbul": { + "optional": true + }, + "@vitest/coverage-v8": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + }, + "vite": { + "optional": false + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workerd": { + "version": "1.20260617.1", + "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20260617.1.tgz", + "integrity": "sha512-Re5pl6pdowt3ZmWUzGlOuB7jbRIIPetgKalmo4cYmucQnVhpo7/3e4MfpekbhLi2EhZZz5EY9NWRu8zFzuEZew==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "bin": { + "workerd": "bin/workerd" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "@cloudflare/workerd-darwin-64": "1.20260617.1", + "@cloudflare/workerd-darwin-arm64": "1.20260617.1", + "@cloudflare/workerd-linux-64": "1.20260617.1", + "@cloudflare/workerd-linux-arm64": "1.20260617.1", + "@cloudflare/workerd-windows-64": "1.20260617.1" + } + }, + "node_modules/wrangler": { + "version": "4.103.0", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.103.0.tgz", + "integrity": "sha512-3Lv1P5t2xcSEkSTKtG+Lz+3JFryuU7YPLkaCUj7gNe+CJsjZJLtUwqsh1x595QBxkIbCE0GAvDx2DCJUU4+oqw==", + "dev": true, + "license": "MIT OR Apache-2.0", + "dependencies": { + "@cloudflare/kv-asset-handler": "0.5.0", + "@cloudflare/unenv-preset": "2.16.1", + "blake3-wasm": "2.1.5", + "esbuild": "0.28.1", + "miniflare": "4.20260617.1", + "path-to-regexp": "6.3.0", + "unenv": "2.0.0-rc.24", + "workerd": "1.20260617.1" + }, + "bin": { + "cf-wrangler": "bin/cf-wrangler.js", + "wrangler": "bin/wrangler.js", + "wrangler2": "bin/wrangler.js" + }, + "engines": { + "node": ">=22.0.0" + }, + "optionalDependencies": { + "fsevents": "2.3.3" + }, + "peerDependencies": { + "@cloudflare/workers-types": "^4.20260617.1" + }, + "peerDependenciesMeta": { + "@cloudflare/workers-types": { + "optional": true + } + } + }, + "node_modules/ws": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", + "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/youch": { + "version": "4.1.0-beta.10", + "resolved": "https://registry.npmjs.org/youch/-/youch-4.1.0-beta.10.tgz", + "integrity": "sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@poppinss/colors": "^4.1.5", + "@poppinss/dumper": "^0.6.4", + "@speed-highlight/core": "^1.2.7", + "cookie": "^1.0.2", + "youch-core": "^0.3.3" + } + }, + "node_modules/youch-core": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/youch-core/-/youch-core-0.3.3.tgz", + "integrity": "sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@poppinss/exception": "^1.2.2", + "error-stack-parser-es": "^1.0.5" + } + } + } +} diff --git a/worker/package.json b/worker/package.json new file mode 100644 index 0000000..d25c8c1 --- /dev/null +++ b/worker/package.json @@ -0,0 +1,27 @@ +{ + "name": "clade-registry-api", + "version": "0.1.0", + "private": true, + "type": "module", + "license": "MPL-2.0", + "description": "Cloudflare Worker API for the hyperpolymath clade registry (gv-clade-index)", + "author": "Jonathan D.A. Jewell ", + "scripts": { + "dev": "wrangler dev", + "deploy": "wrangler deploy", + "deploy:dry": "wrangler deploy --dry-run", + "test": "vitest run", + "test:watch": "vitest", + "lint": "eslint .", + "format": "prettier --write .", + "format:check": "prettier --check ." + }, + "devDependencies": { + "@eslint/js": "^10.0.1", + "eslint": "^10.5.0", + "globals": "^17.6.0", + "prettier": "^3.8.4", + "vitest": "^4.1.9", + "wrangler": "^4.103.0" + } +} diff --git a/worker/src/http.js b/worker/src/http.js new file mode 100644 index 0000000..c2361a8 --- /dev/null +++ b/worker/src/http.js @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: MPL-2.0 +// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell +// +// HTTP response helpers: CORS, security headers, JSON envelopes, request ids. + +export const CORS_HEADERS = { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization', + 'Access-Control-Max-Age': '86400', +}; + +// Hardening headers applied to every response. This is a JSON API that serves +// no HTML, so the CSP is maximally restrictive. +export const SECURITY_HEADERS = { + 'X-Content-Type-Options': 'nosniff', + 'X-Frame-Options': 'DENY', + 'Referrer-Policy': 'no-referrer', + 'Content-Security-Policy': "default-src 'none'; frame-ancestors 'none'", + 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains', +}; + +/** + * Generate a short request id for log correlation and the X-Request-Id header. + * Uses crypto.randomUUID where available (Workers + Node 22), else a fallback. + * + * @returns {string} + */ +export function makeRequestId() { + try { + return crypto.randomUUID(); + } catch { + return `req_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`; + } +} + +/** + * Build a JSON Response with caching, CORS and security headers. + * + * @param {*} data + * @param {object} [opts] + * @param {number} [opts.status=200] + * @param {string} [opts.requestId] + * @param {number} [opts.maxAge=300] - Cache-Control max-age (seconds); 0 → no-store + * @returns {Response} + */ +export function json(data, { status = 200, requestId, maxAge = 300 } = {}) { + const headers = { + 'Content-Type': 'application/json; charset=utf-8', + 'Cache-Control': maxAge > 0 ? `public, max-age=${maxAge}` : 'no-store', + ...CORS_HEADERS, + ...SECURITY_HEADERS, + }; + if (requestId) headers['X-Request-Id'] = requestId; + return new Response(JSON.stringify(data, null, 2), { status, headers }); +} + +/** + * Build a JSON error envelope (never cached). + * + * @param {string} message + * @param {object} [opts] + * @param {number} [opts.status=404] + * @param {string} [opts.requestId] + * @returns {Response} + */ +export function error(message, { status = 404, requestId } = {}) { + return json({ error: message }, { status, requestId, maxAge: 0 }); +} diff --git a/worker/src/index.js b/worker/src/index.js index 455c3e8..99e3afb 100644 --- a/worker/src/index.js +++ b/worker/src/index.js @@ -1,6 +1,8 @@ // SPDX-License-Identifier: MPL-2.0 +// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell +// // Cloudflare Worker: clade-registry-api -// Serves the hyperpolymath clade registry as a read-only API +// Read-only API serving the hyperpolymath clade registry. // // Endpoints: // GET /v1/clades — List all 12 clades with stats @@ -10,115 +12,127 @@ // GET /v1/search?q=... — Full-text search across repos // GET /v1/llm?q=... — Structured output for LLM consumption // GET /v1/dashboard — Ecosystem overview -// GET /v1/health — Health check +// GET /v1/health — Liveness check (no backing store) +// GET /v1/ready — Readiness check (probes VeriSimDB; "degraded" on KV fallback) // GET /v1/query/language?q=.. — Query repos by language (VeriSimDB-backed) // GET /v1/query/tag?q=... — Query repos by tag (VeriSimDB-backed) // -// Storage: Dual-write pattern — Cloudflare KV (primary cache) + VeriSimDB -// (persistent store). loadIndex() prefers VeriSimDB, falls back to KV. - -import { loadIndex as vdbLoadIndex, queryByLanguage, queryByTag } from './verisimdb.js'; - -const CORS_HEADERS = { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - 'Access-Control-Max-Age': '86400', +// Storage: dual-store — Cloudflare KV (cache) + VeriSimDB (persistent). +// loadIndex() prefers VeriSimDB and falls back to KV. + +import { loadIndex, queryByLanguage, queryByTag, refreshFromSource, ping } from './verisim.js'; +import { json, error, makeRequestId, CORS_HEADERS, SECURITY_HEADERS } from './http.js'; +import { isValidClade, VALID_CLADES, positiveInt, safeDecode, boundedQuery } from './validate.js'; +import { allow } from './ratelimit.js'; +import { createLogger } from './log.js'; + +const VERSION = '0.1.0'; + +const ENDPOINT_DOCS = { + '/v1/dashboard': 'Ecosystem overview with clade stats', + '/v1/clades': 'List all 12 clades', + '/v1/clade/:code': 'Single clade with member repos (e.g. /v1/clade/fv)', + '/v1/repo/:name': 'Single repo detail (e.g. /v1/repo/januskey)', + '/v1/repos': 'All repos (params: clade, page, limit)', + '/v1/search?q=...': 'Full-text search across repos', + '/v1/llm?q=...': 'Structured output for LLM consumption', + '/v1/query/language?q=...': 'Query repos by language keyword (VeriSimDB)', + '/v1/query/tag?q=...': 'Query repos by tag (VeriSimDB)', + '/v1/health': 'Liveness check', + '/v1/ready': 'Readiness check (backing-store health)', }; -function json(data, status = 200) { - return new Response(JSON.stringify(data, null, 2), { - status, - headers: { - 'Content-Type': 'application/json; charset=utf-8', - 'Cache-Control': 'public, max-age=300', - ...CORS_HEADERS, - }, - }); -} - -function error(message, status = 404) { - return json({ error: message }, status); -} - -// Load index data — prefers VeriSimDB, falls back to Cloudflare KV. -// Uses the unified loadIndex from verisimdb.js (dual-store aware). -async function loadIndex(env) { - return vdbLoadIndex(env); -} - -// Search repos by query string (simple text matching across name + description) +// Simple text search across name + description + clade. function searchRepos(index, query) { - const q = query.toLowerCase(); - const terms = q.split(/\s+/).filter(t => t.length > 0); + const terms = query + .toLowerCase() + .split(/\s+/) + .filter((t) => t.length > 0); const results = []; for (const [name, repo] of Object.entries(index.by_name)) { - const searchable = `${name} ${repo.description} ${repo.clade}`.toLowerCase(); - const score = terms.reduce((acc, term) => { - if (searchable.includes(term)) return acc + 1; - return acc; - }, 0); - if (score > 0) { - results.push({ ...repo, score }); - } + const searchable = `${name} ${repo.description || ''} ${repo.clade || ''}`.toLowerCase(); + const score = terms.reduce((acc, term) => (searchable.includes(term) ? acc + 1 : acc), 0); + if (score > 0) results.push({ ...repo, score }); } - results.sort((a, b) => b.score - a.score); return results; } -export default { - async fetch(request, env) { - const url = new URL(request.url); - const path = url.pathname; +// Per-route handling. Throwing here is caught by fetch() and turned into a 500. +async function route(request, env, log, requestId) { + const url = new URL(request.url); + const path = url.pathname; + const clientIp = request.headers.get('CF-Connecting-IP') || 'anon'; - // Handle CORS preflight - if (request.method === 'OPTIONS') { - return new Response(null, { headers: CORS_HEADERS }); - } + // CORS preflight + if (request.method === 'OPTIONS') { + return new Response(null, { headers: { ...CORS_HEADERS, ...SECURITY_HEADERS } }); + } - // Only allow GET - if (request.method !== 'GET') { - return error('Method not allowed', 405); - } + // Read-only API + if (request.method !== 'GET') { + return error('Method not allowed', { status: 405, requestId }); + } - // Health check (no KV needed) - if (path === '/v1/health' || path === '/health') { - return json({ + // Liveness — never touches a backing store. + if (path === '/v1/health' || path === '/health') { + return json( + { status: 'ok', service: 'clade-registry-api', - version: '0.1.0', + version: VERSION, timestamp: new Date().toISOString(), - }); - } + }, + { requestId, maxAge: 0 }, + ); + } - // Load index - const index = await loadIndex(env); - if (!index) { - return error('Registry data not loaded — run sync', 503); - } + // Readiness — probe backing stores; "degraded" when serving from KV fallback. + if (path === '/v1/ready' || path === '/ready') { + const probe = await ping(env, log); + const ready = probe.verisimdb || probe.kv; + return json( + { + status: ready ? (probe.verisimdb ? 'ready' : 'degraded') : 'unavailable', + backing: probe.verisimdb ? 'verisimdb' : probe.kv ? 'kv' : 'none', + verisimdb: probe.verisimdb, + kv: probe.kv, + timestamp: new Date().toISOString(), + }, + { status: ready ? 200 : 503, requestId, maxAge: 0 }, + ); + } + + // Load index (VeriSimDB → KV fallback) + const index = await loadIndex(env, log); + if (!index) { + return error('Registry data not loaded — run sync', { status: 503, requestId }); + } - // Route: GET /v1/dashboard - if (path === '/v1/dashboard') { - const cladesSummary = index.clades.map(c => ({ - code: c.code, - name: c.name, - colour: c.colour, - member_count: c.member_count, - })); - return json({ + // GET /v1/dashboard + if (path === '/v1/dashboard') { + return json( + { total_repos: index.total_repos, total_clades: index.total_clades, generated: index.generated, - clades: cladesSummary, - }); - } + clades: index.clades.map((c) => ({ + code: c.code, + name: c.name, + colour: c.colour, + member_count: c.member_count, + })), + }, + { requestId }, + ); + } - // Route: GET /v1/clades - if (path === '/v1/clades') { - return json({ - clades: index.clades.map(c => ({ + // GET /v1/clades + if (path === '/v1/clades') { + return json( + { + clades: index.clades.map((c) => ({ code: c.code, name: c.name, description: c.description, @@ -127,119 +141,118 @@ export default { member_count: c.member_count, keywords: c.keywords, })), - }); - } + }, + { requestId }, + ); + } - // Route: GET /v1/clade/:code - const cladeMatch = path.match(/^\/v1\/clade\/([a-z]{2})$/); - if (cladeMatch) { - const code = cladeMatch[1]; - const clade = index.clades.find(c => c.code === code); - if (!clade) { - return error(`Clade '${code}' not found. Valid codes: ${index.clades.map(c => c.code).join(', ')}`); - } - const members = clade.members.map(name => index.by_name[name]).filter(Boolean); - return json({ - ...clade, - repos: members, + // GET /v1/clade/:code + const cladeMatch = path.match(/^\/v1\/clade\/([a-z]{2})$/); + if (cladeMatch) { + const code = cladeMatch[1]; + if (!isValidClade(code)) { + return error(`Clade '${code}' not found. Valid codes: ${VALID_CLADES.join(', ')}`, { + requestId, }); } + const clade = index.clades.find((c) => c.code === code); + if (!clade) return error(`Clade '${code}' not found`, { requestId }); + const members = clade.members.map((name) => index.by_name[name]).filter(Boolean); + return json({ ...clade, repos: members }, { requestId }); + } - // Route: GET /v1/repo/:name - const repoMatch = path.match(/^\/v1\/repo\/(.+)$/); - if (repoMatch) { - const name = decodeURIComponent(repoMatch[1]); - const repo = index.by_name[name]; - if (!repo) { - return error(`Repo '${name}' not found`); - } - // Find the clade info - const clade = index.clades.find(c => c.code === repo.clade); - return json({ + // GET /v1/repo/:name + const repoMatch = path.match(/^\/v1\/repo\/(.+)$/); + if (repoMatch) { + const name = safeDecode(repoMatch[1]); + if (name === null) return error('Malformed repo name', { status: 400, requestId }); + const repo = index.by_name[name]; + if (!repo) return error(`Repo '${name}' not found`, { requestId }); + const clade = index.clades.find((c) => c.code === repo.clade); + return json( + { ...repo, clade_name: clade ? clade.name : repo.clade, clade_colour: clade ? clade.colour : null, github_url: `https://github.com/${repo.github}`, portal_url: `https://hyperpolymath.github.io/#/project/${name}`, + }, + { requestId }, + ); + } + + // GET /v1/repos?clade=xx&page=1&limit=50 + if (path === '/v1/repos') { + const cladeFilter = url.searchParams.get('clade'); + if (cladeFilter && !isValidClade(cladeFilter)) { + return error(`Invalid clade '${cladeFilter}'. Valid codes: ${VALID_CLADES.join(', ')}`, { + status: 400, + requestId, }); } - - // Route: GET /v1/repos?clade=xx&page=1&limit=50 - if (path === '/v1/repos') { - const cladeFilter = url.searchParams.get('clade'); - const page = parseInt(url.searchParams.get('page') || '1', 10); - const limit = Math.min(parseInt(url.searchParams.get('limit') || '50', 10), 200); - const offset = (page - 1) * limit; - - let repos = Object.values(index.by_name); - if (cladeFilter) { - repos = repos.filter(r => r.clade === cladeFilter); - } - repos.sort((a, b) => a.name.localeCompare(b.name)); - - const total = repos.length; - const paginated = repos.slice(offset, offset + limit); - - return json({ - repos: paginated, + const page = positiveInt(url.searchParams.get('page'), 1); + const limit = positiveInt(url.searchParams.get('limit'), 50, 200); + const offset = (page - 1) * limit; + + let repos = Object.values(index.by_name); + if (cladeFilter) repos = repos.filter((r) => r.clade === cladeFilter); + repos.sort((a, b) => a.name.localeCompare(b.name)); + + const total = repos.length; + return json( + { + repos: repos.slice(offset, offset + limit), total, page, limit, pages: Math.ceil(total / limit), - }); - } - - // Route: GET /v1/search?q=... - if (path === '/v1/search') { - const query = url.searchParams.get('q'); - if (!query || query.trim().length === 0) { - return error('Query parameter q is required', 400); - } - const results = searchRepos(index, query); - const limit = Math.min(parseInt(url.searchParams.get('limit') || '20', 10), 100); + }, + { requestId }, + ); + } - return json({ - query, - results: results.slice(0, limit), - total: results.length, - }); + // GET /v1/search?q=... + if (path === '/v1/search') { + const q = boundedQuery(url.searchParams.get('q')); + if (!q.ok) return error(q.reason, { status: 400, requestId }); + if (!(await allow(env, `search:${clientIp}`))) { + return error('Rate limit exceeded', { status: 429, requestId }); } + const results = searchRepos(index, q.value); + const limit = positiveInt(url.searchParams.get('limit'), 20, 100); + return json( + { query: q.value, results: results.slice(0, limit), total: results.length }, + { requestId }, + ); + } - // Route: GET /v1/llm?q=... - // Structured output optimised for LLM consumption - if (path === '/v1/llm') { - const query = url.searchParams.get('q'); - if (!query || query.trim().length === 0) { - return error('Query parameter q is required', 400); - } - - // Check for API key in Authorization header (optional for now) - // const apiKey = request.headers.get('Authorization'); - - const results = searchRepos(index, query); - const top = results.slice(0, 10); - - // Build relationship hints from clade membership - const relationships = []; - const clades = new Set(top.map(r => r.clade)); - if (clades.size > 1) { - for (const c of clades) { - const inClade = top.filter(r => r.clade === c); - if (inClade.length > 1) { - relationships.push({ - type: 'same-clade', - clade: c, - repos: inClade.map(r => r.name), - }); - } + // GET /v1/llm?q=... — structured output optimised for LLM consumption + if (path === '/v1/llm') { + const q = boundedQuery(url.searchParams.get('q')); + if (!q.ok) return error(q.reason, { status: 400, requestId }); + if (!(await allow(env, `llm:${clientIp}`))) { + return error('Rate limit exceeded', { status: 429, requestId }); + } + const results = searchRepos(index, q.value); + const top = results.slice(0, 10); + + const relationships = []; + const clades = new Set(top.map((r) => r.clade)); + if (clades.size > 1) { + for (const c of clades) { + const inClade = top.filter((r) => r.clade === c); + if (inClade.length > 1) { + relationships.push({ type: 'same-clade', clade: c, repos: inClade.map((r) => r.name) }); } } + } - return json({ - query, + return json( + { + query: q.value, ecosystem: 'hyperpolymath', registry: 'gv-clade-index', - results: top.map(r => ({ + results: top.map((r) => ({ repo: r.prefixed, canonical_name: r.name, summary: r.description, @@ -250,67 +263,95 @@ export default { })), relationships, total_matches: results.length, - }); - } + }, + { requestId }, + ); + } - // Root — API documentation - if (path === '/' || path === '/v1') { - return json({ + // Root — API documentation + if (path === '/' || path === '/v1') { + return json( + { name: 'Hyperpolymath Clade Registry API', - version: '0.1.0', - description: 'Read-only API for the hyperpolymath ecosystem registry. Map and territory — this is the map.', - endpoints: { - '/v1/dashboard': 'Ecosystem overview with clade stats', - '/v1/clades': 'List all 12 clades', - '/v1/clade/:code': 'Single clade with member repos (e.g. /v1/clade/fv)', - '/v1/repo/:name': 'Single repo detail (e.g. /v1/repo/januskey)', - '/v1/repos': 'All repos (params: clade, page, limit)', - '/v1/search?q=...': 'Full-text search across repos', - '/v1/llm?q=...': 'Structured output for LLM consumption', - '/v1/query/language?q=...': 'Query repos by language keyword (VeriSimDB)', - '/v1/query/tag?q=...': 'Query repos by tag (VeriSimDB)', - '/v1/health': 'Health check', - }, - total_repos: index ? index.total_repos : 'loading', - total_clades: index ? index.total_clades : 'loading', + version: VERSION, + description: + 'Read-only API for the hyperpolymath ecosystem registry. Map and territory — this is the map.', + endpoints: ENDPOINT_DOCS, + total_repos: index.total_repos, + total_clades: index.total_clades, source: 'https://github.com/hyperpolymath/gv-clade-index', - }); + }, + { requestId }, + ); + } + + // GET /v1/query/language?q=rust + if (path === '/v1/query/language') { + const q = boundedQuery(url.searchParams.get('q')); + if (!q.ok) return error(q.reason, { status: 400, requestId }); + if (!(await allow(env, `query:${clientIp}`))) { + return error('Rate limit exceeded', { status: 429, requestId }); } + const results = await queryByLanguage(env, q.value, log); + return json( + { query: q.value, type: 'language', results, total: results.length, source: 'verisimdb' }, + { requestId }, + ); + } - // Route: GET /v1/query/language?q=rust - // Query repos by primary language keyword (VeriSimDB-backed, falls back to KV) - if (path === '/v1/query/language') { - const q = url.searchParams.get('q'); - if (!q || q.trim().length === 0) { - return error('Query parameter q is required', 400); - } - const results = await queryByLanguage(env, q.trim()); - return json({ - query: q.trim(), - type: 'language', - results, - total: results.length, - source: 'verisimdb', - }); + // GET /v1/query/tag?q=security + if (path === '/v1/query/tag') { + const q = boundedQuery(url.searchParams.get('q')); + if (!q.ok) return error(q.reason, { status: 400, requestId }); + if (!(await allow(env, `query:${clientIp}`))) { + return error('Rate limit exceeded', { status: 429, requestId }); } + const results = await queryByTag(env, q.value, log); + return json( + { query: q.value, type: 'tag', results, total: results.length, source: 'verisimdb' }, + { requestId }, + ); + } - // Route: GET /v1/query/tag?q=security - // Query repos by tag / keyword (VeriSimDB-backed, falls back to KV) - if (path === '/v1/query/tag') { - const q = url.searchParams.get('q'); - if (!q || q.trim().length === 0) { - return error('Query parameter q is required', 400); - } - const results = await queryByTag(env, q.trim()); - return json({ - query: q.trim(), - type: 'tag', - results, - total: results.length, - source: 'verisimdb', + return error('Not found. Try /v1 for API documentation.', { requestId }); +} + +export default { + async fetch(request, env) { + const requestId = makeRequestId(); + const log = createLogger({ reqId: requestId }); + const start = Date.now(); + const url = new URL(request.url); + try { + const res = await route(request, env, log, requestId); + log.info('request', { + method: request.method, + path: url.pathname, + status: res.status, + ms: Date.now() - start, + }); + return res; + } catch (err) { + log.error('unhandled', { + method: request.method, + path: url.pathname, + error: err && err.message, + stack: err && err.stack, }); + return error('Internal error', { status: 500, requestId }); } + }, - return error('Not found. Try /v1 for API documentation.'); + // Cron trigger — refresh the snapshot into both stores. Configured via + // wrangler.toml [triggers] crons and env.DATA_SOURCE_URL. + async scheduled(event, env) { + const log = createLogger({ reqId: `cron_${event.scheduledTime || Date.now()}` }); + log.info('scheduled.start', { cron: event.cron }); + try { + const result = await refreshFromSource(env, log); + log.info('scheduled.done', result); + } catch (err) { + log.error('scheduled.error', { error: err && err.message }); + } }, }; diff --git a/worker/src/log.js b/worker/src/log.js new file mode 100644 index 0000000..4da5a93 --- /dev/null +++ b/worker/src/log.js @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: MPL-2.0 +// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell +// +// Structured JSON logging for the clade-registry Worker. +// +// Emits one JSON object per line so Cloudflare Logpush / `wrangler tail` +// can parse and filter by field (level, reqId, path, ...). Workers captures +// console.* into its log stream, so we route through console. + +/** + * Create a logger bound to a set of default fields (e.g. a request id). + * + * @param {object} [bindings] - fields merged into every emitted line + * @returns {{debug:Function,info:Function,warn:Function,error:Function,child:Function}} + */ +export function createLogger(bindings = {}) { + function emit(level, msg, fields) { + const line = { level, msg, ts: new Date().toISOString(), ...bindings, ...fields }; + const out = level === 'error' || level === 'warn' ? console.error : console.log; + out(JSON.stringify(line)); + } + return { + debug: (msg, fields) => emit('debug', msg, fields), + info: (msg, fields) => emit('info', msg, fields), + warn: (msg, fields) => emit('warn', msg, fields), + error: (msg, fields) => emit('error', msg, fields), + child: (extra) => createLogger({ ...bindings, ...extra }), + }; +} + +/** Module-level logger with no bindings — used as a default. */ +export const log = createLogger(); diff --git a/worker/src/ratelimit.js b/worker/src/ratelimit.js new file mode 100644 index 0000000..fd63590 --- /dev/null +++ b/worker/src/ratelimit.js @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: MPL-2.0 +// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell +// +// Optional edge rate limiting via Cloudflare's native Rate Limiting binding. +// No-ops when the binding is absent (local dev / tests), and fails open so the +// limiter can never take down the read API. +// +// Configure in wrangler.toml, e.g.: +// [[unsafe.bindings]] +// name = "RATE_LIMITER" +// type = "ratelimit" +// namespace_id = "1001" +// simple = { limit = 100, period = 60 } + +/** + * @param {object} env - Worker env bindings + * @param {string} key - rate-limit bucket key (e.g. client IP + route) + * @returns {Promise} true when the request is allowed + */ +export async function allow(env, key) { + const limiter = env && env.RATE_LIMITER; + if (!limiter || typeof limiter.limit !== 'function') return true; + try { + const { success } = await limiter.limit({ key }); + return success !== false; + } catch { + return true; // fail open + } +} diff --git a/worker/src/validate.js b/worker/src/validate.js new file mode 100644 index 0000000..42a9f6b --- /dev/null +++ b/worker/src/validate.js @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: MPL-2.0 +// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell +// +// Input validation helpers for untrusted path / query parameters. + +// The 12 canonical clade codes. Mirrors contractiles/must/clade-hygiene.a2ml +// and verisim/seed/clades.a2ml — keep in sync if the taxonomy changes. +export const VALID_CLADES = Object.freeze([ + 'fv', + 'nl', + 'rm', + 'gv', + 'db', + 'ap', + 'ix', + 'dx', + 'pt', + 'ax', + 'gm', + 'sc', +]); + +const CLADE_SET = new Set(VALID_CLADES); + +/** + * @param {unknown} code + * @returns {boolean} true when code is one of the 12 canonical clade codes + */ +export function isValidClade(code) { + return typeof code === 'string' && CLADE_SET.has(code); +} + +/** + * Parse a positive integer query param with a default and an inclusive maximum. + * Returns `fallback` (capped at `max`) for missing / NaN / < 1 values. + * + * @param {string|null|undefined} raw + * @param {number} fallback + * @param {number} [max] + * @returns {number} + */ +export function positiveInt(raw, fallback, max = Number.MAX_SAFE_INTEGER) { + const n = Number.parseInt(raw ?? '', 10); + if (!Number.isFinite(n) || n < 1) return Math.min(fallback, max); + return Math.min(n, max); +} + +/** + * Decode a URI component, returning null on malformed input instead of throwing. + * + * @param {string} raw + * @returns {string|null} + */ +export function safeDecode(raw) { + try { + return decodeURIComponent(raw); + } catch { + return null; + } +} + +// Maximum accepted length for free-text search queries. +export const MAX_QUERY_LEN = 256; + +/** + * Normalise and bound a free-text query param. + * + * @param {string|null|undefined} raw + * @returns {{ok:true,value:string}|{ok:false,reason:string}} + */ +export function boundedQuery(raw) { + if (raw == null) return { ok: false, reason: 'Query parameter q is required' }; + const value = raw.trim(); + if (value.length === 0) return { ok: false, reason: 'Query parameter q is required' }; + if (value.length > MAX_QUERY_LEN) { + return { ok: false, reason: `Query too long (max ${MAX_QUERY_LEN} characters)` }; + } + return { ok: true, value }; +} diff --git a/worker/src/verisim.js b/worker/src/verisim.js index e2132fe..6e2eb94 100644 --- a/worker/src/verisim.js +++ b/worker/src/verisim.js @@ -6,33 +6,39 @@ // Collection namespaces used: // clade:repos — all 202+ hyperpolymath repos with clade metadata // clade:clades — 12 clade definitions -// clade:index — pre-built search index (by_name + by_clade maps) +// clade:index — pre-built search index (by_name + clades maps) // -// Dual-write pattern: all mutations go to both Cloudflare KV and VeriSimDB. -// Reads prefer VeriSimDB when VERISIMDB_URL is present in the worker env; -// fall back to KV when VeriSimDB is unreachable. +// Dual-store pattern: reads prefer VeriSimDB when VERISIMDB_URL is present in +// the worker env; fall back to Cloudflare KV when VeriSimDB is unreachable. // -// Configuration (Cloudflare Worker env vars / wrangler.toml [vars]): -// VERISIMDB_URL — Base URL for VeriSimDB (default: http://localhost:8080) +// Configuration (wrangler.toml [vars] / secrets): +// VERISIMDB_URL — Base URL for VeriSimDB (default: http://localhost:8080) +// DATA_SOURCE_URL — Base URL for the canonical JSON snapshot used by the +// scheduled refresh (e.g. the raw worker/data/ directory) // -// Query functions exposed: -// queryByLanguage(env, language) -> [repo, ...] -// queryByTag(env, tag) -> [repo, ...] -// seedFromStaticJson(env, repos, clades) -> { seeded: number } +// Exposed: +// loadIndex(env, log) -> index | null +// queryByLanguage(env, language, log) -> [repo, ...] +// queryByTag(env, tag, log) -> [repo, ...] +// seedFromStaticJson(env, repos, clades, log) -> { seeded, errors } +// refreshFromSource(env, log) -> { seeded, errors } | { skipped } +// ping(env, log) -> { verisimdb: bool, kv: bool } + +import { log as moduleLog } from './log.js'; const API_PREFIX = '/api/v1'; -const COL_REPOS = 'clade:repos'; -const COL_CLADES = 'clade:clades'; -const COL_INDEX = 'clade:index'; +const COL_REPOS = 'clade:repos'; +const COL_CLADES = 'clade:clades'; +const COL_INDEX = 'clade:index'; // ── Low-level HTTP helpers ──────────────────────────────────────────────── /** - * Return the VeriSimDB base URL from the worker env. - * Falls back to localhost (useful for local dev / Miniflare). + * Return the VeriSimDB base URL from the worker env (no trailing slash). + * Falls back to localhost for local dev / Miniflare. * - * @param {object} env - Cloudflare Worker env bindings - * @returns {string} base URL without trailing slash + * @param {object} env + * @returns {string} */ function baseUrl(env) { return (env.VERISIMDB_URL || 'http://localhost:8080').replace(/\/$/, ''); @@ -41,13 +47,14 @@ function baseUrl(env) { /** * PUT a single document into VeriSimDB. * - * @param {object} env - Worker env - * @param {string} collection - Collection name (e.g. "clade:repos") - * @param {string} id - Document ID - * @param {object} data - Document body + * @param {object} env + * @param {string} collection + * @param {string} id + * @param {object} data + * @param {object} [log] * @returns {Promise} true on success */ -async function vdbPut(env, collection, id, data) { +async function vdbPut(env, collection, id, data, log = moduleLog) { const url = `${baseUrl(env)}${API_PREFIX}/${encodeURIComponent(collection)}/${encodeURIComponent(id)}`; try { const res = await fetch(url, { @@ -56,12 +63,12 @@ async function vdbPut(env, collection, id, data) { body: JSON.stringify(data), }); if (!res.ok) { - console.warn(`[verisimdb] PUT ${url} -> ${res.status}`); + log.warn('verisimdb.put.status', { url, status: res.status }); return false; } return true; } catch (err) { - console.warn(`[verisimdb] PUT ${url} network error: ${err.message}`); + log.warn('verisimdb.put.error', { url, error: err.message }); return false; } } @@ -69,49 +76,51 @@ async function vdbPut(env, collection, id, data) { /** * GET a single document from VeriSimDB. * - * @param {object} env - Worker env - * @param {string} collection - Collection name - * @param {string} id - Document ID - * @returns {Promise} document or null when not found / unreachable + * @param {object} env + * @param {string} collection + * @param {string} id + * @param {object} [log] + * @returns {Promise} document, or null when not found / unreachable */ -async function vdbGet(env, collection, id) { +async function vdbGet(env, collection, id, log = moduleLog) { const url = `${baseUrl(env)}${API_PREFIX}/${encodeURIComponent(collection)}/${encodeURIComponent(id)}`; try { const res = await fetch(url); if (res.status === 404) return null; if (!res.ok) { - console.warn(`[verisimdb] GET ${url} -> ${res.status}`); + log.warn('verisimdb.get.status', { url, status: res.status }); return null; } return await res.json(); } catch (err) { - console.warn(`[verisimdb] GET ${url} network error: ${err.message}`); + log.warn('verisimdb.get.error', { url, error: err.message }); return null; } } /** - * List documents in a collection, optionally filtered by prefix. + * List documents in a collection, optionally filtered by id prefix. * - * @param {object} env - Worker env - * @param {string} collection - Collection name - * @param {string} [prefix] - Optional ID prefix filter - * @returns {Promise} array of documents (empty on error) + * @param {object} env + * @param {string} collection + * @param {string} [prefix] + * @param {object} [log] + * @returns {Promise} documents (empty on error) */ -async function vdbList(env, collection, prefix = '') { +async function vdbList(env, collection, prefix = '', log = moduleLog) { const params = prefix ? `?prefix=${encodeURIComponent(prefix)}` : ''; const url = `${baseUrl(env)}${API_PREFIX}/${encodeURIComponent(collection)}${params}`; try { const res = await fetch(url); if (!res.ok) { - console.warn(`[verisimdb] LIST ${url} -> ${res.status}`); + log.warn('verisimdb.list.status', { url, status: res.status }); return []; } const body = await res.json(); - // VeriSimDB may return an array directly or { items: [...] } - return Array.isArray(body) ? body : (body.items || []); + // VeriSimDB may return an array directly or { items: [...] }. + return Array.isArray(body) ? body : body.items || []; } catch (err) { - console.warn(`[verisimdb] LIST ${url} network error: ${err.message}`); + log.warn('verisimdb.list.error', { url, error: err.message }); return []; } } @@ -119,201 +128,219 @@ async function vdbList(env, collection, prefix = '') { // ── Seed / sync functions ───────────────────────────────────────────────── /** - * Seed VeriSimDB from static JSON data files. - * - * Call this from a scheduled Cron trigger or from the sync scripts. - * Each repo is stored as an individual document in clade:repos. - * Each clade definition is stored in clade:clades. - * A pre-built index snapshot is stored in clade:index. + * Build the pre-computed index document from repos + clades arrays. * - * Mirrors writes to Cloudflare KV as well (dual-write). - * - * @param {object} env - Worker env (must have CLADE_KV and VERISIMDB_URL) - * @param {object[]} repos - Array of repo objects (from repos.json) - * @param {object[]} clades - Array of clade objects (from clades.json) - * @returns {Promise<{seeded: number, errors: number}>} + * @param {object[]} repos + * @param {object[]} clades + * @returns {object} */ -async function seedFromStaticJson(env, repos, clades) { - let seeded = 0; - let errors = 0; - - // Seed clade definitions - for (const clade of clades) { - const ok = await vdbPut(env, COL_CLADES, clade.code, clade); - if (ok) seeded++; - else errors++; - } - - // Seed repo documents - for (const repo of repos) { - const ok = await vdbPut(env, COL_REPOS, repo.name, repo); - if (ok) seeded++; - else errors++; - } - - // Build and store pre-computed index (mirrors what KV stores as "index") +function buildIndex(repos, clades) { const byName = {}; - for (const repo of repos) { - byName[repo.name] = repo; - } - const byClade = {}; for (const repo of repos) { + byName[repo.name] = repo; if (!byClade[repo.clade]) byClade[repo.clade] = []; byClade[repo.clade].push(repo.name); } - - const index = { + return { total_repos: repos.length, total_clades: clades.length, generated: new Date().toISOString(), - clades: clades.map(c => ({ + clades: clades.map((c) => ({ ...c, members: byClade[c.code] || [], member_count: (byClade[c.code] || []).length, })), by_name: byName, }; +} + +/** + * Seed VeriSimDB from static JSON data, mirroring the index to Cloudflare KV. + * + * @param {object} env + * @param {object[]} repos + * @param {object[]} clades + * @param {object} [log] + * @returns {Promise<{seeded:number, errors:number}>} + */ +async function seedFromStaticJson(env, repos, clades, log = moduleLog) { + let seeded = 0; + let errors = 0; + + for (const clade of clades) { + (await vdbPut(env, COL_CLADES, clade.code, clade, log)) ? seeded++ : errors++; + } + for (const repo of repos) { + (await vdbPut(env, COL_REPOS, repo.name, repo, log)) ? seeded++ : errors++; + } - const indexOk = await vdbPut(env, COL_INDEX, 'latest', index); - if (indexOk) seeded++; - else errors++; + const index = buildIndex(repos, clades); + (await vdbPut(env, COL_INDEX, 'latest', index, log)) ? seeded++ : errors++; - // Dual-write: also push index to Cloudflare KV (preserves existing behaviour) + // Dual-write: also push the index to Cloudflare KV. if (env.CLADE_KV) { try { await env.CLADE_KV.put('index', JSON.stringify(index)); } catch (err) { - console.warn(`[verisimdb] KV put failed: ${err.message}`); + log.warn('kv.put.error', { error: err.message }); errors++; } } - console.log(`[verisimdb] seedFromStaticJson: seeded=${seeded} errors=${errors}`); + log.info('seed.done', { seeded, errors }); return { seeded, errors }; } +/** + * Scheduled refresh: fetch the canonical JSON snapshot and re-seed both stores. + * No-ops (returns { skipped:true }) when DATA_SOURCE_URL is not configured. + * + * @param {object} env + * @param {object} [log] + * @returns {Promise<{seeded:number,errors:number}|{skipped:true,reason?:string}>} + */ +async function refreshFromSource(env, log = moduleLog) { + const base = (env.DATA_SOURCE_URL || '').replace(/\/$/, ''); + if (!base) { + log.warn('refresh.skip', { reason: 'DATA_SOURCE_URL not set' }); + return { skipped: true, reason: 'DATA_SOURCE_URL not set' }; + } + try { + const [reposRes, cladesRes] = await Promise.all([ + fetch(`${base}/repos.json`), + fetch(`${base}/clades.json`), + ]); + if (!reposRes.ok || !cladesRes.ok) { + log.error('refresh.fetch_failed', { repos: reposRes.status, clades: cladesRes.status }); + return { skipped: true, reason: 'fetch failed' }; + } + const repos = await reposRes.json(); + const clades = await cladesRes.json(); + return await seedFromStaticJson(env, repos, clades, log); + } catch (err) { + log.error('refresh.error', { error: err.message }); + return { skipped: true, reason: err.message }; + } +} + // ── Query functions ─────────────────────────────────────────────────────── /** - * Query repos by primary language keyword. + * Query repos by language keyword (name + description). VeriSimDB first, + * KV index fallback. * - * Searches the repo descriptions and tags in VeriSimDB. Falls back to the - * KV index when VeriSimDB is unavailable. - * - * @param {object} env - Worker env - * @param {string} language - Language name (case-insensitive, e.g. "rust") - * @returns {Promise} matching repos sorted by name + * @param {object} env + * @param {string} language + * @param {object} [log] + * @returns {Promise} */ -async function queryByLanguage(env, language) { +async function queryByLanguage(env, language, log = moduleLog) { const q = language.toLowerCase(); - const docs = await vdbList(env, COL_REPOS); + const match = (repo) => `${repo.name} ${repo.description || ''}`.toLowerCase().includes(q); + const byName = (a, b) => (a.name || '').localeCompare(b.name || ''); - if (docs.length > 0) { - return docs - .filter(repo => { - const searchable = `${repo.name} ${repo.description || ''}`.toLowerCase(); - return searchable.includes(q); - }) - .sort((a, b) => (a.name || '').localeCompare(b.name || '')); - } + const docs = await vdbList(env, COL_REPOS, '', log); + if (docs.length > 0) return docs.filter(match).sort(byName); - // VeriSimDB unavailable — fall back to KV index if (env.CLADE_KV) { const index = await env.CLADE_KV.get('index', { type: 'json' }); - if (index) { + if (index) return Object.values(index.by_name || {}) - .filter(repo => { - const searchable = `${repo.name} ${repo.description || ''}`.toLowerCase(); - return searchable.includes(q); - }) - .sort((a, b) => (a.name || '').localeCompare(b.name || '')); - } + .filter(match) + .sort(byName); } - return []; } /** - * Query repos by tag / keyword. - * - * Searches names, descriptions, clade keywords, and secondary clade codes. + * Query repos by tag / keyword (name, description, clade, secondary, clade keywords). + * VeriSimDB first, KV index fallback. * - * @param {object} env - Worker env - * @param {string} tag - Tag or keyword (case-insensitive) - * @returns {Promise} matching repos sorted by name + * @param {object} env + * @param {string} tag + * @param {object} [log] + * @returns {Promise} */ -async function queryByTag(env, tag) { +async function queryByTag(env, tag, log = moduleLog) { const q = tag.toLowerCase(); - const docs = await vdbList(env, COL_REPOS); + const byName = (a, b) => (a.name || '').localeCompare(b.name || ''); + const docs = await vdbList(env, COL_REPOS, '', log); if (docs.length > 0) { return docs - .filter(repo => { + .filter((repo) => { const secondaryStr = (repo.secondary || []).join(' '); - const searchable = `${repo.name} ${repo.description || ''} ${repo.clade || ''} ${secondaryStr}`.toLowerCase(); - return searchable.includes(q); + return `${repo.name} ${repo.description || ''} ${repo.clade || ''} ${secondaryStr}` + .toLowerCase() + .includes(q); }) - .sort((a, b) => (a.name || '').localeCompare(b.name || '')); + .sort(byName); } - // VeriSimDB unavailable — fall back to KV index if (env.CLADE_KV) { const index = await env.CLADE_KV.get('index', { type: 'json' }); if (index) { - // Also check clade keyword lists from clades array const cladeKeywords = {}; - for (const c of (index.clades || [])) { - cladeKeywords[c.code] = (c.keywords || []); - } - + for (const c of index.clades || []) cladeKeywords[c.code] = c.keywords || []; return Object.values(index.by_name || {}) - .filter(repo => { + .filter((repo) => { const keywords = cladeKeywords[repo.clade] || []; const secondaryStr = (repo.secondary || []).join(' '); - const searchable = [ - repo.name, - repo.description || '', - repo.clade || '', - secondaryStr, - ...keywords, - ].join(' ').toLowerCase(); - return searchable.includes(q); + return [repo.name, repo.description || '', repo.clade || '', secondaryStr, ...keywords] + .join(' ') + .toLowerCase() + .includes(q); }) - .sort((a, b) => (a.name || '').localeCompare(b.name || '')); + .sort(byName); } } - return []; } /** * Load the clade index, preferring VeriSimDB over KV. * - * Drop-in replacement for `loadIndex(env)` in index.js. - * - * @param {object} env - Worker env - * @returns {Promise} index document or null + * @param {object} env + * @param {object} [log] + * @returns {Promise} */ -async function loadIndex(env) { - // Try VeriSimDB first - const vdbIndex = await vdbGet(env, COL_INDEX, 'latest'); +async function loadIndex(env, log = moduleLog) { + const vdbIndex = await vdbGet(env, COL_INDEX, 'latest', log); if (vdbIndex) return vdbIndex; + if (env.CLADE_KV) return await env.CLADE_KV.get('index', { type: 'json' }); + return null; +} - // Fall back to KV +/** + * Probe backing stores for readiness reporting. + * + * @param {object} env + * @param {object} [log] + * @returns {Promise<{verisimdb:boolean, kv:boolean}>} + */ +async function ping(env, log = moduleLog) { + const vdb = await vdbGet(env, COL_INDEX, 'latest', log); + let kv = false; if (env.CLADE_KV) { - return await env.CLADE_KV.get('index', { type: 'json' }); + try { + kv = (await env.CLADE_KV.get('index')) != null; + } catch (err) { + log.warn('kv.ping.error', { error: err.message }); + } } - - return null; + return { verisimdb: vdb != null, kv }; } export { vdbPut, vdbGet, vdbList, + buildIndex, seedFromStaticJson, + refreshFromSource, queryByLanguage, queryByTag, loadIndex, + ping, }; diff --git a/worker/test/data.test.js b/worker/test/data.test.js new file mode 100644 index 0000000..7d24d58 --- /dev/null +++ b/worker/test/data.test.js @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: MPL-2.0 +// Contract tests for the committed registry snapshot (worker/data/*.json): +// enforce the 12-clade invariant and internal count/membership consistency, +// so snapshot drift (e.g. a repo added to repos.json but not re-indexed) fails CI. + +import { readFileSync } from 'node:fs'; +import { fileURLToPath } from 'node:url'; +import path from 'node:path'; +import { describe, it, expect } from 'vitest'; + +import { VALID_CLADES } from '../src/validate.js'; + +const here = path.dirname(fileURLToPath(import.meta.url)); +const load = (f) => JSON.parse(readFileSync(path.join(here, '../data', f), 'utf8')); + +const repos = load('repos.json'); +const clades = load('clades.json'); +const index = load('index.json'); + +describe('clades.json', () => { + it('defines exactly the 12 canonical clades', () => { + expect(clades).toHaveLength(12); + const codes = clades.map((c) => c.code).sort(); + expect(codes).toEqual([...VALID_CLADES].sort()); + }); +}); + +describe('repos.json', () => { + it('every repo has a name, a valid primary clade, and a github slug', () => { + for (const repo of repos) { + expect(typeof repo.name).toBe('string'); + expect(repo.name.length).toBeGreaterThan(0); + expect(VALID_CLADES).toContain(repo.clade); + expect(typeof repo.github).toBe('string'); + } + }); + + it('repo names are unique', () => { + const names = repos.map((r) => r.name); + expect(new Set(names).size).toBe(names.length); + }); +}); + +describe('index.json consistency', () => { + it('total_repos equals repos.json and by_name counts', () => { + expect(index.total_repos).toBe(repos.length); + expect(Object.keys(index.by_name)).toHaveLength(repos.length); + }); + + it('clade membership covers every repo exactly once', () => { + const sum = index.clades.reduce((acc, c) => acc + c.member_count, 0); + expect(sum).toBe(repos.length); + for (const c of index.clades) { + expect(c.members).toHaveLength(c.member_count); + for (const name of c.members) expect(index.by_name[name]).toBeTruthy(); + } + }); +}); diff --git a/worker/test/worker.test.js b/worker/test/worker.test.js new file mode 100644 index 0000000..de953ee --- /dev/null +++ b/worker/test/worker.test.js @@ -0,0 +1,267 @@ +// SPDX-License-Identifier: MPL-2.0 +// Worker integration tests: drive the exported fetch() handler against a mocked +// Cloudflare KV seeded with the real committed snapshot (data/index.json). +// VeriSimDB is simulated as unreachable (global fetch throws) so the KV +// fallback path is exercised. + +import { readFileSync } from 'node:fs'; +import { fileURLToPath } from 'node:url'; +import path from 'node:path'; +import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; + +import worker from '../src/index.js'; + +const here = path.dirname(fileURLToPath(import.meta.url)); +const INDEX = JSON.parse(readFileSync(path.join(here, '../data/index.json'), 'utf8')); + +function makeKv(initial = {}) { + const store = new Map(Object.entries(initial)); + return { + store, + get: async (key, opts) => { + const v = store.get(key); + if (v == null) return null; + return opts && opts.type === 'json' ? JSON.parse(v) : v; + }, + put: async (key, val) => { + store.set(key, typeof val === 'string' ? val : JSON.stringify(val)); + }, + }; +} + +const envWithKv = () => ({ CLADE_KV: makeKv({ index: JSON.stringify(INDEX) }) }); + +async function call(pathAndQuery, { env = envWithKv(), method = 'GET' } = {}) { + const req = new Request(`https://api.test${pathAndQuery}`, { method }); + const res = await worker.fetch(req, env); + let body = null; + try { + body = await res.clone().json(); + } catch { + // non-JSON / empty response — leave body null + } + return { res, body }; +} + +beforeEach(() => { + // Simulate VeriSimDB unreachable → forces KV fallback. + vi.stubGlobal( + 'fetch', + vi.fn(async () => { + throw new Error('verisimdb unreachable'); + }), + ); +}); + +afterEach(() => { + vi.unstubAllGlobals(); +}); + +describe('health & readiness', () => { + it('GET /v1/health → 200 with security + request-id headers', async () => { + const { res, body } = await call('/v1/health'); + expect(res.status).toBe(200); + expect(body.status).toBe('ok'); + expect(res.headers.get('X-Content-Type-Options')).toBe('nosniff'); + expect(res.headers.get('Content-Security-Policy')).toContain("default-src 'none'"); + expect(res.headers.get('X-Request-Id')).toBeTruthy(); + expect(res.headers.get('Cache-Control')).toBe('no-store'); + }); + + it('GET /v1/ready → 200 degraded when only KV is available', async () => { + const { res, body } = await call('/v1/ready'); + expect(res.status).toBe(200); + expect(body.status).toBe('degraded'); + expect(body.backing).toBe('kv'); + }); + + it('GET /v1/ready → 503 unavailable when no backing store', async () => { + const { res, body } = await call('/v1/ready', { env: {} }); + expect(res.status).toBe(503); + expect(body.status).toBe('unavailable'); + }); +}); + +describe('clades', () => { + it('GET /v1/clades → all 12 clades', async () => { + const { res, body } = await call('/v1/clades'); + expect(res.status).toBe(200); + expect(body.clades).toHaveLength(INDEX.total_clades); + }); + + it('GET /v1/clade/fv → clade with member repos', async () => { + const expected = INDEX.clades.find((c) => c.code === 'fv'); + const { res, body } = await call('/v1/clade/fv'); + expect(res.status).toBe(200); + expect(body.code).toBe('fv'); + expect(body.repos).toHaveLength(expected.member_count); + }); + + it('GET /v1/clade/zz → 404 for unknown (but well-formed) code', async () => { + const { res, body } = await call('/v1/clade/zz'); + expect(res.status).toBe(404); + expect(body.error).toContain('not found'); + }); +}); + +describe('repos', () => { + it('GET /v1/repo/:name → repo detail with derived urls', async () => { + const name = Object.keys(INDEX.by_name)[0]; + const { res, body } = await call(`/v1/repo/${encodeURIComponent(name)}`); + expect(res.status).toBe(200); + expect(body.name).toBe(name); + expect(body.github_url).toContain('github.com/'); + expect(body.portal_url).toContain('/#/project/'); + }); + + it('GET /v1/repo/:name → 404 for unknown repo', async () => { + const { res } = await call('/v1/repo/this-repo-does-not-exist-xyz'); + expect(res.status).toBe(404); + }); + + it('GET /v1/repo/:name → 400 for malformed percent-encoding', async () => { + const { res, body } = await call('/v1/repo/%E0%A4%A'); + expect(res.status).toBe(400); + expect(body.error).toContain('Malformed'); + }); + + it('GET /v1/repos → paginated with totals', async () => { + const { res, body } = await call('/v1/repos'); + expect(res.status).toBe(200); + expect(body.total).toBe(INDEX.total_repos); + expect(body.page).toBe(1); + expect(body.limit).toBe(50); + expect(body.repos.length).toBeLessThanOrEqual(50); + }); + + it('GET /v1/repos?clade=fv → filtered to one clade', async () => { + const { res, body } = await call('/v1/repos?clade=fv&limit=200'); + expect(res.status).toBe(200); + expect(body.repos.every((r) => r.clade === 'fv')).toBe(true); + }); + + it('GET /v1/repos?clade=zz → 400 invalid clade', async () => { + const { res } = await call('/v1/repos?clade=zz'); + expect(res.status).toBe(400); + }); + + it('GET /v1/repos clamps NaN/oversized pagination', async () => { + const { res, body } = await call('/v1/repos?page=abc&limit=9999'); + expect(res.status).toBe(200); + expect(body.page).toBe(1); + expect(body.limit).toBe(200); + }); +}); + +describe('search & llm', () => { + it('GET /v1/search without q → 400', async () => { + const { res } = await call('/v1/search'); + expect(res.status).toBe(400); + }); + + it('GET /v1/search with overlong q → 400', async () => { + const { res, body } = await call(`/v1/search?q=${'a'.repeat(300)}`); + expect(res.status).toBe(400); + expect(body.error).toContain('too long'); + }); + + it('GET /v1/search?q= → ranked results', async () => { + const name = Object.keys(INDEX.by_name)[0]; + const { res, body } = await call(`/v1/search?q=${encodeURIComponent(name)}`); + expect(res.status).toBe(200); + expect(body.total).toBeGreaterThanOrEqual(1); + expect(typeof body.results[0].score).toBe('number'); + }); + + it('GET /v1/llm?q=... → structured output capped at 10', async () => { + const { res, body } = await call('/v1/llm?q=proof'); + expect(res.status).toBe(200); + expect(body.ecosystem).toBe('hyperpolymath'); + expect(body.results.length).toBeLessThanOrEqual(10); + }); +}); + +describe('verisimdb-backed queries (KV fallback)', () => { + it('GET /v1/query/language?q=rust → 200 array', async () => { + const { res, body } = await call('/v1/query/language?q=rust'); + expect(res.status).toBe(200); + expect(Array.isArray(body.results)).toBe(true); + }); + + it('GET /v1/query/tag?q=security → 200 array', async () => { + const { res, body } = await call('/v1/query/tag?q=security'); + expect(res.status).toBe(200); + expect(Array.isArray(body.results)).toBe(true); + }); +}); + +describe('method & routing', () => { + it('POST → 405', async () => { + const { res } = await call('/v1/clades', { method: 'POST' }); + expect(res.status).toBe(405); + }); + + it('OPTIONS → CORS preflight headers', async () => { + const { res } = await call('/v1/clades', { method: 'OPTIONS' }); + expect(res.headers.get('Access-Control-Allow-Methods')).toContain('GET'); + }); + + it('unknown path → 404', async () => { + const { res } = await call('/nope'); + expect(res.status).toBe(404); + }); + + it('503 when registry data is absent', async () => { + const { res } = await call('/v1/dashboard', { env: { CLADE_KV: makeKv({}) } }); + expect(res.status).toBe(503); + }); +}); + +describe('error handling', () => { + it('unexpected throw → controlled 500 (not a crash)', async () => { + const env = { + CLADE_KV: { + get: async () => { + throw new Error('kv boom'); + }, + }, + }; + const { res, body } = await call('/v1/dashboard', { env }); + expect(res.status).toBe(500); + expect(body.error).toBe('Internal error'); + expect(res.headers.get('X-Request-Id')).toBeTruthy(); + }); +}); + +describe('fuzz: no uncontrolled 5xx', () => { + const methods = ['GET', 'POST', 'HEAD', 'OPTIONS']; + const segs = [ + 'v1', + 'repo', + 'clade', + 'repos', + 'search', + 'llm', + 'query', + 'language', + 'tag', + 'x', + '', + ]; + const rnd = (a) => a[Math.floor(Math.random() * a.length)]; + + it('200 random requests never return 500', async () => { + const env = envWithKv(); + for (let i = 0; i < 200; i++) { + const depth = 1 + Math.floor(Math.random() * 4); + const p = '/' + Array.from({ length: depth }, () => encodeURIComponent(rnd(segs))).join('/'); + const q = + Math.random() < 0.5 + ? `?q=${encodeURIComponent('x'.repeat(Math.floor(Math.random() * 400)))}` + : ''; + const req = new Request(`https://api.test${p}${q}`, { method: rnd(methods) }); + const res = await worker.fetch(req, env); + expect(res.status).toBeLessThan(500); + } + }); +}); diff --git a/worker/vitest.config.js b/worker/vitest.config.js new file mode 100644 index 0000000..d159049 --- /dev/null +++ b/worker/vitest.config.js @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MPL-2.0 +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + environment: 'node', + include: ['test/**/*.test.js'], + }, +}); diff --git a/worker/wrangler.toml b/worker/wrangler.toml index 066d9e7..8cdabcf 100644 --- a/worker/wrangler.toml +++ b/worker/wrangler.toml @@ -3,9 +3,55 @@ name = "clade-registry-api" main = "src/index.js" compatibility_date = "2026-03-16" +# Structured logs → Cloudflare Logpush / `wrangler tail`. +[observability] +enabled = true + [vars] ENVIRONMENT = "production" +# Base URL of the live VeriSimDB instance (Phase 2). Until it is reachable the +# Worker serves from the Cloudflare KV snapshot. Override per-env / via secret. +VERISIMDB_URL = "http://localhost:8080" +# Canonical JSON snapshot base URL used by the scheduled refresh (raw worker/data/). +DATA_SOURCE_URL = "https://raw.githubusercontent.com/hyperpolymath/gv-clade-index/main/worker/data" [[kv_namespaces]] binding = "CLADE_KV" id = "e34a9970a5684c3fb8bc2f1fa5a6ca77" + +# Hourly snapshot refresh (matches verisim/config.a2ml sync interval = "1h"). +[triggers] +crons = ["0 * * * *"] + +# Native edge rate limiting for the expensive endpoints (search / llm / query). +# The Worker fails open when this binding is absent (local dev / tests). +[[unsafe.bindings]] +name = "RATE_LIMITER" +type = "ratelimit" +namespace_id = "1001" +simple = { limit = 120, period = 60 } + +# ── Environments ─────────────────────────────────────────────────────────── +# Production is the top-level config (deploy with `wrangler deploy`). +# Staging is deployed with `wrangler deploy --env staging`. +# TODO(ops): create a dedicated KV namespace for staging and replace the id below. +[env.staging] +name = "clade-registry-api-staging" + +[env.staging.vars] +ENVIRONMENT = "staging" +VERISIMDB_URL = "http://localhost:8080" +DATA_SOURCE_URL = "https://raw.githubusercontent.com/hyperpolymath/gv-clade-index/main/worker/data" + +[[env.staging.kv_namespaces]] +binding = "CLADE_KV" +id = "e34a9970a5684c3fb8bc2f1fa5a6ca77" + +[env.staging.observability] +enabled = true + +[[env.staging.unsafe.bindings]] +name = "RATE_LIMITER" +type = "ratelimit" +namespace_id = "1002" +simple = { limit = 120, period = 60 }