clone

a browser-first diagram editor with live svg previews, local drafts and encrypted, accountless sharing

feat: add private Browser Run execution bridge

Dami committed 2e8ff8a
Introduce a service-binding-only Browser Run worker with per-engine Durable Object sessions, pinned renderer frames, strict request limits, structured errors, and release-order coverage. Add contract, executor, and worker boundary tests.
commit
2e8ff8a138a78bf85255c7e3683b0cdd3060da8b
parent
6b8292c075c1737deb319d468a32a373be4dd072
author
Dami <dami.etoile@gmail.com>
12 files changed, +4546 -3
Mrelease.sh14+-
Arenderers/browser-run/package-lock.json4108++++++++++++++++++++++++++++++
Arenderers/browser-run/package.json28+
Arenderers/browser-run/src/contracts.ts71+
Arenderers/browser-run/src/executor.ts114+
Arenderers/browser-run/src/index.ts83+
Arenderers/browser-run/test/contracts.test.ts16+
Arenderers/browser-run/test/executor.test.ts38+
Arenderers/browser-run/test/worker.test.ts43+
Arenderers/browser-run/tsconfig.json17+
Arenderers/browser-run/vitest.config.ts3+
Arenderers/browser-run/wrangler.jsonc14+
M release.sh +11 -3
@@ -118,7 +118,7 @@ NPM_DIRECTORIES=("$ROOT")
118118 while IFS= read -r lockfile; do119119 directory="$(cd "$(dirname "$lockfile")" && pwd -P)"120120 [[ "$directory" == "$ROOT" ]] || NPM_DIRECTORIES+=("$directory")121-done < <(find apps/docs services renderers/client renderers/edge -name package-lock.json -not -path '*/node_modules/*' -print | sort)121+done < <(find apps/docs services renderers/browser-run renderers/client renderers/edge -name package-lock.json -not -path '*/node_modules/*' -print | sort)122122 123123 PYTHON_DIRECTORIES=()124124 while IFS= read -r config; do
@@ -130,8 +130,10 @@ while IFS= read -r config; do
130130 CLIENT_DIRECTORIES+=("$(cd "$(dirname "$config")" && pwd -P)")131131 done < <(find renderers/client -mindepth 2 -maxdepth 2 -name wrangler.jsonc -print | sort)132132 133+BROWSER_RUN_DIRECTORY="$ROOT/renderers/browser-run"134+133135 EDGE_CONFIG_COUNT="$(find renderers/edge/config/units -maxdepth 1 -name '*.jsonc' | wc -l | tr -d ' ')"134-DEPLOYMENT_COUNT=$((EDGE_CONFIG_COUNT + ${#PYTHON_DIRECTORIES[@]} + ${#CLIENT_DIRECTORIES[@]} + 4))136+DEPLOYMENT_COUNT=$((EDGE_CONFIG_COUNT + ${#PYTHON_DIRECTORIES[@]} + ${#CLIENT_DIRECTORIES[@]} + 5))135137 WRANGLER_CONFIG_COUNT="$(find apps services renderers \136138 -path '*/node_modules' -prune -o \137139 -path 'renderers/edge/config' -prune -o \
@@ -140,7 +142,7 @@ PRODUCTION_CONFIG_COUNT=$((WRANGLER_CONFIG_COUNT + EDGE_CONFIG_COUNT))
140142 [[ "$PRODUCTION_CONFIG_COUNT" == "$DEPLOYMENT_COUNT" ]] || \141143 die "release ownership covers ${DEPLOYMENT_COUNT} deployments, but ${PRODUCTION_CONFIG_COUNT} production Wrangler configs exist."142144 printf ' Commit: %s (%s)\n' "$RELEASE_SHORT_SHA" "$RELEASE_SUBJECT"143-printf ' Discovered: %s edge + %s Python + %s client + catalog/API/shell/docs = %s deployments\n' \145+printf ' Discovered: %s edge + %s Python + %s client + Browser Run/catalog/API/shell/docs = %s deployments\n' \144146 "$EDGE_CONFIG_COUNT" "${#PYTHON_DIRECTORIES[@]}" "${#CLIENT_DIRECTORIES[@]}" "$DEPLOYMENT_COUNT"145147 146148 section 'locked dependency installation'
@@ -163,11 +165,13 @@ run_in "$ROOT/renderers/edge" "$WRANGLER" types ../catalog/worker-configuration.
163165 run_in "$ROOT/services/api" npm run check164166 run_in "$ROOT/services/shell" npm run check165167 run_in "$ROOT/renderers/edge" npm run check168+run_in "$BROWSER_RUN_DIRECTORY" npm run check166169 167170 section 'tests and production builds'168171 run_in "$ROOT" npm test169172 run_in "$ROOT" npm run build:editor170173 run_in "$ROOT" npm run build:docs174+run_in "$BROWSER_RUN_DIRECTORY" npm test171175 for directory in "${PYTHON_DIRECTORIES[@]}"; do172176 run_in "$directory" uv run pytest -q173177 run_in "$directory" uv run pywrangler sync --force
@@ -185,6 +189,7 @@ run_in "$ROOT/renderers/edge" npm run check:licenses
185189 run_in "$ROOT/renderers/catalog" "$WRANGLER" deploy --dry-run --strict --config wrangler.jsonc186190 run_in "$ROOT/services/api" "$ROOT/services/api/node_modules/.bin/wrangler" deploy --dry-run --strict --config wrangler.jsonc187191 run_in "$ROOT/services/shell" "$ROOT/services/shell/node_modules/.bin/wrangler" deploy --dry-run --strict --config wrangler.jsonc192+run_in "$BROWSER_RUN_DIRECTORY" "$BROWSER_RUN_DIRECTORY/node_modules/.bin/wrangler" deploy --dry-run --strict --config wrangler.jsonc188193 for directory in "${CLIENT_DIRECTORIES[@]}"; do189194 run_in "$directory" "$WRANGLER" deploy --dry-run --strict --config wrangler.jsonc190195 done
@@ -218,6 +223,9 @@ run_in "$ROOT/renderers/edge" npm run deploy:edge
218223 section 'Python renderer deployment'219224 run_in "$ROOT/renderers/edge" npm run deploy:python220225 226+section 'private Browser Run deployment'227+run_in "$BROWSER_RUN_DIRECTORY" "$BROWSER_RUN_DIRECTORY/node_modules/.bin/wrangler" deploy --strict --message "$RELEASE_MESSAGE" --config wrangler.jsonc228+221229 section 'client renderer deployment'222230 for directory in "${CLIENT_DIRECTORIES[@]}"; do223231 run_in "$directory" "$WRANGLER" deploy --strict --message "$RELEASE_MESSAGE" --config wrangler.jsonc
A renderers/browser-run/package-lock.json +4108 -0
@@ -0,0 +1,4108 @@
1+{2+ "name": "@diagramzip/browser-run",3+ "version": "1.0.0",4+ "lockfileVersion": 3,5+ "requires": true,6+ "packages": {7+ "": {8+ "name": "@diagramzip/browser-run",9+ "version": "1.0.0",10+ "license": "UNLICENSED",11+ "dependencies": {12+ "@cloudflare/puppeteer": "^1.4.0"13+ },14+ "devDependencies": {15+ "@cloudflare/workers-types": "^5.20260822.1",16+ "@types/node": "^26.2.0",17+ "typescript": "^7.0.2",18+ "vitest": "^4.1.11",19+ "wrangler": "^4.125.0"20+ },21+ "engines": {22+ "node": ">=24"23+ }24+ },25+ "node_modules/@cloudflare/kv-asset-handler": {26+ "version": "0.5.0",27+ "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.5.0.tgz",28+ "integrity": "sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==",29+ "dev": true,30+ "license": "MIT OR Apache-2.0",31+ "engines": {32+ "node": ">=22.0.0"33+ }34+ },35+ "node_modules/@cloudflare/puppeteer": {36+ "version": "1.4.0",37+ "resolved": "https://registry.npmjs.org/@cloudflare/puppeteer/-/puppeteer-1.4.0.tgz",38+ "integrity": "sha512-39lo96Y7ErOJFmu/KIJU1VLaOibhynx/BauKCZOW5+RVH/mG0jZrAEGJlqCdx5ZxLHyWppm78YX3jLNPCBB+fA==",39+ "license": "Apache-2.0",40+ "dependencies": {41+ "@puppeteer/browsers": "2.2.4",42+ "debug": "^4.3.5",43+ "devtools-protocol": "0.0.1299070",44+ "ws": "^8.18.0"45+ },46+ "engines": {47+ "node": ">=18"48+ }49+ },50+ "node_modules/@cloudflare/unenv-preset": {51+ "version": "2.16.1",52+ "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.16.1.tgz",53+ "integrity": "sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw==",54+ "dev": true,55+ "license": "MIT OR Apache-2.0",56+ "peerDependencies": {57+ "unenv": "2.0.0-rc.24",58+ "workerd": ">1.20260305.0 <2.0.0-0"59+ },60+ "peerDependenciesMeta": {61+ "workerd": {62+ "optional": true63+ }64+ }65+ },66+ "node_modules/@cloudflare/workerd-darwin-64": {67+ "version": "1.20260815.1",68+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260815.1.tgz",69+ "integrity": "sha512-7PsLdcz6pT9EMd1EJGZEgMyYRfs0CHxGs62PS2L1w3s6+xGmQcRXKm/zoMftmqZF45JBa4MzFeownRKbRt/x5g==",70+ "cpu": [71+ "x64"72+ ],73+ "dev": true,74+ "license": "Apache-2.0",75+ "optional": true,76+ "os": [77+ "darwin"78+ ],79+ "peer": true,80+ "engines": {81+ "node": ">=16"82+ }83+ },84+ "node_modules/@cloudflare/workerd-darwin-arm64": {85+ "version": "1.20260815.1",86+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260815.1.tgz",87+ "integrity": "sha512-60wtg8ng7FVWeOg/UMbZ9Ye0sslpRRAKoftPbdtuH2volq676quxVr6Zm2EjVULH/JFZeCn72dbLlrnbh0Mpcw==",88+ "cpu": [89+ "arm64"90+ ],91+ "dev": true,92+ "license": "Apache-2.0",93+ "optional": true,94+ "os": [95+ "darwin"96+ ],97+ "peer": true,98+ "engines": {99+ "node": ">=16"100+ }101+ },102+ "node_modules/@cloudflare/workerd-linux-64": {103+ "version": "1.20260815.1",104+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260815.1.tgz",105+ "integrity": "sha512-MuqKIHPo0Qyo8MZMmy0lP2B5PeAL7f4T9Fu4Usk3QdbV4JIrKG/OoybN3Ign7m/Dff+L1Oo/ZHydB+hEg1ueFw==",106+ "cpu": [107+ "x64"108+ ],109+ "dev": true,110+ "license": "Apache-2.0",111+ "optional": true,112+ "os": [113+ "linux"114+ ],115+ "peer": true,116+ "engines": {117+ "node": ">=16"118+ }119+ },120+ "node_modules/@cloudflare/workerd-linux-arm64": {121+ "version": "1.20260815.1",122+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260815.1.tgz",123+ "integrity": "sha512-XNFtJ5rIqJxnY6ISjkfbhT/ODiWJ6LcBvNbntuPD6I/F2k7aZeKgPaXrvWvKde66LXyzFKzc8Hn+Ydx4shevQg==",124+ "cpu": [125+ "arm64"126+ ],127+ "dev": true,128+ "license": "Apache-2.0",129+ "optional": true,130+ "os": [131+ "linux"132+ ],133+ "peer": true,134+ "engines": {135+ "node": ">=16"136+ }137+ },138+ "node_modules/@cloudflare/workerd-windows-64": {139+ "version": "1.20260815.1",140+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260815.1.tgz",141+ "integrity": "sha512-PiIUWrhbMg3quolwjgMvPOd75vKESjT4aDm7nL6mSjL5IOgmpO/zKstXnYfnEH3pq7sC0UCvKlF8ZPcfsh8NMw==",142+ "cpu": [143+ "x64"144+ ],145+ "dev": true,146+ "license": "Apache-2.0",147+ "optional": true,148+ "os": [149+ "win32"150+ ],151+ "peer": true,152+ "engines": {153+ "node": ">=16"154+ }155+ },156+ "node_modules/@cloudflare/workers-types": {157+ "version": "5.20260822.1",158+ "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-5.20260822.1.tgz",159+ "integrity": "sha512-z922wN0pEWwYaAcYdncSf11fTPfj2j1Q2n2LCLbtBBhpkIu/aC8fotol5q4ek4isWgTKfWzUx389Dsa+lhF6yw==",160+ "dev": true,161+ "license": "MIT OR Apache-2.0"162+ },163+ "node_modules/@cspotcode/source-map-support": {164+ "version": "0.8.1",165+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",166+ "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",167+ "dev": true,168+ "license": "MIT",169+ "dependencies": {170+ "@jridgewell/trace-mapping": "0.3.9"171+ },172+ "engines": {173+ "node": ">=12"174+ }175+ },176+ "node_modules/@emnapi/runtime": {177+ "version": "1.11.3",178+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz",179+ "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==",180+ "dev": true,181+ "license": "MIT",182+ "optional": true,183+ "dependencies": {184+ "tslib": "^2.4.0"185+ }186+ },187+ "node_modules/@esbuild/aix-ppc64": {188+ "version": "0.28.1",189+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz",190+ "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==",191+ "cpu": [192+ "ppc64"193+ ],194+ "dev": true,195+ "license": "MIT",196+ "optional": true,197+ "os": [198+ "aix"199+ ],200+ "engines": {201+ "node": ">=18"202+ }203+ },204+ "node_modules/@esbuild/android-arm": {205+ "version": "0.28.1",206+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz",207+ "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==",208+ "cpu": [209+ "arm"210+ ],211+ "dev": true,212+ "license": "MIT",213+ "optional": true,214+ "os": [215+ "android"216+ ],217+ "engines": {218+ "node": ">=18"219+ }220+ },221+ "node_modules/@esbuild/android-arm64": {222+ "version": "0.28.1",223+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz",224+ "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==",225+ "cpu": [226+ "arm64"227+ ],228+ "dev": true,229+ "license": "MIT",230+ "optional": true,231+ "os": [232+ "android"233+ ],234+ "engines": {235+ "node": ">=18"236+ }237+ },238+ "node_modules/@esbuild/android-x64": {239+ "version": "0.28.1",240+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz",241+ "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==",242+ "cpu": [243+ "x64"244+ ],245+ "dev": true,246+ "license": "MIT",247+ "optional": true,248+ "os": [249+ "android"250+ ],251+ "engines": {252+ "node": ">=18"253+ }254+ },255+ "node_modules/@esbuild/darwin-arm64": {256+ "version": "0.28.1",257+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz",258+ "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==",259+ "cpu": [260+ "arm64"261+ ],262+ "dev": true,263+ "license": "MIT",264+ "optional": true,265+ "os": [266+ "darwin"267+ ],268+ "engines": {269+ "node": ">=18"270+ }271+ },272+ "node_modules/@esbuild/darwin-x64": {273+ "version": "0.28.1",274+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz",275+ "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==",276+ "cpu": [277+ "x64"278+ ],279+ "dev": true,280+ "license": "MIT",281+ "optional": true,282+ "os": [283+ "darwin"284+ ],285+ "engines": {286+ "node": ">=18"287+ }288+ },289+ "node_modules/@esbuild/freebsd-arm64": {290+ "version": "0.28.1",291+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz",292+ "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==",293+ "cpu": [294+ "arm64"295+ ],296+ "dev": true,297+ "license": "MIT",298+ "optional": true,299+ "os": [300+ "freebsd"301+ ],302+ "engines": {303+ "node": ">=18"304+ }305+ },306+ "node_modules/@esbuild/freebsd-x64": {307+ "version": "0.28.1",308+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz",309+ "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==",310+ "cpu": [311+ "x64"312+ ],313+ "dev": true,314+ "license": "MIT",315+ "optional": true,316+ "os": [317+ "freebsd"318+ ],319+ "engines": {320+ "node": ">=18"321+ }322+ },323+ "node_modules/@esbuild/linux-arm": {324+ "version": "0.28.1",325+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz",326+ "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==",327+ "cpu": [328+ "arm"329+ ],330+ "dev": true,331+ "license": "MIT",332+ "optional": true,333+ "os": [334+ "linux"335+ ],336+ "engines": {337+ "node": ">=18"338+ }339+ },340+ "node_modules/@esbuild/linux-arm64": {341+ "version": "0.28.1",342+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz",343+ "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==",344+ "cpu": [345+ "arm64"346+ ],347+ "dev": true,348+ "license": "MIT",349+ "optional": true,350+ "os": [351+ "linux"352+ ],353+ "engines": {354+ "node": ">=18"355+ }356+ },357+ "node_modules/@esbuild/linux-ia32": {358+ "version": "0.28.1",359+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz",360+ "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==",361+ "cpu": [362+ "ia32"363+ ],364+ "dev": true,365+ "license": "MIT",366+ "optional": true,367+ "os": [368+ "linux"369+ ],370+ "engines": {371+ "node": ">=18"372+ }373+ },374+ "node_modules/@esbuild/linux-loong64": {375+ "version": "0.28.1",376+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz",377+ "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==",378+ "cpu": [379+ "loong64"380+ ],381+ "dev": true,382+ "license": "MIT",383+ "optional": true,384+ "os": [385+ "linux"386+ ],387+ "engines": {388+ "node": ">=18"389+ }390+ },391+ "node_modules/@esbuild/linux-mips64el": {392+ "version": "0.28.1",393+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz",394+ "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==",395+ "cpu": [396+ "mips64el"397+ ],398+ "dev": true,399+ "license": "MIT",400+ "optional": true,401+ "os": [402+ "linux"403+ ],404+ "engines": {405+ "node": ">=18"406+ }407+ },408+ "node_modules/@esbuild/linux-ppc64": {409+ "version": "0.28.1",410+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz",411+ "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==",412+ "cpu": [413+ "ppc64"414+ ],415+ "dev": true,416+ "license": "MIT",417+ "optional": true,418+ "os": [419+ "linux"420+ ],421+ "engines": {422+ "node": ">=18"423+ }424+ },425+ "node_modules/@esbuild/linux-riscv64": {426+ "version": "0.28.1",427+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz",428+ "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==",429+ "cpu": [430+ "riscv64"431+ ],432+ "dev": true,433+ "license": "MIT",434+ "optional": true,435+ "os": [436+ "linux"437+ ],438+ "engines": {439+ "node": ">=18"440+ }441+ },442+ "node_modules/@esbuild/linux-s390x": {443+ "version": "0.28.1",444+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz",445+ "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==",446+ "cpu": [447+ "s390x"448+ ],449+ "dev": true,450+ "license": "MIT",451+ "optional": true,452+ "os": [453+ "linux"454+ ],455+ "engines": {456+ "node": ">=18"457+ }458+ },459+ "node_modules/@esbuild/linux-x64": {460+ "version": "0.28.1",461+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz",462+ "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==",463+ "cpu": [464+ "x64"465+ ],466+ "dev": true,467+ "license": "MIT",468+ "optional": true,469+ "os": [470+ "linux"471+ ],472+ "engines": {473+ "node": ">=18"474+ }475+ },476+ "node_modules/@esbuild/netbsd-arm64": {477+ "version": "0.28.1",478+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz",479+ "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==",480+ "cpu": [481+ "arm64"482+ ],483+ "dev": true,484+ "license": "MIT",485+ "optional": true,486+ "os": [487+ "netbsd"488+ ],489+ "engines": {490+ "node": ">=18"491+ }492+ },493+ "node_modules/@esbuild/netbsd-x64": {494+ "version": "0.28.1",495+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz",496+ "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==",497+ "cpu": [498+ "x64"499+ ],500+ "dev": true,501+ "license": "MIT",502+ "optional": true,503+ "os": [504+ "netbsd"505+ ],506+ "engines": {507+ "node": ">=18"508+ }509+ },510+ "node_modules/@esbuild/openbsd-arm64": {511+ "version": "0.28.1",512+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz",513+ "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==",514+ "cpu": [515+ "arm64"516+ ],517+ "dev": true,518+ "license": "MIT",519+ "optional": true,520+ "os": [521+ "openbsd"522+ ],523+ "engines": {524+ "node": ">=18"525+ }526+ },527+ "node_modules/@esbuild/openbsd-x64": {528+ "version": "0.28.1",529+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz",530+ "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==",531+ "cpu": [532+ "x64"533+ ],534+ "dev": true,535+ "license": "MIT",536+ "optional": true,537+ "os": [538+ "openbsd"539+ ],540+ "engines": {541+ "node": ">=18"542+ }543+ },544+ "node_modules/@esbuild/openharmony-arm64": {545+ "version": "0.28.1",546+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz",547+ "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==",548+ "cpu": [549+ "arm64"550+ ],551+ "dev": true,552+ "license": "MIT",553+ "optional": true,554+ "os": [555+ "openharmony"556+ ],557+ "engines": {558+ "node": ">=18"559+ }560+ },561+ "node_modules/@esbuild/sunos-x64": {562+ "version": "0.28.1",563+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz",564+ "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==",565+ "cpu": [566+ "x64"567+ ],568+ "dev": true,569+ "license": "MIT",570+ "optional": true,571+ "os": [572+ "sunos"573+ ],574+ "engines": {575+ "node": ">=18"576+ }577+ },578+ "node_modules/@esbuild/win32-arm64": {579+ "version": "0.28.1",580+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz",581+ "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==",582+ "cpu": [583+ "arm64"584+ ],585+ "dev": true,586+ "license": "MIT",587+ "optional": true,588+ "os": [589+ "win32"590+ ],591+ "engines": {592+ "node": ">=18"593+ }594+ },595+ "node_modules/@esbuild/win32-ia32": {596+ "version": "0.28.1",597+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz",598+ "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==",599+ "cpu": [600+ "ia32"601+ ],602+ "dev": true,603+ "license": "MIT",604+ "optional": true,605+ "os": [606+ "win32"607+ ],608+ "engines": {609+ "node": ">=18"610+ }611+ },612+ "node_modules/@esbuild/win32-x64": {613+ "version": "0.28.1",614+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz",615+ "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==",616+ "cpu": [617+ "x64"618+ ],619+ "dev": true,620+ "license": "MIT",621+ "optional": true,622+ "os": [623+ "win32"624+ ],625+ "engines": {626+ "node": ">=18"627+ }628+ },629+ "node_modules/@img/colour": {630+ "version": "1.1.0",631+ "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz",632+ "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==",633+ "dev": true,634+ "license": "MIT",635+ "engines": {636+ "node": ">=18"637+ }638+ },639+ "node_modules/@img/sharp-darwin-arm64": {640+ "version": "0.35.2",641+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.2.tgz",642+ "integrity": "sha512-eEieHsMksAW4IiO5NzauESRl2D2qz3J/kwUxUrSfV06A93eEaRfMpHXyUb1mAqrR7i8U9A0GRqE9pjn6u1Jjpg==",643+ "cpu": [644+ "arm64"645+ ],646+ "dev": true,647+ "license": "Apache-2.0",648+ "optional": true,649+ "os": [650+ "darwin"651+ ],652+ "engines": {653+ "node": ">=20.9.0"654+ },655+ "funding": {656+ "url": "https://opencollective.com/libvips"657+ },658+ "optionalDependencies": {659+ "@img/sharp-libvips-darwin-arm64": "1.3.1"660+ }661+ },662+ "node_modules/@img/sharp-darwin-x64": {663+ "version": "0.35.2",664+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.2.tgz",665+ "integrity": "sha512-BaktuGPCeHJMARpodR8jK4uKiZrPAy9WrfQW0sdI37clracq8Bp01AYS3SZgi5FS/y5twa9t4+LIuuxQjqRrWw==",666+ "cpu": [667+ "x64"668+ ],669+ "dev": true,670+ "license": "Apache-2.0",671+ "optional": true,672+ "os": [673+ "darwin"674+ ],675+ "engines": {676+ "node": ">=20.9.0"677+ },678+ "funding": {679+ "url": "https://opencollective.com/libvips"680+ },681+ "optionalDependencies": {682+ "@img/sharp-libvips-darwin-x64": "1.3.1"683+ }684+ },685+ "node_modules/@img/sharp-freebsd-wasm32": {686+ "version": "0.35.2",687+ "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.2.tgz",688+ "integrity": "sha512-YoAxdnd8hPUkvLHd3bWY+YA8nw3xM/RyRopYucNsWHVSan8NLVM3X2volsfoRDcXdUJPg6tXahSd7HXPK7lRnw==",689+ "dev": true,690+ "license": "Apache-2.0",691+ "optional": true,692+ "os": [693+ "freebsd"694+ ],695+ "dependencies": {696+ "@img/sharp-wasm32": "0.35.2"697+ },698+ "engines": {699+ "node": ">=20.9.0"700+ },701+ "funding": {702+ "url": "https://opencollective.com/libvips"703+ }704+ },705+ "node_modules/@img/sharp-libvips-darwin-arm64": {706+ "version": "1.3.1",707+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.1.tgz",708+ "integrity": "sha512-4V/M3roRMTYjiwZY9IOVQOE8OyeCxFAkYmyZDrZl51uOKjibm3oeEJ4WAmLxutAfzFbC9jqUiPs2gbnGflH+7g==",709+ "cpu": [710+ "arm64"711+ ],712+ "dev": true,713+ "license": "LGPL-3.0-or-later",714+ "optional": true,715+ "os": [716+ "darwin"717+ ],718+ "funding": {719+ "url": "https://opencollective.com/libvips"720+ }721+ },722+ "node_modules/@img/sharp-libvips-darwin-x64": {723+ "version": "1.3.1",724+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.1.tgz",725+ "integrity": "sha512-c0/DxItpJv2+dGhgycJBBgotdqruGYDvA79drdh0MD1dFpy7JzJ/PlXwi1H4rFf0eTy8tgbI91aHDnZIceY3jQ==",726+ "cpu": [727+ "x64"728+ ],729+ "dev": true,730+ "license": "LGPL-3.0-or-later",731+ "optional": true,732+ "os": [733+ "darwin"734+ ],735+ "funding": {736+ "url": "https://opencollective.com/libvips"737+ }738+ },739+ "node_modules/@img/sharp-libvips-linux-arm": {740+ "version": "1.3.1",741+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.1.tgz",742+ "integrity": "sha512-aGGy9aWzXgHBG7HNyQPWorZthlp7+x6fDRoPAQbGO3ThcttuTyKIx3NuSHb6zb4gBNq6/yNn9f1cy9nFKS/Vmg==",743+ "cpu": [744+ "arm"745+ ],746+ "dev": true,747+ "license": "LGPL-3.0-or-later",748+ "optional": true,749+ "os": [750+ "linux"751+ ],752+ "funding": {753+ "url": "https://opencollective.com/libvips"754+ }755+ },756+ "node_modules/@img/sharp-libvips-linux-arm64": {757+ "version": "1.3.1",758+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.1.tgz",759+ "integrity": "sha512-JznefmcK9j1JKPz8AkQDh89kjojubyfOasWBPKfzMIhPwsgDy9evpE/naJTXXXmghS1iFwR8u/kTwh/I2/+GCw==",760+ "cpu": [761+ "arm64"762+ ],763+ "dev": true,764+ "license": "LGPL-3.0-or-later",765+ "optional": true,766+ "os": [767+ "linux"768+ ],769+ "funding": {770+ "url": "https://opencollective.com/libvips"771+ }772+ },773+ "node_modules/@img/sharp-libvips-linux-ppc64": {774+ "version": "1.3.1",775+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.1.tgz",776+ "integrity": "sha512-1EkwGNCZk6iWNCMWqrvdJ+r1j0PT1zIz60CNPhYnJlK/zyeWqlsPZIe+ocBVqPF8k/Ssee/NCk+tE9Ryrko6ng==",777+ "cpu": [778+ "ppc64"779+ ],780+ "dev": true,781+ "license": "LGPL-3.0-or-later",782+ "optional": true,783+ "os": [784+ "linux"785+ ],786+ "funding": {787+ "url": "https://opencollective.com/libvips"788+ }789+ },790+ "node_modules/@img/sharp-libvips-linux-riscv64": {791+ "version": "1.3.1",792+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.1.tgz",793+ "integrity": "sha512-Ilays+w2bXdnxzxtQdmXR62u8o8GYa3eL4+Gr+1KiE4xperMZUslRaVPJwwPkzlHEjGfXAfRVAa/7CYCtSqsBw==",794+ "cpu": [795+ "riscv64"796+ ],797+ "dev": true,798+ "license": "LGPL-3.0-or-later",799+ "optional": true,800+ "os": [801+ "linux"802+ ],803+ "funding": {804+ "url": "https://opencollective.com/libvips"805+ }806+ },807+ "node_modules/@img/sharp-libvips-linux-s390x": {808+ "version": "1.3.1",809+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.1.tgz",810+ "integrity": "sha512-VfBwVHQTbRoj4XlpA/KLZ7ltgMpz+4WSejFzQ+GnoImjo1PtEJ59QB2qR1xQEeRPYIkNrPIm2L4cICMvz4C2ew==",811+ "cpu": [812+ "s390x"813+ ],814+ "dev": true,815+ "license": "LGPL-3.0-or-later",816+ "optional": true,817+ "os": [818+ "linux"819+ ],820+ "funding": {821+ "url": "https://opencollective.com/libvips"822+ }823+ },824+ "node_modules/@img/sharp-libvips-linux-x64": {825+ "version": "1.3.1",826+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.1.tgz",827+ "integrity": "sha512-+c8ukgwU62DS54nCAjw7keOfHUkmr0B5QHEdcOqRnodF/MNXJbVI8Eopoj4B/0H8Asr65I+A4Amrn7a85/md6A==",828+ "cpu": [829+ "x64"830+ ],831+ "dev": true,832+ "license": "LGPL-3.0-or-later",833+ "optional": true,834+ "os": [835+ "linux"836+ ],837+ "funding": {838+ "url": "https://opencollective.com/libvips"839+ }840+ },841+ "node_modules/@img/sharp-libvips-linuxmusl-arm64": {842+ "version": "1.3.1",843+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.1.tgz",844+ "integrity": "sha512-qlKb/pwbkAi1WMsJrYHk7CuDrd12s27U2QnRhFYUoJNrRCmkosMTttuRFat/DDB3IlDm5qE1TJgZ4JDnHX8Ldw==",845+ "cpu": [846+ "arm64"847+ ],848+ "dev": true,849+ "license": "LGPL-3.0-or-later",850+ "optional": true,851+ "os": [852+ "linux"853+ ],854+ "funding": {855+ "url": "https://opencollective.com/libvips"856+ }857+ },858+ "node_modules/@img/sharp-libvips-linuxmusl-x64": {859+ "version": "1.3.1",860+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.1.tgz",861+ "integrity": "sha512-yO21HwoUVLN8Qa+/SBjQLMYwBWAVJjeGPNe+hc0OUeMeifEtJqu5a1c4HayE1nNpDih9y3/KkoltfkDodmKAlg==",862+ "cpu": [863+ "x64"864+ ],865+ "dev": true,866+ "license": "LGPL-3.0-or-later",867+ "optional": true,868+ "os": [869+ "linux"870+ ],871+ "funding": {872+ "url": "https://opencollective.com/libvips"873+ }874+ },875+ "node_modules/@img/sharp-linux-arm": {876+ "version": "0.35.2",877+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.2.tgz",878+ "integrity": "sha512-SE4kzF2mepn6z+6E7L6lsV8FzuLL6IPQdyX8ZiwROAG/G8td+hP/m7FsFPwidtrF19gvajuC9l6TxAVcsA4S7A==",879+ "cpu": [880+ "arm"881+ ],882+ "dev": true,883+ "license": "Apache-2.0",884+ "optional": true,885+ "os": [886+ "linux"887+ ],888+ "engines": {889+ "node": ">=20.9.0"890+ },891+ "funding": {892+ "url": "https://opencollective.com/libvips"893+ },894+ "optionalDependencies": {895+ "@img/sharp-libvips-linux-arm": "1.3.1"896+ }897+ },898+ "node_modules/@img/sharp-linux-arm64": {899+ "version": "0.35.2",900+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.2.tgz",901+ "integrity": "sha512-af12Pnd0ZGu2HfP8NayB0kk6eC/lrfbQE6HlR4jD+34wdJ1Vw9TF6TMn6ZvffT+WgqVsl0hRbmNvz2u/23VmwA==",902+ "cpu": [903+ "arm64"904+ ],905+ "dev": true,906+ "license": "Apache-2.0",907+ "optional": true,908+ "os": [909+ "linux"910+ ],911+ "engines": {912+ "node": ">=20.9.0"913+ },914+ "funding": {915+ "url": "https://opencollective.com/libvips"916+ },917+ "optionalDependencies": {918+ "@img/sharp-libvips-linux-arm64": "1.3.1"919+ }920+ },921+ "node_modules/@img/sharp-linux-ppc64": {922+ "version": "0.35.2",923+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.2.tgz",924+ "integrity": "sha512-hYSBm7zcNtDCozCxQHYZJiu63b/bXsgRZuOxCIBZsStMM9Vap47iFHdbX4kCvQsblPB/k+clhELpdQJHQLSHvg==",925+ "cpu": [926+ "ppc64"927+ ],928+ "dev": true,929+ "license": "Apache-2.0",930+ "optional": true,931+ "os": [932+ "linux"933+ ],934+ "engines": {935+ "node": ">=20.9.0"936+ },937+ "funding": {938+ "url": "https://opencollective.com/libvips"939+ },940+ "optionalDependencies": {941+ "@img/sharp-libvips-linux-ppc64": "1.3.1"942+ }943+ },944+ "node_modules/@img/sharp-linux-riscv64": {945+ "version": "0.35.2",946+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.2.tgz",947+ "integrity": "sha512-qQt0Kc13+Hoan/Awq/qMSQw3L+RI1NCRPgD5cUJ/1WSSmIoysLOc72jlRM3E0OHN9Yr313jgeQ2T+zW+F03QFA==",948+ "cpu": [949+ "riscv64"950+ ],951+ "dev": true,952+ "license": "Apache-2.0",953+ "optional": true,954+ "os": [955+ "linux"956+ ],957+ "engines": {958+ "node": ">=20.9.0"959+ },960+ "funding": {961+ "url": "https://opencollective.com/libvips"962+ },963+ "optionalDependencies": {964+ "@img/sharp-libvips-linux-riscv64": "1.3.1"965+ }966+ },967+ "node_modules/@img/sharp-linux-s390x": {968+ "version": "0.35.2",969+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.2.tgz",970+ "integrity": "sha512-E4fLLfRPzDLlEeDaTzI98OFLcv++WL5ChLLMwPoVd0CIoZQqupBSNbOisPL5am9XsbQ9T84+iiMpUvbFtkunbA==",971+ "cpu": [972+ "s390x"973+ ],974+ "dev": true,975+ "license": "Apache-2.0",976+ "optional": true,977+ "os": [978+ "linux"979+ ],980+ "engines": {981+ "node": ">=20.9.0"982+ },983+ "funding": {984+ "url": "https://opencollective.com/libvips"985+ },986+ "optionalDependencies": {987+ "@img/sharp-libvips-linux-s390x": "1.3.1"988+ }989+ },990+ "node_modules/@img/sharp-linux-x64": {991+ "version": "0.35.2",992+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.2.tgz",993+ "integrity": "sha512-gi0zFJJRLswfCZmHtJdikXPOc5u7qamSOS3NHedLqLd4W8Q0NqjdBr6TTRIgsfFjqfTsHFgdfvJ9LwqSgcHiAA==",994+ "cpu": [995+ "x64"996+ ],997+ "dev": true,998+ "license": "Apache-2.0",999+ "optional": true,1000+ "os": [1001+ "linux"1002+ ],1003+ "engines": {1004+ "node": ">=20.9.0"1005+ },1006+ "funding": {1007+ "url": "https://opencollective.com/libvips"1008+ },1009+ "optionalDependencies": {1010+ "@img/sharp-libvips-linux-x64": "1.3.1"1011+ }1012+ },1013+ "node_modules/@img/sharp-linuxmusl-arm64": {1014+ "version": "0.35.2",1015+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.2.tgz",1016+ "integrity": "sha512-siWbOW1u6HFnFLrp0waKyW7VEf7jYvcDWdrXEFa8AkdAQgEvuu5Fz8/Y70w9EeqAdwDtfU012BhEHHaDqvQNzg==",1017+ "cpu": [1018+ "arm64"1019+ ],1020+ "dev": true,1021+ "license": "Apache-2.0",1022+ "optional": true,1023+ "os": [1024+ "linux"1025+ ],1026+ "engines": {1027+ "node": ">=20.9.0"1028+ },1029+ "funding": {1030+ "url": "https://opencollective.com/libvips"1031+ },1032+ "optionalDependencies": {1033+ "@img/sharp-libvips-linuxmusl-arm64": "1.3.1"1034+ }1035+ },1036+ "node_modules/@img/sharp-linuxmusl-x64": {1037+ "version": "0.35.2",1038+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.2.tgz",1039+ "integrity": "sha512-YBqMMcjDi4QGYiSn4vNOYBhmlC4z5AXqkOUUqI2e0AFA4urNv4ESgOgwNl3K+4etQhha0twXlzeF20bbULm9Yg==",1040+ "cpu": [1041+ "x64"1042+ ],1043+ "dev": true,1044+ "license": "Apache-2.0",1045+ "optional": true,1046+ "os": [1047+ "linux"1048+ ],1049+ "engines": {1050+ "node": ">=20.9.0"1051+ },1052+ "funding": {1053+ "url": "https://opencollective.com/libvips"1054+ },1055+ "optionalDependencies": {1056+ "@img/sharp-libvips-linuxmusl-x64": "1.3.1"1057+ }1058+ },1059+ "node_modules/@img/sharp-wasm32": {1060+ "version": "0.35.2",1061+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.2.tgz",1062+ "integrity": "sha512-Mrv4JQNYVQ94xH+jzZ9r+gowleN8mv2FTgKT+PI6bx5C0G8TdNYndu161pg2i7uoBwxy2ImPMHrJOM2LZef7Bw==",1063+ "dev": true,1064+ "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",1065+ "optional": true,1066+ "dependencies": {1067+ "@emnapi/runtime": "^1.11.1"1068+ },1069+ "engines": {1070+ "node": ">=20.9.0"1071+ },1072+ "funding": {1073+ "url": "https://opencollective.com/libvips"1074+ }1075+ },1076+ "node_modules/@img/sharp-webcontainers-wasm32": {1077+ "version": "0.35.2",1078+ "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.2.tgz",1079+ "integrity": "sha512-QNV27pxs9wpApEiCfvHM1RDoP1w1+2KrUWWDPEhEwg+latvOrfuhWrHWZKwdSFwU6jh3myjw/yOCRsUIuOft3g==",1080+ "cpu": [1081+ "wasm32"1082+ ],1083+ "dev": true,1084+ "license": "Apache-2.0",1085+ "optional": true,1086+ "dependencies": {1087+ "@img/sharp-wasm32": "0.35.2"1088+ },1089+ "engines": {1090+ "node": ">=20.9.0"1091+ },1092+ "funding": {1093+ "url": "https://opencollective.com/libvips"1094+ }1095+ },1096+ "node_modules/@img/sharp-win32-arm64": {1097+ "version": "0.35.2",1098+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.2.tgz",1099+ "integrity": "sha512-BiVRYc/t6/Vl3e1hBx0hugG4oN9Pydf4fgMSpxTQJmwGUg/YoXTWHiFeRymHfCZzifxu4F4rpk/I67D0LQ20wQ==",1100+ "cpu": [1101+ "arm64"1102+ ],1103+ "dev": true,1104+ "license": "Apache-2.0 AND LGPL-3.0-or-later",1105+ "optional": true,1106+ "os": [1107+ "win32"1108+ ],1109+ "engines": {1110+ "node": ">=20.9.0"1111+ },1112+ "funding": {1113+ "url": "https://opencollective.com/libvips"1114+ }1115+ },1116+ "node_modules/@img/sharp-win32-ia32": {1117+ "version": "0.35.2",1118+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.2.tgz",1119+ "integrity": "sha512-YYEhx9PImCC7T0tI8JDMi4DB9LwLCXCU5OWNYEXAxh5Q1ShKkyC6byxzoBJ3gEFDnH2lQckWuDe70G7mB2XJog==",1120+ "cpu": [1121+ "ia32"1122+ ],1123+ "dev": true,1124+ "license": "Apache-2.0 AND LGPL-3.0-or-later",1125+ "optional": true,1126+ "os": [1127+ "win32"1128+ ],1129+ "engines": {1130+ "node": "^20.9.0"1131+ },1132+ "funding": {1133+ "url": "https://opencollective.com/libvips"1134+ }1135+ },1136+ "node_modules/@img/sharp-win32-x64": {1137+ "version": "0.35.2",1138+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.2.tgz",1139+ "integrity": "sha512-imoOyBcoM/iiUr4J6VPpCNjPnjvP/Gks95898yB8YqoGGYmHYbOyCuNv9FMhFgtaiHFGbHW8bxKqRV6VjtXThQ==",1140+ "cpu": [1141+ "x64"1142+ ],1143+ "dev": true,1144+ "license": "Apache-2.0 AND LGPL-3.0-or-later",1145+ "optional": true,1146+ "os": [1147+ "win32"1148+ ],1149+ "engines": {1150+ "node": ">=20.9.0"1151+ },1152+ "funding": {1153+ "url": "https://opencollective.com/libvips"1154+ }1155+ },1156+ "node_modules/@jridgewell/resolve-uri": {1157+ "version": "3.1.2",1158+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",1159+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",1160+ "dev": true,1161+ "license": "MIT",1162+ "engines": {1163+ "node": ">=6.0.0"1164+ }1165+ },1166+ "node_modules/@jridgewell/sourcemap-codec": {1167+ "version": "1.5.5",1168+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",1169+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",1170+ "dev": true,1171+ "license": "MIT"1172+ },1173+ "node_modules/@jridgewell/trace-mapping": {1174+ "version": "0.3.9",1175+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",1176+ "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",1177+ "dev": true,1178+ "license": "MIT",1179+ "dependencies": {1180+ "@jridgewell/resolve-uri": "^3.0.3",1181+ "@jridgewell/sourcemap-codec": "^1.4.10"1182+ }1183+ },1184+ "node_modules/@oxc-project/types": {1185+ "version": "0.146.0",1186+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.146.0.tgz",1187+ "integrity": "sha512-XC0QsnnhVe7sLIWmYmdPw7x5P0h4W8vUU3Nv1ySgWXtvCz8NizoAEpGXA0sOYoJQV2Rl13LgURAHQ5cI5ILCSA==",1188+ "dev": true,1189+ "license": "MIT",1190+ "funding": {1191+ "url": "https://github.com/sponsors/Boshen"1192+ }1193+ },1194+ "node_modules/@poppinss/colors": {1195+ "version": "4.1.6",1196+ "resolved": "https://registry.npmjs.org/@poppinss/colors/-/colors-4.1.6.tgz",1197+ "integrity": "sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==",1198+ "dev": true,1199+ "license": "MIT",1200+ "dependencies": {1201+ "kleur": "^4.1.5"1202+ }1203+ },1204+ "node_modules/@poppinss/dumper": {1205+ "version": "0.6.5",1206+ "resolved": "https://registry.npmjs.org/@poppinss/dumper/-/dumper-0.6.5.tgz",1207+ "integrity": "sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==",1208+ "dev": true,1209+ "license": "MIT",1210+ "dependencies": {1211+ "@poppinss/colors": "^4.1.5",1212+ "@sindresorhus/is": "^7.0.2",1213+ "supports-color": "^10.0.0"1214+ }1215+ },1216+ "node_modules/@poppinss/exception": {1217+ "version": "1.2.3",1218+ "resolved": "https://registry.npmjs.org/@poppinss/exception/-/exception-1.2.3.tgz",1219+ "integrity": "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==",1220+ "dev": true,1221+ "license": "MIT"1222+ },1223+ "node_modules/@puppeteer/browsers": {1224+ "version": "2.2.4",1225+ "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.2.4.tgz",1226+ "integrity": "sha512-BdG2qiI1dn89OTUUsx2GZSpUzW+DRffR1wlMJyKxVHYrhnKoELSDxDd+2XImUkuWPEKk76H5FcM/gPFrEK1Tfw==",1227+ "license": "Apache-2.0",1228+ "dependencies": {1229+ "debug": "^4.3.5",1230+ "extract-zip": "^2.0.1",1231+ "progress": "^2.0.3",1232+ "proxy-agent": "^6.4.0",1233+ "semver": "^7.6.2",1234+ "tar-fs": "^3.0.6",1235+ "unbzip2-stream": "^1.4.3",1236+ "yargs": "^17.7.2"1237+ },1238+ "bin": {1239+ "browsers": "lib/cjs/main-cli.js"1240+ },1241+ "engines": {1242+ "node": ">=18"1243+ }1244+ },1245+ "node_modules/@rolldown/binding-android-arm-eabi": {1246+ "version": "1.2.5",1247+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.5.tgz",1248+ "integrity": "sha512-DLe/i+l8ynIBY7XEQ191TeZvCoowIGa18R+dIV30GW7DiOtp74i/xX8hs8GUjW5ARV7VZuie3d6AumSmCwbeRA==",1249+ "cpu": [1250+ "arm"1251+ ],1252+ "dev": true,1253+ "license": "MIT",1254+ "optional": true,1255+ "os": [1256+ "android"1257+ ],1258+ "engines": {1259+ "node": "^20.19.0 || >=22.12.0"1260+ }1261+ },1262+ "node_modules/@rolldown/binding-android-arm64": {1263+ "version": "1.2.5",1264+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.5.tgz",1265+ "integrity": "sha512-zXcwKlQApYAOELHd8PwKDFkagYF9Wy4e0RJ+0qnzl9Pjnpj75TEG8ufv40p2J7kCEfwZAsNiuzRIyNNMWT38ig==",1266+ "cpu": [1267+ "arm64"1268+ ],1269+ "dev": true,1270+ "license": "MIT",1271+ "optional": true,1272+ "os": [1273+ "android"1274+ ],1275+ "engines": {1276+ "node": "^20.19.0 || >=22.12.0"1277+ }1278+ },1279+ "node_modules/@rolldown/binding-darwin-arm64": {1280+ "version": "1.2.5",1281+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.5.tgz",1282+ "integrity": "sha512-dK4QakI42nzWgJT5sm4y4y/O//D4OxM75/cH28RLV+nzIN9AY+YsbuUVrUTjlLjXR6vpyxFbSsbmNuJ6BP9sww==",1283+ "cpu": [1284+ "arm64"1285+ ],1286+ "dev": true,1287+ "license": "MIT",1288+ "optional": true,1289+ "os": [1290+ "darwin"1291+ ],1292+ "engines": {1293+ "node": "^20.19.0 || >=22.12.0"1294+ }1295+ },1296+ "node_modules/@rolldown/binding-darwin-x64": {1297+ "version": "1.2.5",1298+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.5.tgz",1299+ "integrity": "sha512-fqSALaUu1Wjd1nK2uW2kJDWdLCc8lx1IcY+MTY26Aurfdx19anlzhqXOgCFbBFQnlFDTn4TC1/7Nz4Bl2mLP3A==",1300+ "cpu": [1301+ "x64"1302+ ],1303+ "dev": true,1304+ "license": "MIT",1305+ "optional": true,1306+ "os": [1307+ "darwin"1308+ ],1309+ "engines": {1310+ "node": "^20.19.0 || >=22.12.0"1311+ }1312+ },1313+ "node_modules/@rolldown/binding-freebsd-x64": {1314+ "version": "1.2.5",1315+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.5.tgz",1316+ "integrity": "sha512-/vCnNxlkxs9tKxNDcyWUePpJ/PgTzxIaVhoM5SmG8UV+GR/IcPam4VYxi7GIMo7PSDuNqlJqvprqii9NqqVCMw==",1317+ "cpu": [1318+ "x64"1319+ ],1320+ "dev": true,1321+ "license": "MIT",1322+ "optional": true,1323+ "os": [1324+ "freebsd"1325+ ],1326+ "engines": {1327+ "node": "^20.19.0 || >=22.12.0"1328+ }1329+ },1330+ "node_modules/@rolldown/binding-linux-arm-gnueabihf": {1331+ "version": "1.2.5",1332+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.5.tgz",1333+ "integrity": "sha512-abk0NLA519LxRCszmbE0jYKuQ9YPocOXTiOXOo6Yr+YAT95VH+PtqYAjOJvGKt3viEd/x4qzabAlwd5bHOOARg==",1334+ "cpu": [1335+ "arm"1336+ ],1337+ "dev": true,1338+ "license": "MIT",1339+ "optional": true,1340+ "os": [1341+ "linux"1342+ ],1343+ "engines": {1344+ "node": "^20.19.0 || >=22.12.0"1345+ }1346+ },1347+ "node_modules/@rolldown/binding-linux-arm64-gnu": {1348+ "version": "1.2.5",1349+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.5.tgz",1350+ "integrity": "sha512-Y7eALiJ8lr0M2HH103Js+g7V34wf6snlpZLAsHI90uLhr3PVlNsbFVAXJC9d/V6BnPyKtpSwI+NcB/RLxsQxuA==",1351+ "cpu": [1352+ "arm64"1353+ ],1354+ "dev": true,1355+ "license": "MIT",1356+ "optional": true,1357+ "os": [1358+ "linux"1359+ ],1360+ "engines": {1361+ "node": "^20.19.0 || >=22.12.0"1362+ }1363+ },1364+ "node_modules/@rolldown/binding-linux-arm64-musl": {1365+ "version": "1.2.5",1366+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.5.tgz",1367+ "integrity": "sha512-xMvZgnbZg4YVnR/AX2b3oOPDTFYJvUVaJg5FedA/LuvexAtXibZQej4cnTkw3rjsJ/ggUROB64TdtETiim+FYA==",1368+ "cpu": [1369+ "arm64"1370+ ],1371+ "dev": true,1372+ "license": "MIT",1373+ "optional": true,1374+ "os": [1375+ "linux"1376+ ],1377+ "engines": {1378+ "node": "^20.19.0 || >=22.12.0"1379+ }1380+ },1381+ "node_modules/@rolldown/binding-linux-ppc64-gnu": {1382+ "version": "1.2.5",1383+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.5.tgz",1384+ "integrity": "sha512-GRjeqTUDHTo5GwntsLaAMcBahG3nlpjftXWZLN73HiYQlhwEowvarFgQnRnQZtIp4keXX7quXFbG38uPZBa2EA==",1385+ "cpu": [1386+ "ppc64"1387+ ],1388+ "dev": true,1389+ "license": "MIT",1390+ "optional": true,1391+ "os": [1392+ "linux"1393+ ],1394+ "engines": {1395+ "node": "^20.19.0 || >=22.12.0"1396+ }1397+ },1398+ "node_modules/@rolldown/binding-linux-s390x-gnu": {1399+ "version": "1.2.5",1400+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.5.tgz",1401+ "integrity": "sha512-vLNTR45F2Uwc8AufkNXPmB4VliaXs+FvcheEogIzOXzO4l+LzieXF5A/TWxLy5HtqpsRCHUfd0lPVrrdgXdLHQ==",1402+ "cpu": [1403+ "s390x"1404+ ],1405+ "dev": true,1406+ "license": "MIT",1407+ "optional": true,1408+ "os": [1409+ "linux"1410+ ],1411+ "engines": {1412+ "node": "^20.19.0 || >=22.12.0"1413+ }1414+ },1415+ "node_modules/@rolldown/binding-linux-x64-gnu": {1416+ "version": "1.2.5",1417+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.5.tgz",1418+ "integrity": "sha512-Mgj59/HTuYeK9Gz2MA+mBWKnHsAgkBSec15ZMb1st3oIfFbX7gCjOae7GydHhzcyQi9Z/7M1QuN9bR3oFqF0jQ==",1419+ "cpu": [1420+ "x64"1421+ ],1422+ "dev": true,1423+ "license": "MIT",1424+ "optional": true,1425+ "os": [1426+ "linux"1427+ ],1428+ "engines": {1429+ "node": "^20.19.0 || >=22.12.0"1430+ }1431+ },1432+ "node_modules/@rolldown/binding-linux-x64-musl": {1433+ "version": "1.2.5",1434+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.5.tgz",1435+ "integrity": "sha512-mY8AP0/ichsbhAxGnLa3d3+MwV0EfgrPND2bplI3Ym8T6R2pJ0N87bvrKVwNXmdy3jnr6eQBecdqx/HMknBmpA==",1436+ "cpu": [1437+ "x64"1438+ ],1439+ "dev": true,1440+ "license": "MIT",1441+ "optional": true,1442+ "os": [1443+ "linux"1444+ ],1445+ "engines": {1446+ "node": "^20.19.0 || >=22.12.0"1447+ }1448+ },1449+ "node_modules/@rolldown/binding-openharmony-arm64": {1450+ "version": "1.2.5",1451+ "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.5.tgz",1452+ "integrity": "sha512-8SLssA2oweAxyRgDp789ACfRb/3P+zNRJpzZxSizxF9m8NUDQ4+3xjo8ttjhVGGw6Qxb70oZiEtIjaKikCO7Yw==",1453+ "cpu": [1454+ "arm64"1455+ ],1456+ "dev": true,1457+ "license": "MIT",1458+ "optional": true,1459+ "os": [1460+ "openharmony"1461+ ],1462+ "engines": {1463+ "node": "^20.19.0 || >=22.12.0"1464+ }1465+ },1466+ "node_modules/@rolldown/binding-win32-arm64-msvc": {1467+ "version": "1.2.5",1468+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.5.tgz",1469+ "integrity": "sha512-vGbruD5zquhoc8D9SViXgN2FBJtNdTyQ4DtG+SWiEGlJiAzoKcZ2xp+xuXCffhubVdt0NJlTZqkeRuERy7g8Cw==",1470+ "cpu": [1471+ "arm64"1472+ ],1473+ "dev": true,1474+ "license": "MIT",1475+ "optional": true,1476+ "os": [1477+ "win32"1478+ ],1479+ "engines": {1480+ "node": "^20.19.0 || >=22.12.0"1481+ }1482+ },1483+ "node_modules/@rolldown/binding-win32-x64-msvc": {1484+ "version": "1.2.5",1485+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.5.tgz",1486+ "integrity": "sha512-e/SXpgISz+IoqVcSSI0rx/d/he8zqLex+/rCWpnHpmVfmPIUjag9H6P7zotf0gJHwPUhQxZ/mF8tr6acebT9yw==",1487+ "cpu": [1488+ "x64"1489+ ],1490+ "dev": true,1491+ "license": "MIT",1492+ "optional": true,1493+ "os": [1494+ "win32"1495+ ],1496+ "engines": {1497+ "node": "^20.19.0 || >=22.12.0"1498+ }1499+ },1500+ "node_modules/@rolldown/pluginutils": {1501+ "version": "1.0.1",1502+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz",1503+ "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==",1504+ "dev": true,1505+ "license": "MIT"1506+ },1507+ "node_modules/@sindresorhus/is": {1508+ "version": "7.2.0",1509+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.2.0.tgz",1510+ "integrity": "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==",1511+ "dev": true,1512+ "license": "MIT",1513+ "engines": {1514+ "node": ">=18"1515+ },1516+ "funding": {1517+ "url": "https://github.com/sindresorhus/is?sponsor=1"1518+ }1519+ },1520+ "node_modules/@speed-highlight/core": {1521+ "version": "1.2.24",1522+ "resolved": "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.24.tgz",1523+ "integrity": "sha512-qeW2e1l78afw8VhRPfPQ1Gjj+KU5XFQ/OFV5ti6eTa9bruO7mJyZtA4vw0ofqmA3tKCkROE9xLk3VZoeRc98nw==",1524+ "dev": true,1525+ "license": "CC0-1.0"1526+ },1527+ "node_modules/@standard-schema/spec": {1528+ "version": "1.1.0",1529+ "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",1530+ "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",1531+ "dev": true,1532+ "license": "MIT"1533+ },1534+ "node_modules/@tootallnate/quickjs-emscripten": {1535+ "version": "0.23.0",1536+ "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz",1537+ "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==",1538+ "license": "MIT"1539+ },1540+ "node_modules/@types/chai": {1541+ "version": "5.2.3",1542+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz",1543+ "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==",1544+ "dev": true,1545+ "license": "MIT",1546+ "dependencies": {1547+ "@types/deep-eql": "*",1548+ "assertion-error": "^2.0.1"1549+ }1550+ },1551+ "node_modules/@types/deep-eql": {1552+ "version": "4.0.2",1553+ "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz",1554+ "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==",1555+ "dev": true,1556+ "license": "MIT"1557+ },1558+ "node_modules/@types/estree": {1559+ "version": "1.0.9",1560+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",1561+ "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",1562+ "dev": true,1563+ "license": "MIT"1564+ },1565+ "node_modules/@types/node": {1566+ "version": "26.2.0",1567+ "resolved": "https://registry.npmjs.org/@types/node/-/node-26.2.0.tgz",1568+ "integrity": "sha512-5IviulTZeRNp2vAJ514cc/HUlY5nZ9fCbq9DMyC52BrhFZACo3nI0R7qBxhQmo/d27NFe96ur/b7Wwxklda+kg==",1569+ "devOptional": true,1570+ "license": "MIT",1571+ "dependencies": {1572+ "undici-types": "~8.3.0"1573+ }1574+ },1575+ "node_modules/@types/yauzl": {1576+ "version": "2.10.3",1577+ "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",1578+ "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==",1579+ "license": "MIT",1580+ "optional": true,1581+ "dependencies": {1582+ "@types/node": "*"1583+ }1584+ },1585+ "node_modules/@typescript/typescript-aix-ppc64": {1586+ "version": "7.0.2",1587+ "resolved": "https://registry.npmjs.org/@typescript/typescript-aix-ppc64/-/typescript-aix-ppc64-7.0.2.tgz",1588+ "integrity": "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==",1589+ "cpu": [1590+ "ppc64"1591+ ],1592+ "dev": true,1593+ "license": "Apache-2.0",1594+ "optional": true,1595+ "os": [1596+ "aix"1597+ ],1598+ "engines": {1599+ "node": ">=16.20.0"1600+ }1601+ },1602+ "node_modules/@typescript/typescript-darwin-arm64": {1603+ "version": "7.0.2",1604+ "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-arm64/-/typescript-darwin-arm64-7.0.2.tgz",1605+ "integrity": "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==",1606+ "cpu": [1607+ "arm64"1608+ ],1609+ "dev": true,1610+ "license": "Apache-2.0",1611+ "optional": true,1612+ "os": [1613+ "darwin"1614+ ],1615+ "engines": {1616+ "node": ">=16.20.0"1617+ }1618+ },1619+ "node_modules/@typescript/typescript-darwin-x64": {1620+ "version": "7.0.2",1621+ "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-x64/-/typescript-darwin-x64-7.0.2.tgz",1622+ "integrity": "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==",1623+ "cpu": [1624+ "x64"1625+ ],1626+ "dev": true,1627+ "license": "Apache-2.0",1628+ "optional": true,1629+ "os": [1630+ "darwin"1631+ ],1632+ "engines": {1633+ "node": ">=16.20.0"1634+ }1635+ },1636+ "node_modules/@typescript/typescript-freebsd-arm64": {1637+ "version": "7.0.2",1638+ "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-arm64/-/typescript-freebsd-arm64-7.0.2.tgz",1639+ "integrity": "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==",1640+ "cpu": [1641+ "arm64"1642+ ],1643+ "dev": true,1644+ "license": "Apache-2.0",1645+ "optional": true,1646+ "os": [1647+ "freebsd"1648+ ],1649+ "engines": {1650+ "node": ">=16.20.0"1651+ }1652+ },1653+ "node_modules/@typescript/typescript-freebsd-x64": {1654+ "version": "7.0.2",1655+ "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-x64/-/typescript-freebsd-x64-7.0.2.tgz",1656+ "integrity": "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==",1657+ "cpu": [1658+ "x64"1659+ ],1660+ "dev": true,1661+ "license": "Apache-2.0",1662+ "optional": true,1663+ "os": [1664+ "freebsd"1665+ ],1666+ "engines": {1667+ "node": ">=16.20.0"1668+ }1669+ },1670+ "node_modules/@typescript/typescript-linux-arm": {1671+ "version": "7.0.2",1672+ "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm/-/typescript-linux-arm-7.0.2.tgz",1673+ "integrity": "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==",1674+ "cpu": [1675+ "arm"1676+ ],1677+ "dev": true,1678+ "license": "Apache-2.0",1679+ "optional": true,1680+ "os": [1681+ "linux"1682+ ],1683+ "engines": {1684+ "node": ">=16.20.0"1685+ }1686+ },1687+ "node_modules/@typescript/typescript-linux-arm64": {1688+ "version": "7.0.2",1689+ "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm64/-/typescript-linux-arm64-7.0.2.tgz",1690+ "integrity": "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==",1691+ "cpu": [1692+ "arm64"1693+ ],1694+ "dev": true,1695+ "license": "Apache-2.0",1696+ "optional": true,1697+ "os": [1698+ "linux"1699+ ],1700+ "engines": {1701+ "node": ">=16.20.0"1702+ }1703+ },1704+ "node_modules/@typescript/typescript-linux-loong64": {1705+ "version": "7.0.2",1706+ "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-loong64/-/typescript-linux-loong64-7.0.2.tgz",1707+ "integrity": "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==",1708+ "cpu": [1709+ "loong64"1710+ ],1711+ "dev": true,1712+ "license": "Apache-2.0",1713+ "optional": true,1714+ "os": [1715+ "linux"1716+ ],1717+ "engines": {1718+ "node": ">=16.20.0"1719+ }1720+ },1721+ "node_modules/@typescript/typescript-linux-mips64el": {1722+ "version": "7.0.2",1723+ "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-mips64el/-/typescript-linux-mips64el-7.0.2.tgz",1724+ "integrity": "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==",1725+ "cpu": [1726+ "mips64el"1727+ ],1728+ "dev": true,1729+ "license": "Apache-2.0",1730+ "optional": true,1731+ "os": [1732+ "linux"1733+ ],1734+ "engines": {1735+ "node": ">=16.20.0"1736+ }1737+ },1738+ "node_modules/@typescript/typescript-linux-ppc64": {1739+ "version": "7.0.2",1740+ "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-ppc64/-/typescript-linux-ppc64-7.0.2.tgz",1741+ "integrity": "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==",1742+ "cpu": [1743+ "ppc64"1744+ ],1745+ "dev": true,1746+ "license": "Apache-2.0",1747+ "optional": true,1748+ "os": [1749+ "linux"1750+ ],1751+ "engines": {1752+ "node": ">=16.20.0"1753+ }1754+ },1755+ "node_modules/@typescript/typescript-linux-riscv64": {1756+ "version": "7.0.2",1757+ "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-riscv64/-/typescript-linux-riscv64-7.0.2.tgz",1758+ "integrity": "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==",1759+ "cpu": [1760+ "riscv64"1761+ ],1762+ "dev": true,1763+ "license": "Apache-2.0",1764+ "optional": true,1765+ "os": [1766+ "linux"1767+ ],1768+ "engines": {1769+ "node": ">=16.20.0"1770+ }1771+ },1772+ "node_modules/@typescript/typescript-linux-s390x": {1773+ "version": "7.0.2",1774+ "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-s390x/-/typescript-linux-s390x-7.0.2.tgz",1775+ "integrity": "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==",1776+ "cpu": [1777+ "s390x"1778+ ],1779+ "dev": true,1780+ "license": "Apache-2.0",1781+ "optional": true,1782+ "os": [1783+ "linux"1784+ ],1785+ "engines": {1786+ "node": ">=16.20.0"1787+ }1788+ },1789+ "node_modules/@typescript/typescript-linux-x64": {1790+ "version": "7.0.2",1791+ "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-x64/-/typescript-linux-x64-7.0.2.tgz",1792+ "integrity": "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==",1793+ "cpu": [1794+ "x64"1795+ ],1796+ "dev": true,1797+ "license": "Apache-2.0",1798+ "optional": true,1799+ "os": [1800+ "linux"1801+ ],1802+ "engines": {1803+ "node": ">=16.20.0"1804+ }1805+ },1806+ "node_modules/@typescript/typescript-netbsd-arm64": {1807+ "version": "7.0.2",1808+ "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-arm64/-/typescript-netbsd-arm64-7.0.2.tgz",1809+ "integrity": "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==",1810+ "cpu": [1811+ "arm64"1812+ ],1813+ "dev": true,1814+ "license": "Apache-2.0",1815+ "optional": true,1816+ "os": [1817+ "netbsd"1818+ ],1819+ "engines": {1820+ "node": ">=16.20.0"1821+ }1822+ },1823+ "node_modules/@typescript/typescript-netbsd-x64": {1824+ "version": "7.0.2",1825+ "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-x64/-/typescript-netbsd-x64-7.0.2.tgz",1826+ "integrity": "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==",1827+ "cpu": [1828+ "x64"1829+ ],1830+ "dev": true,1831+ "license": "Apache-2.0",1832+ "optional": true,1833+ "os": [1834+ "netbsd"1835+ ],1836+ "engines": {1837+ "node": ">=16.20.0"1838+ }1839+ },1840+ "node_modules/@typescript/typescript-openbsd-arm64": {1841+ "version": "7.0.2",1842+ "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-arm64/-/typescript-openbsd-arm64-7.0.2.tgz",1843+ "integrity": "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==",1844+ "cpu": [1845+ "arm64"1846+ ],1847+ "dev": true,1848+ "license": "Apache-2.0",1849+ "optional": true,1850+ "os": [1851+ "openbsd"1852+ ],1853+ "engines": {1854+ "node": ">=16.20.0"1855+ }1856+ },1857+ "node_modules/@typescript/typescript-openbsd-x64": {1858+ "version": "7.0.2",1859+ "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-x64/-/typescript-openbsd-x64-7.0.2.tgz",1860+ "integrity": "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==",1861+ "cpu": [1862+ "x64"1863+ ],1864+ "dev": true,1865+ "license": "Apache-2.0",1866+ "optional": true,1867+ "os": [1868+ "openbsd"1869+ ],1870+ "engines": {1871+ "node": ">=16.20.0"1872+ }1873+ },1874+ "node_modules/@typescript/typescript-sunos-x64": {1875+ "version": "7.0.2",1876+ "resolved": "https://registry.npmjs.org/@typescript/typescript-sunos-x64/-/typescript-sunos-x64-7.0.2.tgz",1877+ "integrity": "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==",1878+ "cpu": [1879+ "x64"1880+ ],1881+ "dev": true,1882+ "license": "Apache-2.0",1883+ "optional": true,1884+ "os": [1885+ "sunos"1886+ ],1887+ "engines": {1888+ "node": ">=16.20.0"1889+ }1890+ },1891+ "node_modules/@typescript/typescript-win32-arm64": {1892+ "version": "7.0.2",1893+ "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-arm64/-/typescript-win32-arm64-7.0.2.tgz",1894+ "integrity": "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==",1895+ "cpu": [1896+ "arm64"1897+ ],1898+ "dev": true,1899+ "license": "Apache-2.0",1900+ "optional": true,1901+ "os": [1902+ "win32"1903+ ],1904+ "engines": {1905+ "node": ">=16.20.0"1906+ }1907+ },1908+ "node_modules/@typescript/typescript-win32-x64": {1909+ "version": "7.0.2",1910+ "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-x64/-/typescript-win32-x64-7.0.2.tgz",1911+ "integrity": "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==",1912+ "cpu": [1913+ "x64"1914+ ],1915+ "dev": true,1916+ "license": "Apache-2.0",1917+ "optional": true,1918+ "os": [1919+ "win32"1920+ ],1921+ "engines": {1922+ "node": ">=16.20.0"1923+ }1924+ },1925+ "node_modules/@vitest/expect": {1926+ "version": "4.1.11",1927+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.11.tgz",1928+ "integrity": "sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw==",1929+ "dev": true,1930+ "license": "MIT",1931+ "dependencies": {1932+ "@standard-schema/spec": "^1.1.0",1933+ "@types/chai": "^5.2.2",1934+ "@vitest/spy": "4.1.11",1935+ "@vitest/utils": "4.1.11",1936+ "chai": "^6.2.2",1937+ "tinyrainbow": "^3.1.0"1938+ },1939+ "funding": {1940+ "url": "https://opencollective.com/vitest"1941+ }1942+ },1943+ "node_modules/@vitest/mocker": {1944+ "version": "4.1.11",1945+ "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.11.tgz",1946+ "integrity": "sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ==",1947+ "dev": true,1948+ "license": "MIT",1949+ "dependencies": {1950+ "@vitest/spy": "4.1.11",1951+ "estree-walker": "^3.0.3",1952+ "magic-string": "^0.30.21"1953+ },1954+ "funding": {1955+ "url": "https://opencollective.com/vitest"1956+ },1957+ "peerDependencies": {1958+ "msw": "^2.4.9",1959+ "vite": "^6.0.0 || ^7.0.0 || ^8.0.0"1960+ },1961+ "peerDependenciesMeta": {1962+ "msw": {1963+ "optional": true1964+ },1965+ "vite": {1966+ "optional": true1967+ }1968+ }1969+ },1970+ "node_modules/@vitest/pretty-format": {1971+ "version": "4.1.11",1972+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.11.tgz",1973+ "integrity": "sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==",1974+ "dev": true,1975+ "license": "MIT",1976+ "dependencies": {1977+ "tinyrainbow": "^3.1.0"1978+ },1979+ "funding": {1980+ "url": "https://opencollective.com/vitest"1981+ }1982+ },1983+ "node_modules/@vitest/runner": {1984+ "version": "4.1.11",1985+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.11.tgz",1986+ "integrity": "sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw==",1987+ "dev": true,1988+ "license": "MIT",1989+ "dependencies": {1990+ "@vitest/utils": "4.1.11",1991+ "pathe": "^2.0.3"1992+ },1993+ "funding": {1994+ "url": "https://opencollective.com/vitest"1995+ }1996+ },1997+ "node_modules/@vitest/snapshot": {1998+ "version": "4.1.11",1999+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.11.tgz",2000+ "integrity": "sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog==",2001+ "dev": true,2002+ "license": "MIT",2003+ "dependencies": {2004+ "@vitest/pretty-format": "4.1.11",2005+ "@vitest/utils": "4.1.11",2006+ "magic-string": "^0.30.21",2007+ "pathe": "^2.0.3"2008+ },2009+ "funding": {2010+ "url": "https://opencollective.com/vitest"2011+ }2012+ },2013+ "node_modules/@vitest/spy": {2014+ "version": "4.1.11",2015+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.11.tgz",2016+ "integrity": "sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA==",2017+ "dev": true,2018+ "license": "MIT",2019+ "funding": {2020+ "url": "https://opencollective.com/vitest"2021+ }2022+ },2023+ "node_modules/@vitest/utils": {2024+ "version": "4.1.11",2025+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.11.tgz",2026+ "integrity": "sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==",2027+ "dev": true,2028+ "license": "MIT",2029+ "dependencies": {2030+ "@vitest/pretty-format": "4.1.11",2031+ "convert-source-map": "^2.0.0",2032+ "tinyrainbow": "^3.1.0"2033+ },2034+ "funding": {2035+ "url": "https://opencollective.com/vitest"2036+ }2037+ },2038+ "node_modules/agent-base": {2039+ "version": "7.1.4",2040+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",2041+ "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",2042+ "license": "MIT",2043+ "engines": {2044+ "node": ">= 14"2045+ }2046+ },2047+ "node_modules/ansi-regex": {2048+ "version": "5.0.1",2049+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",2050+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",2051+ "license": "MIT",2052+ "engines": {2053+ "node": ">=8"2054+ }2055+ },2056+ "node_modules/ansi-styles": {2057+ "version": "4.3.0",2058+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",2059+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",2060+ "license": "MIT",2061+ "dependencies": {2062+ "color-convert": "^2.0.1"2063+ },2064+ "engines": {2065+ "node": ">=8"2066+ },2067+ "funding": {2068+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"2069+ }2070+ },2071+ "node_modules/assertion-error": {2072+ "version": "2.0.1",2073+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",2074+ "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",2075+ "dev": true,2076+ "license": "MIT",2077+ "engines": {2078+ "node": ">=12"2079+ }2080+ },2081+ "node_modules/ast-types": {2082+ "version": "0.13.4",2083+ "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz",2084+ "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==",2085+ "license": "MIT",2086+ "dependencies": {2087+ "tslib": "^2.0.1"2088+ },2089+ "engines": {2090+ "node": ">=4"2091+ }2092+ },2093+ "node_modules/b4a": {2094+ "version": "1.8.1",2095+ "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.1.tgz",2096+ "integrity": "sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw==",2097+ "license": "Apache-2.0",2098+ "peerDependencies": {2099+ "react-native-b4a": "*"2100+ },2101+ "peerDependenciesMeta": {2102+ "react-native-b4a": {2103+ "optional": true2104+ }2105+ }2106+ },2107+ "node_modules/bare-events": {2108+ "version": "2.9.1",2109+ "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.9.1.tgz",2110+ "integrity": "sha512-Z0oHEHAFDZkffN8Qc39zNZjQlMDkPJRyyyZieU1VH7u8c5S+qHZ2S8ixdKIAxEjfHO7FJxXmJWgteOghVanIsg==",2111+ "license": "Apache-2.0",2112+ "peerDependencies": {2113+ "bare-abort-controller": "*"2114+ },2115+ "peerDependenciesMeta": {2116+ "bare-abort-controller": {2117+ "optional": true2118+ }2119+ }2120+ },2121+ "node_modules/bare-fs": {2122+ "version": "4.8.0",2123+ "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.8.0.tgz",2124+ "integrity": "sha512-fM+MhCvdQhZ7NV6S95a07gPSqjIYKn6mFaXfx266wN3ajZGl/+1AzH+ubkXQ0fFZvOe2nk9VHkzdYkQE5zMV3Q==",2125+ "license": "Apache-2.0",2126+ "dependencies": {2127+ "bare-events": "^2.5.4",2128+ "bare-path": "^3.0.0",2129+ "bare-stream": "^2.6.4",2130+ "bare-url": "^2.2.2",2131+ "fast-fifo": "^1.3.2"2132+ },2133+ "engines": {2134+ "bare": ">=1.28.0"2135+ },2136+ "peerDependencies": {2137+ "bare-buffer": "*"2138+ },2139+ "peerDependenciesMeta": {2140+ "bare-buffer": {2141+ "optional": true2142+ }2143+ }2144+ },2145+ "node_modules/bare-path": {2146+ "version": "3.1.1",2147+ "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.1.1.tgz",2148+ "integrity": "sha512-JprUlveX3QjApC1cTpsUOiscADftCGVWkzitbHsRqv84hzYwYHw2mbluddsq5TvI8mH/8Ov1f4BiMAdcB0oYnQ==",2149+ "license": "Apache-2.0"2150+ },2151+ "node_modules/bare-stream": {2152+ "version": "2.13.3",2153+ "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.13.3.tgz",2154+ "integrity": "sha512-Kc+brLqvEqGkjyfiwJmImAOqLZL7OsoLKuavx+hJjgVV3nLTOjloJyPMFxjUPerGGHrNH0fLU06jjykMLWrERQ==",2155+ "license": "Apache-2.0",2156+ "dependencies": {2157+ "b4a": "^1.8.1",2158+ "streamx": "^2.25.0",2159+ "teex": "^1.0.1"2160+ },2161+ "peerDependencies": {2162+ "bare-abort-controller": "*",2163+ "bare-buffer": "*",2164+ "bare-events": "*"2165+ },2166+ "peerDependenciesMeta": {2167+ "bare-abort-controller": {2168+ "optional": true2169+ },2170+ "bare-buffer": {2171+ "optional": true2172+ },2173+ "bare-events": {2174+ "optional": true2175+ }2176+ }2177+ },2178+ "node_modules/bare-url": {2179+ "version": "2.5.2",2180+ "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.5.2.tgz",2181+ "integrity": "sha512-L13PCJzKG8RGvx8V1/DdMi12ERhC3tprr7/8a94BxpmnRsFqxh5XZNdhtMxu5HPkRshYOOWRGY8lDP7ZhpG9Cg==",2182+ "license": "Apache-2.0",2183+ "dependencies": {2184+ "bare-path": "^3.0.0"2185+ }2186+ },2187+ "node_modules/base64-js": {2188+ "version": "1.5.1",2189+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",2190+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",2191+ "funding": [2192+ {2193+ "type": "github",2194+ "url": "https://github.com/sponsors/feross"2195+ },2196+ {2197+ "type": "patreon",2198+ "url": "https://www.patreon.com/feross"2199+ },2200+ {2201+ "type": "consulting",2202+ "url": "https://feross.org/support"2203+ }2204+ ],2205+ "license": "MIT"2206+ },2207+ "node_modules/basic-ftp": {2208+ "version": "5.3.1",2209+ "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.3.1.tgz",2210+ "integrity": "sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==",2211+ "license": "MIT",2212+ "engines": {2213+ "node": ">=10.0.0"2214+ }2215+ },2216+ "node_modules/blake3-wasm": {2217+ "version": "2.1.5",2218+ "resolved": "https://registry.npmjs.org/blake3-wasm/-/blake3-wasm-2.1.5.tgz",2219+ "integrity": "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==",2220+ "dev": true,2221+ "license": "MIT"2222+ },2223+ "node_modules/buffer": {2224+ "version": "5.7.1",2225+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",2226+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",2227+ "funding": [2228+ {2229+ "type": "github",2230+ "url": "https://github.com/sponsors/feross"2231+ },2232+ {2233+ "type": "patreon",2234+ "url": "https://www.patreon.com/feross"2235+ },2236+ {2237+ "type": "consulting",2238+ "url": "https://feross.org/support"2239+ }2240+ ],2241+ "license": "MIT",2242+ "dependencies": {2243+ "base64-js": "^1.3.1",2244+ "ieee754": "^1.1.13"2245+ }2246+ },2247+ "node_modules/buffer-crc32": {2248+ "version": "0.2.13",2249+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",2250+ "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",2251+ "license": "MIT",2252+ "engines": {2253+ "node": "*"2254+ }2255+ },2256+ "node_modules/chai": {2257+ "version": "6.2.2",2258+ "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz",2259+ "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==",2260+ "dev": true,2261+ "license": "MIT",2262+ "engines": {2263+ "node": ">=18"2264+ }2265+ },2266+ "node_modules/cliui": {2267+ "version": "8.0.1",2268+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",2269+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",2270+ "license": "ISC",2271+ "dependencies": {2272+ "string-width": "^4.2.0",2273+ "strip-ansi": "^6.0.1",2274+ "wrap-ansi": "^7.0.0"2275+ },2276+ "engines": {2277+ "node": ">=12"2278+ }2279+ },2280+ "node_modules/color-convert": {2281+ "version": "2.0.1",2282+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",2283+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",2284+ "license": "MIT",2285+ "dependencies": {2286+ "color-name": "~1.1.4"2287+ },2288+ "engines": {2289+ "node": ">=7.0.0"2290+ }2291+ },2292+ "node_modules/color-name": {2293+ "version": "1.1.4",2294+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",2295+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",2296+ "license": "MIT"2297+ },2298+ "node_modules/convert-source-map": {2299+ "version": "2.0.0",2300+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",2301+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",2302+ "dev": true,2303+ "license": "MIT"2304+ },2305+ "node_modules/cookie": {2306+ "version": "1.1.1",2307+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz",2308+ "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==",2309+ "dev": true,2310+ "license": "MIT",2311+ "engines": {2312+ "node": ">=18"2313+ },2314+ "funding": {2315+ "type": "opencollective",2316+ "url": "https://opencollective.com/express"2317+ }2318+ },2319+ "node_modules/data-uri-to-buffer": {2320+ "version": "6.0.2",2321+ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz",2322+ "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==",2323+ "license": "MIT",2324+ "engines": {2325+ "node": ">= 14"2326+ }2327+ },2328+ "node_modules/debug": {2329+ "version": "4.4.3",2330+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",2331+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",2332+ "license": "MIT",2333+ "dependencies": {2334+ "ms": "^2.1.3"2335+ },2336+ "engines": {2337+ "node": ">=6.0"2338+ },2339+ "peerDependenciesMeta": {2340+ "supports-color": {2341+ "optional": true2342+ }2343+ }2344+ },2345+ "node_modules/degenerator": {2346+ "version": "5.0.1",2347+ "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz",2348+ "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==",2349+ "license": "MIT",2350+ "dependencies": {2351+ "ast-types": "^0.13.4",2352+ "escodegen": "^2.1.0",2353+ "esprima": "^4.0.1"2354+ },2355+ "engines": {2356+ "node": ">= 14"2357+ }2358+ },2359+ "node_modules/detect-libc": {2360+ "version": "2.1.2",2361+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",2362+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",2363+ "dev": true,2364+ "license": "Apache-2.0",2365+ "engines": {2366+ "node": ">=8"2367+ }2368+ },2369+ "node_modules/devtools-protocol": {2370+ "version": "0.0.1299070",2371+ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1299070.tgz",2372+ "integrity": "sha512-+qtL3eX50qsJ7c+qVyagqi7AWMoQCBGNfoyJZMwm/NSXVqLYbuitrWEEIzxfUmTNy7//Xe8yhMmQ+elj3uAqSg==",2373+ "license": "BSD-3-Clause"2374+ },2375+ "node_modules/emoji-regex": {2376+ "version": "8.0.0",2377+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",2378+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",2379+ "license": "MIT"2380+ },2381+ "node_modules/end-of-stream": {2382+ "version": "1.4.5",2383+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",2384+ "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",2385+ "license": "MIT",2386+ "dependencies": {2387+ "once": "^1.4.0"2388+ }2389+ },2390+ "node_modules/error-stack-parser-es": {2391+ "version": "1.0.5",2392+ "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz",2393+ "integrity": "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==",2394+ "dev": true,2395+ "license": "MIT",2396+ "funding": {2397+ "url": "https://github.com/sponsors/antfu"2398+ }2399+ },2400+ "node_modules/es-module-lexer": {2401+ "version": "2.3.2",2402+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz",2403+ "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==",2404+ "dev": true,2405+ "license": "MIT"2406+ },2407+ "node_modules/esbuild": {2408+ "version": "0.28.1",2409+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz",2410+ "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==",2411+ "dev": true,2412+ "hasInstallScript": true,2413+ "license": "MIT",2414+ "bin": {2415+ "esbuild": "bin/esbuild"2416+ },2417+ "engines": {2418+ "node": ">=18"2419+ },2420+ "optionalDependencies": {2421+ "@esbuild/aix-ppc64": "0.28.1",2422+ "@esbuild/android-arm": "0.28.1",2423+ "@esbuild/android-arm64": "0.28.1",2424+ "@esbuild/android-x64": "0.28.1",2425+ "@esbuild/darwin-arm64": "0.28.1",2426+ "@esbuild/darwin-x64": "0.28.1",2427+ "@esbuild/freebsd-arm64": "0.28.1",2428+ "@esbuild/freebsd-x64": "0.28.1",2429+ "@esbuild/linux-arm": "0.28.1",2430+ "@esbuild/linux-arm64": "0.28.1",2431+ "@esbuild/linux-ia32": "0.28.1",2432+ "@esbuild/linux-loong64": "0.28.1",2433+ "@esbuild/linux-mips64el": "0.28.1",2434+ "@esbuild/linux-ppc64": "0.28.1",2435+ "@esbuild/linux-riscv64": "0.28.1",2436+ "@esbuild/linux-s390x": "0.28.1",2437+ "@esbuild/linux-x64": "0.28.1",2438+ "@esbuild/netbsd-arm64": "0.28.1",2439+ "@esbuild/netbsd-x64": "0.28.1",2440+ "@esbuild/openbsd-arm64": "0.28.1",2441+ "@esbuild/openbsd-x64": "0.28.1",2442+ "@esbuild/openharmony-arm64": "0.28.1",2443+ "@esbuild/sunos-x64": "0.28.1",2444+ "@esbuild/win32-arm64": "0.28.1",2445+ "@esbuild/win32-ia32": "0.28.1",2446+ "@esbuild/win32-x64": "0.28.1"2447+ }2448+ },2449+ "node_modules/escalade": {2450+ "version": "3.2.0",2451+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",2452+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",2453+ "license": "MIT",2454+ "engines": {2455+ "node": ">=6"2456+ }2457+ },2458+ "node_modules/escodegen": {2459+ "version": "2.1.0",2460+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz",2461+ "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",2462+ "license": "BSD-2-Clause",2463+ "dependencies": {2464+ "esprima": "^4.0.1",2465+ "estraverse": "^5.2.0",2466+ "esutils": "^2.0.2"2467+ },2468+ "bin": {2469+ "escodegen": "bin/escodegen.js",2470+ "esgenerate": "bin/esgenerate.js"2471+ },2472+ "engines": {2473+ "node": ">=6.0"2474+ },2475+ "optionalDependencies": {2476+ "source-map": "~0.6.1"2477+ }2478+ },2479+ "node_modules/esprima": {2480+ "version": "4.0.1",2481+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",2482+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",2483+ "license": "BSD-2-Clause",2484+ "bin": {2485+ "esparse": "bin/esparse.js",2486+ "esvalidate": "bin/esvalidate.js"2487+ },2488+ "engines": {2489+ "node": ">=4"2490+ }2491+ },2492+ "node_modules/estraverse": {2493+ "version": "5.3.0",2494+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",2495+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",2496+ "license": "BSD-2-Clause",2497+ "engines": {2498+ "node": ">=4.0"2499+ }2500+ },2501+ "node_modules/estree-walker": {2502+ "version": "3.0.3",2503+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",2504+ "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",2505+ "dev": true,2506+ "license": "MIT",2507+ "dependencies": {2508+ "@types/estree": "^1.0.0"2509+ }2510+ },2511+ "node_modules/esutils": {2512+ "version": "2.0.3",2513+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",2514+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",2515+ "license": "BSD-2-Clause",2516+ "engines": {2517+ "node": ">=0.10.0"2518+ }2519+ },2520+ "node_modules/events-universal": {2521+ "version": "1.0.1",2522+ "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz",2523+ "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==",2524+ "license": "Apache-2.0",2525+ "dependencies": {2526+ "bare-events": "^2.7.0"2527+ }2528+ },2529+ "node_modules/expect-type": {2530+ "version": "1.4.0",2531+ "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz",2532+ "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==",2533+ "dev": true,2534+ "license": "Apache-2.0",2535+ "engines": {2536+ "node": ">=12.0.0"2537+ }2538+ },2539+ "node_modules/extract-zip": {2540+ "version": "2.0.1",2541+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",2542+ "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",2543+ "license": "BSD-2-Clause",2544+ "dependencies": {2545+ "debug": "^4.1.1",2546+ "get-stream": "^5.1.0",2547+ "yauzl": "^2.10.0"2548+ },2549+ "bin": {2550+ "extract-zip": "cli.js"2551+ },2552+ "engines": {2553+ "node": ">= 10.17.0"2554+ },2555+ "optionalDependencies": {2556+ "@types/yauzl": "^2.9.1"2557+ }2558+ },2559+ "node_modules/fast-fifo": {2560+ "version": "1.3.2",2561+ "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",2562+ "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==",2563+ "license": "MIT"2564+ },2565+ "node_modules/fd-slicer": {2566+ "version": "1.1.0",2567+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",2568+ "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",2569+ "license": "MIT",2570+ "dependencies": {2571+ "pend": "~1.2.0"2572+ }2573+ },2574+ "node_modules/fdir": {2575+ "version": "6.5.0",2576+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",2577+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",2578+ "dev": true,2579+ "license": "MIT",2580+ "engines": {2581+ "node": ">=12.0.0"2582+ },2583+ "peerDependencies": {2584+ "picomatch": "^3 || ^4"2585+ },2586+ "peerDependenciesMeta": {2587+ "picomatch": {2588+ "optional": true2589+ }2590+ }2591+ },2592+ "node_modules/fsevents": {2593+ "version": "2.3.3",2594+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",2595+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",2596+ "dev": true,2597+ "hasInstallScript": true,2598+ "license": "MIT",2599+ "optional": true,2600+ "os": [2601+ "darwin"2602+ ],2603+ "engines": {2604+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"2605+ }2606+ },2607+ "node_modules/get-caller-file": {2608+ "version": "2.0.5",2609+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",2610+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",2611+ "license": "ISC",2612+ "engines": {2613+ "node": "6.* || 8.* || >= 10.*"2614+ }2615+ },2616+ "node_modules/get-stream": {2617+ "version": "5.2.0",2618+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",2619+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",2620+ "license": "MIT",2621+ "dependencies": {2622+ "pump": "^3.0.0"2623+ },2624+ "engines": {2625+ "node": ">=8"2626+ },2627+ "funding": {2628+ "url": "https://github.com/sponsors/sindresorhus"2629+ }2630+ },2631+ "node_modules/get-uri": {2632+ "version": "6.0.5",2633+ "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz",2634+ "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==",2635+ "license": "MIT",2636+ "dependencies": {2637+ "basic-ftp": "^5.0.2",2638+ "data-uri-to-buffer": "^6.0.2",2639+ "debug": "^4.3.4"2640+ },2641+ "engines": {2642+ "node": ">= 14"2643+ }2644+ },2645+ "node_modules/http-proxy-agent": {2646+ "version": "7.0.2",2647+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",2648+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",2649+ "license": "MIT",2650+ "dependencies": {2651+ "agent-base": "^7.1.0",2652+ "debug": "^4.3.4"2653+ },2654+ "engines": {2655+ "node": ">= 14"2656+ }2657+ },2658+ "node_modules/https-proxy-agent": {2659+ "version": "7.0.6",2660+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",2661+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",2662+ "license": "MIT",2663+ "dependencies": {2664+ "agent-base": "^7.1.2",2665+ "debug": "4"2666+ },2667+ "engines": {2668+ "node": ">= 14"2669+ }2670+ },2671+ "node_modules/ieee754": {2672+ "version": "1.2.1",2673+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",2674+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",2675+ "funding": [2676+ {2677+ "type": "github",2678+ "url": "https://github.com/sponsors/feross"2679+ },2680+ {2681+ "type": "patreon",2682+ "url": "https://www.patreon.com/feross"2683+ },2684+ {2685+ "type": "consulting",2686+ "url": "https://feross.org/support"2687+ }2688+ ],2689+ "license": "BSD-3-Clause"2690+ },2691+ "node_modules/ip-address": {2692+ "version": "10.5.0",2693+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.5.0.tgz",2694+ "integrity": "sha512-R5SnVLJmgYYvf2F2ZgwSBnelz5G4q5AxIC277GDfUaNbrZKNANcBC7RHqYYePlszf4kBolVkJauG0ZjHHFh55g==",2695+ "license": "MIT",2696+ "engines": {2697+ "node": ">= 12"2698+ }2699+ },2700+ "node_modules/is-fullwidth-code-point": {2701+ "version": "3.0.0",2702+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",2703+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",2704+ "license": "MIT",2705+ "engines": {2706+ "node": ">=8"2707+ }2708+ },2709+ "node_modules/kleur": {2710+ "version": "4.1.5",2711+ "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",2712+ "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",2713+ "dev": true,2714+ "license": "MIT",2715+ "engines": {2716+ "node": ">=6"2717+ }2718+ },2719+ "node_modules/lightningcss": {2720+ "version": "1.33.0",2721+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz",2722+ "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==",2723+ "dev": true,2724+ "license": "MPL-2.0",2725+ "dependencies": {2726+ "detect-libc": "^2.0.3"2727+ },2728+ "engines": {2729+ "node": ">= 12.0.0"2730+ },2731+ "funding": {2732+ "type": "opencollective",2733+ "url": "https://opencollective.com/parcel"2734+ },2735+ "optionalDependencies": {2736+ "lightningcss-android-arm64": "1.33.0",2737+ "lightningcss-darwin-arm64": "1.33.0",2738+ "lightningcss-darwin-x64": "1.33.0",2739+ "lightningcss-freebsd-x64": "1.33.0",2740+ "lightningcss-linux-arm-gnueabihf": "1.33.0",2741+ "lightningcss-linux-arm64-gnu": "1.33.0",2742+ "lightningcss-linux-arm64-musl": "1.33.0",2743+ "lightningcss-linux-x64-gnu": "1.33.0",2744+ "lightningcss-linux-x64-musl": "1.33.0",2745+ "lightningcss-win32-arm64-msvc": "1.33.0",2746+ "lightningcss-win32-x64-msvc": "1.33.0"2747+ }2748+ },2749+ "node_modules/lightningcss-android-arm64": {2750+ "version": "1.33.0",2751+ "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz",2752+ "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==",2753+ "cpu": [2754+ "arm64"2755+ ],2756+ "dev": true,2757+ "license": "MPL-2.0",2758+ "optional": true,2759+ "os": [2760+ "android"2761+ ],2762+ "engines": {2763+ "node": ">= 12.0.0"2764+ },2765+ "funding": {2766+ "type": "opencollective",2767+ "url": "https://opencollective.com/parcel"2768+ }2769+ },2770+ "node_modules/lightningcss-darwin-arm64": {2771+ "version": "1.33.0",2772+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz",2773+ "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==",2774+ "cpu": [2775+ "arm64"2776+ ],2777+ "dev": true,2778+ "license": "MPL-2.0",2779+ "optional": true,2780+ "os": [2781+ "darwin"2782+ ],2783+ "engines": {2784+ "node": ">= 12.0.0"2785+ },2786+ "funding": {2787+ "type": "opencollective",2788+ "url": "https://opencollective.com/parcel"2789+ }2790+ },2791+ "node_modules/lightningcss-darwin-x64": {2792+ "version": "1.33.0",2793+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz",2794+ "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==",2795+ "cpu": [2796+ "x64"2797+ ],2798+ "dev": true,2799+ "license": "MPL-2.0",2800+ "optional": true,2801+ "os": [2802+ "darwin"2803+ ],2804+ "engines": {2805+ "node": ">= 12.0.0"2806+ },2807+ "funding": {2808+ "type": "opencollective",2809+ "url": "https://opencollective.com/parcel"2810+ }2811+ },2812+ "node_modules/lightningcss-freebsd-x64": {2813+ "version": "1.33.0",2814+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz",2815+ "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==",2816+ "cpu": [2817+ "x64"2818+ ],2819+ "dev": true,2820+ "license": "MPL-2.0",2821+ "optional": true,2822+ "os": [2823+ "freebsd"2824+ ],2825+ "engines": {2826+ "node": ">= 12.0.0"2827+ },2828+ "funding": {2829+ "type": "opencollective",2830+ "url": "https://opencollective.com/parcel"2831+ }2832+ },2833+ "node_modules/lightningcss-linux-arm-gnueabihf": {2834+ "version": "1.33.0",2835+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz",2836+ "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==",2837+ "cpu": [2838+ "arm"2839+ ],2840+ "dev": true,2841+ "license": "MPL-2.0",2842+ "optional": true,2843+ "os": [2844+ "linux"2845+ ],2846+ "engines": {2847+ "node": ">= 12.0.0"2848+ },2849+ "funding": {2850+ "type": "opencollective",2851+ "url": "https://opencollective.com/parcel"2852+ }2853+ },2854+ "node_modules/lightningcss-linux-arm64-gnu": {2855+ "version": "1.33.0",2856+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz",2857+ "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==",2858+ "cpu": [2859+ "arm64"2860+ ],2861+ "dev": true,2862+ "license": "MPL-2.0",2863+ "optional": true,2864+ "os": [2865+ "linux"2866+ ],2867+ "engines": {2868+ "node": ">= 12.0.0"2869+ },2870+ "funding": {2871+ "type": "opencollective",2872+ "url": "https://opencollective.com/parcel"2873+ }2874+ },2875+ "node_modules/lightningcss-linux-arm64-musl": {2876+ "version": "1.33.0",2877+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz",2878+ "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==",2879+ "cpu": [2880+ "arm64"2881+ ],2882+ "dev": true,2883+ "license": "MPL-2.0",2884+ "optional": true,2885+ "os": [2886+ "linux"2887+ ],2888+ "engines": {2889+ "node": ">= 12.0.0"2890+ },2891+ "funding": {2892+ "type": "opencollective",2893+ "url": "https://opencollective.com/parcel"2894+ }2895+ },2896+ "node_modules/lightningcss-linux-x64-gnu": {2897+ "version": "1.33.0",2898+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz",2899+ "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==",2900+ "cpu": [2901+ "x64"2902+ ],2903+ "dev": true,2904+ "license": "MPL-2.0",2905+ "optional": true,2906+ "os": [2907+ "linux"2908+ ],2909+ "engines": {2910+ "node": ">= 12.0.0"2911+ },2912+ "funding": {2913+ "type": "opencollective",2914+ "url": "https://opencollective.com/parcel"2915+ }2916+ },2917+ "node_modules/lightningcss-linux-x64-musl": {2918+ "version": "1.33.0",2919+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz",2920+ "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==",2921+ "cpu": [2922+ "x64"2923+ ],2924+ "dev": true,2925+ "license": "MPL-2.0",2926+ "optional": true,2927+ "os": [2928+ "linux"2929+ ],2930+ "engines": {2931+ "node": ">= 12.0.0"2932+ },2933+ "funding": {2934+ "type": "opencollective",2935+ "url": "https://opencollective.com/parcel"2936+ }2937+ },2938+ "node_modules/lightningcss-win32-arm64-msvc": {2939+ "version": "1.33.0",2940+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz",2941+ "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==",2942+ "cpu": [2943+ "arm64"2944+ ],2945+ "dev": true,2946+ "license": "MPL-2.0",2947+ "optional": true,2948+ "os": [2949+ "win32"2950+ ],2951+ "engines": {2952+ "node": ">= 12.0.0"2953+ },2954+ "funding": {2955+ "type": "opencollective",2956+ "url": "https://opencollective.com/parcel"2957+ }2958+ },2959+ "node_modules/lightningcss-win32-x64-msvc": {2960+ "version": "1.33.0",2961+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz",2962+ "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==",2963+ "cpu": [2964+ "x64"2965+ ],2966+ "dev": true,2967+ "license": "MPL-2.0",2968+ "optional": true,2969+ "os": [2970+ "win32"2971+ ],2972+ "engines": {2973+ "node": ">= 12.0.0"2974+ },2975+ "funding": {2976+ "type": "opencollective",2977+ "url": "https://opencollective.com/parcel"2978+ }2979+ },2980+ "node_modules/lru-cache": {2981+ "version": "7.18.3",2982+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",2983+ "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",2984+ "license": "ISC",2985+ "engines": {2986+ "node": ">=12"2987+ }2988+ },2989+ "node_modules/magic-string": {2990+ "version": "0.30.21",2991+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",2992+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",2993+ "dev": true,2994+ "license": "MIT",2995+ "dependencies": {2996+ "@jridgewell/sourcemap-codec": "^1.5.5"2997+ }2998+ },2999+ "node_modules/ms": {3000+ "version": "2.1.3",
diff truncated
A renderers/browser-run/package.json +28 -0
A renderers/browser-run/src/contracts.ts +71 -0
@@ -0,0 +1,71 @@
1+export const CHANNEL = 'diagram.zip:renderer:v1' as const2+3+export const ENGINES = ['bpmn', 'mermaid', 'excalidraw', 'diagramsnet', 'tikz'] as const4+export type Engine = (typeof ENGINES)[number]5+6+export const FRAME_URLS: Readonly<Record<Engine, string>> = Object.freeze({7+ bpmn: 'https://bpmn.render.diagram.zip/index.html?v=1',8+ mermaid: 'https://mermaid.render.diagram.zip/index.html?v=1',9+ excalidraw: 'https://excalidraw.render.diagram.zip/index.html?v=4',10+ diagramsnet: 'https://diagramsnet.render.diagram.zip/index.html?v=1',11+ tikz: 'https://tikz.render.diagram.zip/index.html?v=2',12+})13+14+export const LIMITS = Object.freeze({15+ source: 524_288,16+ output: 4_194_304,17+ timeoutMs: 60_000,18+})19+20+export interface RenderRequest {21+ engine: Engine22+ requestId: string23+ source: string24+}25+26+export interface RenderResult {27+ ok: true28+ svg: string29+ version: string30+ build: string31+ pipeline: string[]32+}33+34+export interface RenderFailure {35+ ok: false36+ error: string37+}38+39+export type RenderResponse = RenderResult | RenderFailure40+41+export function isEngine(value: unknown): value is Engine {42+ return typeof value === 'string' && (ENGINES as readonly string[]).includes(value)43+}44+45+export function validateRenderRequest(value: unknown): RenderRequest {46+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {47+ throw new RenderInputError('invalid_request', 'Request body must be a JSON object.')48+ }49+ const request = value as Record<string, unknown>50+ if (!isEngine(request.engine)) throw new RenderInputError('invalid_engine', 'Unsupported renderer engine.')51+ if (typeof request.requestId !== 'string' || !/^[A-Za-z0-9_-]{1,128}$/.test(request.requestId)) {52+ throw new RenderInputError('invalid_request_id', 'requestId must be 1-128 safe identifier characters.')53+ }54+ if (typeof request.source !== 'string') throw new RenderInputError('invalid_source', 'source must be a string.')55+ if (request.source.length > LIMITS.source) throw new RenderInputError('source_too_large', 'Source exceeds the 512 KiB limit.')56+ return { engine: request.engine, requestId: request.requestId, source: request.source }57+}58+59+export class RenderInputError extends Error {60+ constructor(readonly code: string, message: string) {61+ super(message)62+ this.name = 'RenderInputError'63+ }64+}65+66+export function errorResponse(error: unknown): Response {67+ const input = error instanceof RenderInputError68+ const code = input ? error.code : 'render_failed'69+ const message = input ? error.message : error instanceof Error ? error.message.slice(0, 500) : 'Rendering failed.'70+ return Response.json({ error: { code, message } }, { status: input ? 400 : 500 })71+}
A renderers/browser-run/src/executor.ts +114 -0
@@ -0,0 +1,114 @@
1+import puppeteer from '@cloudflare/puppeteer'2+import type { Browser, Page, BrowserWorker } from '@cloudflare/puppeteer'3+import { CHANNEL, FRAME_URLS, LIMITS, type RenderRequest, type RenderResponse } from './contracts'4+5+export interface BrowserExecutor {6+ render(request: RenderRequest): Promise<RenderResponse>7+ close(): Promise<void>8+}9+10+export interface PageLike {11+ goto(url: string, options?: { waitUntil?: 'load' | 'domcontentloaded' | 'networkidle0' | 'networkidle2' }): Promise<unknown>12+ evaluate<T>(pageFunction: (payload: unknown) => Promise<T>, payload: unknown): Promise<T>13+}14+15+export interface BrowserLike {16+ newPage(): Promise<PageLike>17+ close(): Promise<void>18+ isConnected(): boolean19+}20+21+/** This function is serialized by Puppeteer and executed in the renderer page. */22+export async function browserHarness(payload: unknown): Promise<unknown> {23+ return new Promise((resolve) => {24+ const pageWindow = globalThis as unknown as {25+ addEventListener(type: string, listener: (event: { source: unknown; data: unknown }) => void): void26+ removeEventListener(type: string, listener: (event: { source: unknown; data: unknown }) => void): void27+ postMessage(message: unknown, targetOrigin: string): void28+ }29+ const request = payload as { engine: string; requestId: string; source: string }30+ const channel = 'diagram.zip:renderer:v1'31+ let settled = false32+ const finish = (value: unknown) => {33+ if (!settled) { settled = true; pageWindow.removeEventListener('message', onMessage); resolve(value) }34+ }35+ const onMessage = (event: { source: unknown; data: unknown }) => {36+ const message = event.data37+ if (event.source !== pageWindow || (message as Record<string, unknown>)?.channel !== channel || (message as Record<string, unknown>)?.type !== 'result' || (message as Record<string, unknown>)?.requestId !== request.requestId) return38+ finish(message)39+ }40+ pageWindow.addEventListener('message', onMessage)41+ pageWindow.postMessage({ channel, type: 'render', engine: request.engine, requestId: request.requestId, source: request.source }, '*')42+ })43+}44+45+export function createPageExecutor(page: PageLike, timeoutMs = LIMITS.timeoutMs, initialEngine?: string): BrowserExecutor {46+ let loadedEngine: string | undefined = initialEngine47+ return {48+ async render(request) {49+ if (loadedEngine !== request.engine) {50+ await page.goto(FRAME_URLS[request.engine], { waitUntil: 'domcontentloaded' })51+ loadedEngine = request.engine52+ }53+ const result = await Promise.race([54+ page.evaluate<RenderResponse>(browserHarness as unknown as (payload: unknown) => Promise<RenderResponse>, request),55+ new Promise<never>((_, reject) => setTimeout(() => reject(new Error('Renderer timed out.')), timeoutMs)),56+ ])57+ if (!isFrameResponse(result)) throw new Error('Renderer returned an invalid response.')58+ if (result.ok && result.svg.length > LIMITS.output) throw new Error('Renderer SVG output is too large.')59+ return result60+ },61+ async close() { /* Page ownership is managed by the browser session. */ },62+ }63+}64+65+function isFrameResponse(value: unknown): value is RenderResponse {66+ if (typeof value !== 'object' || value === null) return false67+ const result = value as Record<string, unknown>68+ if (result.ok === false) return typeof result.error === 'string' && result.error.length > 0 && result.error.length <= 50069+ return result.ok === true70+ && typeof result.svg === 'string'71+ && typeof result.version === 'string' && result.version.length > 072+ && typeof result.build === 'string' && result.build.length > 073+ && Array.isArray(result.pipeline)74+ && result.pipeline.every(item => typeof item === 'string')75+}76+77+export class PuppeteerExecutor implements BrowserExecutor {78+ private browser?: Browser79+ private page?: Page80+ private loadedEngine?: string81+82+ constructor(private readonly endpoint: BrowserWorker) {}83+84+ private async pageFor(engine: RenderRequest['engine']): Promise<Page> {85+ if (!this.browser?.isConnected()) {86+ this.browser = await puppeteer.launch(this.endpoint, {87+ keep_alive: 60_000,88+ guardrails: {89+ allowedDomains: ['bpmn.render.diagram.zip', 'mermaid.render.diagram.zip', 'excalidraw.render.diagram.zip', 'diagramsnet.render.diagram.zip', 'tikz.render.diagram.zip'],90+ },91+ })92+ this.page = undefined93+ this.loadedEngine = undefined94+ }95+ if (!this.page) this.page = await this.browser!.newPage()96+ if (this.loadedEngine !== engine) {97+ await this.page.goto(FRAME_URLS[engine], { waitUntil: 'domcontentloaded' })98+ this.loadedEngine = engine99+ }100+ return this.page101+ }102+103+ async render(request: RenderRequest): Promise<RenderResponse> {104+ const page = await this.pageFor(request.engine)105+ return createPageExecutor(page, LIMITS.timeoutMs, this.loadedEngine).render(request)106+ }107+108+ async close(): Promise<void> {109+ if (this.browser?.isConnected()) await this.browser.close()110+ this.browser = undefined111+ this.page = undefined112+ this.loadedEngine = undefined113+ }114+}
A renderers/browser-run/src/index.ts +83 -0
@@ -0,0 +1,83 @@
1+import { DurableObject } from 'cloudflare:workers'2+import type { BrowserWorker } from '@cloudflare/puppeteer'3+import { PuppeteerExecutor, type BrowserExecutor } from './executor'4+import { errorResponse, FRAME_URLS, LIMITS, validateRenderRequest, type Engine, type RenderRequest } from './contracts'5+6+export interface Env {7+ BROWSER: BrowserWorker8+ BROWSER_SESSIONS: DurableObjectNamespace<BrowserSession>9+ INTERNAL_TOKEN?: string10+}11+12+function json(value: unknown, init: ResponseInit = {}): Response {13+ const headers = new Headers(init.headers)14+ headers.set('Content-Type', 'application/json; charset=utf-8')15+ headers.set('Cache-Control', 'no-store')16+ return Response.json(value, { ...init, headers })17+}18+19+function sessionName(engine: Engine): string { return `renderer:${engine}` }20+21+export function responseFromRenderResult(result: Awaited<ReturnType<BrowserExecutor['render']>>): Response {22+ if (!result.ok) return json({ error: { code: 'frame_failed', message: result.error } }, { status: 422 })23+ return json({ svg: result.svg, version: result.version, build: result.build, pipeline: result.pipeline })24+}25+26+export class BrowserSession extends DurableObject<Env> {27+ private executor?: BrowserExecutor28+ private queue: Promise<unknown> = Promise.resolve()29+30+ private getExecutor(): BrowserExecutor {31+ return this.executor ??= new PuppeteerExecutor(this.env.BROWSER)32+ }33+34+ private enqueue<T>(operation: () => Promise<T>): Promise<T> {35+ const next = this.queue.then(operation, operation)36+ this.queue = next.then(() => undefined, () => undefined)37+ return next38+ }39+40+ async fetch(request: Request): Promise<Response> {41+ if (request.method !== 'POST') return json({ error: { code: 'method_not_allowed', message: 'POST required.' } }, { status: 405 })42+ let input: RenderRequest43+ try { input = validateRenderRequest(await request.json()) } catch (error) { return errorResponse(error) }44+ return this.enqueue(async () => {45+ try {46+ const result = await this.getExecutor().render(input)47+ await this.ctx.storage.setAlarm(Date.now() + 60_000)48+ return responseFromRenderResult(result)49+ } catch (error) {50+ await this.close()51+ return errorResponse(error)52+ }53+ })54+ }55+56+ async close(): Promise<void> {57+ if (this.executor) await this.executor.close()58+ this.executor = undefined59+ }60+61+ async alarm(): Promise<void> { await this.close() }62+}63+64+export default {65+ async fetch(request: Request, env: Env): Promise<Response> {66+ const url = new URL(request.url)67+ if (url.pathname !== '/render') return json({ error: { code: 'not_found', message: 'Route not found.' } }, { status: 404 })68+ if (request.method !== 'POST') return json({ error: { code: 'method_not_allowed', message: 'POST required.' } }, { status: 405 })69+ if (env.INTERNAL_TOKEN && request.headers.get('Authorization') !== `Bearer ${env.INTERNAL_TOKEN}`) return json({ error: { code: 'unauthorized', message: 'Internal authorization required.' } }, { status: 401 })70+ const contentLength = Number(request.headers.get('Content-Length') ?? 0)71+ if (contentLength > LIMITS.source + 4_096) return json({ error: { code: 'request_too_large', message: 'Request exceeds the source limit.' } }, { status: 413 })72+ let input: RenderRequest73+ try {74+ const body = await request.arrayBuffer()75+ if (body.byteLength > LIMITS.source + 16_384) return json({ error: { code: 'request_too_large', message: 'Request exceeds the source limit.' } }, { status: 413 })76+ input = validateRenderRequest(JSON.parse(new TextDecoder().decode(body)))77+ } catch (error) { return errorResponse(error) }78+ const stub = env.BROWSER_SESSIONS.getByName(sessionName(input.engine))79+ return stub.fetch(new Request('https://browser-session.internal/render', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(input) }))80+ },81+}82+83+export { FRAME_URLS }
A renderers/browser-run/test/contracts.test.ts +16 -0
A renderers/browser-run/test/executor.test.ts +38 -0
@@ -0,0 +1,38 @@
1+import { describe, expect, it } from 'vitest'2+import { browserHarness, createPageExecutor } from '../src/executor'3+4+describe('browser page executor', () => {5+ it('posts the renderer protocol message and accepts the matching result', async () => {6+ const listeners = new Set<(event: MessageEvent) => void>()7+ const fakeWindow = {8+ addEventListener: (_type: string, listener: (event: MessageEvent) => void) => listeners.add(listener),9+ removeEventListener: (_type: string, listener: (event: MessageEvent) => void) => listeners.delete(listener),10+ postMessage: (data: unknown) => queueMicrotask(() => listeners.forEach(listener => listener({ source: globalThis, data: { channel: 'diagram.zip:renderer:v1', type: 'result', requestId: (data as any).requestId, ok: true, svg: '<svg/>', version: 'v', build: 'b', pipeline: ['bpmn'] } } as unknown as MessageEvent))),11+ }12+ const oldMethods = { addEventListener: (globalThis as any).addEventListener, removeEventListener: (globalThis as any).removeEventListener, postMessage: (globalThis as any).postMessage }13+ Object.assign(globalThis, fakeWindow)14+ await expect(browserHarness({ engine: 'bpmn', requestId: 'r', source: '<xml/>' })).resolves.toMatchObject({ ok: true, svg: '<svg/>' })15+ Object.assign(globalThis, oldMethods)16+ })17+18+ it('navigates only to the pinned frame and returns the protocol result', async () => {19+ const navigated: string[] = []20+ const page = {21+ async goto(url: string) { navigated.push(url) },22+ async evaluate<T>(_fn: unknown, payload: any): Promise<T> {23+ return { ok: true, svg: '<svg />', version: 'test', build: 'test', pipeline: [payload.engine] } as T24+ },25+ }26+ const result = await createPageExecutor(page).render({ engine: 'mermaid', requestId: 'r', source: 'graph TD' })27+ expect(result.ok).toBe(true)28+ expect(navigated).toEqual(['https://mermaid.render.diagram.zip/index.html?v=1'])29+ })30+31+ it('rejects output above the hard limit', async () => {32+ const page = {33+ async goto() {},34+ async evaluate<T>(): Promise<T> { return { ok: true, svg: 'x'.repeat(4_194_305), version: 'v', build: 'b', pipeline: [] } as T },35+ }36+ await expect(createPageExecutor(page).render({ engine: 'bpmn', requestId: 'r', source: '' })).rejects.toThrow(/output is too large/)37+ })38+})
A renderers/browser-run/test/worker.test.ts +43 -0
@@ -0,0 +1,43 @@
1+import { describe, expect, it, vi } from 'vitest'2+vi.mock('cloudflare:workers', () => ({ DurableObject: class {} }))3+import worker, { responseFromRenderResult } from '../src/index'4+5+function environment(response = { ok: true, svg: '<svg/>', version: 'v', build: 'b', pipeline: ['bpmn'] }) {6+ const forwarded: Request[] = []7+ const stub = { fetch: vi.fn(async (request: Request) => { forwarded.push(request); return Response.json(response) }) }8+ return {9+ env: {10+ INTERNAL_TOKEN: 'secret',11+ BROWSER: {},12+ BROWSER_SESSIONS: { getByName: vi.fn(() => stub) },13+ } as any,14+ stub,15+ forwarded,16+ }17+}18+19+describe('private Worker boundary', () => {20+ it('rejects public paths and non-POST methods', async () => {21+ const setup = environment()22+ expect((await worker.fetch(new Request('https://bridge.example/'), setup.env)).status).toBe(404)23+ expect((await worker.fetch(new Request('https://bridge.example/render'), setup.env)).status).toBe(405)24+ expect(setup.stub.fetch).not.toHaveBeenCalled()25+ })26+27+ it('requires auth, validates JSON, and forwards the exact render contract to the DO', async () => {28+ const setup = environment()29+ const body = JSON.stringify({ engine: 'bpmn', requestId: 'request-1', source: '<definitions/>' })30+ expect((await worker.fetch(new Request('https://bridge.example/render', { method: 'POST', body }), setup.env)).status).toBe(401)31+ const request = new Request('https://bridge.example/render', { method: 'POST', body, headers: { Authorization: 'Bearer secret' } })32+ expect((await worker.fetch(request, setup.env)).status).toBe(200)33+ expect(setup.env.BROWSER_SESSIONS.getByName).toHaveBeenCalledWith('renderer:bpmn')34+ expect(setup.forwarded).toHaveLength(1)35+ expect(await setup.forwarded[0]!.json()).toEqual({ engine: 'bpmn', requestId: 'request-1', source: '<definitions/>' })36+ })37+38+ it('maps a frame failure to a non-success structured error', async () => {39+ const result = responseFromRenderResult({ ok: false, error: 'diagram is invalid' })40+ expect(result.status).toBe(422)41+ expect(await result.json()).toEqual({ error: { code: 'frame_failed', message: 'diagram is invalid' } })42+ })43+})
A renderers/browser-run/tsconfig.json +17 -0
A renderers/browser-run/vitest.config.ts +3 -0
A renderers/browser-run/wrangler.jsonc +14 -0