From 3b1992d98999b82cb1129e0e4790320e8861dcbe Mon Sep 17 00:00:00 2001
From: pkurcx
Date: Thu, 3 Sep 2026 19:15:54 +0200
Subject: [PATCH 01/17] feat(website): scaffold the playground page and engine
bundle
Co-Authored-By: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_011t8uBVY6h4kfN5cXHXuCpR
---
.github/workflows/docs.yml | 2 +-
.gitignore | 2 +
pnpm-lock.yaml | 327 ++
website/astro.config.mjs | 5 +
website/package.json | 11 +
website/pnpm-lock.yaml | 3993 -------------------------
website/public/_headers | 9 +
website/scripts/bundle-engine.mjs | 66 +
website/src/pages/playground.astro | 35 +
website/src/playground/main.ts | 1 +
website/src/playground/playground.css | 112 +
11 files changed, 569 insertions(+), 3994 deletions(-)
delete mode 100644 website/pnpm-lock.yaml
create mode 100644 website/public/_headers
create mode 100644 website/scripts/bundle-engine.mjs
create mode 100644 website/src/pages/playground.astro
create mode 100644 website/src/playground/main.ts
create mode 100644 website/src/playground/playground.css
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index a6f1f22..9104f4c 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -33,7 +33,7 @@ jobs:
with:
node-version: 22
cache: pnpm
- cache-dependency-path: website/pnpm-lock.yaml
+ cache-dependency-path: pnpm-lock.yaml
- name: Install dependencies
working-directory: website
run: pnpm install --frozen-lockfile
diff --git a/.gitignore b/.gitignore
index 50ca5a6..d85cdec 100644
--- a/.gitignore
+++ b/.gitignore
@@ -240,3 +240,5 @@ tmp/
*.bak
+website/public/playground-engine/
+
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 516cadc..618b1fa 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -100,13 +100,40 @@ importers:
'@astrojs/starlight':
specifier: 0.41.7
version: 0.41.7(@astrojs/markdown-remark@7.2.4)(astro@7.2.4(@astrojs/markdown-remark@7.2.4)(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)(@types/node@26.2.0)(yaml@2.9.0))(typescript@6.0.3)
+ '@avsystem/openapi-ng':
+ specifier: 0.5.1
+ version: 0.5.1(@angular/common@22.1.3(@angular/core@22.1.3(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.1.3(rxjs@7.8.2))(@angular/forms@22.1.3(@angular/common@22.1.3(@angular/core@22.1.3(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.1.3(rxjs@7.8.2))(@angular/platform-browser@22.1.3(@angular/common@22.1.3(@angular/core@22.1.3(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.1.3(rxjs@7.8.2)))(rxjs@7.8.2))(rxjs@7.8.2)
+ '@avsystem/openapi-ng-wasm32-wasi':
+ specifier: 0.5.1
+ version: 0.5.1
+ '@codemirror/lang-json':
+ specifier: 6.0.2
+ version: 6.0.2
+ '@codemirror/lang-yaml':
+ specifier: 6.1.3
+ version: 6.1.3
astro:
specifier: 7.2.4
version: 7.2.4(@astrojs/markdown-remark@7.2.4)(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)(@types/node@26.2.0)(yaml@2.9.0)
+ codemirror:
+ specifier: 6.0.2
+ version: 6.0.2
+ highlight.js:
+ specifier: 11.12.0
+ version: 11.12.0
+ lz-string:
+ specifier: 1.5.0
+ version: 1.5.0
sharp:
specifier: 0.35.3
version: 0.35.3(@types/node@26.2.0)
devDependencies:
+ '@types/lz-string':
+ specifier: 1.5.0
+ version: 1.5.0
+ esbuild:
+ specifier: 0.28.2
+ version: 0.28.2
wrangler:
specifier: 4.124.0
version: 4.124.0
@@ -257,6 +284,81 @@ packages:
resolution: {integrity: sha512-C1TLn5sPJr0x4vk56piHWKbnqlEB8BKyte5Y45V02U+D7BGO5eMqZDH5aPjnkXQWJggvmsTXxH03QMZ9NgWLzQ==}
engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0}
+ '@avsystem/openapi-ng-darwin-arm64@0.5.1':
+ resolution: {integrity: sha512-eRkWjsVRQmMcbcVy0uqDhrT1rBUmKemnHIO5gyy+c9nahJTZgb2MUK4uACMnan8z9k9HFTHoa6htbJKxAdqF8Q==}
+ engines: {node: '>=22.12.0'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@avsystem/openapi-ng-darwin-x64@0.5.1':
+ resolution: {integrity: sha512-wQCbR7+Djfvn12MFCIxT46Kg9B4bZfd05RxFvLoecuTdVSr3Cbf1xfDOV5G0fEPHBQoUTjjMrRJ3YzV2JQwOcw==}
+ engines: {node: '>=22.12.0'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@avsystem/openapi-ng-linux-arm64-gnu@0.5.1':
+ resolution: {integrity: sha512-Gpr5lD6K+PaUOGDuoIt4ubf0naPRKGKTwDBn1L/b9upkcI9FLIZUVUbz2xOwTvnkEuJW9lkvYRYV9xfB5d1YVA==}
+ engines: {node: '>=22.12.0'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@avsystem/openapi-ng-linux-arm64-musl@0.5.1':
+ resolution: {integrity: sha512-sdpOa0/dwQa88sHQRccXndaVPCWyDOi/+KEvr40oQ9w+QfXtgM379pCGkueO9yTjWXWRopnPwjPy6QXV0ybC1A==}
+ engines: {node: '>=22.12.0'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@avsystem/openapi-ng-linux-x64-gnu@0.5.1':
+ resolution: {integrity: sha512-2vS0gvvUivZQJtns1GJ7kh3H5BrYTWK8TirPRQymeG4XTHw4VemrSB8Cb1OV4runOr0Lpd9GBwO7hfvkrSRgvw==}
+ engines: {node: '>=22.12.0'}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@avsystem/openapi-ng-linux-x64-musl@0.5.1':
+ resolution: {integrity: sha512-iSELKxFPV81K396+kNUm1uG5eTLWAYVILJABZhI9kqdKP3wZslch/0A8+Qd51J2X88Ii0YG8T10Kaei3F37tKg==}
+ engines: {node: '>=22.12.0'}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@avsystem/openapi-ng-wasm32-wasi@0.5.1':
+ resolution: {integrity: sha512-0vIVR1jjBYOWrrDzGqpTmZJSKZ/VbP30npKw4YgErnCOyRNiFZgvjxbwf5LJa4ag7ZUYLh/vFMHW0Zd+pnaPZw==}
+ engines: {node: '>=22.13.0 <23.0.0-0 || >=23.5.0'}
+
+ '@avsystem/openapi-ng-win32-arm64-msvc@0.5.1':
+ resolution: {integrity: sha512-a+iUKZ2Litf0Cka+BaOKkGTeOQHoZsNmm1FG5vF9rAjb9n8mBfnKBZaeZHe6fZ1Z0Eh0uptKOv+KDcVSNkZm/Q==}
+ engines: {node: '>=22.12.0'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@avsystem/openapi-ng-win32-x64-msvc@0.5.1':
+ resolution: {integrity: sha512-tkfCdDbOhwDu3jRWTNklh8LZfwX7WIy/ZYEd5UvID+l1KlLy7AFTHT5of+uyqv0gwaXIkqj+I99YXiLdZJPrzQ==}
+ engines: {node: '>=22.12.0'}
+ cpu: [x64]
+ os: [win32]
+
+ '@avsystem/openapi-ng@0.5.1':
+ resolution: {integrity: sha512-vHEteiYAmabM/p8iomjzhLUfzrGPIKNB1gt8oXZkBPB7Cq6RFod0i5oYtnW1eBevMOcHuen9cyEaSNbpWs4obA==}
+ engines: {node: '>=22.12.0'}
+ hasBin: true
+ peerDependencies:
+ '@angular/common': '>=20.0.0'
+ '@angular/core': '>=20.0.0'
+ '@angular/forms': '>=21.0.0'
+ rxjs: '>=7.0.0'
+ peerDependenciesMeta:
+ '@angular/common':
+ optional: true
+ '@angular/core':
+ optional: true
+ '@angular/forms':
+ optional: true
+ rxjs:
+ optional: true
+
'@babel/helper-string-parser@7.27.1':
resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
engines: {node: '>=6.9.0'}
@@ -427,6 +529,33 @@ packages:
cpu: [x64]
os: [win32]
+ '@codemirror/autocomplete@6.20.3':
+ resolution: {integrity: sha512-tlosUqb+3BbxCxZdu4tKeRghPFC+QM7q4X5YhKV2eCmPG+1r2F3f4AaSz5sCrFqUtX4Jh20VFTKecl16MgiV9g==}
+
+ '@codemirror/commands@6.11.0':
+ resolution: {integrity: sha512-/K4Rl5BN0OtTiPWmJCdqODu38XnDMsDxKY5rgrPnCkutPTJf2wVbkoixLfealF5Kwse/s8P8M5jAiURiwSwnFA==}
+
+ '@codemirror/lang-json@6.0.2':
+ resolution: {integrity: sha512-x2OtO+AvwEHrEwR0FyyPtfDUiloG3rnVTSZV1W8UteaLL8/MajQd8DpvUb2YVzC+/T18aSDv0H9mu+xw0EStoQ==}
+
+ '@codemirror/lang-yaml@6.1.3':
+ resolution: {integrity: sha512-AZ8DJBuXGVHybpBQhmZtgew5//4hv3tdkXnr3vDmOUMJRuB6vn/uuwtmTOTlqEaQFg3hQSVeA90NmvIQyUV6FQ==}
+
+ '@codemirror/language@6.12.4':
+ resolution: {integrity: sha512-1q4PaT+o6PbgpkJt4Q8Fv5XJxTy4FUZ4MWETtyiDw3J0Pyr9E2vqcKL+k9wcvjNTIsauxvE7OfmWj3FRPHQ76A==}
+
+ '@codemirror/lint@6.9.7':
+ resolution: {integrity: sha512-28/+iWLYxKxsvGYhSYL7zaCZqLz5+FFFDq9tVsvGv9kv8RY4fFAchJ5WX9M3YrrRlTIsECjsXPqeNgnSmNP2dg==}
+
+ '@codemirror/search@6.7.2':
+ resolution: {integrity: sha512-gUYkYhT2+n/+VGZ+8EzE5WFkYZUZYm1VOKDudIsNqh42uRVQJ0a6Yss9sdKT3MeOYfuL1N6AZA57oza0Oyr0LA==}
+
+ '@codemirror/state@6.7.2':
+ resolution: {integrity: sha512-U3RiPX62Wl/Gx4ftQ7UxLlloSfsFTQqKa+7vFBYteZGCzkp6oBqcsD7iSwniWRGobCAmDcwZSY+Six3+3ztdfg==}
+
+ '@codemirror/view@6.43.11':
+ resolution: {integrity: sha512-2+esucbQX6wB2JYi1eDvdCPFTA31BN8oSy6xCmk3G6CloV11yOvEjYk+gH7kLrP0MuHG94E8WDhjs5oMiu3+Wg==}
+
'@cspotcode/source-map-support@0.8.1':
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
engines: {node: '>=12'}
@@ -1240,11 +1369,29 @@ packages:
'@jridgewell/trace-mapping@0.3.9':
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
+ '@lezer/common@1.5.2':
+ resolution: {integrity: sha512-sxQE460fPZyU3sdc8lafxiPwJHBzZRy/udNFynGQky1SePYBdhkBl1kOagA9uT3pxR8K09bOrmTUqA9wb/PjSQ==}
+
+ '@lezer/highlight@1.2.3':
+ resolution: {integrity: sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g==}
+
+ '@lezer/json@1.0.3':
+ resolution: {integrity: sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==}
+
+ '@lezer/lr@1.4.10':
+ resolution: {integrity: sha512-rnCpTIBafOx4mRp43xOxDJbFipJm/c0cia/V5TiGlhmMa+wsSdoGmUN3w5Bqrks/09Q/D4tNAmWaT8p6NRi77A==}
+
+ '@lezer/yaml@1.0.4':
+ resolution: {integrity: sha512-2lrrHqxalACEbxIbsjhqGpSW8kWpUKuY6RHgnSAFZa6qK62wvnPxA8hGOwOoDbwHcOFs5M4o27mjGu+P7TvBmw==}
+
'@mapbox/node-pre-gyp@2.0.0':
resolution: {integrity: sha512-llMXd39jtP0HpQLVI37Bf1m2ADlEb35GYSh1SDSLsBhR+5iCxiNGlT31yqbNtVHygHAtMy6dWFERpU2JgufhPg==}
engines: {node: '>=18'}
hasBin: true
+ '@marijn/find-cluster-break@1.0.4':
+ resolution: {integrity: sha512-Wy0V7+SGUjnF9/TkiM1hKVDPj7jKXduPNboMVtHTA8dySMURWqfg/JZ9E2Sq8JgSJmkl7k7Qe9FLeMSrSraWmQ==}
+
'@mdx-js/mdx@3.1.1':
resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==}
@@ -2379,6 +2526,10 @@ packages:
'@types/js-yaml@4.0.9':
resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==}
+ '@types/lz-string@1.5.0':
+ resolution: {integrity: sha512-s84fKOrzqqNCAPljhVyC5TjAo6BH4jKHw9NRNFNiRUY5QSgZCmVm5XILlWbisiKl+0OcS7eWihmKGS5akc2iQw==}
+ deprecated: This is a stub types definition. lz-string provides its own type definitions, so you do not need this installed.
+
'@types/mdast@4.0.4':
resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
@@ -2642,6 +2793,9 @@ packages:
resolution: {integrity: sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ codemirror@6.0.2:
+ resolution: {integrity: sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==}
+
collapse-white-space@2.1.0:
resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==}
@@ -2696,6 +2850,9 @@ packages:
resolution: {integrity: sha512-yuToqVvRrj6pfDXREyQAAv8SkAEk/8GS3jQRTiUMm66TVtBYmqQeoEjL2Lmq8Rpo6271vH76InTChTitEAm65w==}
engines: {node: '>=22'}
+ crelt@1.0.7:
+ resolution: {integrity: sha512-aK6BbWfhf4U/wCcLHKPJl/xa6VkVstRaPywWtMKGwuOLc/wZTyQYuoxgvZnNsBvv7Kg3YTBQYYBCggcviQczuA==}
+
cross-spawn@7.0.6:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
@@ -3060,6 +3217,10 @@ packages:
hastscript@9.0.1:
resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==}
+ highlight.js@11.12.0:
+ resolution: {integrity: sha512-nbfWpyRMcMrPMmDwJB+dhX/eiaPKtc2RB+0QZskqJ3WjRA/FDS0e9hZrx8EC/lbEv8gXy98FcDbNa/dspAaJMg==}
+ engines: {node: '>=12.0.0'}
+
html-escaper@3.0.3:
resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==}
@@ -3305,6 +3466,10 @@ packages:
resolution: {integrity: sha512-5YgH9UJd7wVb9hIouI2adWpgqrrICkt070Dnj8EUY1+B4B2P9eRLPAkAAo6NICA7CEhOIeBHl46u9zSNpNu7zA==}
engines: {node: 20 || >=22}
+ lz-string@1.5.0:
+ resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==}
+ hasBin: true
+
magic-string@0.30.21:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
@@ -4007,6 +4172,9 @@ packages:
resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==}
engines: {node: '>=12'}
+ style-mod@4.1.3:
+ resolution: {integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==}
+
style-to-js@1.1.21:
resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==}
@@ -4299,6 +4467,9 @@ packages:
vite:
optional: true
+ w3c-keyname@2.2.8:
+ resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==}
+
web-namespaces@2.0.1:
resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
@@ -4597,6 +4768,53 @@ snapshots:
is-docker: 4.0.0
package-manager-detector: 1.6.0
+ '@avsystem/openapi-ng-darwin-arm64@0.5.1':
+ optional: true
+
+ '@avsystem/openapi-ng-darwin-x64@0.5.1':
+ optional: true
+
+ '@avsystem/openapi-ng-linux-arm64-gnu@0.5.1':
+ optional: true
+
+ '@avsystem/openapi-ng-linux-arm64-musl@0.5.1':
+ optional: true
+
+ '@avsystem/openapi-ng-linux-x64-gnu@0.5.1':
+ optional: true
+
+ '@avsystem/openapi-ng-linux-x64-musl@0.5.1':
+ optional: true
+
+ '@avsystem/openapi-ng-wasm32-wasi@0.5.1':
+ dependencies:
+ '@emnapi/core': 1.11.3
+ '@emnapi/runtime': 1.11.3
+ '@napi-rs/wasm-runtime': 1.2.3(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)
+
+ '@avsystem/openapi-ng-win32-arm64-msvc@0.5.1':
+ optional: true
+
+ '@avsystem/openapi-ng-win32-x64-msvc@0.5.1':
+ optional: true
+
+ '@avsystem/openapi-ng@0.5.1(@angular/common@22.1.3(@angular/core@22.1.3(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.1.3(rxjs@7.8.2))(@angular/forms@22.1.3(@angular/common@22.1.3(@angular/core@22.1.3(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.1.3(rxjs@7.8.2))(@angular/platform-browser@22.1.3(@angular/common@22.1.3(@angular/core@22.1.3(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.1.3(rxjs@7.8.2)))(rxjs@7.8.2))(rxjs@7.8.2)':
+ dependencies:
+ yaml: 2.9.0
+ optionalDependencies:
+ '@angular/common': 22.1.3(@angular/core@22.1.3(rxjs@7.8.2))(rxjs@7.8.2)
+ '@angular/core': 22.1.3(rxjs@7.8.2)
+ '@angular/forms': 22.1.3(@angular/common@22.1.3(@angular/core@22.1.3(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.1.3(rxjs@7.8.2))(@angular/platform-browser@22.1.3(@angular/common@22.1.3(@angular/core@22.1.3(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.1.3(rxjs@7.8.2)))(rxjs@7.8.2)
+ '@avsystem/openapi-ng-darwin-arm64': 0.5.1
+ '@avsystem/openapi-ng-darwin-x64': 0.5.1
+ '@avsystem/openapi-ng-linux-arm64-gnu': 0.5.1
+ '@avsystem/openapi-ng-linux-arm64-musl': 0.5.1
+ '@avsystem/openapi-ng-linux-x64-gnu': 0.5.1
+ '@avsystem/openapi-ng-linux-x64-musl': 0.5.1
+ '@avsystem/openapi-ng-win32-arm64-msvc': 0.5.1
+ '@avsystem/openapi-ng-win32-x64-msvc': 0.5.1
+ rxjs: 7.8.2
+
'@babel/helper-string-parser@7.27.1': {}
'@babel/helper-validator-identifier@7.28.5': {}
@@ -4711,6 +4929,67 @@ snapshots:
'@cloudflare/workerd-windows-64@1.20260815.1':
optional: true
+ '@codemirror/autocomplete@6.20.3':
+ dependencies:
+ '@codemirror/language': 6.12.4
+ '@codemirror/state': 6.7.2
+ '@codemirror/view': 6.43.11
+ '@lezer/common': 1.5.2
+
+ '@codemirror/commands@6.11.0':
+ dependencies:
+ '@codemirror/language': 6.12.4
+ '@codemirror/state': 6.7.2
+ '@codemirror/view': 6.43.11
+ '@lezer/common': 1.5.2
+
+ '@codemirror/lang-json@6.0.2':
+ dependencies:
+ '@codemirror/language': 6.12.4
+ '@lezer/json': 1.0.3
+
+ '@codemirror/lang-yaml@6.1.3':
+ dependencies:
+ '@codemirror/autocomplete': 6.20.3
+ '@codemirror/language': 6.12.4
+ '@codemirror/state': 6.7.2
+ '@lezer/common': 1.5.2
+ '@lezer/highlight': 1.2.3
+ '@lezer/lr': 1.4.10
+ '@lezer/yaml': 1.0.4
+
+ '@codemirror/language@6.12.4':
+ dependencies:
+ '@codemirror/state': 6.7.2
+ '@codemirror/view': 6.43.11
+ '@lezer/common': 1.5.2
+ '@lezer/highlight': 1.2.3
+ '@lezer/lr': 1.4.10
+ style-mod: 4.1.3
+
+ '@codemirror/lint@6.9.7':
+ dependencies:
+ '@codemirror/state': 6.7.2
+ '@codemirror/view': 6.43.11
+ crelt: 1.0.7
+
+ '@codemirror/search@6.7.2':
+ dependencies:
+ '@codemirror/state': 6.7.2
+ '@codemirror/view': 6.43.11
+ crelt: 1.0.7
+
+ '@codemirror/state@6.7.2':
+ dependencies:
+ '@marijn/find-cluster-break': 1.0.4
+
+ '@codemirror/view@6.43.11':
+ dependencies:
+ '@codemirror/state': 6.7.2
+ crelt: 1.0.7
+ style-mod: 4.1.3
+ w3c-keyname: 2.2.8
+
'@cspotcode/source-map-support@0.8.1':
dependencies:
'@jridgewell/trace-mapping': 0.3.9
@@ -5255,6 +5534,28 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.5
+ '@lezer/common@1.5.2': {}
+
+ '@lezer/highlight@1.2.3':
+ dependencies:
+ '@lezer/common': 1.5.2
+
+ '@lezer/json@1.0.3':
+ dependencies:
+ '@lezer/common': 1.5.2
+ '@lezer/highlight': 1.2.3
+ '@lezer/lr': 1.4.10
+
+ '@lezer/lr@1.4.10':
+ dependencies:
+ '@lezer/common': 1.5.2
+
+ '@lezer/yaml@1.0.4':
+ dependencies:
+ '@lezer/common': 1.5.2
+ '@lezer/highlight': 1.2.3
+ '@lezer/lr': 1.4.10
+
'@mapbox/node-pre-gyp@2.0.0':
dependencies:
consola: 3.4.0
@@ -5268,6 +5569,8 @@ snapshots:
- encoding
- supports-color
+ '@marijn/find-cluster-break@1.0.4': {}
+
'@mdx-js/mdx@3.1.1':
dependencies:
'@types/estree': 1.0.8
@@ -6068,6 +6371,10 @@ snapshots:
'@types/js-yaml@4.0.9': {}
+ '@types/lz-string@1.5.0':
+ dependencies:
+ lz-string: 1.5.0
+
'@types/mdast@4.0.4':
dependencies:
'@types/unist': 3.0.3
@@ -6415,6 +6722,16 @@ snapshots:
dependencies:
convert-to-spaces: 2.0.1
+ codemirror@6.0.2:
+ dependencies:
+ '@codemirror/autocomplete': 6.20.3
+ '@codemirror/commands': 6.11.0
+ '@codemirror/language': 6.12.4
+ '@codemirror/lint': 6.9.7
+ '@codemirror/search': 6.7.2
+ '@codemirror/state': 6.7.2
+ '@codemirror/view': 6.43.11
+
collapse-white-space@2.1.0: {}
color-convert@2.0.1:
@@ -6456,6 +6773,8 @@ snapshots:
cookie@2.0.1: {}
+ crelt@1.0.7: {}
+
cross-spawn@7.0.6:
dependencies:
path-key: 3.1.1
@@ -6992,6 +7311,8 @@ snapshots:
property-information: 7.1.0
space-separated-tokens: 2.0.2
+ highlight.js@11.12.0: {}
+
html-escaper@3.0.3: {}
html-void-elements@3.0.0: {}
@@ -7160,6 +7481,8 @@ snapshots:
lru-cache@11.5.0: {}
+ lz-string@1.5.0: {}
+
magic-string@0.30.21:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
@@ -8346,6 +8669,8 @@ snapshots:
dependencies:
ansi-regex: 6.2.2
+ style-mod@4.1.3: {}
+
style-to-js@1.1.21:
dependencies:
style-to-object: 1.0.14
@@ -8560,6 +8885,8 @@ snapshots:
optionalDependencies:
vite: 8.2.2(@types/node@26.2.0)(esbuild@0.28.2)(yaml@2.9.0)
+ w3c-keyname@2.2.8: {}
+
web-namespaces@2.0.1: {}
webidl-conversions@3.0.1: {}
diff --git a/website/astro.config.mjs b/website/astro.config.mjs
index 60f8976..acfb070 100644
--- a/website/astro.config.mjs
+++ b/website/astro.config.mjs
@@ -30,6 +30,7 @@ export default defineConfig({
items: [
{ label: 'Introduction', slug: '' },
{ label: 'Getting started', slug: 'getting-started' },
+ { label: 'Playground', link: '/playground/' },
],
},
{
@@ -53,4 +54,8 @@ export default defineConfig({
],
}),
],
+ vite: {
+ build: { target: 'es2022' },
+ server: { fs: { allow: ['..'] } },
+ },
});
diff --git a/website/package.json b/website/package.json
index c2b3474..30dc823 100644
--- a/website/package.json
+++ b/website/package.json
@@ -4,18 +4,29 @@
"private": true,
"type": "module",
"scripts": {
+ "predev": "node scripts/bundle-engine.mjs",
"dev": "astro dev",
"start": "astro dev",
+ "prebuild": "node scripts/bundle-engine.mjs",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/starlight": "0.41.7",
+ "@avsystem/openapi-ng": "0.5.1",
+ "@avsystem/openapi-ng-wasm32-wasi": "0.5.1",
+ "@codemirror/lang-json": "6.0.2",
+ "@codemirror/lang-yaml": "6.1.3",
"astro": "7.2.4",
+ "codemirror": "6.0.2",
+ "highlight.js": "11.12.0",
+ "lz-string": "1.5.0",
"sharp": "0.35.3"
},
"devDependencies": {
+ "@types/lz-string": "1.5.0",
+ "esbuild": "0.28.2",
"wrangler": "4.124.0"
},
"packageManager": "pnpm@10.33.3"
diff --git a/website/pnpm-lock.yaml b/website/pnpm-lock.yaml
deleted file mode 100644
index 1f3e1f3..0000000
--- a/website/pnpm-lock.yaml
+++ /dev/null
@@ -1,3993 +0,0 @@
-lockfileVersion: '9.0'
-
-settings:
- autoInstallPeers: true
- excludeLinksFromLockfile: false
-
-importers:
-
- .:
- dependencies:
- '@astrojs/starlight':
- specifier: 0.39.2
- version: 0.39.2(astro@6.3.6(@types/node@24.12.4)(rollup@4.60.4))(typescript@5.9.3)
- astro:
- specifier: 6.3.6
- version: 6.3.6(@types/node@24.12.4)(rollup@4.60.4)
- sharp:
- specifier: 0.34.5
- version: 0.34.5
-
-packages:
-
- '@astrojs/compiler@4.0.0':
- resolution: {integrity: sha512-eouss7G8ygdZqHuke033VMcVw5HTZUu+PXd/h06DGDUg/jt5btPYPqh66ENWw/mU78rBrf/oeC4oqoBwMtDMNA==}
-
- '@astrojs/internal-helpers@0.9.1':
- resolution: {integrity: sha512-1pWuARqYom/TzuU3+0ZugsTrKlUydWKuULmDqSMTuonY+9IRDUEGKX/8PXQ1nBxRq3w85uGtd9q9SXfqEldMIQ==}
-
- '@astrojs/markdown-remark@7.1.2':
- resolution: {integrity: sha512-caXZ4Dc2St2dW8luEg22GlP0gupLdztCTQE4EzZOxW1pqWXz9mbeJEuHUkgDYcKWW8tjIHkydYDhWLVoxJ327Q==}
-
- '@astrojs/mdx@5.0.6':
- resolution: {integrity: sha512-4dKe0ZMmqujofPNDHahzClkwinn9f8jHPcaXcgdGvPAlboD2mjzkUCofli2cBnxYAkdfhC6d50gBJ8i/cH8gHw==}
- engines: {node: '>=22.12.0'}
- peerDependencies:
- astro: ^6.0.0
-
- '@astrojs/prism@4.0.2':
- resolution: {integrity: sha512-KTivpmnz6lDsC6o9H4+DNm2SrE/GHzw8cNAvEJwAvUT+eoaEnn/4NtbDNfRRaxaJHdp15gf+tfHAWiXR4wB3BA==}
- engines: {node: '>=22.12.0'}
-
- '@astrojs/sitemap@3.7.2':
- resolution: {integrity: sha512-PqkzkcZTb5ICiyIR8VoKbIAP/laNRXi5tw616N1Ckk+40oNB8Can1AzVV56lrbC5GKSZFCyJYUVYqVivMisvpA==}
-
- '@astrojs/starlight@0.39.2':
- resolution: {integrity: sha512-vlw+bwnjtf5buCTUtLU7JfV6D3knslxqnspr6LKs6hfRuFZiyr5hT44F7GyDqR9FKANUqFxnIzWM81F1k/kOUA==}
- peerDependencies:
- astro: ^6.0.0
-
- '@astrojs/telemetry@3.3.2':
- resolution: {integrity: sha512-j8DNruA8ors99Al39RYZPJK4DC1bKkoNm93mAMuBhY9TCNC4R8n1q7ovFnJ5qhGh5Lsh7pa1gpQVpYpsJPeTHQ==}
- engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0}
-
- '@babel/helper-string-parser@7.27.1':
- resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
- engines: {node: '>=6.9.0'}
-
- '@babel/helper-validator-identifier@7.28.5':
- resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
- engines: {node: '>=6.9.0'}
-
- '@babel/parser@7.29.3':
- resolution: {integrity: sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==}
- engines: {node: '>=6.0.0'}
- hasBin: true
-
- '@babel/types@7.29.0':
- resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==}
- engines: {node: '>=6.9.0'}
-
- '@capsizecss/unpack@4.0.0':
- resolution: {integrity: sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA==}
- engines: {node: '>=18'}
-
- '@clack/core@1.3.1':
- resolution: {integrity: sha512-fT1qHVGAag4IEkrupZ6lRRbNCs1vS9P01KB/sG8zKgvUztbYtFBtQpjSITNwooDZ83tpsPzP0mRNs1/KVszCRA==}
- engines: {node: '>= 20.12.0'}
-
- '@clack/prompts@1.4.0':
- resolution: {integrity: sha512-S0My7XPGIgpRWMDG8uRqalbgT+a6FmCUdOW+HaIOVVpUPHOb7RrpvjTjiODadKp06fsrVDJZlIzc6yCTp4AnxA==}
- engines: {node: '>= 20.12.0'}
-
- '@ctrl/tinycolor@4.2.0':
- resolution: {integrity: sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==}
- engines: {node: '>=14'}
-
- '@emnapi/runtime@1.10.0':
- resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==}
-
- '@esbuild/aix-ppc64@0.27.7':
- resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==}
- engines: {node: '>=18'}
- cpu: [ppc64]
- os: [aix]
-
- '@esbuild/android-arm64@0.27.7':
- resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [android]
-
- '@esbuild/android-arm@0.27.7':
- resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==}
- engines: {node: '>=18'}
- cpu: [arm]
- os: [android]
-
- '@esbuild/android-x64@0.27.7':
- resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [android]
-
- '@esbuild/darwin-arm64@0.27.7':
- resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [darwin]
-
- '@esbuild/darwin-x64@0.27.7':
- resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [darwin]
-
- '@esbuild/freebsd-arm64@0.27.7':
- resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [freebsd]
-
- '@esbuild/freebsd-x64@0.27.7':
- resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [freebsd]
-
- '@esbuild/linux-arm64@0.27.7':
- resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [linux]
-
- '@esbuild/linux-arm@0.27.7':
- resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==}
- engines: {node: '>=18'}
- cpu: [arm]
- os: [linux]
-
- '@esbuild/linux-ia32@0.27.7':
- resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==}
- engines: {node: '>=18'}
- cpu: [ia32]
- os: [linux]
-
- '@esbuild/linux-loong64@0.27.7':
- resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==}
- engines: {node: '>=18'}
- cpu: [loong64]
- os: [linux]
-
- '@esbuild/linux-mips64el@0.27.7':
- resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==}
- engines: {node: '>=18'}
- cpu: [mips64el]
- os: [linux]
-
- '@esbuild/linux-ppc64@0.27.7':
- resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==}
- engines: {node: '>=18'}
- cpu: [ppc64]
- os: [linux]
-
- '@esbuild/linux-riscv64@0.27.7':
- resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==}
- engines: {node: '>=18'}
- cpu: [riscv64]
- os: [linux]
-
- '@esbuild/linux-s390x@0.27.7':
- resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==}
- engines: {node: '>=18'}
- cpu: [s390x]
- os: [linux]
-
- '@esbuild/linux-x64@0.27.7':
- resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [linux]
-
- '@esbuild/netbsd-arm64@0.27.7':
- resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [netbsd]
-
- '@esbuild/netbsd-x64@0.27.7':
- resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [netbsd]
-
- '@esbuild/openbsd-arm64@0.27.7':
- resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [openbsd]
-
- '@esbuild/openbsd-x64@0.27.7':
- resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [openbsd]
-
- '@esbuild/openharmony-arm64@0.27.7':
- resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [openharmony]
-
- '@esbuild/sunos-x64@0.27.7':
- resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [sunos]
-
- '@esbuild/win32-arm64@0.27.7':
- resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==}
- engines: {node: '>=18'}
- cpu: [arm64]
- os: [win32]
-
- '@esbuild/win32-ia32@0.27.7':
- resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==}
- engines: {node: '>=18'}
- cpu: [ia32]
- os: [win32]
-
- '@esbuild/win32-x64@0.27.7':
- resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==}
- engines: {node: '>=18'}
- cpu: [x64]
- os: [win32]
-
- '@expressive-code/core@0.42.0':
- resolution: {integrity: sha512-MN11+9nfmaC7sYu2BZJXAXqwkBRt8t1xTSqP+Ti1NfTEskgl6xUnzDxoaiQkg0BMzpglA0pys4dpDKquP/cyIw==}
-
- '@expressive-code/plugin-frames@0.42.0':
- resolution: {integrity: sha512-XtkPm+941Uta7Y+81Acv+OA/20F1NJmJhCX6UYGKpqEIGqplNh3PTOhcURp6tcruhlzJcWcvpWy6Oigz3SrjqA==}
-
- '@expressive-code/plugin-shiki@0.42.0':
- resolution: {integrity: sha512-PMKey/kLmewttAHQezL+Y5Fx3vVssfDi3+FJOYQQS2mXP3tQspFELtKKAfsXfmSXdToZYgwoO69HJndqfE+09g==}
-
- '@expressive-code/plugin-text-markers@0.42.0':
- resolution: {integrity: sha512-l59lUx8fq1v5g6SpmbDjiU0+7IdfbiWnAyRmtTVSpfhyq+nZMN4UcmYyu2b9Mynhzt7Gr+O+cXyEPDNb2AVWVQ==}
-
- '@img/colour@1.1.0':
- resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==}
- engines: {node: '>=18'}
-
- '@img/sharp-darwin-arm64@0.34.5':
- resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==}
- engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
- cpu: [arm64]
- os: [darwin]
-
- '@img/sharp-darwin-x64@0.34.5':
- resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==}
- engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
- cpu: [x64]
- os: [darwin]
-
- '@img/sharp-libvips-darwin-arm64@1.2.4':
- resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==}
- cpu: [arm64]
- os: [darwin]
-
- '@img/sharp-libvips-darwin-x64@1.2.4':
- resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==}
- cpu: [x64]
- os: [darwin]
-
- '@img/sharp-libvips-linux-arm64@1.2.4':
- resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
- cpu: [arm64]
- os: [linux]
- libc: [glibc]
-
- '@img/sharp-libvips-linux-arm@1.2.4':
- resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
- cpu: [arm]
- os: [linux]
- libc: [glibc]
-
- '@img/sharp-libvips-linux-ppc64@1.2.4':
- resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
- cpu: [ppc64]
- os: [linux]
- libc: [glibc]
-
- '@img/sharp-libvips-linux-riscv64@1.2.4':
- resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
- cpu: [riscv64]
- os: [linux]
- libc: [glibc]
-
- '@img/sharp-libvips-linux-s390x@1.2.4':
- resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
- cpu: [s390x]
- os: [linux]
- libc: [glibc]
-
- '@img/sharp-libvips-linux-x64@1.2.4':
- resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
- cpu: [x64]
- os: [linux]
- libc: [glibc]
-
- '@img/sharp-libvips-linuxmusl-arm64@1.2.4':
- resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
- cpu: [arm64]
- os: [linux]
- libc: [musl]
-
- '@img/sharp-libvips-linuxmusl-x64@1.2.4':
- resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
- cpu: [x64]
- os: [linux]
- libc: [musl]
-
- '@img/sharp-linux-arm64@0.34.5':
- resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
- engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
- cpu: [arm64]
- os: [linux]
- libc: [glibc]
-
- '@img/sharp-linux-arm@0.34.5':
- resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
- engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
- cpu: [arm]
- os: [linux]
- libc: [glibc]
-
- '@img/sharp-linux-ppc64@0.34.5':
- resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
- engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
- cpu: [ppc64]
- os: [linux]
- libc: [glibc]
-
- '@img/sharp-linux-riscv64@0.34.5':
- resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
- engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
- cpu: [riscv64]
- os: [linux]
- libc: [glibc]
-
- '@img/sharp-linux-s390x@0.34.5':
- resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
- engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
- cpu: [s390x]
- os: [linux]
- libc: [glibc]
-
- '@img/sharp-linux-x64@0.34.5':
- resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
- engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
- cpu: [x64]
- os: [linux]
- libc: [glibc]
-
- '@img/sharp-linuxmusl-arm64@0.34.5':
- resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
- engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
- cpu: [arm64]
- os: [linux]
- libc: [musl]
-
- '@img/sharp-linuxmusl-x64@0.34.5':
- resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
- engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
- cpu: [x64]
- os: [linux]
- libc: [musl]
-
- '@img/sharp-wasm32@0.34.5':
- resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
- engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
- cpu: [wasm32]
-
- '@img/sharp-win32-arm64@0.34.5':
- resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==}
- engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
- cpu: [arm64]
- os: [win32]
-
- '@img/sharp-win32-ia32@0.34.5':
- resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==}
- engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
- cpu: [ia32]
- os: [win32]
-
- '@img/sharp-win32-x64@0.34.5':
- resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==}
- engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
- cpu: [x64]
- os: [win32]
-
- '@jridgewell/sourcemap-codec@1.5.5':
- resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
-
- '@mdx-js/mdx@3.1.1':
- resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==}
-
- '@oslojs/encoding@1.1.0':
- resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==}
-
- '@pagefind/darwin-arm64@1.5.2':
- resolution: {integrity: sha512-MXpI+7HsAdPkvJ0gk9xj9g541BCqBZOBbdwj9g6lB5LCj6kSV6nqDSjzcAJwvOsfu0fjwvC8hQU+ecfhp+MpiQ==}
- cpu: [arm64]
- os: [darwin]
-
- '@pagefind/darwin-x64@1.5.2':
- resolution: {integrity: sha512-IojxFWMEJe0RQ7PQ3KXQsPIImNsbpPYpoZ+QUDrL8fAl/O27IX+LVLs74/UzEZy5uA2LD8Nz1AiwKr72vrkZQw==}
- cpu: [x64]
- os: [darwin]
-
- '@pagefind/default-ui@1.5.2':
- resolution: {integrity: sha512-pm1LMnQg8N2B3n2TnjKlhaFihpz6zTiA4HiGQ6/slKO/+8K9CAU5kcjdSSPgpuk1PMuuN4hxLipUIifnrkl3Sg==}
-
- '@pagefind/freebsd-x64@1.5.2':
- resolution: {integrity: sha512-7EVzo9+0w+2cbe671BtMj10UlNo83I+HrLVLfRxO731svHRJKUfJ/mo05gU14pe9PCfpKNQT8FS3Xc/oDN6pOA==}
- cpu: [x64]
- os: [freebsd]
-
- '@pagefind/linux-arm64@1.5.2':
- resolution: {integrity: sha512-Ovt9+K35sqzn8H3ZMXGwls4TD/wMJuvRtShHIsmUQREmaxjrDEX7gHckRCrwYJ4XE1H1p6HkLz3wukrAnsfXQw==}
- cpu: [arm64]
- os: [linux]
-
- '@pagefind/linux-x64@1.5.2':
- resolution: {integrity: sha512-V+tFqHKXhQKq/WqPBD67AFy7scn1/aZID00ws4fSDd+1daSi5UHR9VVlRrOUYKxn3VuFQYRD7lYXdZK1WED1YA==}
- cpu: [x64]
- os: [linux]
-
- '@pagefind/windows-arm64@1.5.2':
- resolution: {integrity: sha512-hN9Nh90fNW61nNRCW9ZyQrAj/mD0eRvmJ8NlTUzkbuW8kIzGJUi3cxjFkEcMZ5h/8FsKWD/VcouZl4yo1F7B6g==}
- cpu: [arm64]
- os: [win32]
-
- '@pagefind/windows-x64@1.5.2':
- resolution: {integrity: sha512-Fa2Iyw7kaDRzGMfNYNUXNW2zbL5FQVDgSOcbDHdzBrDEdpqOqg8TcZ68F22ol6NJ9IGzvUdmeyZypLW5dyhqsg==}
- cpu: [x64]
- os: [win32]
-
- '@rollup/pluginutils@5.3.0':
- resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==}
- engines: {node: '>=14.0.0'}
- peerDependencies:
- rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
- peerDependenciesMeta:
- rollup:
- optional: true
-
- '@rollup/rollup-android-arm-eabi@4.60.4':
- resolution: {integrity: sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==}
- cpu: [arm]
- os: [android]
-
- '@rollup/rollup-android-arm64@4.60.4':
- resolution: {integrity: sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==}
- cpu: [arm64]
- os: [android]
-
- '@rollup/rollup-darwin-arm64@4.60.4':
- resolution: {integrity: sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==}
- cpu: [arm64]
- os: [darwin]
-
- '@rollup/rollup-darwin-x64@4.60.4':
- resolution: {integrity: sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==}
- cpu: [x64]
- os: [darwin]
-
- '@rollup/rollup-freebsd-arm64@4.60.4':
- resolution: {integrity: sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==}
- cpu: [arm64]
- os: [freebsd]
-
- '@rollup/rollup-freebsd-x64@4.60.4':
- resolution: {integrity: sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==}
- cpu: [x64]
- os: [freebsd]
-
- '@rollup/rollup-linux-arm-gnueabihf@4.60.4':
- resolution: {integrity: sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==}
- cpu: [arm]
- os: [linux]
- libc: [glibc]
-
- '@rollup/rollup-linux-arm-musleabihf@4.60.4':
- resolution: {integrity: sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==}
- cpu: [arm]
- os: [linux]
- libc: [musl]
-
- '@rollup/rollup-linux-arm64-gnu@4.60.4':
- resolution: {integrity: sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==}
- cpu: [arm64]
- os: [linux]
- libc: [glibc]
-
- '@rollup/rollup-linux-arm64-musl@4.60.4':
- resolution: {integrity: sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==}
- cpu: [arm64]
- os: [linux]
- libc: [musl]
-
- '@rollup/rollup-linux-loong64-gnu@4.60.4':
- resolution: {integrity: sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==}
- cpu: [loong64]
- os: [linux]
- libc: [glibc]
-
- '@rollup/rollup-linux-loong64-musl@4.60.4':
- resolution: {integrity: sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==}
- cpu: [loong64]
- os: [linux]
- libc: [musl]
-
- '@rollup/rollup-linux-ppc64-gnu@4.60.4':
- resolution: {integrity: sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==}
- cpu: [ppc64]
- os: [linux]
- libc: [glibc]
-
- '@rollup/rollup-linux-ppc64-musl@4.60.4':
- resolution: {integrity: sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==}
- cpu: [ppc64]
- os: [linux]
- libc: [musl]
-
- '@rollup/rollup-linux-riscv64-gnu@4.60.4':
- resolution: {integrity: sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==}
- cpu: [riscv64]
- os: [linux]
- libc: [glibc]
-
- '@rollup/rollup-linux-riscv64-musl@4.60.4':
- resolution: {integrity: sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==}
- cpu: [riscv64]
- os: [linux]
- libc: [musl]
-
- '@rollup/rollup-linux-s390x-gnu@4.60.4':
- resolution: {integrity: sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==}
- cpu: [s390x]
- os: [linux]
- libc: [glibc]
-
- '@rollup/rollup-linux-x64-gnu@4.60.4':
- resolution: {integrity: sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==}
- cpu: [x64]
- os: [linux]
- libc: [glibc]
-
- '@rollup/rollup-linux-x64-musl@4.60.4':
- resolution: {integrity: sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==}
- cpu: [x64]
- os: [linux]
- libc: [musl]
-
- '@rollup/rollup-openbsd-x64@4.60.4':
- resolution: {integrity: sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==}
- cpu: [x64]
- os: [openbsd]
-
- '@rollup/rollup-openharmony-arm64@4.60.4':
- resolution: {integrity: sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==}
- cpu: [arm64]
- os: [openharmony]
-
- '@rollup/rollup-win32-arm64-msvc@4.60.4':
- resolution: {integrity: sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==}
- cpu: [arm64]
- os: [win32]
-
- '@rollup/rollup-win32-ia32-msvc@4.60.4':
- resolution: {integrity: sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==}
- cpu: [ia32]
- os: [win32]
-
- '@rollup/rollup-win32-x64-gnu@4.60.4':
- resolution: {integrity: sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==}
- cpu: [x64]
- os: [win32]
-
- '@rollup/rollup-win32-x64-msvc@4.60.4':
- resolution: {integrity: sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==}
- cpu: [x64]
- os: [win32]
-
- '@shikijs/core@4.1.0':
- resolution: {integrity: sha512-jLJtSJeuFffqX6/inRE1zqU5aFv2hrszvYgq3OjbAgFRZiWv7abKMDdQzYxuSDfmUPQozZvI/kuy6VMTvnvqTQ==}
- engines: {node: '>=20'}
-
- '@shikijs/engine-javascript@4.1.0':
- resolution: {integrity: sha512-YquhawCUgaBfhsS72e2Y/dI59gCBNPHu3fEO/tvLaXrTssxZrY5ddjtNLTwndrMgPo8b3IscE+xoICDzpTmlFQ==}
- engines: {node: '>=20'}
-
- '@shikijs/engine-oniguruma@4.1.0':
- resolution: {integrity: sha512-axLpjVs45YBvvINa+dJF+NPW+KtFkNXsFr4SDw2BMj9GdeMnGxVB9PQb2xXlJYovslt/nz6giedAyOANkfc7hg==}
- engines: {node: '>=20'}
-
- '@shikijs/langs@4.1.0':
- resolution: {integrity: sha512-nwOMruEkbgdZfQ/b8CgpNBVOpvG1k0N5tbmgiFeqsan401+x3ILqlzZJowSla4Agmq4hG2Uf2wh5jLTEhR8VSg==}
- engines: {node: '>=20'}
-
- '@shikijs/primitive@4.1.0':
- resolution: {integrity: sha512-zx2/2Uwj2q9X3KSyYREEhXO23xBw5WUhP4orK2lE4r+t9JGITmEe0JH+wPmJhqHpOT2bRRs6lAL945+LDvOAGw==}
- engines: {node: '>=20'}
-
- '@shikijs/themes@4.1.0':
- resolution: {integrity: sha512-emCcTnUM7yO2wltYbaxm+yLvcCI4+h8XBKc4KmJ7EZUXoSGjcCHifkI//R4OFit9ewpg7H2/9tjOuXrT2v/Knw==}
- engines: {node: '>=20'}
-
- '@shikijs/types@4.1.0':
- resolution: {integrity: sha512-3EQWX54fMpniOrDblzAhiwiJwpiTMW6+B9DWyUd9ska483tbayFYuw47UxwuPknI31bKnySfVQ/QW+jFL4rFdA==}
- engines: {node: '>=20'}
-
- '@shikijs/vscode-textmate@10.0.2':
- resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==}
-
- '@types/debug@4.1.13':
- resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==}
-
- '@types/estree-jsx@1.0.5':
- resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==}
-
- '@types/estree@1.0.8':
- resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
-
- '@types/estree@1.0.9':
- resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==}
-
- '@types/hast@3.0.4':
- resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
-
- '@types/js-yaml@4.0.9':
- resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==}
-
- '@types/mdast@4.0.4':
- resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
-
- '@types/mdx@2.0.13':
- resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==}
-
- '@types/ms@2.1.0':
- resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
-
- '@types/nlcst@2.0.3':
- resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==}
-
- '@types/node@24.12.4':
- resolution: {integrity: sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==}
-
- '@types/sax@1.2.7':
- resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==}
-
- '@types/unist@2.0.11':
- resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
-
- '@types/unist@3.0.3':
- resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
-
- '@ungap/structured-clone@1.3.1':
- resolution: {integrity: sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==}
-
- acorn-jsx@5.3.2:
- resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
- peerDependencies:
- acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
-
- acorn@8.16.0:
- resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==}
- engines: {node: '>=0.4.0'}
- hasBin: true
-
- anymatch@3.1.3:
- resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
- engines: {node: '>= 8'}
-
- arg@5.0.2:
- resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
-
- argparse@2.0.1:
- resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
-
- aria-query@5.3.2:
- resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
- engines: {node: '>= 0.4'}
-
- array-iterate@2.0.1:
- resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==}
-
- astring@1.9.0:
- resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==}
- hasBin: true
-
- astro-expressive-code@0.42.0:
- resolution: {integrity: sha512-aiTePi2Cn0mJPYWZSzP1GcxCinX9mNtJyCCshVVPSg1yRwM7ADvFJOx0FnS440M9t65hp8JH//dc2qr22Bm4ag==}
- peerDependencies:
- astro: ^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta
-
- astro@6.3.6:
- resolution: {integrity: sha512-lM30gGI/iASK9Z1WQVnBBYzxVwDv8slkXbJOF7FNJdZQeBrFETpsQvYoLRupM/adt2ObP5hkYAWEeCjofoqlRw==}
- engines: {node: '>=22.12.0', npm: '>=9.6.5', pnpm: '>=7.1.0'}
- hasBin: true
-
- axobject-query@4.1.0:
- resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
- engines: {node: '>= 0.4'}
-
- bail@2.0.2:
- resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
-
- bcp-47-match@2.0.3:
- resolution: {integrity: sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==}
-
- bcp-47@2.1.0:
- resolution: {integrity: sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==}
-
- boolbase@1.0.0:
- resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
-
- ccount@2.0.1:
- resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
-
- character-entities-html4@2.1.0:
- resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
-
- character-entities-legacy@3.0.0:
- resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==}
-
- character-entities@2.0.2:
- resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==}
-
- character-reference-invalid@2.0.1:
- resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==}
-
- chokidar@5.0.0:
- resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==}
- engines: {node: '>= 20.19.0'}
-
- ci-info@4.4.0:
- resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==}
- engines: {node: '>=8'}
-
- clsx@2.1.1:
- resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
- engines: {node: '>=6'}
-
- collapse-white-space@2.1.0:
- resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==}
-
- comma-separated-tokens@2.0.3:
- resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
-
- commander@11.1.0:
- resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==}
- engines: {node: '>=16'}
-
- common-ancestor-path@2.0.0:
- resolution: {integrity: sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng==}
- engines: {node: '>= 18'}
-
- cookie-es@1.2.3:
- resolution: {integrity: sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw==}
-
- cookie@1.1.1:
- resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==}
- engines: {node: '>=18'}
-
- crossws@0.3.5:
- resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==}
-
- css-select@5.2.2:
- resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==}
-
- css-selector-parser@3.3.0:
- resolution: {integrity: sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g==}
-
- css-tree@2.2.1:
- resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==}
- engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'}
-
- css-tree@3.2.1:
- resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==}
- engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
-
- css-what@6.2.2:
- resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==}
- engines: {node: '>= 6'}
-
- cssesc@3.0.0:
- resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
- engines: {node: '>=4'}
- hasBin: true
-
- csso@5.0.5:
- resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==}
- engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'}
-
- debug@4.4.3:
- resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
- engines: {node: '>=6.0'}
- peerDependencies:
- supports-color: '*'
- peerDependenciesMeta:
- supports-color:
- optional: true
-
- decode-named-character-reference@1.3.0:
- resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==}
-
- defu@6.1.7:
- resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==}
-
- dequal@2.0.3:
- resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
- engines: {node: '>=6'}
-
- destr@2.0.5:
- resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==}
-
- detect-libc@2.1.2:
- resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
- engines: {node: '>=8'}
-
- devalue@5.8.1:
- resolution: {integrity: sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw==}
-
- devlop@1.1.0:
- resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
-
- diff@8.0.4:
- resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==}
- engines: {node: '>=0.3.1'}
-
- direction@2.0.1:
- resolution: {integrity: sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==}
- hasBin: true
-
- dom-serializer@2.0.0:
- resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
-
- domelementtype@2.3.0:
- resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
-
- domhandler@5.0.3:
- resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
- engines: {node: '>= 4'}
-
- domutils@3.2.2:
- resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==}
-
- dset@3.1.4:
- resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==}
- engines: {node: '>=4'}
-
- entities@4.5.0:
- resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
- engines: {node: '>=0.12'}
-
- entities@6.0.1:
- resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==}
- engines: {node: '>=0.12'}
-
- es-module-lexer@2.1.0:
- resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==}
-
- esast-util-from-estree@2.0.0:
- resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==}
-
- esast-util-from-js@2.0.1:
- resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==}
-
- esbuild@0.27.7:
- resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==}
- engines: {node: '>=18'}
- hasBin: true
-
- escape-string-regexp@5.0.0:
- resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
- engines: {node: '>=12'}
-
- estree-util-attach-comments@3.0.0:
- resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==}
-
- estree-util-build-jsx@3.0.1:
- resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==}
-
- estree-util-is-identifier-name@3.0.0:
- resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==}
-
- estree-util-scope@1.0.0:
- resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==}
-
- estree-util-to-js@2.0.0:
- resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==}
-
- estree-util-visit@2.0.0:
- resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==}
-
- estree-walker@2.0.2:
- resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
-
- estree-walker@3.0.3:
- resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
-
- eventemitter3@5.0.4:
- resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==}
-
- expressive-code@0.42.0:
- resolution: {integrity: sha512-V5DtJLEKuj4wf9O6IRtPtRObkMVy2ggR+S0MdjrTw6m58krZnDioyhW1si3Y04c5YPeooP4nd85Yq9NwEVHS4g==}
-
- extend@3.0.2:
- resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
-
- fast-string-truncated-width@3.0.3:
- resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==}
-
- fast-string-width@3.0.2:
- resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==}
-
- fast-wrap-ansi@0.2.2:
- resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==}
-
- fdir@6.5.0:
- resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
- engines: {node: '>=12.0.0'}
- peerDependencies:
- picomatch: ^3 || ^4
- peerDependenciesMeta:
- picomatch:
- optional: true
-
- flattie@1.1.1:
- resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==}
- engines: {node: '>=8'}
-
- fontace@0.4.1:
- resolution: {integrity: sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw==}
-
- fontkitten@1.0.3:
- resolution: {integrity: sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw==}
- engines: {node: '>=20'}
-
- fsevents@2.3.3:
- resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
- engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
- os: [darwin]
-
- get-tsconfig@5.0.0-beta.4:
- resolution: {integrity: sha512-7nF7C9fIPFEMHgEMEfgIlO9wDdZ8CyHw27rWciFZfHvHDReIiPhsYuzPRXsfvBCqFy1l8RRyyWV7QLM+ZhUJsQ==}
- engines: {node: '>=20.20.0'}
-
- github-slugger@2.0.0:
- resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==}
-
- h3@1.15.11:
- resolution: {integrity: sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==}
-
- hast-util-embedded@3.0.0:
- resolution: {integrity: sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==}
-
- hast-util-format@1.1.0:
- resolution: {integrity: sha512-yY1UDz6bC9rDvCWHpx12aIBGRG7krurX0p0Fm6pT547LwDIZZiNr8a+IHDogorAdreULSEzP82Nlv5SZkHZcjA==}
-
- hast-util-from-html@2.0.3:
- resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==}
-
- hast-util-from-parse5@8.0.3:
- resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==}
-
- hast-util-has-property@3.0.0:
- resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==}
-
- hast-util-is-body-ok-link@3.0.1:
- resolution: {integrity: sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==}
-
- hast-util-is-element@3.0.0:
- resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==}
-
- hast-util-minify-whitespace@1.0.1:
- resolution: {integrity: sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==}
-
- hast-util-parse-selector@4.0.0:
- resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==}
-
- hast-util-phrasing@3.0.1:
- resolution: {integrity: sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==}
-
- hast-util-raw@9.1.0:
- resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==}
-
- hast-util-select@6.0.4:
- resolution: {integrity: sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw==}
-
- hast-util-to-estree@3.1.3:
- resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==}
-
- hast-util-to-html@9.0.5:
- resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==}
-
- hast-util-to-jsx-runtime@2.3.6:
- resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==}
-
- hast-util-to-parse5@8.0.1:
- resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==}
-
- hast-util-to-string@3.0.1:
- resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==}
-
- hast-util-to-text@4.0.2:
- resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==}
-
- hast-util-whitespace@3.0.0:
- resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
-
- hastscript@9.0.1:
- resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==}
-
- html-escaper@3.0.3:
- resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==}
-
- html-void-elements@3.0.0:
- resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
-
- html-whitespace-sensitive-tag-names@3.0.1:
- resolution: {integrity: sha512-q+310vW8zmymYHALr1da4HyXUQ0zgiIwIicEfotYPWGN0OJVEN/58IJ3A4GBYcEq3LGAZqKb+ugvP0GNB9CEAA==}
-
- http-cache-semantics@4.2.0:
- resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==}
-
- i18next@26.2.0:
- resolution: {integrity: sha512-zwBHldHdTmwN7r6UNc7lC6GWNN+YYg3DrRSeHR5PRRBf5QnJZcYHrQc0uaU26qZeYxR7iFZD+Y315dPnKP47wA==}
- peerDependencies:
- typescript: ^5 || ^6
- peerDependenciesMeta:
- typescript:
- optional: true
-
- inline-style-parser@0.2.7:
- resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==}
-
- iron-webcrypto@1.2.1:
- resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==}
-
- is-alphabetical@2.0.1:
- resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==}
-
- is-alphanumerical@2.0.1:
- resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==}
-
- is-decimal@2.0.1:
- resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==}
-
- is-docker@3.0.0:
- resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==}
- engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
- hasBin: true
-
- is-docker@4.0.0:
- resolution: {integrity: sha512-LHE+wROyG/Y/0ZnbktRCoTix2c1RhgWaZraMZ8o1Q7zCh0VSrICJQO5oqIIISrcSBtrXv0o233w1IYwsWCjTzA==}
- engines: {node: '>=20'}
- hasBin: true
-
- is-hexadecimal@2.0.1:
- resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==}
-
- is-inside-container@1.0.0:
- resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==}
- engines: {node: '>=14.16'}
- hasBin: true
-
- is-plain-obj@4.1.0:
- resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
- engines: {node: '>=12'}
-
- is-wsl@3.1.1:
- resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==}
- engines: {node: '>=16'}
-
- js-yaml@4.1.1:
- resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
- hasBin: true
-
- jsonc-parser@3.3.1:
- resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==}
-
- klona@2.0.6:
- resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==}
- engines: {node: '>= 8'}
-
- longest-streak@3.1.0:
- resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
-
- lru-cache@11.5.0:
- resolution: {integrity: sha512-5YgH9UJd7wVb9hIouI2adWpgqrrICkt070Dnj8EUY1+B4B2P9eRLPAkAAo6NICA7CEhOIeBHl46u9zSNpNu7zA==}
- engines: {node: 20 || >=22}
-
- magic-string@0.30.21:
- resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
-
- magicast@0.5.3:
- resolution: {integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==}
-
- markdown-extensions@2.0.0:
- resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==}
- engines: {node: '>=16'}
-
- markdown-table@3.0.4:
- resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
-
- mdast-util-definitions@6.0.0:
- resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==}
-
- mdast-util-directive@3.1.0:
- resolution: {integrity: sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==}
-
- mdast-util-find-and-replace@3.0.2:
- resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==}
-
- mdast-util-from-markdown@2.0.3:
- resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==}
-
- mdast-util-gfm-autolink-literal@2.0.1:
- resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==}
-
- mdast-util-gfm-footnote@2.1.0:
- resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==}
-
- mdast-util-gfm-strikethrough@2.0.0:
- resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==}
-
- mdast-util-gfm-table@2.0.0:
- resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==}
-
- mdast-util-gfm-task-list-item@2.0.0:
- resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==}
-
- mdast-util-gfm@3.1.0:
- resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==}
-
- mdast-util-mdx-expression@2.0.1:
- resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==}
-
- mdast-util-mdx-jsx@3.2.0:
- resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==}
-
- mdast-util-mdx@3.0.0:
- resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==}
-
- mdast-util-mdxjs-esm@2.0.1:
- resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==}
-
- mdast-util-phrasing@4.1.0:
- resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==}
-
- mdast-util-to-hast@13.2.1:
- resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==}
-
- mdast-util-to-markdown@2.1.2:
- resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==}
-
- mdast-util-to-string@4.0.0:
- resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==}
-
- mdn-data@2.0.28:
- resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==}
-
- mdn-data@2.27.1:
- resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==}
-
- micromark-core-commonmark@2.0.3:
- resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==}
-
- micromark-extension-directive@4.0.0:
- resolution: {integrity: sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==}
-
- micromark-extension-gfm-autolink-literal@2.1.0:
- resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==}
-
- micromark-extension-gfm-footnote@2.1.0:
- resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==}
-
- micromark-extension-gfm-strikethrough@2.1.0:
- resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==}
-
- micromark-extension-gfm-table@2.1.1:
- resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==}
-
- micromark-extension-gfm-tagfilter@2.0.0:
- resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==}
-
- micromark-extension-gfm-task-list-item@2.1.0:
- resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==}
-
- micromark-extension-gfm@3.0.0:
- resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==}
-
- micromark-extension-mdx-expression@3.0.1:
- resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==}
-
- micromark-extension-mdx-jsx@3.0.2:
- resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==}
-
- micromark-extension-mdx-md@2.0.0:
- resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==}
-
- micromark-extension-mdxjs-esm@3.0.0:
- resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==}
-
- micromark-extension-mdxjs@3.0.0:
- resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==}
-
- micromark-factory-destination@2.0.1:
- resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==}
-
- micromark-factory-label@2.0.1:
- resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==}
-
- micromark-factory-mdx-expression@2.0.3:
- resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==}
-
- micromark-factory-space@2.0.1:
- resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==}
-
- micromark-factory-title@2.0.1:
- resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==}
-
- micromark-factory-whitespace@2.0.1:
- resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==}
-
- micromark-util-character@2.1.1:
- resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==}
-
- micromark-util-chunked@2.0.1:
- resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==}
-
- micromark-util-classify-character@2.0.1:
- resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==}
-
- micromark-util-combine-extensions@2.0.1:
- resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==}
-
- micromark-util-decode-numeric-character-reference@2.0.2:
- resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==}
-
- micromark-util-decode-string@2.0.1:
- resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==}
-
- micromark-util-encode@2.0.1:
- resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==}
-
- micromark-util-events-to-acorn@2.0.3:
- resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==}
-
- micromark-util-html-tag-name@2.0.1:
- resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==}
-
- micromark-util-normalize-identifier@2.0.1:
- resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==}
-
- micromark-util-resolve-all@2.0.1:
- resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==}
-
- micromark-util-sanitize-uri@2.0.1:
- resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==}
-
- micromark-util-subtokenize@2.1.0:
- resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==}
-
- micromark-util-symbol@2.0.1:
- resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==}
-
- micromark-util-types@2.0.2:
- resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==}
-
- micromark@4.0.2:
- resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==}
-
- mrmime@2.0.1:
- resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==}
- engines: {node: '>=10'}
-
- ms@2.1.3:
- resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
-
- nanoid@3.3.12:
- resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==}
- engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
- hasBin: true
-
- neotraverse@0.6.18:
- resolution: {integrity: sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==}
- engines: {node: '>= 10'}
-
- nlcst-to-string@4.0.0:
- resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==}
-
- node-fetch-native@1.6.7:
- resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==}
-
- node-mock-http@1.0.4:
- resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==}
-
- normalize-path@3.0.0:
- resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
- engines: {node: '>=0.10.0'}
-
- nth-check@2.1.1:
- resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
-
- obug@2.1.1:
- resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==}
-
- ofetch@1.5.1:
- resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==}
-
- ohash@2.0.11:
- resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==}
-
- oniguruma-parser@0.12.2:
- resolution: {integrity: sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==}
-
- oniguruma-to-es@4.3.6:
- resolution: {integrity: sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==}
-
- p-limit@7.3.0:
- resolution: {integrity: sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==}
- engines: {node: '>=20'}
-
- p-queue@9.3.0:
- resolution: {integrity: sha512-7NED7xhQ74Ngp4JP/2e0VZHp7vSWfJfqeiR92jPgxsz6m0Se4P03YoTKa9dDXyZ3r6P616gUXttrB6nnHYKang==}
- engines: {node: '>=20'}
-
- p-timeout@7.0.1:
- resolution: {integrity: sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==}
- engines: {node: '>=20'}
-
- package-manager-detector@1.6.0:
- resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==}
-
- pagefind@1.5.2:
- resolution: {integrity: sha512-XTUaK0hXMCu2jszWE584JGQT7y284TmMV9l/HX3rnG5uo3rHI/uHU56XTyyyPFjeWEBxECbAi0CaFDJOONtG0Q==}
- hasBin: true
-
- parse-entities@4.0.2:
- resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==}
-
- parse-latin@7.0.0:
- resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==}
-
- parse5@7.3.0:
- resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==}
-
- piccolore@0.1.3:
- resolution: {integrity: sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==}
-
- picocolors@1.1.1:
- resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
-
- picomatch@2.3.2:
- resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==}
- engines: {node: '>=8.6'}
-
- picomatch@4.0.4:
- resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==}
- engines: {node: '>=12'}
-
- postcss-nested@6.2.0:
- resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==}
- engines: {node: '>=12.0'}
- peerDependencies:
- postcss: ^8.2.14
-
- postcss-selector-parser@6.1.2:
- resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
- engines: {node: '>=4'}
-
- postcss@8.5.15:
- resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==}
- engines: {node: ^10 || ^12 || >=14}
-
- prismjs@1.30.0:
- resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==}
- engines: {node: '>=6'}
-
- property-information@7.1.0:
- resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==}
-
- radix3@1.1.2:
- resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==}
-
- readdirp@5.0.0:
- resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==}
- engines: {node: '>= 20.19.0'}
-
- recma-build-jsx@1.0.0:
- resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==}
-
- recma-jsx@1.0.1:
- resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==}
- peerDependencies:
- acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
-
- recma-parse@1.0.0:
- resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==}
-
- recma-stringify@1.0.0:
- resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==}
-
- regex-recursion@6.0.2:
- resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==}
-
- regex-utilities@2.3.0:
- resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==}
-
- regex@6.1.0:
- resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==}
-
- rehype-expressive-code@0.42.0:
- resolution: {integrity: sha512-8rp/1YMEVVSYbtz+bFBx+uSx3vA4i4T8RwRm5Q/IWbucQnnQqQ0hDqtmKOr8tv+59Cik6cu5aH3WPo0I7csuTA==}
-
- rehype-format@5.0.1:
- resolution: {integrity: sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ==}
-
- rehype-parse@9.0.1:
- resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==}
-
- rehype-raw@7.0.0:
- resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==}
-
- rehype-recma@1.0.0:
- resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==}
-
- rehype-stringify@10.0.1:
- resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==}
-
- rehype@13.0.2:
- resolution: {integrity: sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==}
-
- remark-directive@4.0.0:
- resolution: {integrity: sha512-7sxn4RfF1o3izevPV1DheyGDD6X4c9hrGpfdUpm7uC++dqrnJxIZVkk7CoKqcLm0VUMAuOol7Mno3m6g8cfMuA==}
-
- remark-gfm@4.0.1:
- resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==}
-
- remark-mdx@3.1.1:
- resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==}
-
- remark-parse@11.0.0:
- resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==}
-
- remark-rehype@11.1.2:
- resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==}
-
- remark-smartypants@3.0.2:
- resolution: {integrity: sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==}
- engines: {node: '>=16.0.0'}
-
- remark-stringify@11.0.0:
- resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
-
- resolve-pkg-maps@1.0.0:
- resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
-
- retext-latin@4.0.0:
- resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==}
-
- retext-smartypants@6.2.0:
- resolution: {integrity: sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==}
-
- retext-stringify@4.0.0:
- resolution: {integrity: sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==}
-
- retext@9.0.0:
- resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==}
-
- rollup@4.60.4:
- resolution: {integrity: sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==}
- engines: {node: '>=18.0.0', npm: '>=8.0.0'}
- hasBin: true
-
- sax@1.6.0:
- resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==}
- engines: {node: '>=11.0.0'}
-
- semver@7.8.0:
- resolution: {integrity: sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==}
- engines: {node: '>=10'}
- hasBin: true
-
- sharp@0.34.5:
- resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==}
- engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
-
- shiki@4.1.0:
- resolution: {integrity: sha512-l/ABZPUR5v70jI10EzqfMS/I96vjSGv2y0ihUV+WYFzv0EfvW4s54m0Lg8wCrrL+2IkwBzFTuxkZjPf8b2NX9Q==}
- engines: {node: '>=20'}
-
- sisteransi@1.0.5:
- resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
-
- sitemap@9.0.1:
- resolution: {integrity: sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ==}
- engines: {node: '>=20.19.5', npm: '>=10.8.2'}
- hasBin: true
-
- smol-toml@1.6.1:
- resolution: {integrity: sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==}
- engines: {node: '>= 18'}
-
- source-map-js@1.2.1:
- resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
- engines: {node: '>=0.10.0'}
-
- source-map@0.7.6:
- resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==}
- engines: {node: '>= 12'}
-
- space-separated-tokens@2.0.2:
- resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
-
- stream-replace-string@2.0.0:
- resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==}
-
- stringify-entities@4.0.4:
- resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==}
-
- style-to-js@1.1.21:
- resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==}
-
- style-to-object@1.0.14:
- resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==}
-
- svgo@4.0.1:
- resolution: {integrity: sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==}
- engines: {node: '>=16'}
- hasBin: true
-
- tiny-inflate@1.0.3:
- resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==}
-
- tinyclip@0.1.12:
- resolution: {integrity: sha512-Ae3OVUqifDw0wBriIBS7yVaW44Dp6eSHQcyq4Igc7eN2TJH/2YsicswaW+J/OuMvhpDPOKEgpAZCjkb4hpoyeA==}
- engines: {node: ^16.14.0 || >= 17.3.0}
-
- tinyexec@1.1.2:
- resolution: {integrity: sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==}
- engines: {node: '>=18'}
-
- tinyglobby@0.2.16:
- resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==}
- engines: {node: '>=12.0.0'}
-
- trim-lines@3.0.1:
- resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
-
- trough@2.2.0:
- resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==}
-
- tslib@2.8.1:
- resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
-
- typescript@5.9.3:
- resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
- engines: {node: '>=14.17'}
- hasBin: true
-
- ufo@1.6.4:
- resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==}
-
- ultrahtml@1.6.0:
- resolution: {integrity: sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==}
-
- uncrypto@0.1.3:
- resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==}
-
- undici-types@7.16.0:
- resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
-
- unified@11.0.5:
- resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==}
-
- unifont@0.7.4:
- resolution: {integrity: sha512-oHeis4/xl42HUIeHuNZRGEvxj5AaIKR+bHPNegRq5LV1gdc3jundpONbjglKpihmJf+dswygdMJn3eftGIMemg==}
-
- unist-util-find-after@5.0.0:
- resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==}
-
- unist-util-is@6.0.1:
- resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==}
-
- unist-util-modify-children@4.0.0:
- resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==}
-
- unist-util-position-from-estree@2.0.0:
- resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==}
-
- unist-util-position@5.0.0:
- resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==}
-
- unist-util-remove-position@5.0.0:
- resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==}
-
- unist-util-stringify-position@4.0.0:
- resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==}
-
- unist-util-visit-children@3.0.0:
- resolution: {integrity: sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==}
-
- unist-util-visit-parents@6.0.2:
- resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==}
-
- unist-util-visit@5.1.0:
- resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==}
-
- unstorage@1.17.5:
- resolution: {integrity: sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg==}
- peerDependencies:
- '@azure/app-configuration': ^1.8.0
- '@azure/cosmos': ^4.2.0
- '@azure/data-tables': ^13.3.0
- '@azure/identity': ^4.6.0
- '@azure/keyvault-secrets': ^4.9.0
- '@azure/storage-blob': ^12.26.0
- '@capacitor/preferences': ^6 || ^7 || ^8
- '@deno/kv': '>=0.9.0'
- '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0
- '@planetscale/database': ^1.19.0
- '@upstash/redis': ^1.34.3
- '@vercel/blob': '>=0.27.1'
- '@vercel/functions': ^2.2.12 || ^3.0.0
- '@vercel/kv': ^1 || ^2 || ^3
- aws4fetch: ^1.0.20
- db0: '>=0.2.1'
- idb-keyval: ^6.2.1
- ioredis: ^5.4.2
- uploadthing: ^7.4.4
- peerDependenciesMeta:
- '@azure/app-configuration':
- optional: true
- '@azure/cosmos':
- optional: true
- '@azure/data-tables':
- optional: true
- '@azure/identity':
- optional: true
- '@azure/keyvault-secrets':
- optional: true
- '@azure/storage-blob':
- optional: true
- '@capacitor/preferences':
- optional: true
- '@deno/kv':
- optional: true
- '@netlify/blobs':
- optional: true
- '@planetscale/database':
- optional: true
- '@upstash/redis':
- optional: true
- '@vercel/blob':
- optional: true
- '@vercel/functions':
- optional: true
- '@vercel/kv':
- optional: true
- aws4fetch:
- optional: true
- db0:
- optional: true
- idb-keyval:
- optional: true
- ioredis:
- optional: true
- uploadthing:
- optional: true
-
- util-deprecate@1.0.2:
- resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
-
- vfile-location@5.0.3:
- resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==}
-
- vfile-message@4.0.3:
- resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==}
-
- vfile@6.0.3:
- resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
-
- vite@7.3.3:
- resolution: {integrity: sha512-/4XH147Ui7OGTjg3HbdWe5arnZQSbfuRzdr9Ec7TQi5I7R+ir0Rlc9GIvD4v0XZurELqA035KVXJXpR61xhiTA==}
- engines: {node: ^20.19.0 || >=22.12.0}
- hasBin: true
- peerDependencies:
- '@types/node': ^20.19.0 || >=22.12.0
- jiti: '>=1.21.0'
- less: ^4.0.0
- lightningcss: ^1.21.0
- sass: ^1.70.0
- sass-embedded: ^1.70.0
- stylus: '>=0.54.8'
- sugarss: ^5.0.0
- terser: ^5.16.0
- tsx: ^4.8.1
- yaml: ^2.4.2
- peerDependenciesMeta:
- '@types/node':
- optional: true
- jiti:
- optional: true
- less:
- optional: true
- lightningcss:
- optional: true
- sass:
- optional: true
- sass-embedded:
- optional: true
- stylus:
- optional: true
- sugarss:
- optional: true
- terser:
- optional: true
- tsx:
- optional: true
- yaml:
- optional: true
-
- vitefu@1.1.3:
- resolution: {integrity: sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==}
- peerDependencies:
- vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0
- peerDependenciesMeta:
- vite:
- optional: true
-
- web-namespaces@2.0.1:
- resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
-
- which-pm-runs@1.1.0:
- resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==}
- engines: {node: '>=4'}
-
- xxhash-wasm@1.1.0:
- resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==}
-
- yargs-parser@22.0.0:
- resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==}
- engines: {node: ^20.19.0 || ^22.12.0 || >=23}
-
- yocto-queue@1.2.2:
- resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==}
- engines: {node: '>=12.20'}
-
- zod@4.4.3:
- resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==}
-
- zwitch@2.0.4:
- resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
-
-snapshots:
-
- '@astrojs/compiler@4.0.0': {}
-
- '@astrojs/internal-helpers@0.9.1':
- dependencies:
- picomatch: 4.0.4
-
- '@astrojs/markdown-remark@7.1.2':
- dependencies:
- '@astrojs/internal-helpers': 0.9.1
- '@astrojs/prism': 4.0.2
- github-slugger: 2.0.0
- hast-util-from-html: 2.0.3
- hast-util-to-text: 4.0.2
- js-yaml: 4.1.1
- mdast-util-definitions: 6.0.0
- rehype-raw: 7.0.0
- rehype-stringify: 10.0.1
- remark-gfm: 4.0.1
- remark-parse: 11.0.0
- remark-rehype: 11.1.2
- remark-smartypants: 3.0.2
- retext-smartypants: 6.2.0
- shiki: 4.1.0
- smol-toml: 1.6.1
- unified: 11.0.5
- unist-util-remove-position: 5.0.0
- unist-util-visit: 5.1.0
- unist-util-visit-parents: 6.0.2
- vfile: 6.0.3
- transitivePeerDependencies:
- - supports-color
-
- '@astrojs/mdx@5.0.6(astro@6.3.6(@types/node@24.12.4)(rollup@4.60.4))':
- dependencies:
- '@astrojs/markdown-remark': 7.1.2
- '@mdx-js/mdx': 3.1.1
- acorn: 8.16.0
- astro: 6.3.6(@types/node@24.12.4)(rollup@4.60.4)
- es-module-lexer: 2.1.0
- estree-util-visit: 2.0.0
- hast-util-to-html: 9.0.5
- piccolore: 0.1.3
- rehype-raw: 7.0.0
- remark-gfm: 4.0.1
- remark-smartypants: 3.0.2
- source-map: 0.7.6
- unist-util-visit: 5.1.0
- vfile: 6.0.3
- transitivePeerDependencies:
- - supports-color
-
- '@astrojs/prism@4.0.2':
- dependencies:
- prismjs: 1.30.0
-
- '@astrojs/sitemap@3.7.2':
- dependencies:
- sitemap: 9.0.1
- stream-replace-string: 2.0.0
- zod: 4.4.3
-
- '@astrojs/starlight@0.39.2(astro@6.3.6(@types/node@24.12.4)(rollup@4.60.4))(typescript@5.9.3)':
- dependencies:
- '@astrojs/markdown-remark': 7.1.2
- '@astrojs/mdx': 5.0.6(astro@6.3.6(@types/node@24.12.4)(rollup@4.60.4))
- '@astrojs/sitemap': 3.7.2
- '@pagefind/default-ui': 1.5.2
- '@types/hast': 3.0.4
- '@types/js-yaml': 4.0.9
- '@types/mdast': 4.0.4
- astro: 6.3.6(@types/node@24.12.4)(rollup@4.60.4)
- astro-expressive-code: 0.42.0(astro@6.3.6(@types/node@24.12.4)(rollup@4.60.4))
- bcp-47: 2.1.0
- hast-util-from-html: 2.0.3
- hast-util-select: 6.0.4
- hast-util-to-string: 3.0.1
- hastscript: 9.0.1
- i18next: 26.2.0(typescript@5.9.3)
- js-yaml: 4.1.1
- klona: 2.0.6
- magic-string: 0.30.21
- mdast-util-directive: 3.1.0
- mdast-util-to-markdown: 2.1.2
- mdast-util-to-string: 4.0.0
- pagefind: 1.5.2
- rehype: 13.0.2
- rehype-format: 5.0.1
- remark-directive: 4.0.0
- ultrahtml: 1.6.0
- unified: 11.0.5
- unist-util-visit: 5.1.0
- vfile: 6.0.3
- transitivePeerDependencies:
- - supports-color
- - typescript
-
- '@astrojs/telemetry@3.3.2':
- dependencies:
- ci-info: 4.4.0
- dset: 3.1.4
- is-docker: 4.0.0
- is-wsl: 3.1.1
- which-pm-runs: 1.1.0
-
- '@babel/helper-string-parser@7.27.1': {}
-
- '@babel/helper-validator-identifier@7.28.5': {}
-
- '@babel/parser@7.29.3':
- dependencies:
- '@babel/types': 7.29.0
-
- '@babel/types@7.29.0':
- dependencies:
- '@babel/helper-string-parser': 7.27.1
- '@babel/helper-validator-identifier': 7.28.5
-
- '@capsizecss/unpack@4.0.0':
- dependencies:
- fontkitten: 1.0.3
-
- '@clack/core@1.3.1':
- dependencies:
- fast-wrap-ansi: 0.2.2
- sisteransi: 1.0.5
-
- '@clack/prompts@1.4.0':
- dependencies:
- '@clack/core': 1.3.1
- fast-string-width: 3.0.2
- fast-wrap-ansi: 0.2.2
- sisteransi: 1.0.5
-
- '@ctrl/tinycolor@4.2.0': {}
-
- '@emnapi/runtime@1.10.0':
- dependencies:
- tslib: 2.8.1
- optional: true
-
- '@esbuild/aix-ppc64@0.27.7':
- optional: true
-
- '@esbuild/android-arm64@0.27.7':
- optional: true
-
- '@esbuild/android-arm@0.27.7':
- optional: true
-
- '@esbuild/android-x64@0.27.7':
- optional: true
-
- '@esbuild/darwin-arm64@0.27.7':
- optional: true
-
- '@esbuild/darwin-x64@0.27.7':
- optional: true
-
- '@esbuild/freebsd-arm64@0.27.7':
- optional: true
-
- '@esbuild/freebsd-x64@0.27.7':
- optional: true
-
- '@esbuild/linux-arm64@0.27.7':
- optional: true
-
- '@esbuild/linux-arm@0.27.7':
- optional: true
-
- '@esbuild/linux-ia32@0.27.7':
- optional: true
-
- '@esbuild/linux-loong64@0.27.7':
- optional: true
-
- '@esbuild/linux-mips64el@0.27.7':
- optional: true
-
- '@esbuild/linux-ppc64@0.27.7':
- optional: true
-
- '@esbuild/linux-riscv64@0.27.7':
- optional: true
-
- '@esbuild/linux-s390x@0.27.7':
- optional: true
-
- '@esbuild/linux-x64@0.27.7':
- optional: true
-
- '@esbuild/netbsd-arm64@0.27.7':
- optional: true
-
- '@esbuild/netbsd-x64@0.27.7':
- optional: true
-
- '@esbuild/openbsd-arm64@0.27.7':
- optional: true
-
- '@esbuild/openbsd-x64@0.27.7':
- optional: true
-
- '@esbuild/openharmony-arm64@0.27.7':
- optional: true
-
- '@esbuild/sunos-x64@0.27.7':
- optional: true
-
- '@esbuild/win32-arm64@0.27.7':
- optional: true
-
- '@esbuild/win32-ia32@0.27.7':
- optional: true
-
- '@esbuild/win32-x64@0.27.7':
- optional: true
-
- '@expressive-code/core@0.42.0':
- dependencies:
- '@ctrl/tinycolor': 4.2.0
- hast-util-select: 6.0.4
- hast-util-to-html: 9.0.5
- hast-util-to-text: 4.0.2
- hastscript: 9.0.1
- postcss: 8.5.15
- postcss-nested: 6.2.0(postcss@8.5.15)
- unist-util-visit: 5.1.0
- unist-util-visit-parents: 6.0.2
-
- '@expressive-code/plugin-frames@0.42.0':
- dependencies:
- '@expressive-code/core': 0.42.0
-
- '@expressive-code/plugin-shiki@0.42.0':
- dependencies:
- '@expressive-code/core': 0.42.0
- shiki: 4.1.0
-
- '@expressive-code/plugin-text-markers@0.42.0':
- dependencies:
- '@expressive-code/core': 0.42.0
-
- '@img/colour@1.1.0': {}
-
- '@img/sharp-darwin-arm64@0.34.5':
- optionalDependencies:
- '@img/sharp-libvips-darwin-arm64': 1.2.4
- optional: true
-
- '@img/sharp-darwin-x64@0.34.5':
- optionalDependencies:
- '@img/sharp-libvips-darwin-x64': 1.2.4
- optional: true
-
- '@img/sharp-libvips-darwin-arm64@1.2.4':
- optional: true
-
- '@img/sharp-libvips-darwin-x64@1.2.4':
- optional: true
-
- '@img/sharp-libvips-linux-arm64@1.2.4':
- optional: true
-
- '@img/sharp-libvips-linux-arm@1.2.4':
- optional: true
-
- '@img/sharp-libvips-linux-ppc64@1.2.4':
- optional: true
-
- '@img/sharp-libvips-linux-riscv64@1.2.4':
- optional: true
-
- '@img/sharp-libvips-linux-s390x@1.2.4':
- optional: true
-
- '@img/sharp-libvips-linux-x64@1.2.4':
- optional: true
-
- '@img/sharp-libvips-linuxmusl-arm64@1.2.4':
- optional: true
-
- '@img/sharp-libvips-linuxmusl-x64@1.2.4':
- optional: true
-
- '@img/sharp-linux-arm64@0.34.5':
- optionalDependencies:
- '@img/sharp-libvips-linux-arm64': 1.2.4
- optional: true
-
- '@img/sharp-linux-arm@0.34.5':
- optionalDependencies:
- '@img/sharp-libvips-linux-arm': 1.2.4
- optional: true
-
- '@img/sharp-linux-ppc64@0.34.5':
- optionalDependencies:
- '@img/sharp-libvips-linux-ppc64': 1.2.4
- optional: true
-
- '@img/sharp-linux-riscv64@0.34.5':
- optionalDependencies:
- '@img/sharp-libvips-linux-riscv64': 1.2.4
- optional: true
-
- '@img/sharp-linux-s390x@0.34.5':
- optionalDependencies:
- '@img/sharp-libvips-linux-s390x': 1.2.4
- optional: true
-
- '@img/sharp-linux-x64@0.34.5':
- optionalDependencies:
- '@img/sharp-libvips-linux-x64': 1.2.4
- optional: true
-
- '@img/sharp-linuxmusl-arm64@0.34.5':
- optionalDependencies:
- '@img/sharp-libvips-linuxmusl-arm64': 1.2.4
- optional: true
-
- '@img/sharp-linuxmusl-x64@0.34.5':
- optionalDependencies:
- '@img/sharp-libvips-linuxmusl-x64': 1.2.4
- optional: true
-
- '@img/sharp-wasm32@0.34.5':
- dependencies:
- '@emnapi/runtime': 1.10.0
- optional: true
-
- '@img/sharp-win32-arm64@0.34.5':
- optional: true
-
- '@img/sharp-win32-ia32@0.34.5':
- optional: true
-
- '@img/sharp-win32-x64@0.34.5':
- optional: true
-
- '@jridgewell/sourcemap-codec@1.5.5': {}
-
- '@mdx-js/mdx@3.1.1':
- dependencies:
- '@types/estree': 1.0.9
- '@types/estree-jsx': 1.0.5
- '@types/hast': 3.0.4
- '@types/mdx': 2.0.13
- acorn: 8.16.0
- collapse-white-space: 2.1.0
- devlop: 1.1.0
- estree-util-is-identifier-name: 3.0.0
- estree-util-scope: 1.0.0
- estree-walker: 3.0.3
- hast-util-to-jsx-runtime: 2.3.6
- markdown-extensions: 2.0.0
- recma-build-jsx: 1.0.0
- recma-jsx: 1.0.1(acorn@8.16.0)
- recma-stringify: 1.0.0
- rehype-recma: 1.0.0
- remark-mdx: 3.1.1
- remark-parse: 11.0.0
- remark-rehype: 11.1.2
- source-map: 0.7.6
- unified: 11.0.5
- unist-util-position-from-estree: 2.0.0
- unist-util-stringify-position: 4.0.0
- unist-util-visit: 5.1.0
- vfile: 6.0.3
- transitivePeerDependencies:
- - supports-color
-
- '@oslojs/encoding@1.1.0': {}
-
- '@pagefind/darwin-arm64@1.5.2':
- optional: true
-
- '@pagefind/darwin-x64@1.5.2':
- optional: true
-
- '@pagefind/default-ui@1.5.2': {}
-
- '@pagefind/freebsd-x64@1.5.2':
- optional: true
-
- '@pagefind/linux-arm64@1.5.2':
- optional: true
-
- '@pagefind/linux-x64@1.5.2':
- optional: true
-
- '@pagefind/windows-arm64@1.5.2':
- optional: true
-
- '@pagefind/windows-x64@1.5.2':
- optional: true
-
- '@rollup/pluginutils@5.3.0(rollup@4.60.4)':
- dependencies:
- '@types/estree': 1.0.9
- estree-walker: 2.0.2
- picomatch: 4.0.4
- optionalDependencies:
- rollup: 4.60.4
-
- '@rollup/rollup-android-arm-eabi@4.60.4':
- optional: true
-
- '@rollup/rollup-android-arm64@4.60.4':
- optional: true
-
- '@rollup/rollup-darwin-arm64@4.60.4':
- optional: true
-
- '@rollup/rollup-darwin-x64@4.60.4':
- optional: true
-
- '@rollup/rollup-freebsd-arm64@4.60.4':
- optional: true
-
- '@rollup/rollup-freebsd-x64@4.60.4':
- optional: true
-
- '@rollup/rollup-linux-arm-gnueabihf@4.60.4':
- optional: true
-
- '@rollup/rollup-linux-arm-musleabihf@4.60.4':
- optional: true
-
- '@rollup/rollup-linux-arm64-gnu@4.60.4':
- optional: true
-
- '@rollup/rollup-linux-arm64-musl@4.60.4':
- optional: true
-
- '@rollup/rollup-linux-loong64-gnu@4.60.4':
- optional: true
-
- '@rollup/rollup-linux-loong64-musl@4.60.4':
- optional: true
-
- '@rollup/rollup-linux-ppc64-gnu@4.60.4':
- optional: true
-
- '@rollup/rollup-linux-ppc64-musl@4.60.4':
- optional: true
-
- '@rollup/rollup-linux-riscv64-gnu@4.60.4':
- optional: true
-
- '@rollup/rollup-linux-riscv64-musl@4.60.4':
- optional: true
-
- '@rollup/rollup-linux-s390x-gnu@4.60.4':
- optional: true
-
- '@rollup/rollup-linux-x64-gnu@4.60.4':
- optional: true
-
- '@rollup/rollup-linux-x64-musl@4.60.4':
- optional: true
-
- '@rollup/rollup-openbsd-x64@4.60.4':
- optional: true
-
- '@rollup/rollup-openharmony-arm64@4.60.4':
- optional: true
-
- '@rollup/rollup-win32-arm64-msvc@4.60.4':
- optional: true
-
- '@rollup/rollup-win32-ia32-msvc@4.60.4':
- optional: true
-
- '@rollup/rollup-win32-x64-gnu@4.60.4':
- optional: true
-
- '@rollup/rollup-win32-x64-msvc@4.60.4':
- optional: true
-
- '@shikijs/core@4.1.0':
- dependencies:
- '@shikijs/primitive': 4.1.0
- '@shikijs/types': 4.1.0
- '@shikijs/vscode-textmate': 10.0.2
- '@types/hast': 3.0.4
- hast-util-to-html: 9.0.5
-
- '@shikijs/engine-javascript@4.1.0':
- dependencies:
- '@shikijs/types': 4.1.0
- '@shikijs/vscode-textmate': 10.0.2
- oniguruma-to-es: 4.3.6
-
- '@shikijs/engine-oniguruma@4.1.0':
- dependencies:
- '@shikijs/types': 4.1.0
- '@shikijs/vscode-textmate': 10.0.2
-
- '@shikijs/langs@4.1.0':
- dependencies:
- '@shikijs/types': 4.1.0
-
- '@shikijs/primitive@4.1.0':
- dependencies:
- '@shikijs/types': 4.1.0
- '@shikijs/vscode-textmate': 10.0.2
- '@types/hast': 3.0.4
-
- '@shikijs/themes@4.1.0':
- dependencies:
- '@shikijs/types': 4.1.0
-
- '@shikijs/types@4.1.0':
- dependencies:
- '@shikijs/vscode-textmate': 10.0.2
- '@types/hast': 3.0.4
-
- '@shikijs/vscode-textmate@10.0.2': {}
-
- '@types/debug@4.1.13':
- dependencies:
- '@types/ms': 2.1.0
-
- '@types/estree-jsx@1.0.5':
- dependencies:
- '@types/estree': 1.0.9
-
- '@types/estree@1.0.8': {}
-
- '@types/estree@1.0.9': {}
-
- '@types/hast@3.0.4':
- dependencies:
- '@types/unist': 3.0.3
-
- '@types/js-yaml@4.0.9': {}
-
- '@types/mdast@4.0.4':
- dependencies:
- '@types/unist': 3.0.3
-
- '@types/mdx@2.0.13': {}
-
- '@types/ms@2.1.0': {}
-
- '@types/nlcst@2.0.3':
- dependencies:
- '@types/unist': 3.0.3
-
- '@types/node@24.12.4':
- dependencies:
- undici-types: 7.16.0
-
- '@types/sax@1.2.7':
- dependencies:
- '@types/node': 24.12.4
-
- '@types/unist@2.0.11': {}
-
- '@types/unist@3.0.3': {}
-
- '@ungap/structured-clone@1.3.1': {}
-
- acorn-jsx@5.3.2(acorn@8.16.0):
- dependencies:
- acorn: 8.16.0
-
- acorn@8.16.0: {}
-
- anymatch@3.1.3:
- dependencies:
- normalize-path: 3.0.0
- picomatch: 2.3.2
-
- arg@5.0.2: {}
-
- argparse@2.0.1: {}
-
- aria-query@5.3.2: {}
-
- array-iterate@2.0.1: {}
-
- astring@1.9.0: {}
-
- astro-expressive-code@0.42.0(astro@6.3.6(@types/node@24.12.4)(rollup@4.60.4)):
- dependencies:
- astro: 6.3.6(@types/node@24.12.4)(rollup@4.60.4)
- rehype-expressive-code: 0.42.0
-
- astro@6.3.6(@types/node@24.12.4)(rollup@4.60.4):
- dependencies:
- '@astrojs/compiler': 4.0.0
- '@astrojs/internal-helpers': 0.9.1
- '@astrojs/markdown-remark': 7.1.2
- '@astrojs/telemetry': 3.3.2
- '@capsizecss/unpack': 4.0.0
- '@clack/prompts': 1.4.0
- '@oslojs/encoding': 1.1.0
- '@rollup/pluginutils': 5.3.0(rollup@4.60.4)
- aria-query: 5.3.2
- axobject-query: 4.1.0
- ci-info: 4.4.0
- clsx: 2.1.1
- common-ancestor-path: 2.0.0
- cookie: 1.1.1
- devalue: 5.8.1
- diff: 8.0.4
- dset: 3.1.4
- es-module-lexer: 2.1.0
- esbuild: 0.27.7
- flattie: 1.1.1
- fontace: 0.4.1
- get-tsconfig: 5.0.0-beta.4
- github-slugger: 2.0.0
- html-escaper: 3.0.3
- http-cache-semantics: 4.2.0
- js-yaml: 4.1.1
- jsonc-parser: 3.3.1
- magic-string: 0.30.21
- magicast: 0.5.3
- mrmime: 2.0.1
- neotraverse: 0.6.18
- obug: 2.1.1
- p-limit: 7.3.0
- p-queue: 9.3.0
- package-manager-detector: 1.6.0
- piccolore: 0.1.3
- picomatch: 4.0.4
- rehype: 13.0.2
- semver: 7.8.0
- shiki: 4.1.0
- smol-toml: 1.6.1
- svgo: 4.0.1
- tinyclip: 0.1.12
- tinyexec: 1.1.2
- tinyglobby: 0.2.16
- ultrahtml: 1.6.0
- unifont: 0.7.4
- unist-util-visit: 5.1.0
- unstorage: 1.17.5
- vfile: 6.0.3
- vite: 7.3.3(@types/node@24.12.4)
- vitefu: 1.1.3(vite@7.3.3(@types/node@24.12.4))
- xxhash-wasm: 1.1.0
- yargs-parser: 22.0.0
- zod: 4.4.3
- optionalDependencies:
- sharp: 0.34.5
- transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@types/node'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/functions'
- - '@vercel/kv'
- - aws4fetch
- - db0
- - idb-keyval
- - ioredis
- - jiti
- - less
- - lightningcss
- - rollup
- - sass
- - sass-embedded
- - stylus
- - sugarss
- - supports-color
- - terser
- - tsx
- - uploadthing
- - yaml
-
- axobject-query@4.1.0: {}
-
- bail@2.0.2: {}
-
- bcp-47-match@2.0.3: {}
-
- bcp-47@2.1.0:
- dependencies:
- is-alphabetical: 2.0.1
- is-alphanumerical: 2.0.1
- is-decimal: 2.0.1
-
- boolbase@1.0.0: {}
-
- ccount@2.0.1: {}
-
- character-entities-html4@2.1.0: {}
-
- character-entities-legacy@3.0.0: {}
-
- character-entities@2.0.2: {}
-
- character-reference-invalid@2.0.1: {}
-
- chokidar@5.0.0:
- dependencies:
- readdirp: 5.0.0
-
- ci-info@4.4.0: {}
-
- clsx@2.1.1: {}
-
- collapse-white-space@2.1.0: {}
-
- comma-separated-tokens@2.0.3: {}
-
- commander@11.1.0: {}
-
- common-ancestor-path@2.0.0: {}
-
- cookie-es@1.2.3: {}
-
- cookie@1.1.1: {}
-
- crossws@0.3.5:
- dependencies:
- uncrypto: 0.1.3
-
- css-select@5.2.2:
- dependencies:
- boolbase: 1.0.0
- css-what: 6.2.2
- domhandler: 5.0.3
- domutils: 3.2.2
- nth-check: 2.1.1
-
- css-selector-parser@3.3.0: {}
-
- css-tree@2.2.1:
- dependencies:
- mdn-data: 2.0.28
- source-map-js: 1.2.1
-
- css-tree@3.2.1:
- dependencies:
- mdn-data: 2.27.1
- source-map-js: 1.2.1
-
- css-what@6.2.2: {}
-
- cssesc@3.0.0: {}
-
- csso@5.0.5:
- dependencies:
- css-tree: 2.2.1
-
- debug@4.4.3:
- dependencies:
- ms: 2.1.3
-
- decode-named-character-reference@1.3.0:
- dependencies:
- character-entities: 2.0.2
-
- defu@6.1.7: {}
-
- dequal@2.0.3: {}
-
- destr@2.0.5: {}
-
- detect-libc@2.1.2: {}
-
- devalue@5.8.1: {}
-
- devlop@1.1.0:
- dependencies:
- dequal: 2.0.3
-
- diff@8.0.4: {}
-
- direction@2.0.1: {}
-
- dom-serializer@2.0.0:
- dependencies:
- domelementtype: 2.3.0
- domhandler: 5.0.3
- entities: 4.5.0
-
- domelementtype@2.3.0: {}
-
- domhandler@5.0.3:
- dependencies:
- domelementtype: 2.3.0
-
- domutils@3.2.2:
- dependencies:
- dom-serializer: 2.0.0
- domelementtype: 2.3.0
- domhandler: 5.0.3
-
- dset@3.1.4: {}
-
- entities@4.5.0: {}
-
- entities@6.0.1: {}
-
- es-module-lexer@2.1.0: {}
-
- esast-util-from-estree@2.0.0:
- dependencies:
- '@types/estree-jsx': 1.0.5
- devlop: 1.1.0
- estree-util-visit: 2.0.0
- unist-util-position-from-estree: 2.0.0
-
- esast-util-from-js@2.0.1:
- dependencies:
- '@types/estree-jsx': 1.0.5
- acorn: 8.16.0
- esast-util-from-estree: 2.0.0
- vfile-message: 4.0.3
-
- esbuild@0.27.7:
- optionalDependencies:
- '@esbuild/aix-ppc64': 0.27.7
- '@esbuild/android-arm': 0.27.7
- '@esbuild/android-arm64': 0.27.7
- '@esbuild/android-x64': 0.27.7
- '@esbuild/darwin-arm64': 0.27.7
- '@esbuild/darwin-x64': 0.27.7
- '@esbuild/freebsd-arm64': 0.27.7
- '@esbuild/freebsd-x64': 0.27.7
- '@esbuild/linux-arm': 0.27.7
- '@esbuild/linux-arm64': 0.27.7
- '@esbuild/linux-ia32': 0.27.7
- '@esbuild/linux-loong64': 0.27.7
- '@esbuild/linux-mips64el': 0.27.7
- '@esbuild/linux-ppc64': 0.27.7
- '@esbuild/linux-riscv64': 0.27.7
- '@esbuild/linux-s390x': 0.27.7
- '@esbuild/linux-x64': 0.27.7
- '@esbuild/netbsd-arm64': 0.27.7
- '@esbuild/netbsd-x64': 0.27.7
- '@esbuild/openbsd-arm64': 0.27.7
- '@esbuild/openbsd-x64': 0.27.7
- '@esbuild/openharmony-arm64': 0.27.7
- '@esbuild/sunos-x64': 0.27.7
- '@esbuild/win32-arm64': 0.27.7
- '@esbuild/win32-ia32': 0.27.7
- '@esbuild/win32-x64': 0.27.7
-
- escape-string-regexp@5.0.0: {}
-
- estree-util-attach-comments@3.0.0:
- dependencies:
- '@types/estree': 1.0.9
-
- estree-util-build-jsx@3.0.1:
- dependencies:
- '@types/estree-jsx': 1.0.5
- devlop: 1.1.0
- estree-util-is-identifier-name: 3.0.0
- estree-walker: 3.0.3
-
- estree-util-is-identifier-name@3.0.0: {}
-
- estree-util-scope@1.0.0:
- dependencies:
- '@types/estree': 1.0.9
- devlop: 1.1.0
-
- estree-util-to-js@2.0.0:
- dependencies:
- '@types/estree-jsx': 1.0.5
- astring: 1.9.0
- source-map: 0.7.6
-
- estree-util-visit@2.0.0:
- dependencies:
- '@types/estree-jsx': 1.0.5
- '@types/unist': 3.0.3
-
- estree-walker@2.0.2: {}
-
- estree-walker@3.0.3:
- dependencies:
- '@types/estree': 1.0.9
-
- eventemitter3@5.0.4: {}
-
- expressive-code@0.42.0:
- dependencies:
- '@expressive-code/core': 0.42.0
- '@expressive-code/plugin-frames': 0.42.0
- '@expressive-code/plugin-shiki': 0.42.0
- '@expressive-code/plugin-text-markers': 0.42.0
-
- extend@3.0.2: {}
-
- fast-string-truncated-width@3.0.3: {}
-
- fast-string-width@3.0.2:
- dependencies:
- fast-string-truncated-width: 3.0.3
-
- fast-wrap-ansi@0.2.2:
- dependencies:
- fast-string-width: 3.0.2
-
- fdir@6.5.0(picomatch@4.0.4):
- optionalDependencies:
- picomatch: 4.0.4
-
- flattie@1.1.1: {}
-
- fontace@0.4.1:
- dependencies:
- fontkitten: 1.0.3
-
- fontkitten@1.0.3:
- dependencies:
- tiny-inflate: 1.0.3
-
- fsevents@2.3.3:
- optional: true
-
- get-tsconfig@5.0.0-beta.4:
- dependencies:
- resolve-pkg-maps: 1.0.0
-
- github-slugger@2.0.0: {}
-
- h3@1.15.11:
- dependencies:
- cookie-es: 1.2.3
- crossws: 0.3.5
- defu: 6.1.7
- destr: 2.0.5
- iron-webcrypto: 1.2.1
- node-mock-http: 1.0.4
- radix3: 1.1.2
- ufo: 1.6.4
- uncrypto: 0.1.3
-
- hast-util-embedded@3.0.0:
- dependencies:
- '@types/hast': 3.0.4
- hast-util-is-element: 3.0.0
-
- hast-util-format@1.1.0:
- dependencies:
- '@types/hast': 3.0.4
- hast-util-embedded: 3.0.0
- hast-util-minify-whitespace: 1.0.1
- hast-util-phrasing: 3.0.1
- hast-util-whitespace: 3.0.0
- html-whitespace-sensitive-tag-names: 3.0.1
- unist-util-visit-parents: 6.0.2
-
- hast-util-from-html@2.0.3:
- dependencies:
- '@types/hast': 3.0.4
- devlop: 1.1.0
- hast-util-from-parse5: 8.0.3
- parse5: 7.3.0
- vfile: 6.0.3
- vfile-message: 4.0.3
-
- hast-util-from-parse5@8.0.3:
- dependencies:
- '@types/hast': 3.0.4
- '@types/unist': 3.0.3
- devlop: 1.1.0
- hastscript: 9.0.1
- property-information: 7.1.0
- vfile: 6.0.3
- vfile-location: 5.0.3
- web-namespaces: 2.0.1
-
- hast-util-has-property@3.0.0:
- dependencies:
- '@types/hast': 3.0.4
-
- hast-util-is-body-ok-link@3.0.1:
- dependencies:
- '@types/hast': 3.0.4
-
- hast-util-is-element@3.0.0:
- dependencies:
- '@types/hast': 3.0.4
-
- hast-util-minify-whitespace@1.0.1:
- dependencies:
- '@types/hast': 3.0.4
- hast-util-embedded: 3.0.0
- hast-util-is-element: 3.0.0
- hast-util-whitespace: 3.0.0
- unist-util-is: 6.0.1
-
- hast-util-parse-selector@4.0.0:
- dependencies:
- '@types/hast': 3.0.4
-
- hast-util-phrasing@3.0.1:
- dependencies:
- '@types/hast': 3.0.4
- hast-util-embedded: 3.0.0
- hast-util-has-property: 3.0.0
- hast-util-is-body-ok-link: 3.0.1
- hast-util-is-element: 3.0.0
-
- hast-util-raw@9.1.0:
- dependencies:
- '@types/hast': 3.0.4
- '@types/unist': 3.0.3
- '@ungap/structured-clone': 1.3.1
- hast-util-from-parse5: 8.0.3
- hast-util-to-parse5: 8.0.1
- html-void-elements: 3.0.0
- mdast-util-to-hast: 13.2.1
- parse5: 7.3.0
- unist-util-position: 5.0.0
- unist-util-visit: 5.1.0
- vfile: 6.0.3
- web-namespaces: 2.0.1
- zwitch: 2.0.4
-
- hast-util-select@6.0.4:
- dependencies:
- '@types/hast': 3.0.4
- '@types/unist': 3.0.3
- bcp-47-match: 2.0.3
- comma-separated-tokens: 2.0.3
- css-selector-parser: 3.3.0
- devlop: 1.1.0
- direction: 2.0.1
- hast-util-has-property: 3.0.0
- hast-util-to-string: 3.0.1
- hast-util-whitespace: 3.0.0
- nth-check: 2.1.1
- property-information: 7.1.0
- space-separated-tokens: 2.0.2
- unist-util-visit: 5.1.0
- zwitch: 2.0.4
-
- hast-util-to-estree@3.1.3:
- dependencies:
- '@types/estree': 1.0.9
- '@types/estree-jsx': 1.0.5
- '@types/hast': 3.0.4
- comma-separated-tokens: 2.0.3
- devlop: 1.1.0
- estree-util-attach-comments: 3.0.0
- estree-util-is-identifier-name: 3.0.0
- hast-util-whitespace: 3.0.0
- mdast-util-mdx-expression: 2.0.1
- mdast-util-mdx-jsx: 3.2.0
- mdast-util-mdxjs-esm: 2.0.1
- property-information: 7.1.0
- space-separated-tokens: 2.0.2
- style-to-js: 1.1.21
- unist-util-position: 5.0.0
- zwitch: 2.0.4
- transitivePeerDependencies:
- - supports-color
-
- hast-util-to-html@9.0.5:
- dependencies:
- '@types/hast': 3.0.4
- '@types/unist': 3.0.3
- ccount: 2.0.1
- comma-separated-tokens: 2.0.3
- hast-util-whitespace: 3.0.0
- html-void-elements: 3.0.0
- mdast-util-to-hast: 13.2.1
- property-information: 7.1.0
- space-separated-tokens: 2.0.2
- stringify-entities: 4.0.4
- zwitch: 2.0.4
-
- hast-util-to-jsx-runtime@2.3.6:
- dependencies:
- '@types/estree': 1.0.9
- '@types/hast': 3.0.4
- '@types/unist': 3.0.3
- comma-separated-tokens: 2.0.3
- devlop: 1.1.0
- estree-util-is-identifier-name: 3.0.0
- hast-util-whitespace: 3.0.0
- mdast-util-mdx-expression: 2.0.1
- mdast-util-mdx-jsx: 3.2.0
- mdast-util-mdxjs-esm: 2.0.1
- property-information: 7.1.0
- space-separated-tokens: 2.0.2
- style-to-js: 1.1.21
- unist-util-position: 5.0.0
- vfile-message: 4.0.3
- transitivePeerDependencies:
- - supports-color
-
- hast-util-to-parse5@8.0.1:
- dependencies:
- '@types/hast': 3.0.4
- comma-separated-tokens: 2.0.3
- devlop: 1.1.0
- property-information: 7.1.0
- space-separated-tokens: 2.0.2
- web-namespaces: 2.0.1
- zwitch: 2.0.4
-
- hast-util-to-string@3.0.1:
- dependencies:
- '@types/hast': 3.0.4
-
- hast-util-to-text@4.0.2:
- dependencies:
- '@types/hast': 3.0.4
- '@types/unist': 3.0.3
- hast-util-is-element: 3.0.0
- unist-util-find-after: 5.0.0
-
- hast-util-whitespace@3.0.0:
- dependencies:
- '@types/hast': 3.0.4
-
- hastscript@9.0.1:
- dependencies:
- '@types/hast': 3.0.4
- comma-separated-tokens: 2.0.3
- hast-util-parse-selector: 4.0.0
- property-information: 7.1.0
- space-separated-tokens: 2.0.2
-
- html-escaper@3.0.3: {}
-
- html-void-elements@3.0.0: {}
-
- html-whitespace-sensitive-tag-names@3.0.1: {}
-
- http-cache-semantics@4.2.0: {}
-
- i18next@26.2.0(typescript@5.9.3):
- optionalDependencies:
- typescript: 5.9.3
-
- inline-style-parser@0.2.7: {}
-
- iron-webcrypto@1.2.1: {}
-
- is-alphabetical@2.0.1: {}
-
- is-alphanumerical@2.0.1:
- dependencies:
- is-alphabetical: 2.0.1
- is-decimal: 2.0.1
-
- is-decimal@2.0.1: {}
-
- is-docker@3.0.0: {}
-
- is-docker@4.0.0: {}
-
- is-hexadecimal@2.0.1: {}
-
- is-inside-container@1.0.0:
- dependencies:
- is-docker: 3.0.0
-
- is-plain-obj@4.1.0: {}
-
- is-wsl@3.1.1:
- dependencies:
- is-inside-container: 1.0.0
-
- js-yaml@4.1.1:
- dependencies:
- argparse: 2.0.1
-
- jsonc-parser@3.3.1: {}
-
- klona@2.0.6: {}
-
- longest-streak@3.1.0: {}
-
- lru-cache@11.5.0: {}
-
- magic-string@0.30.21:
- dependencies:
- '@jridgewell/sourcemap-codec': 1.5.5
-
- magicast@0.5.3:
- dependencies:
- '@babel/parser': 7.29.3
- '@babel/types': 7.29.0
- source-map-js: 1.2.1
-
- markdown-extensions@2.0.0: {}
-
- markdown-table@3.0.4: {}
-
- mdast-util-definitions@6.0.0:
- dependencies:
- '@types/mdast': 4.0.4
- '@types/unist': 3.0.3
- unist-util-visit: 5.1.0
-
- mdast-util-directive@3.1.0:
- dependencies:
- '@types/mdast': 4.0.4
- '@types/unist': 3.0.3
- ccount: 2.0.1
- devlop: 1.1.0
- mdast-util-from-markdown: 2.0.3
- mdast-util-to-markdown: 2.1.2
- parse-entities: 4.0.2
- stringify-entities: 4.0.4
- unist-util-visit-parents: 6.0.2
- transitivePeerDependencies:
- - supports-color
-
- mdast-util-find-and-replace@3.0.2:
- dependencies:
- '@types/mdast': 4.0.4
- escape-string-regexp: 5.0.0
- unist-util-is: 6.0.1
- unist-util-visit-parents: 6.0.2
-
- mdast-util-from-markdown@2.0.3:
- dependencies:
- '@types/mdast': 4.0.4
- '@types/unist': 3.0.3
- decode-named-character-reference: 1.3.0
- devlop: 1.1.0
- mdast-util-to-string: 4.0.0
- micromark: 4.0.2
- micromark-util-decode-numeric-character-reference: 2.0.2
- micromark-util-decode-string: 2.0.1
- micromark-util-normalize-identifier: 2.0.1
- micromark-util-symbol: 2.0.1
- micromark-util-types: 2.0.2
- unist-util-stringify-position: 4.0.0
- transitivePeerDependencies:
- - supports-color
-
- mdast-util-gfm-autolink-literal@2.0.1:
- dependencies:
- '@types/mdast': 4.0.4
- ccount: 2.0.1
- devlop: 1.1.0
- mdast-util-find-and-replace: 3.0.2
- micromark-util-character: 2.1.1
-
- mdast-util-gfm-footnote@2.1.0:
- dependencies:
- '@types/mdast': 4.0.4
- devlop: 1.1.0
- mdast-util-from-markdown: 2.0.3
- mdast-util-to-markdown: 2.1.2
- micromark-util-normalize-identifier: 2.0.1
- transitivePeerDependencies:
- - supports-color
-
- mdast-util-gfm-strikethrough@2.0.0:
- dependencies:
- '@types/mdast': 4.0.4
- mdast-util-from-markdown: 2.0.3
- mdast-util-to-markdown: 2.1.2
- transitivePeerDependencies:
- - supports-color
-
- mdast-util-gfm-table@2.0.0:
- dependencies:
- '@types/mdast': 4.0.4
- devlop: 1.1.0
- markdown-table: 3.0.4
- mdast-util-from-markdown: 2.0.3
- mdast-util-to-markdown: 2.1.2
- transitivePeerDependencies:
- - supports-color
-
- mdast-util-gfm-task-list-item@2.0.0:
- dependencies:
- '@types/mdast': 4.0.4
- devlop: 1.1.0
- mdast-util-from-markdown: 2.0.3
- mdast-util-to-markdown: 2.1.2
- transitivePeerDependencies:
- - supports-color
-
- mdast-util-gfm@3.1.0:
- dependencies:
- mdast-util-from-markdown: 2.0.3
- mdast-util-gfm-autolink-literal: 2.0.1
- mdast-util-gfm-footnote: 2.1.0
- mdast-util-gfm-strikethrough: 2.0.0
- mdast-util-gfm-table: 2.0.0
- mdast-util-gfm-task-list-item: 2.0.0
- mdast-util-to-markdown: 2.1.2
- transitivePeerDependencies:
- - supports-color
-
- mdast-util-mdx-expression@2.0.1:
- dependencies:
- '@types/estree-jsx': 1.0.5
- '@types/hast': 3.0.4
- '@types/mdast': 4.0.4
- devlop: 1.1.0
- mdast-util-from-markdown: 2.0.3
- mdast-util-to-markdown: 2.1.2
- transitivePeerDependencies:
- - supports-color
-
- mdast-util-mdx-jsx@3.2.0:
- dependencies:
- '@types/estree-jsx': 1.0.5
- '@types/hast': 3.0.4
- '@types/mdast': 4.0.4
- '@types/unist': 3.0.3
- ccount: 2.0.1
- devlop: 1.1.0
- mdast-util-from-markdown: 2.0.3
- mdast-util-to-markdown: 2.1.2
- parse-entities: 4.0.2
- stringify-entities: 4.0.4
- unist-util-stringify-position: 4.0.0
- vfile-message: 4.0.3
- transitivePeerDependencies:
- - supports-color
-
- mdast-util-mdx@3.0.0:
- dependencies:
- mdast-util-from-markdown: 2.0.3
- mdast-util-mdx-expression: 2.0.1
- mdast-util-mdx-jsx: 3.2.0
- mdast-util-mdxjs-esm: 2.0.1
- mdast-util-to-markdown: 2.1.2
- transitivePeerDependencies:
- - supports-color
-
- mdast-util-mdxjs-esm@2.0.1:
- dependencies:
- '@types/estree-jsx': 1.0.5
- '@types/hast': 3.0.4
- '@types/mdast': 4.0.4
- devlop: 1.1.0
- mdast-util-from-markdown: 2.0.3
- mdast-util-to-markdown: 2.1.2
- transitivePeerDependencies:
- - supports-color
-
- mdast-util-phrasing@4.1.0:
- dependencies:
- '@types/mdast': 4.0.4
- unist-util-is: 6.0.1
-
- mdast-util-to-hast@13.2.1:
- dependencies:
- '@types/hast': 3.0.4
- '@types/mdast': 4.0.4
- '@ungap/structured-clone': 1.3.1
- devlop: 1.1.0
- micromark-util-sanitize-uri: 2.0.1
- trim-lines: 3.0.1
- unist-util-position: 5.0.0
- unist-util-visit: 5.1.0
- vfile: 6.0.3
-
- mdast-util-to-markdown@2.1.2:
- dependencies:
- '@types/mdast': 4.0.4
- '@types/unist': 3.0.3
- longest-streak: 3.1.0
- mdast-util-phrasing: 4.1.0
- mdast-util-to-string: 4.0.0
- micromark-util-classify-character: 2.0.1
- micromark-util-decode-string: 2.0.1
- unist-util-visit: 5.1.0
- zwitch: 2.0.4
-
- mdast-util-to-string@4.0.0:
- dependencies:
- '@types/mdast': 4.0.4
-
- mdn-data@2.0.28: {}
-
- mdn-data@2.27.1: {}
-
- micromark-core-commonmark@2.0.3:
- dependencies:
- decode-named-character-reference: 1.3.0
- devlop: 1.1.0
- micromark-factory-destination: 2.0.1
- micromark-factory-label: 2.0.1
- micromark-factory-space: 2.0.1
- micromark-factory-title: 2.0.1
- micromark-factory-whitespace: 2.0.1
- micromark-util-character: 2.1.1
- micromark-util-chunked: 2.0.1
- micromark-util-classify-character: 2.0.1
- micromark-util-html-tag-name: 2.0.1
- micromark-util-normalize-identifier: 2.0.1
- micromark-util-resolve-all: 2.0.1
- micromark-util-subtokenize: 2.1.0
- micromark-util-symbol: 2.0.1
- micromark-util-types: 2.0.2
-
- micromark-extension-directive@4.0.0:
- dependencies:
- devlop: 1.1.0
- micromark-factory-space: 2.0.1
- micromark-factory-whitespace: 2.0.1
- micromark-util-character: 2.1.1
- micromark-util-symbol: 2.0.1
- micromark-util-types: 2.0.2
- parse-entities: 4.0.2
-
- micromark-extension-gfm-autolink-literal@2.1.0:
- dependencies:
- micromark-util-character: 2.1.1
- micromark-util-sanitize-uri: 2.0.1
- micromark-util-symbol: 2.0.1
- micromark-util-types: 2.0.2
-
- micromark-extension-gfm-footnote@2.1.0:
- dependencies:
- devlop: 1.1.0
- micromark-core-commonmark: 2.0.3
- micromark-factory-space: 2.0.1
- micromark-util-character: 2.1.1
- micromark-util-normalize-identifier: 2.0.1
- micromark-util-sanitize-uri: 2.0.1
- micromark-util-symbol: 2.0.1
- micromark-util-types: 2.0.2
-
- micromark-extension-gfm-strikethrough@2.1.0:
- dependencies:
- devlop: 1.1.0
- micromark-util-chunked: 2.0.1
- micromark-util-classify-character: 2.0.1
- micromark-util-resolve-all: 2.0.1
- micromark-util-symbol: 2.0.1
- micromark-util-types: 2.0.2
-
- micromark-extension-gfm-table@2.1.1:
- dependencies:
- devlop: 1.1.0
- micromark-factory-space: 2.0.1
- micromark-util-character: 2.1.1
- micromark-util-symbol: 2.0.1
- micromark-util-types: 2.0.2
-
- micromark-extension-gfm-tagfilter@2.0.0:
- dependencies:
- micromark-util-types: 2.0.2
-
- micromark-extension-gfm-task-list-item@2.1.0:
- dependencies:
- devlop: 1.1.0
- micromark-factory-space: 2.0.1
- micromark-util-character: 2.1.1
- micromark-util-symbol: 2.0.1
- micromark-util-types: 2.0.2
-
- micromark-extension-gfm@3.0.0:
- dependencies:
- micromark-extension-gfm-autolink-literal: 2.1.0
- micromark-extension-gfm-footnote: 2.1.0
- micromark-extension-gfm-strikethrough: 2.1.0
- micromark-extension-gfm-table: 2.1.1
- micromark-extension-gfm-tagfilter: 2.0.0
- micromark-extension-gfm-task-list-item: 2.1.0
- micromark-util-combine-extensions: 2.0.1
- micromark-util-types: 2.0.2
-
- micromark-extension-mdx-expression@3.0.1:
- dependencies:
- '@types/estree': 1.0.9
- devlop: 1.1.0
- micromark-factory-mdx-expression: 2.0.3
- micromark-factory-space: 2.0.1
- micromark-util-character: 2.1.1
- micromark-util-events-to-acorn: 2.0.3
- micromark-util-symbol: 2.0.1
- micromark-util-types: 2.0.2
-
- micromark-extension-mdx-jsx@3.0.2:
- dependencies:
- '@types/estree': 1.0.9
- devlop: 1.1.0
- estree-util-is-identifier-name: 3.0.0
- micromark-factory-mdx-expression: 2.0.3
- micromark-factory-space: 2.0.1
- micromark-util-character: 2.1.1
- micromark-util-events-to-acorn: 2.0.3
- micromark-util-symbol: 2.0.1
- micromark-util-types: 2.0.2
- vfile-message: 4.0.3
-
- micromark-extension-mdx-md@2.0.0:
- dependencies:
- micromark-util-types: 2.0.2
-
- micromark-extension-mdxjs-esm@3.0.0:
- dependencies:
- '@types/estree': 1.0.9
- devlop: 1.1.0
- micromark-core-commonmark: 2.0.3
- micromark-util-character: 2.1.1
- micromark-util-events-to-acorn: 2.0.3
- micromark-util-symbol: 2.0.1
- micromark-util-types: 2.0.2
- unist-util-position-from-estree: 2.0.0
- vfile-message: 4.0.3
-
- micromark-extension-mdxjs@3.0.0:
- dependencies:
- acorn: 8.16.0
- acorn-jsx: 5.3.2(acorn@8.16.0)
- micromark-extension-mdx-expression: 3.0.1
- micromark-extension-mdx-jsx: 3.0.2
- micromark-extension-mdx-md: 2.0.0
- micromark-extension-mdxjs-esm: 3.0.0
- micromark-util-combine-extensions: 2.0.1
- micromark-util-types: 2.0.2
-
- micromark-factory-destination@2.0.1:
- dependencies:
- micromark-util-character: 2.1.1
- micromark-util-symbol: 2.0.1
- micromark-util-types: 2.0.2
-
- micromark-factory-label@2.0.1:
- dependencies:
- devlop: 1.1.0
- micromark-util-character: 2.1.1
- micromark-util-symbol: 2.0.1
- micromark-util-types: 2.0.2
-
- micromark-factory-mdx-expression@2.0.3:
- dependencies:
- '@types/estree': 1.0.9
- devlop: 1.1.0
- micromark-factory-space: 2.0.1
- micromark-util-character: 2.1.1
- micromark-util-events-to-acorn: 2.0.3
- micromark-util-symbol: 2.0.1
- micromark-util-types: 2.0.2
- unist-util-position-from-estree: 2.0.0
- vfile-message: 4.0.3
-
- micromark-factory-space@2.0.1:
- dependencies:
- micromark-util-character: 2.1.1
- micromark-util-types: 2.0.2
-
- micromark-factory-title@2.0.1:
- dependencies:
- micromark-factory-space: 2.0.1
- micromark-util-character: 2.1.1
- micromark-util-symbol: 2.0.1
- micromark-util-types: 2.0.2
-
- micromark-factory-whitespace@2.0.1:
- dependencies:
- micromark-factory-space: 2.0.1
- micromark-util-character: 2.1.1
- micromark-util-symbol: 2.0.1
- micromark-util-types: 2.0.2
-
- micromark-util-character@2.1.1:
- dependencies:
- micromark-util-symbol: 2.0.1
- micromark-util-types: 2.0.2
-
- micromark-util-chunked@2.0.1:
- dependencies:
- micromark-util-symbol: 2.0.1
-
- micromark-util-classify-character@2.0.1:
- dependencies:
- micromark-util-character: 2.1.1
- micromark-util-symbol: 2.0.1
- micromark-util-types: 2.0.2
-
- micromark-util-combine-extensions@2.0.1:
- dependencies:
- micromark-util-chunked: 2.0.1
- micromark-util-types: 2.0.2
-
- micromark-util-decode-numeric-character-reference@2.0.2:
- dependencies:
- micromark-util-symbol: 2.0.1
-
- micromark-util-decode-string@2.0.1:
- dependencies:
- decode-named-character-reference: 1.3.0
- micromark-util-character: 2.1.1
- micromark-util-decode-numeric-character-reference: 2.0.2
- micromark-util-symbol: 2.0.1
-
- micromark-util-encode@2.0.1: {}
-
- micromark-util-events-to-acorn@2.0.3:
- dependencies:
- '@types/estree': 1.0.9
- '@types/unist': 3.0.3
- devlop: 1.1.0
- estree-util-visit: 2.0.0
- micromark-util-symbol: 2.0.1
- micromark-util-types: 2.0.2
- vfile-message: 4.0.3
-
- micromark-util-html-tag-name@2.0.1: {}
-
- micromark-util-normalize-identifier@2.0.1:
- dependencies:
- micromark-util-symbol: 2.0.1
-
- micromark-util-resolve-all@2.0.1:
- dependencies:
- micromark-util-types: 2.0.2
-
- micromark-util-sanitize-uri@2.0.1:
- dependencies:
- micromark-util-character: 2.1.1
- micromark-util-encode: 2.0.1
- micromark-util-symbol: 2.0.1
-
- micromark-util-subtokenize@2.1.0:
- dependencies:
- devlop: 1.1.0
- micromark-util-chunked: 2.0.1
- micromark-util-symbol: 2.0.1
- micromark-util-types: 2.0.2
-
- micromark-util-symbol@2.0.1: {}
-
- micromark-util-types@2.0.2: {}
-
- micromark@4.0.2:
- dependencies:
- '@types/debug': 4.1.13
- debug: 4.4.3
- decode-named-character-reference: 1.3.0
- devlop: 1.1.0
- micromark-core-commonmark: 2.0.3
- micromark-factory-space: 2.0.1
- micromark-util-character: 2.1.1
- micromark-util-chunked: 2.0.1
- micromark-util-combine-extensions: 2.0.1
- micromark-util-decode-numeric-character-reference: 2.0.2
- micromark-util-encode: 2.0.1
- micromark-util-normalize-identifier: 2.0.1
- micromark-util-resolve-all: 2.0.1
- micromark-util-sanitize-uri: 2.0.1
- micromark-util-subtokenize: 2.1.0
- micromark-util-symbol: 2.0.1
- micromark-util-types: 2.0.2
- transitivePeerDependencies:
- - supports-color
-
- mrmime@2.0.1: {}
-
- ms@2.1.3: {}
-
- nanoid@3.3.12: {}
-
- neotraverse@0.6.18: {}
-
- nlcst-to-string@4.0.0:
- dependencies:
- '@types/nlcst': 2.0.3
-
- node-fetch-native@1.6.7: {}
-
- node-mock-http@1.0.4: {}
-
- normalize-path@3.0.0: {}
-
- nth-check@2.1.1:
- dependencies:
- boolbase: 1.0.0
-
- obug@2.1.1: {}
-
- ofetch@1.5.1:
- dependencies:
- destr: 2.0.5
- node-fetch-native: 1.6.7
- ufo: 1.6.4
-
- ohash@2.0.11: {}
-
- oniguruma-parser@0.12.2: {}
-
- oniguruma-to-es@4.3.6:
- dependencies:
- oniguruma-parser: 0.12.2
- regex: 6.1.0
- regex-recursion: 6.0.2
-
- p-limit@7.3.0:
- dependencies:
- yocto-queue: 1.2.2
-
- p-queue@9.3.0:
- dependencies:
- eventemitter3: 5.0.4
- p-timeout: 7.0.1
-
- p-timeout@7.0.1: {}
-
- package-manager-detector@1.6.0: {}
-
- pagefind@1.5.2:
- optionalDependencies:
- '@pagefind/darwin-arm64': 1.5.2
- '@pagefind/darwin-x64': 1.5.2
- '@pagefind/freebsd-x64': 1.5.2
- '@pagefind/linux-arm64': 1.5.2
- '@pagefind/linux-x64': 1.5.2
- '@pagefind/windows-arm64': 1.5.2
- '@pagefind/windows-x64': 1.5.2
-
- parse-entities@4.0.2:
- dependencies:
- '@types/unist': 2.0.11
- character-entities-legacy: 3.0.0
- character-reference-invalid: 2.0.1
- decode-named-character-reference: 1.3.0
- is-alphanumerical: 2.0.1
- is-decimal: 2.0.1
- is-hexadecimal: 2.0.1
-
- parse-latin@7.0.0:
- dependencies:
- '@types/nlcst': 2.0.3
- '@types/unist': 3.0.3
- nlcst-to-string: 4.0.0
- unist-util-modify-children: 4.0.0
- unist-util-visit-children: 3.0.0
- vfile: 6.0.3
-
- parse5@7.3.0:
- dependencies:
- entities: 6.0.1
-
- piccolore@0.1.3: {}
-
- picocolors@1.1.1: {}
-
- picomatch@2.3.2: {}
-
- picomatch@4.0.4: {}
-
- postcss-nested@6.2.0(postcss@8.5.15):
- dependencies:
- postcss: 8.5.15
- postcss-selector-parser: 6.1.2
-
- postcss-selector-parser@6.1.2:
- dependencies:
- cssesc: 3.0.0
- util-deprecate: 1.0.2
-
- postcss@8.5.15:
- dependencies:
- nanoid: 3.3.12
- picocolors: 1.1.1
- source-map-js: 1.2.1
-
- prismjs@1.30.0: {}
-
- property-information@7.1.0: {}
-
- radix3@1.1.2: {}
-
- readdirp@5.0.0: {}
-
- recma-build-jsx@1.0.0:
- dependencies:
- '@types/estree': 1.0.9
- estree-util-build-jsx: 3.0.1
- vfile: 6.0.3
-
- recma-jsx@1.0.1(acorn@8.16.0):
- dependencies:
- acorn: 8.16.0
- acorn-jsx: 5.3.2(acorn@8.16.0)
- estree-util-to-js: 2.0.0
- recma-parse: 1.0.0
- recma-stringify: 1.0.0
- unified: 11.0.5
-
- recma-parse@1.0.0:
- dependencies:
- '@types/estree': 1.0.9
- esast-util-from-js: 2.0.1
- unified: 11.0.5
- vfile: 6.0.3
-
- recma-stringify@1.0.0:
- dependencies:
- '@types/estree': 1.0.9
- estree-util-to-js: 2.0.0
- unified: 11.0.5
- vfile: 6.0.3
-
- regex-recursion@6.0.2:
- dependencies:
- regex-utilities: 2.3.0
-
- regex-utilities@2.3.0: {}
-
- regex@6.1.0:
- dependencies:
- regex-utilities: 2.3.0
-
- rehype-expressive-code@0.42.0:
- dependencies:
- expressive-code: 0.42.0
-
- rehype-format@5.0.1:
- dependencies:
- '@types/hast': 3.0.4
- hast-util-format: 1.1.0
-
- rehype-parse@9.0.1:
- dependencies:
- '@types/hast': 3.0.4
- hast-util-from-html: 2.0.3
- unified: 11.0.5
-
- rehype-raw@7.0.0:
- dependencies:
- '@types/hast': 3.0.4
- hast-util-raw: 9.1.0
- vfile: 6.0.3
-
- rehype-recma@1.0.0:
- dependencies:
- '@types/estree': 1.0.9
- '@types/hast': 3.0.4
- hast-util-to-estree: 3.1.3
- transitivePeerDependencies:
- - supports-color
-
- rehype-stringify@10.0.1:
- dependencies:
- '@types/hast': 3.0.4
- hast-util-to-html: 9.0.5
- unified: 11.0.5
-
- rehype@13.0.2:
- dependencies:
- '@types/hast': 3.0.4
- rehype-parse: 9.0.1
- rehype-stringify: 10.0.1
- unified: 11.0.5
-
- remark-directive@4.0.0:
- dependencies:
- '@types/mdast': 4.0.4
- mdast-util-directive: 3.1.0
- micromark-extension-directive: 4.0.0
- unified: 11.0.5
- transitivePeerDependencies:
- - supports-color
-
- remark-gfm@4.0.1:
- dependencies:
- '@types/mdast': 4.0.4
- mdast-util-gfm: 3.1.0
- micromark-extension-gfm: 3.0.0
- remark-parse: 11.0.0
- remark-stringify: 11.0.0
- unified: 11.0.5
- transitivePeerDependencies:
- - supports-color
-
- remark-mdx@3.1.1:
- dependencies:
- mdast-util-mdx: 3.0.0
- micromark-extension-mdxjs: 3.0.0
- transitivePeerDependencies:
- - supports-color
-
- remark-parse@11.0.0:
- dependencies:
- '@types/mdast': 4.0.4
- mdast-util-from-markdown: 2.0.3
- micromark-util-types: 2.0.2
- unified: 11.0.5
- transitivePeerDependencies:
- - supports-color
-
- remark-rehype@11.1.2:
- dependencies:
- '@types/hast': 3.0.4
- '@types/mdast': 4.0.4
- mdast-util-to-hast: 13.2.1
- unified: 11.0.5
- vfile: 6.0.3
-
- remark-smartypants@3.0.2:
- dependencies:
- retext: 9.0.0
- retext-smartypants: 6.2.0
- unified: 11.0.5
- unist-util-visit: 5.1.0
-
- remark-stringify@11.0.0:
- dependencies:
- '@types/mdast': 4.0.4
- mdast-util-to-markdown: 2.1.2
- unified: 11.0.5
-
- resolve-pkg-maps@1.0.0: {}
-
- retext-latin@4.0.0:
- dependencies:
- '@types/nlcst': 2.0.3
- parse-latin: 7.0.0
- unified: 11.0.5
-
- retext-smartypants@6.2.0:
- dependencies:
- '@types/nlcst': 2.0.3
- nlcst-to-string: 4.0.0
- unist-util-visit: 5.1.0
-
- retext-stringify@4.0.0:
- dependencies:
- '@types/nlcst': 2.0.3
- nlcst-to-string: 4.0.0
- unified: 11.0.5
-
- retext@9.0.0:
- dependencies:
- '@types/nlcst': 2.0.3
- retext-latin: 4.0.0
- retext-stringify: 4.0.0
- unified: 11.0.5
-
- rollup@4.60.4:
- dependencies:
- '@types/estree': 1.0.8
- optionalDependencies:
- '@rollup/rollup-android-arm-eabi': 4.60.4
- '@rollup/rollup-android-arm64': 4.60.4
- '@rollup/rollup-darwin-arm64': 4.60.4
- '@rollup/rollup-darwin-x64': 4.60.4
- '@rollup/rollup-freebsd-arm64': 4.60.4
- '@rollup/rollup-freebsd-x64': 4.60.4
- '@rollup/rollup-linux-arm-gnueabihf': 4.60.4
- '@rollup/rollup-linux-arm-musleabihf': 4.60.4
- '@rollup/rollup-linux-arm64-gnu': 4.60.4
- '@rollup/rollup-linux-arm64-musl': 4.60.4
- '@rollup/rollup-linux-loong64-gnu': 4.60.4
- '@rollup/rollup-linux-loong64-musl': 4.60.4
- '@rollup/rollup-linux-ppc64-gnu': 4.60.4
- '@rollup/rollup-linux-ppc64-musl': 4.60.4
- '@rollup/rollup-linux-riscv64-gnu': 4.60.4
- '@rollup/rollup-linux-riscv64-musl': 4.60.4
- '@rollup/rollup-linux-s390x-gnu': 4.60.4
- '@rollup/rollup-linux-x64-gnu': 4.60.4
- '@rollup/rollup-linux-x64-musl': 4.60.4
- '@rollup/rollup-openbsd-x64': 4.60.4
- '@rollup/rollup-openharmony-arm64': 4.60.4
- '@rollup/rollup-win32-arm64-msvc': 4.60.4
- '@rollup/rollup-win32-ia32-msvc': 4.60.4
- '@rollup/rollup-win32-x64-gnu': 4.60.4
- '@rollup/rollup-win32-x64-msvc': 4.60.4
- fsevents: 2.3.3
-
- sax@1.6.0: {}
-
- semver@7.8.0: {}
-
- sharp@0.34.5:
- dependencies:
- '@img/colour': 1.1.0
- detect-libc: 2.1.2
- semver: 7.8.0
- optionalDependencies:
- '@img/sharp-darwin-arm64': 0.34.5
- '@img/sharp-darwin-x64': 0.34.5
- '@img/sharp-libvips-darwin-arm64': 1.2.4
- '@img/sharp-libvips-darwin-x64': 1.2.4
- '@img/sharp-libvips-linux-arm': 1.2.4
- '@img/sharp-libvips-linux-arm64': 1.2.4
- '@img/sharp-libvips-linux-ppc64': 1.2.4
- '@img/sharp-libvips-linux-riscv64': 1.2.4
- '@img/sharp-libvips-linux-s390x': 1.2.4
- '@img/sharp-libvips-linux-x64': 1.2.4
- '@img/sharp-libvips-linuxmusl-arm64': 1.2.4
- '@img/sharp-libvips-linuxmusl-x64': 1.2.4
- '@img/sharp-linux-arm': 0.34.5
- '@img/sharp-linux-arm64': 0.34.5
- '@img/sharp-linux-ppc64': 0.34.5
- '@img/sharp-linux-riscv64': 0.34.5
- '@img/sharp-linux-s390x': 0.34.5
- '@img/sharp-linux-x64': 0.34.5
- '@img/sharp-linuxmusl-arm64': 0.34.5
- '@img/sharp-linuxmusl-x64': 0.34.5
- '@img/sharp-wasm32': 0.34.5
- '@img/sharp-win32-arm64': 0.34.5
- '@img/sharp-win32-ia32': 0.34.5
- '@img/sharp-win32-x64': 0.34.5
-
- shiki@4.1.0:
- dependencies:
- '@shikijs/core': 4.1.0
- '@shikijs/engine-javascript': 4.1.0
- '@shikijs/engine-oniguruma': 4.1.0
- '@shikijs/langs': 4.1.0
- '@shikijs/themes': 4.1.0
- '@shikijs/types': 4.1.0
- '@shikijs/vscode-textmate': 10.0.2
- '@types/hast': 3.0.4
-
- sisteransi@1.0.5: {}
-
- sitemap@9.0.1:
- dependencies:
- '@types/node': 24.12.4
- '@types/sax': 1.2.7
- arg: 5.0.2
- sax: 1.6.0
-
- smol-toml@1.6.1: {}
-
- source-map-js@1.2.1: {}
-
- source-map@0.7.6: {}
-
- space-separated-tokens@2.0.2: {}
-
- stream-replace-string@2.0.0: {}
-
- stringify-entities@4.0.4:
- dependencies:
- character-entities-html4: 2.1.0
- character-entities-legacy: 3.0.0
-
- style-to-js@1.1.21:
- dependencies:
- style-to-object: 1.0.14
-
- style-to-object@1.0.14:
- dependencies:
- inline-style-parser: 0.2.7
-
- svgo@4.0.1:
- dependencies:
- commander: 11.1.0
- css-select: 5.2.2
- css-tree: 3.2.1
- css-what: 6.2.2
- csso: 5.0.5
- picocolors: 1.1.1
- sax: 1.6.0
-
- tiny-inflate@1.0.3: {}
-
- tinyclip@0.1.12: {}
-
- tinyexec@1.1.2: {}
-
- tinyglobby@0.2.16:
- dependencies:
- fdir: 6.5.0(picomatch@4.0.4)
- picomatch: 4.0.4
-
- trim-lines@3.0.1: {}
-
- trough@2.2.0: {}
-
- tslib@2.8.1:
- optional: true
-
- typescript@5.9.3:
- optional: true
-
- ufo@1.6.4: {}
-
- ultrahtml@1.6.0: {}
-
- uncrypto@0.1.3: {}
-
- undici-types@7.16.0: {}
-
- unified@11.0.5:
- dependencies:
- '@types/unist': 3.0.3
- bail: 2.0.2
- devlop: 1.1.0
- extend: 3.0.2
- is-plain-obj: 4.1.0
- trough: 2.2.0
- vfile: 6.0.3
-
- unifont@0.7.4:
- dependencies:
- css-tree: 3.2.1
- ofetch: 1.5.1
- ohash: 2.0.11
-
- unist-util-find-after@5.0.0:
- dependencies:
- '@types/unist': 3.0.3
- unist-util-is: 6.0.1
-
- unist-util-is@6.0.1:
- dependencies:
- '@types/unist': 3.0.3
-
- unist-util-modify-children@4.0.0:
- dependencies:
- '@types/unist': 3.0.3
- array-iterate: 2.0.1
-
- unist-util-position-from-estree@2.0.0:
- dependencies:
- '@types/unist': 3.0.3
-
- unist-util-position@5.0.0:
- dependencies:
- '@types/unist': 3.0.3
-
- unist-util-remove-position@5.0.0:
- dependencies:
- '@types/unist': 3.0.3
- unist-util-visit: 5.1.0
-
- unist-util-stringify-position@4.0.0:
- dependencies:
- '@types/unist': 3.0.3
-
- unist-util-visit-children@3.0.0:
- dependencies:
- '@types/unist': 3.0.3
-
- unist-util-visit-parents@6.0.2:
- dependencies:
- '@types/unist': 3.0.3
- unist-util-is: 6.0.1
-
- unist-util-visit@5.1.0:
- dependencies:
- '@types/unist': 3.0.3
- unist-util-is: 6.0.1
- unist-util-visit-parents: 6.0.2
-
- unstorage@1.17.5:
- dependencies:
- anymatch: 3.1.3
- chokidar: 5.0.0
- destr: 2.0.5
- h3: 1.15.11
- lru-cache: 11.5.0
- node-fetch-native: 1.6.7
- ofetch: 1.5.1
- ufo: 1.6.4
-
- util-deprecate@1.0.2: {}
-
- vfile-location@5.0.3:
- dependencies:
- '@types/unist': 3.0.3
- vfile: 6.0.3
-
- vfile-message@4.0.3:
- dependencies:
- '@types/unist': 3.0.3
- unist-util-stringify-position: 4.0.0
-
- vfile@6.0.3:
- dependencies:
- '@types/unist': 3.0.3
- vfile-message: 4.0.3
-
- vite@7.3.3(@types/node@24.12.4):
- dependencies:
- esbuild: 0.27.7
- fdir: 6.5.0(picomatch@4.0.4)
- picomatch: 4.0.4
- postcss: 8.5.15
- rollup: 4.60.4
- tinyglobby: 0.2.16
- optionalDependencies:
- '@types/node': 24.12.4
- fsevents: 2.3.3
-
- vitefu@1.1.3(vite@7.3.3(@types/node@24.12.4)):
- optionalDependencies:
- vite: 7.3.3(@types/node@24.12.4)
-
- web-namespaces@2.0.1: {}
-
- which-pm-runs@1.1.0: {}
-
- xxhash-wasm@1.1.0: {}
-
- yargs-parser@22.0.0: {}
-
- yocto-queue@1.2.2: {}
-
- zod@4.4.3: {}
-
- zwitch@2.0.4: {}
diff --git a/website/public/_headers b/website/public/_headers
new file mode 100644
index 0000000..66a82bb
--- /dev/null
+++ b/website/public/_headers
@@ -0,0 +1,9 @@
+/playground
+ Cross-Origin-Opener-Policy: same-origin
+ Cross-Origin-Embedder-Policy: require-corp
+/playground/*
+ Cross-Origin-Opener-Policy: same-origin
+ Cross-Origin-Embedder-Policy: require-corp
+/playground-engine/*
+ Cross-Origin-Opener-Policy: same-origin
+ Cross-Origin-Embedder-Policy: require-corp
diff --git a/website/scripts/bundle-engine.mjs b/website/scripts/bundle-engine.mjs
new file mode 100644
index 0000000..06a656e
--- /dev/null
+++ b/website/scripts/bundle-engine.mjs
@@ -0,0 +1,66 @@
+#!/usr/bin/env node
+// Pre-bundles the napi-rs WASI browser loader so the page can import it
+// from /playground-engine/ without Vite processing node_modules internals.
+import { build } from 'esbuild';
+import fs from 'node:fs';
+import { createRequire } from 'node:module';
+import path from 'node:path';
+import { fileURLToPath } from 'node:url';
+
+const require = createRequire(import.meta.url);
+const websiteRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
+const outDir = path.join(websiteRoot, 'public', 'playground-engine');
+const pkgDir = path.dirname(
+ require.resolve('@avsystem/openapi-ng-wasm32-wasi/package.json'),
+);
+
+const PACKAGE_WORKER_URL =
+ "new URL('@avsystem/openapi-ng-wasm32-wasi/wasi-worker-browser.mjs', import.meta.url)";
+const LOCAL_WORKER_URL = "new URL('./wasi-worker-browser.mjs', import.meta.url)";
+
+fs.rmSync(outDir, { recursive: true, force: true });
+fs.mkdirSync(outDir, { recursive: true });
+
+const loaderSource = fs.readFileSync(
+ path.join(pkgDir, 'openapi-ng.wasi-browser.js'),
+ 'utf8',
+);
+if (!loaderSource.includes(PACKAGE_WORKER_URL)) {
+ throw new Error(
+ 'bundle-engine: worker URL in the WASI loader changed; update PACKAGE_WORKER_URL',
+ );
+}
+
+await build({
+ stdin: {
+ contents: loaderSource.replace(PACKAGE_WORKER_URL, LOCAL_WORKER_URL),
+ resolveDir: pkgDir,
+ sourcefile: 'openapi-ng.wasi-browser.js',
+ loader: 'js',
+ },
+ bundle: true,
+ format: 'esm',
+ platform: 'browser',
+ target: 'es2022',
+ minify: true,
+ outfile: path.join(outDir, 'openapi-ng.wasi-browser.js'),
+});
+
+await build({
+ entryPoints: [path.join(pkgDir, 'wasi-worker-browser.mjs')],
+ bundle: true,
+ format: 'esm',
+ platform: 'browser',
+ target: 'es2022',
+ minify: true,
+ outfile: path.join(outDir, 'wasi-worker-browser.mjs'),
+});
+
+fs.copyFileSync(
+ path.join(pkgDir, 'openapi-ng.wasm32-wasi.wasm'),
+ path.join(outDir, 'openapi-ng.wasm32-wasi.wasm'),
+);
+
+const { version } = require('@avsystem/openapi-ng-wasm32-wasi/package.json');
+fs.writeFileSync(path.join(outDir, 'version.json'), JSON.stringify({ version }));
+console.log(`bundle-engine: wrote ${outDir} (v${version})`);
diff --git a/website/src/pages/playground.astro b/website/src/pages/playground.astro
new file mode 100644
index 0000000..aa359be
--- /dev/null
+++ b/website/src/pages/playground.astro
@@ -0,0 +1,35 @@
+---
+import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
+import '../playground/playground.css';
+---
+
+
+
+
+
+
diff --git a/website/src/playground/main.ts b/website/src/playground/main.ts
new file mode 100644
index 0000000..c827bbe
--- /dev/null
+++ b/website/src/playground/main.ts
@@ -0,0 +1 @@
+export function start(_doc: Document): void {}
diff --git a/website/src/playground/playground.css b/website/src/playground/playground.css
new file mode 100644
index 0000000..c675a28
--- /dev/null
+++ b/website/src/playground/playground.css
@@ -0,0 +1,112 @@
+.pg {
+ display: grid;
+ grid-template-rows: auto 1fr auto;
+ gap: 0.75rem;
+ height: calc(100vh - var(--sl-nav-height) - 3rem);
+ min-height: 32rem;
+}
+.pg-toolbar,
+.pg-footer {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ gap: 1rem;
+ font-size: var(--sl-text-sm);
+}
+.pg-actions {
+ display: flex;
+ gap: 0.5rem;
+}
+.pg button {
+ border: 1px solid var(--sl-color-gray-5);
+ background: var(--sl-color-bg-nav);
+ color: var(--sl-color-white);
+ border-radius: 0.375rem;
+ padding: 0.25rem 0.75rem;
+ cursor: pointer;
+}
+.pg-panes {
+ display: grid;
+ grid-template-columns: minmax(0, 5fr) 14rem minmax(0, 6fr);
+ gap: 0.75rem;
+ min-height: 0;
+}
+.pg-editor,
+.pg-tree,
+.pg-output {
+ border: 1px solid var(--sl-color-gray-5);
+ border-radius: 0.5rem;
+ overflow: auto;
+ min-height: 0;
+}
+.pg-editor .cm-editor {
+ height: 100%;
+ font-size: 0.8rem;
+}
+.pg-tree ul {
+ list-style: none;
+ margin: 0;
+ padding: 0.5rem 0;
+}
+.pg-tree li {
+ padding: 0.25rem 0.75rem;
+ font-family: var(--__sl-font-mono);
+ font-size: 0.75rem;
+ display: flex;
+ justify-content: space-between;
+ cursor: pointer;
+}
+.pg-tree li[data-depth='1'] {
+ padding-left: 1.75rem;
+}
+.pg-tree li.is-dir {
+ cursor: default;
+ color: var(--sl-color-gray-3);
+}
+.pg-tree li.is-selected {
+ background: var(--sl-color-gray-6);
+}
+.pg-tree .size {
+ color: var(--sl-color-gray-3);
+}
+.pg-output {
+ position: relative;
+}
+.pg-output pre {
+ margin: 0;
+ height: 100%;
+ font-size: 0.75rem;
+}
+.pg-copy {
+ position: absolute;
+ top: 0.5rem;
+ right: 0.5rem;
+}
+.pg-diagnostics {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5rem;
+}
+.pg-diagnostics li {
+ font-family: var(--__sl-font-mono);
+ font-size: 0.75rem;
+}
+.pg-diagnostics li.is-error {
+ color: var(--sl-color-red);
+}
+.pg.is-stale .pg-tree,
+.pg.is-stale .pg-output {
+ opacity: 0.5;
+}
+.pg-unsupported {
+ padding: 2rem;
+}
+@media (max-width: 72rem) {
+ .pg-panes {
+ grid-template-columns: 1fr;
+ grid-template-rows: 20rem auto 20rem;
+ }
+}
From da4102964bd0d2239165946ecf290ecd76e69f18 Mon Sep 17 00:00:00 2001
From: pkurcx
Date: Thu, 3 Sep 2026 19:25:16 +0200
Subject: [PATCH 02/17] feat(website): playground format, share and tree
modules
Co-Authored-By: Claude Fable 5.1
---
pnpm-lock.yaml | 186 +++++++++++++++++++++++++-
website/package.json | 4 +-
website/src/playground/format.test.ts | 19 +++
website/src/playground/format.ts | 9 ++
website/src/playground/share.test.ts | 17 +++
website/src/playground/share.ts | 16 +++
website/src/playground/tree.test.ts | 25 ++++
website/src/playground/tree.ts | 68 ++++++++++
website/vitest.config.ts | 8 ++
9 files changed, 347 insertions(+), 5 deletions(-)
create mode 100644 website/src/playground/format.test.ts
create mode 100644 website/src/playground/format.ts
create mode 100644 website/src/playground/share.test.ts
create mode 100644 website/src/playground/share.ts
create mode 100644 website/src/playground/tree.test.ts
create mode 100644 website/src/playground/tree.ts
create mode 100644 website/vitest.config.ts
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 618b1fa..4fd087b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -134,6 +134,9 @@ importers:
esbuild:
specifier: 0.28.2
version: 0.28.2
+ vitest:
+ specifier: 5.0.0
+ version: 5.0.0(@types/node@26.2.0)(vite@8.2.2(@types/node@26.2.0)(esbuild@0.28.2)(yaml@2.9.0))
wrangler:
specifier: 4.124.0
version: 4.124.0
@@ -1366,6 +1369,9 @@ packages:
'@jridgewell/sourcemap-codec@1.5.5':
resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
+ '@jridgewell/trace-mapping@0.3.31':
+ resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
+
'@jridgewell/trace-mapping@0.3.9':
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
@@ -2508,9 +2514,15 @@ packages:
'@tybys/wasm-util@0.10.3':
resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==}
+ '@types/chai@5.2.3':
+ resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==}
+
'@types/debug@4.1.13':
resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==}
+ '@types/deep-eql@4.0.2':
+ resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
+
'@types/estree-jsx@1.0.5':
resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==}
@@ -2565,6 +2577,20 @@ packages:
engines: {node: '>=20'}
hasBin: true
+ '@vitest/mocker@5.0.0':
+ resolution: {integrity: sha512-66PGTMIiVJP3t4a5yxU9qPtf7MdTBs8jmToMvy+HVflB3Yy13WJZTtPePdvU+wjRV02SKK5doLbSA6o9pwOmiA==}
+ peerDependencies:
+ msw: ^2.4.9
+ vite: ^6.0.0 || ^7.0.0 || ^8.0.0
+ peerDependenciesMeta:
+ msw:
+ optional: true
+ vite:
+ optional: true
+
+ '@vitest/spy@5.0.0':
+ resolution: {integrity: sha512-uy+luWBAPw9XfthoHi5AkfHUnuPYEESjl0p/r+meoBnU8bxg5GDQ3Ey8MjcJ6sqahkL4PFyrvfMJJBw7LbU06g==}
+
abbrev@3.0.0:
resolution: {integrity: sha512-+/kfrslGQ7TNV2ecmQwMJj/B65g5KVq1/L3SGVZ3tCYGqlzFuFCGBZJtMP99wH3NpEUyAjn0zPdPUg0D+DwrOA==}
engines: {node: ^18.17.0 || >=20.5.0}
@@ -2644,6 +2670,10 @@ packages:
resolution: {integrity: sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==}
engines: {node: '>=12'}
+ assertion-error@2.0.1:
+ resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
+ engines: {node: '>=12'}
+
astring@1.9.0:
resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==}
hasBin: true
@@ -2727,6 +2757,10 @@ packages:
ccount@2.0.1:
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
+ chai@6.2.2:
+ resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==}
+ engines: {node: '>=18'}
+
chalk@4.1.2:
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
engines: {node: '>=10'}
@@ -2981,6 +3015,9 @@ packages:
es-module-lexer@2.1.0:
resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==}
+ es-module-lexer@2.3.2:
+ resolution: {integrity: sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==}
+
es-toolkit@1.51.0:
resolution: {integrity: sha512-zC2lQGkM7QX+Gm6iM3+WIdZJzthsEd14LvRNJneSO2hzyz/zNBENR8+YXWo1cKxgPBtV6ksPYHELbcwBRzmdCw==}
@@ -3048,6 +3085,10 @@ packages:
eventemitter3@5.0.4:
resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==}
+ expect-type@1.4.0:
+ resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==}
+ engines: {node: '>=12.0.0'}
+
expressive-code@0.44.1:
resolution: {integrity: sha512-GakidxhapWDzpKLqEaFQ8wGk6gAqEtPQibu8+yPBfnDLgev5Vdsh1pasTxnrXL/mzIknyqeTwhMHTghdaiUrTg==}
@@ -3476,6 +3517,9 @@ packages:
magic-string@1.2.2:
resolution: {integrity: sha512-veT/+7iXrXzT39XnEN4lOxtNl72dMgJ8Lp+5Bd6YcMSWpb0n0MjBM8Uuooi6jgJr8dhUW2swQgBmoZVMni5SVg==}
+ magic-string@1.2.3:
+ resolution: {integrity: sha512-Bpb0W2TbLKOZ7vJnOUnVRGq3WL2p+ISV29M6hYPL1AFCpyKZpdr5ytiXoTSSxRVhg8YW7f65+6gbG8WG6PCa/g==}
+
magicast@0.5.3:
resolution: {integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==}
@@ -3883,6 +3927,10 @@ packages:
resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==}
engines: {node: '>=12'}
+ picomatch@4.0.7:
+ resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==}
+ engines: {node: '>=12'}
+
pidtree@1.0.0:
resolution: {integrity: sha512-avfAvjB9Dd0wdj3rjJX//yS+G79OO0KrS5pJHFJENjYGX6N4SMgEDBBI/yFy0lloOYSaC6XQxzpOAMPfSYFV/Q==}
engines: {node: '>=18'}
@@ -4108,6 +4156,9 @@ packages:
resolution: {integrity: sha512-l/ABZPUR5v70jI10EzqfMS/I96vjSGv2y0ihUV+WYFzv0EfvW4s54m0Lg8wCrrL+2IkwBzFTuxkZjPf8b2NX9Q==}
engines: {node: '>=20'}
+ siginfo@2.0.0:
+ resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
+
signal-exit@4.1.0:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'}
@@ -4150,6 +4201,12 @@ packages:
resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==}
engines: {node: '>=10'}
+ stackback@0.0.2:
+ resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
+
+ std-env@4.2.0:
+ resolution: {integrity: sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==}
+
stream-replace-string@2.0.0:
resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==}
@@ -4217,6 +4274,10 @@ packages:
resolution: {integrity: sha512-8k25iNSZHnzkjp3nrpEmx6YkrTNs41PzOHYc28DR5Z2l/CId/Nzw+Ume/41jCeDDmCUMPuK5GkQ/VxJaJ2P6Qg==}
engines: {node: '>=20.0.0'}
+ tinybench@6.1.4:
+ resolution: {integrity: sha512-9APumHG7r4yOk4X4WlkmE71aZcv1gvin1czO3OQ1U9iJcFA5Ja/ygyb0vPOVHTthFozUYs8CLoLUlM8grb2lTQ==}
+ engines: {node: '>=20.0.0'}
+
tinyclip@0.1.12:
resolution: {integrity: sha512-Ae3OVUqifDw0wBriIBS7yVaW44Dp6eSHQcyq4Igc7eN2TJH/2YsicswaW+J/OuMvhpDPOKEgpAZCjkb4hpoyeA==}
engines: {node: ^16.14.0 || >= 17.3.0}
@@ -4467,6 +4528,47 @@ packages:
vite:
optional: true
+ vitest@5.0.0:
+ resolution: {integrity: sha512-gpsMNoRhMjMktVxPtstOH4/PJuPyovVaMDr4oDilXaGH1EcqM2OE96SoHT2VIQ6fTGtTjqmHDrEu2X9RQiXf8Q==}
+ engines: {node: ^22.12.0 || ^24.0.0 || >=26.0.0}
+ hasBin: true
+ peerDependencies:
+ '@edge-runtime/vm': '*'
+ '@opentelemetry/api': ^1.9.0
+ '@types/node': ^22.0.0 || >=24.0.0
+ '@vitest/browser-playwright': 5.0.0
+ '@vitest/browser-preview': 5.0.0
+ '@vitest/browser-webdriverio': ^5.0.0-beta.5 || >=5.0.0
+ '@vitest/coverage-istanbul': 5.0.0
+ '@vitest/coverage-v8': 5.0.0
+ '@vitest/ui': 5.0.0
+ happy-dom: '*'
+ jsdom: '*'
+ vite: ^6.4.0 || ^7.0.0 || ^8.0.0
+ peerDependenciesMeta:
+ '@edge-runtime/vm':
+ optional: true
+ '@opentelemetry/api':
+ optional: true
+ '@types/node':
+ optional: true
+ '@vitest/browser-playwright':
+ optional: true
+ '@vitest/browser-preview':
+ optional: true
+ '@vitest/browser-webdriverio':
+ optional: true
+ '@vitest/coverage-istanbul':
+ optional: true
+ '@vitest/coverage-v8':
+ optional: true
+ '@vitest/ui':
+ optional: true
+ happy-dom:
+ optional: true
+ jsdom:
+ optional: true
+
w3c-keyname@2.2.8:
resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==}
@@ -4493,6 +4595,11 @@ packages:
engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0}
hasBin: true
+ why-is-node-running@2.3.0:
+ resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
+ engines: {node: '>=8'}
+ hasBin: true
+
workerd@1.20260815.1:
resolution: {integrity: sha512-8bArFkHmlp7qFEKVPyNzDzHzS35gc2fg0PYBcDtaNLF7UCDryCX2BQnpkUkTHYIy824IRrHOTwOEoTj0sUO2Fg==}
engines: {node: '>=16'}
@@ -5529,6 +5636,11 @@ snapshots:
'@jridgewell/sourcemap-codec@1.5.5': {}
+ '@jridgewell/trace-mapping@0.3.31':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.5
+
'@jridgewell/trace-mapping@0.3.9':
dependencies:
'@jridgewell/resolve-uri': 3.1.2
@@ -6351,10 +6463,17 @@ snapshots:
dependencies:
tslib: 2.6.3
+ '@types/chai@5.2.3':
+ dependencies:
+ '@types/deep-eql': 4.0.2
+ assertion-error: 2.0.1
+
'@types/debug@4.1.13':
dependencies:
'@types/ms': 2.1.0
+ '@types/deep-eql@4.0.2': {}
+
'@types/estree-jsx@1.0.5':
dependencies:
'@types/estree': 1.0.8
@@ -6424,6 +6543,17 @@ snapshots:
- rollup
- supports-color
+ '@vitest/mocker@5.0.0(vite@8.2.2(@types/node@26.2.0)(esbuild@0.28.2)(yaml@2.9.0))':
+ dependencies:
+ '@jridgewell/trace-mapping': 0.3.31
+ '@vitest/spy': 5.0.0
+ estree-walker: 3.0.3
+ magic-string: 1.2.3
+ optionalDependencies:
+ vite: 8.2.2(@types/node@26.2.0)(esbuild@0.28.2)(yaml@2.9.0)
+
+ '@vitest/spy@5.0.0': {}
+
abbrev@3.0.0: {}
acorn-import-attributes@1.9.5(acorn@8.16.0):
@@ -6479,6 +6609,8 @@ snapshots:
arrify@3.0.0: {}
+ assertion-error@2.0.1: {}
+
astring@1.9.0: {}
astro-expressive-code@0.44.1(astro@7.2.4(@astrojs/markdown-remark@7.2.4)(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)(@types/node@26.2.0)(yaml@2.9.0)):
@@ -6670,6 +6802,8 @@ snapshots:
ccount@2.0.1: {}
+ chai@6.2.2: {}
+
chalk@4.1.2:
dependencies:
ansi-styles: 4.3.0
@@ -6881,6 +7015,8 @@ snapshots:
es-module-lexer@2.1.0: {}
+ es-module-lexer@2.3.2: {}
+
es-toolkit@1.51.0: {}
esast-util-from-estree@2.0.0:
@@ -7002,6 +7138,8 @@ snapshots:
eventemitter3@5.0.4: {}
+ expect-type@1.4.0: {}
+
expressive-code@0.44.1:
dependencies:
'@expressive-code/core': 0.44.1
@@ -7041,9 +7179,9 @@ snapshots:
optionalDependencies:
picomatch: 4.0.4
- fdir@6.5.0(picomatch@4.0.5):
+ fdir@6.5.0(picomatch@4.0.7):
optionalDependencies:
- picomatch: 4.0.5
+ picomatch: 4.0.7
figures@6.1.0:
dependencies:
@@ -7491,6 +7629,10 @@ snapshots:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
+ magic-string@1.2.3:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+
magicast@0.5.3:
dependencies:
'@babel/parser': 7.29.3
@@ -8198,6 +8340,8 @@ snapshots:
picomatch@4.0.5: {}
+ picomatch@4.0.7: {}
+
pidtree@1.0.0: {}
pirates@4.0.7: {}
@@ -8613,6 +8757,8 @@ snapshots:
'@shikijs/vscode-textmate': 10.0.2
'@types/hast': 3.0.4
+ siginfo@2.0.0: {}
+
signal-exit@4.1.0: {}
sisteransi@1.0.5: {}
@@ -8645,6 +8791,10 @@ snapshots:
dependencies:
escape-string-regexp: 2.0.0
+ stackback@0.0.2: {}
+
+ std-env@4.2.0: {}
+
stream-replace-string@2.0.0: {}
string-argv@0.3.2: {}
@@ -8718,6 +8868,8 @@ snapshots:
tinybench@6.1.3: {}
+ tinybench@6.1.4: {}
+
tinyclip@0.1.12: {}
tinyexec@1.0.4: {}
@@ -8731,8 +8883,8 @@ snapshots:
tinyglobby@0.2.17:
dependencies:
- fdir: 6.5.0(picomatch@4.0.5)
- picomatch: 4.0.5
+ fdir: 6.5.0(picomatch@4.0.7)
+ picomatch: 4.0.7
tinypool@2.1.0: {}
@@ -8885,6 +9037,27 @@ snapshots:
optionalDependencies:
vite: 8.2.2(@types/node@26.2.0)(esbuild@0.28.2)(yaml@2.9.0)
+ vitest@5.0.0(@types/node@26.2.0)(vite@8.2.2(@types/node@26.2.0)(esbuild@0.28.2)(yaml@2.9.0)):
+ dependencies:
+ '@types/chai': 5.2.3
+ '@vitest/mocker': 5.0.0(vite@8.2.2(@types/node@26.2.0)(esbuild@0.28.2)(yaml@2.9.0))
+ chai: 6.2.2
+ es-module-lexer: 2.3.2
+ expect-type: 1.4.0
+ magic-string: 1.2.3
+ obug: 2.1.4
+ picomatch: 4.0.7
+ std-env: 4.2.0
+ tinybench: 6.1.4
+ tinyexec: 1.3.0
+ tinyglobby: 0.2.17
+ vite: 8.2.2(@types/node@26.2.0)(esbuild@0.28.2)(yaml@2.9.0)
+ why-is-node-running: 2.3.0
+ optionalDependencies:
+ '@types/node': 26.2.0
+ transitivePeerDependencies:
+ - msw
+
w3c-keyname@2.2.8: {}
web-namespaces@2.0.1: {}
@@ -8906,6 +9079,11 @@ snapshots:
dependencies:
isexe: 4.0.0
+ why-is-node-running@2.3.0:
+ dependencies:
+ siginfo: 2.0.0
+ stackback: 0.0.2
+
workerd@1.20260815.1:
optionalDependencies:
'@cloudflare/workerd-darwin-64': 1.20260815.1
diff --git a/website/package.json b/website/package.json
index 30dc823..937eaf9 100644
--- a/website/package.json
+++ b/website/package.json
@@ -10,7 +10,8 @@
"prebuild": "node scripts/bundle-engine.mjs",
"build": "astro build",
"preview": "astro preview",
- "astro": "astro"
+ "astro": "astro",
+ "test:unit": "vitest run"
},
"dependencies": {
"@astrojs/starlight": "0.41.7",
@@ -27,6 +28,7 @@
"devDependencies": {
"@types/lz-string": "1.5.0",
"esbuild": "0.28.2",
+ "vitest": "5.0.0",
"wrangler": "4.124.0"
},
"packageManager": "pnpm@10.33.3"
diff --git a/website/src/playground/format.test.ts b/website/src/playground/format.test.ts
new file mode 100644
index 0000000..3e8155e
--- /dev/null
+++ b/website/src/playground/format.test.ts
@@ -0,0 +1,19 @@
+import { describe, expect, it } from 'vitest';
+import { detectFormat, displayPathFor } from './format';
+
+describe('detectFormat', () => {
+ it('treats a leading brace as JSON', () => {
+ expect(detectFormat(' \n{ "openapi": "3.0.3" }')).toBe('json');
+ });
+ it('treats anything else as YAML', () => {
+ expect(detectFormat('openapi: 3.0.3')).toBe('yaml');
+ expect(detectFormat('')).toBe('yaml');
+ });
+});
+
+describe('displayPathFor', () => {
+ it('maps format to a file name with the matching extension', () => {
+ expect(displayPathFor('json')).toBe('spec.json');
+ expect(displayPathFor('yaml')).toBe('spec.yaml');
+ });
+});
diff --git a/website/src/playground/format.ts b/website/src/playground/format.ts
new file mode 100644
index 0000000..614f91e
--- /dev/null
+++ b/website/src/playground/format.ts
@@ -0,0 +1,9 @@
+export type SpecFormat = 'json' | 'yaml';
+
+export function detectFormat(source: string): SpecFormat {
+ return source.trimStart().startsWith('{') ? 'json' : 'yaml';
+}
+
+export function displayPathFor(format: SpecFormat): 'spec.json' | 'spec.yaml' {
+ return format === 'json' ? 'spec.json' : 'spec.yaml';
+}
diff --git a/website/src/playground/share.test.ts b/website/src/playground/share.test.ts
new file mode 100644
index 0000000..67689c0
--- /dev/null
+++ b/website/src/playground/share.test.ts
@@ -0,0 +1,17 @@
+import { describe, expect, it } from 'vitest';
+import { decodeShareHash, encodeShareHash } from './share';
+
+describe('share hash', () => {
+ it('round-trips a spec through the URL hash', () => {
+ const spec = 'openapi: 3.0.3\ninfo:\n title: Ünïcode & spaces\n';
+ const hash = encodeShareHash(spec);
+ expect(hash.startsWith('#spec=')).toBe(true);
+ expect(decodeShareHash(hash)).toBe(spec);
+ });
+ it('returns null for missing, foreign or corrupt hashes', () => {
+ expect(decodeShareHash('')).toBeNull();
+ expect(decodeShareHash('#section-anchor')).toBeNull();
+ expect(decodeShareHash('#spec=')).toBeNull();
+ expect(decodeShareHash('#spec=%%%not-lz%%%')).toBeNull();
+ });
+});
diff --git a/website/src/playground/share.ts b/website/src/playground/share.ts
new file mode 100644
index 0000000..c623587
--- /dev/null
+++ b/website/src/playground/share.ts
@@ -0,0 +1,16 @@
+import LZString from 'lz-string';
+
+const PREFIX = '#spec=';
+
+export function encodeShareHash(spec: string): string {
+ return PREFIX + LZString.compressToEncodedURIComponent(spec);
+}
+
+// lz-string returns '' or null for input it cannot decode; both mean "no spec".
+export function decodeShareHash(hash: string): string | null {
+ if (!hash.startsWith(PREFIX)) return null;
+ const payload = hash.slice(PREFIX.length);
+ if (payload === '') return null;
+ const decoded = LZString.decompressFromEncodedURIComponent(payload);
+ return decoded ? decoded : null;
+}
diff --git a/website/src/playground/tree.test.ts b/website/src/playground/tree.test.ts
new file mode 100644
index 0000000..4a2c1ed
--- /dev/null
+++ b/website/src/playground/tree.test.ts
@@ -0,0 +1,25 @@
+import { describe, expect, it } from 'vitest';
+import { buildTree } from './tree';
+
+const artifact = (path: string, contents = 'x') => ({ path, contents });
+
+describe('buildTree', () => {
+ it('lists root files alphabetically, then each directory with its files', () => {
+ const rows = buildTree([
+ artifact('rest/pet.rest.generated.ts', 'abc'),
+ artifact('rest.util.ts'),
+ artifact('model.generated.ts'),
+ artifact('rest/account.rest.generated.ts'),
+ ]);
+ expect(rows).toEqual([
+ { kind: 'file', path: 'model.generated.ts', name: 'model.generated.ts', depth: 0, bytes: 1 },
+ { kind: 'file', path: 'rest.util.ts', name: 'rest.util.ts', depth: 0, bytes: 1 },
+ { kind: 'dir', name: 'rest', depth: 0 },
+ { kind: 'file', path: 'rest/account.rest.generated.ts', name: 'account.rest.generated.ts', depth: 1, bytes: 1 },
+ { kind: 'file', path: 'rest/pet.rest.generated.ts', name: 'pet.rest.generated.ts', depth: 1, bytes: 3 },
+ ]);
+ });
+ it('measures bytes as UTF-8', () => {
+ expect(buildTree([artifact('a.ts', 'é')])[0]).toMatchObject({ bytes: 2 });
+ });
+});
diff --git a/website/src/playground/tree.ts b/website/src/playground/tree.ts
new file mode 100644
index 0000000..8ed1839
--- /dev/null
+++ b/website/src/playground/tree.ts
@@ -0,0 +1,68 @@
+export interface Artifact {
+ path: string;
+ contents: string;
+}
+
+export type TreeRow =
+ | { kind: 'dir'; name: string; depth: 0 }
+ | { kind: 'file'; path: string; name: string; depth: 0 | 1; bytes: number };
+
+const encoder = new TextEncoder();
+
+export function buildTree(artifacts: ReadonlyArray): TreeRow[] {
+ const root: TreeRow[] = [];
+ const dirs = new Map();
+ for (const artifact of artifacts) {
+ const slash = artifact.path.indexOf('/');
+ const bytes = encoder.encode(artifact.contents).length;
+ if (slash === -1) {
+ root.push({ kind: 'file', path: artifact.path, name: artifact.path, depth: 0, bytes });
+ continue;
+ }
+ const dir = artifact.path.slice(0, slash);
+ const name = artifact.path.slice(slash + 1);
+ const rows = dirs.get(dir) ?? [];
+ rows.push({ kind: 'file', path: artifact.path, name, depth: 1, bytes });
+ dirs.set(dir, rows);
+ }
+ const byName = (a: { name: string }, b: { name: string }) => a.name.localeCompare(b.name);
+ root.sort(byName);
+ for (const dir of [...dirs.keys()].sort()) {
+ root.push({ kind: 'dir', name: dir, depth: 0 });
+ root.push(...(dirs.get(dir) ?? []).sort(byName));
+ }
+ return root;
+}
+
+function formatBytes(bytes: number): string {
+ return bytes < 1024 ? `${bytes} B` : `${(bytes / 1024).toFixed(1)} kB`;
+}
+
+export function renderTree(
+ container: HTMLElement,
+ rows: TreeRow[],
+ selectedPath: string | null,
+ onSelect: (path: string) => void,
+): void {
+ const list = document.createElement('ul');
+ for (const row of rows) {
+ const item = document.createElement('li');
+ item.dataset.depth = String(row.depth);
+ if (row.kind === 'dir') {
+ item.className = 'is-dir';
+ item.textContent = `${row.name}/`;
+ } else {
+ item.dataset.path = row.path;
+ if (row.path === selectedPath) item.className = 'is-selected';
+ const name = document.createElement('span');
+ name.textContent = row.name;
+ const size = document.createElement('span');
+ size.className = 'size';
+ size.textContent = formatBytes(row.bytes);
+ item.append(name, size);
+ item.addEventListener('click', () => onSelect(row.path));
+ }
+ list.append(item);
+ }
+ container.replaceChildren(list);
+}
diff --git a/website/vitest.config.ts b/website/vitest.config.ts
new file mode 100644
index 0000000..96eb6ab
--- /dev/null
+++ b/website/vitest.config.ts
@@ -0,0 +1,8 @@
+import { defineConfig } from 'vitest/config';
+
+export default defineConfig({
+ test: {
+ include: ['src/**/*.test.ts'],
+ environment: 'node',
+ },
+});
From 5941328ac58c6ab3e2c8e9b1b003e7fb41c798e3 Mon Sep 17 00:00:00 2001
From: pkurcx
Date: Thu, 3 Sep 2026 19:39:10 +0200
Subject: [PATCH 03/17] feat(website): interactive playground backed by the
WebAssembly generator
Co-Authored-By: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_011t8uBVY6h4kfN5cXHXuCpR
---
.github/workflows/docs.yml | 3 +
pnpm-lock.yaml | 558 +++++++++++++++++++++++++-
stackblitz/petstore.openapi.yaml | 146 +++++++
website/astro.config.mjs | 35 ++
website/package.json | 5 +-
website/src/pages/playground.astro | 1 +
website/src/playground/editor.ts | 54 +++
website/src/playground/generator.ts | 23 ++
website/src/playground/hljs-theme.css | 236 +++++++++++
website/src/playground/main.ts | 169 +++++++-
website/src/playground/output.ts | 15 +
website/src/playground/playground.css | 31 +-
website/src/playground/tree.ts | 27 +-
website/tsconfig.json | 2 +-
14 files changed, 1274 insertions(+), 31 deletions(-)
create mode 100644 stackblitz/petstore.openapi.yaml
create mode 100644 website/src/playground/editor.ts
create mode 100644 website/src/playground/generator.ts
create mode 100644 website/src/playground/hljs-theme.css
create mode 100644 website/src/playground/output.ts
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index 9104f4c..fd265cc 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -40,6 +40,9 @@ jobs:
- name: Build site
working-directory: website
run: pnpm build
+ - name: Type-check
+ working-directory: website
+ run: pnpm check
- name: Deploy to production
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
uses: cloudflare/wrangler-action@v3
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 4fd087b..3310fd0 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -112,6 +112,9 @@ importers:
'@codemirror/lang-yaml':
specifier: 6.1.3
version: 6.1.3
+ '@codemirror/state':
+ specifier: 6.7.2
+ version: 6.7.2
astro:
specifier: 7.2.4
version: 7.2.4(@astrojs/markdown-remark@7.2.4)(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)(@types/node@26.2.0)(yaml@2.9.0)
@@ -128,12 +131,15 @@ importers:
specifier: 0.35.3
version: 0.35.3(@types/node@26.2.0)
devDependencies:
- '@types/lz-string':
- specifier: 1.5.0
- version: 1.5.0
+ '@astrojs/check':
+ specifier: 0.9.10
+ version: 0.9.10(prettier@3.9.6)(typescript@6.0.3)
esbuild:
specifier: 0.28.2
version: 0.28.2
+ typescript:
+ specifier: 6.0.3
+ version: 6.0.3
vitest:
specifier: 5.0.0
version: 5.0.0(@types/node@26.2.0)(vite@8.2.2(@types/node@26.2.0)(esbuild@0.28.2)(yaml@2.9.0))
@@ -183,6 +189,12 @@ packages:
'@angular/animations':
optional: true
+ '@astrojs/check@0.9.10':
+ resolution: {integrity: sha512-zgx/UQMozdjOa3bOxjgeCFdtpE3c9rRX6xHwa+2QXvy8z8Akifu2AtubHyv/zzC2znO8dl8fFWL4K+Ba9kS8HQ==}
+ hasBin: true
+ peerDependencies:
+ typescript: ^5.0.0 || ^6.0.0
+
'@astrojs/compiler-binding-darwin-arm64@0.3.2':
resolution: {integrity: sha512-MM8tn8CSimcfytaOla4b6acN8mKWiL/rlAA1fpT3/Wl7dNGSE4y8FjTN/zJVNnb63CsLWG5zZwCt01TXtDKh9g==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -248,9 +260,24 @@ packages:
resolution: {integrity: sha512-xlx/T7JovIKduu4ucbTQUxQ5+Q8wxkHxhLjnZk3VlJbhbQ9RLvvuDk1p2YYFYFQ5y14dVm3FGGO4isQXa4F+Tg==}
engines: {node: '>=22.12.0'}
+ '@astrojs/compiler@2.13.1':
+ resolution: {integrity: sha512-f3FN83d2G/v32ipNClRKgYv30onQlMZX1vCeZMjPsMMPl1mDpmbl0+N5BYo4S/ofzqJyS5hvwacEo0CCVDn/Qg==}
+
'@astrojs/internal-helpers@0.10.4':
resolution: {integrity: sha512-nozZSy/mKYLqe4YrqbKtdOszedAfXYCtw3wZ0d+CAjz4GqQ4L9rl1ltIL5BlgwmYVinJg/RZ0MgGuWOdlyRZlA==}
+ '@astrojs/language-server@2.16.16':
+ resolution: {integrity: sha512-KuS17AOOqH/M5mHXPmKvtp8L+NNteARC7Xjf395+9R9dtJOBndqdStwU4V+OKzYZpgZ+hliV13knzx/oMtFl7Q==}
+ hasBin: true
+ peerDependencies:
+ prettier: ^3.0.0
+ prettier-plugin-astro: '>=0.11.0'
+ peerDependenciesMeta:
+ prettier:
+ optional: true
+ prettier-plugin-astro:
+ optional: true
+
'@astrojs/markdown-remark@7.2.4':
resolution: {integrity: sha512-MvspGMynWKAjTe4/lTUdmBPHIFKNVLTCF6UlyWGogTGzNrTvjD+D4n48k7h8swxsEPKHK2TwxkZO7uoaCv1Pow==}
@@ -287,6 +314,9 @@ packages:
resolution: {integrity: sha512-C1TLn5sPJr0x4vk56piHWKbnqlEB8BKyte5Y45V02U+D7BGO5eMqZDH5aPjnkXQWJggvmsTXxH03QMZ9NgWLzQ==}
engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0}
+ '@astrojs/yaml2ts@0.2.4':
+ resolution: {integrity: sha512-8oddpOae35pJsXPQXhTkM0ypfKPskVsh2bCxRtbf7e+/Epw2nReakFYpLKjZMEr75CsoF203PMnCocpfz0s69A==}
+
'@avsystem/openapi-ng-darwin-arm64@0.5.1':
resolution: {integrity: sha512-eRkWjsVRQmMcbcVy0uqDhrT1rBUmKemnHIO5gyy+c9nahJTZgb2MUK4uACMnan8z9k9HFTHoa6htbJKxAdqF8Q==}
engines: {node: '>=22.12.0'}
@@ -571,6 +601,27 @@ packages:
resolution: {integrity: sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==}
engines: {node: '>=14'}
+ '@emmetio/abbreviation@2.3.3':
+ resolution: {integrity: sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA==}
+
+ '@emmetio/css-abbreviation@2.1.8':
+ resolution: {integrity: sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw==}
+
+ '@emmetio/css-parser@0.4.1':
+ resolution: {integrity: sha512-2bC6m0MV/voF4CTZiAbG5MWKbq5EBmDPKu9Sb7s7nVcEzNQlrZP6mFFFlIaISM8X6514H9shWMme1fCm8cWAfQ==}
+
+ '@emmetio/html-matcher@1.3.0':
+ resolution: {integrity: sha512-NTbsvppE5eVyBMuyGfVu2CRrLvo7J4YHb6t9sBFLyY03WYhXET37qA4zOYUjBWFCRHO7pS1B9khERtY0f5JXPQ==}
+
+ '@emmetio/scanner@1.0.4':
+ resolution: {integrity: sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA==}
+
+ '@emmetio/stream-reader-utils@0.1.0':
+ resolution: {integrity: sha512-ZsZ2I9Vzso3Ho/pjZFsmmZ++FWeEd/txqybHTm4OgaZzdS8V9V/YYWQwg5TC38Z7uLWUV1vavpLLbjJtKubR1A==}
+
+ '@emmetio/stream-reader@2.2.0':
+ resolution: {integrity: sha512-fXVXEyFA5Yv3M3n8sUGT7+fvecGrZP4k6FnWWMSZVQf69kAq0LLpaBQLGcPR30m3zMmKYhECP4k/ZkzvhEW5kw==}
+
'@emnapi/core@1.11.3':
resolution: {integrity: sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg==}
@@ -2538,10 +2589,6 @@ packages:
'@types/js-yaml@4.0.9':
resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==}
- '@types/lz-string@1.5.0':
- resolution: {integrity: sha512-s84fKOrzqqNCAPljhVyC5TjAo6BH4jKHw9NRNFNiRUY5QSgZCmVm5XILlWbisiKl+0OcS7eWihmKGS5akc2iQw==}
- deprecated: This is a stub types definition. lz-string provides its own type definitions, so you do not need this installed.
-
'@types/mdast@4.0.4':
resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
@@ -2591,6 +2638,32 @@ packages:
'@vitest/spy@5.0.0':
resolution: {integrity: sha512-uy+luWBAPw9XfthoHi5AkfHUnuPYEESjl0p/r+meoBnU8bxg5GDQ3Ey8MjcJ6sqahkL4PFyrvfMJJBw7LbU06g==}
+ '@volar/kit@2.4.28':
+ resolution: {integrity: sha512-cKX4vK9dtZvDRaAzeoUdaAJEew6IdxHNCRrdp5Kvcl6zZOqb6jTOfk3kXkIkG3T7oTFXguEMt5+9ptyqYR84Pg==}
+ peerDependencies:
+ typescript: '*'
+
+ '@volar/language-core@2.4.28':
+ resolution: {integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==}
+
+ '@volar/language-server@2.4.28':
+ resolution: {integrity: sha512-NqcLnE5gERKuS4PUFwlhMxf6vqYo7hXtbMFbViXcbVkbZ905AIVWhnSo0ZNBC2V127H1/2zP7RvVOVnyITFfBw==}
+
+ '@volar/language-service@2.4.28':
+ resolution: {integrity: sha512-Rh/wYCZJrI5vCwMk9xyw/Z+MsWxlJY1rmMZPsxUoJKfzIRjS/NF1NmnuEcrMbEVGja00aVpCsInJfixQTMdvLw==}
+
+ '@volar/source-map@2.4.28':
+ resolution: {integrity: sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==}
+
+ '@volar/typescript@2.4.28':
+ resolution: {integrity: sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==}
+
+ '@vscode/emmet-helper@2.11.0':
+ resolution: {integrity: sha512-QLxjQR3imPZPQltfbWRnHU6JecWTF1QSWhx3GAKQpslx7y3Dp6sIIXhKjiUJ/BR9FX8PVthjr9PD6pNwOJfAzw==}
+
+ '@vscode/l10n@0.0.18':
+ resolution: {integrity: sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==}
+
abbrev@3.0.0:
resolution: {integrity: sha512-+/kfrslGQ7TNV2ecmQwMJj/B65g5KVq1/L3SGVZ3tCYGqlzFuFCGBZJtMP99wH3NpEUyAjn0zPdPUg0D+DwrOA==}
engines: {node: ^18.17.0 || >=20.5.0}
@@ -2618,6 +2691,22 @@ packages:
resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==}
engines: {node: '>= 14'}
+ ajv-draft-04@1.0.0:
+ resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==}
+ peerDependencies:
+ ajv: ^8.5.0
+ peerDependenciesMeta:
+ ajv:
+ optional: true
+
+ ajv-i18n@4.2.0:
+ resolution: {integrity: sha512-v/ei2UkCEeuKNXh8RToiFsUclmU+G57LO1Oo22OagNMENIw+Yb8eMwvHu7Vn9fmkjJyv6XclhJ8TbuigSglPkg==}
+ peerDependencies:
+ ajv: ^8.0.0-beta.0
+
+ ajv@8.20.0:
+ resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==}
+
am-i-vibing@0.4.0:
resolution: {integrity: sha512-MxT4XZL7pzLHpuvhDKdMaQHMGGkJDLluKBLsbstn+8wv9sWcFT6h+0ve9qkml95amVTZtZV83gQe2hY+ojgHLg==}
hasBin: true
@@ -2784,6 +2873,10 @@ packages:
chardet@2.1.1:
resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==}
+ chokidar@4.0.3:
+ resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
+ engines: {node: '>= 14.16.0'}
+
chokidar@5.0.0:
resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==}
engines: {node: '>= 20.19.0'}
@@ -2990,6 +3083,9 @@ packages:
resolution: {integrity: sha512-FLtgn/CGBXiX3ZtPAm5q4LWWepHChOt55J9u01WFu3dyap2U7IwptlrqoE1COR/kxwdy/DOxIBALSxIW449I1g==}
engines: {node: '>=22'}
+ emmet@2.4.11:
+ resolution: {integrity: sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ==}
+
emnapi@1.11.3:
resolution: {integrity: sha512-+/ZS90YK/rYfVOHtGLHkGffVsnmD/MAKaBHio+Y4XAtg75RLr4cveV/w0jTkUdLM1CcAlaRgG76mpIemWAlk0A==}
peerDependencies:
@@ -3098,6 +3194,9 @@ packages:
fast-content-type-parse@3.0.0:
resolution: {integrity: sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==}
+ fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+
fast-diff@1.3.0:
resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==}
@@ -3111,6 +3210,9 @@ packages:
fast-string-width@3.0.2:
resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==}
+ fast-uri@3.1.7:
+ resolution: {integrity: sha512-dOvZVzjdZdz7phd9v6jCbwxrBW3fK6n8Rc0CtdmM4bumzMnxywBYhuph6J819RRw/ku+rLbelwfMunktuzVVHg==}
+
fast-wrap-ansi@0.2.0:
resolution: {integrity: sha512-rLV8JHxTyhVmFYhBJuMujcrHqOT2cnO5Zxj37qROj23CP39GXubJRBUFF0z8KFK77Uc0SukZUf7JZhsVEQ6n8w==}
@@ -3396,9 +3498,15 @@ packages:
resolution: {integrity: sha512-2/8adwnK1/+Fdjyts4r6wSpfANWw8zdNhU9U/Llk59c6O+DjSisPWPykwoL8gZmocP9Dy64S7oie2g+Mia123A==}
engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0}
+ json-schema-traverse@1.0.0:
+ resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
+
json-with-bigint@3.5.7:
resolution: {integrity: sha512-7ei3MdAI5+fJPVnKlW77TKNKwQ5ppSzWvhPuSuINT/GYW9ZOC1eRKOuhV9yHG5aEsUPj9BBx5JIekkmoLHxZOw==}
+ jsonc-parser@2.3.1:
+ resolution: {integrity: sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==}
+
jsonc-parser@3.3.1:
resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==}
@@ -3749,6 +3857,9 @@ packages:
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+ muggle-string@0.4.1:
+ resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==}
+
mute-stream@3.0.0:
resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==}
engines: {node: ^20.17.0 || >=22.9.0}
@@ -3895,6 +4006,9 @@ packages:
parse5@7.3.0:
resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==}
+ path-browserify@1.0.1:
+ resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
+
path-key@3.1.1:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
@@ -3962,6 +4076,11 @@ packages:
resolution: {integrity: sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==}
engines: {node: ^10 || ^12 || >=14}
+ prettier@3.9.6:
+ resolution: {integrity: sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==}
+ engines: {node: '>=14'}
+ hasBin: true
+
pretty-ms@9.3.0:
resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==}
engines: {node: '>=18'}
@@ -3987,6 +4106,10 @@ packages:
resolution: {integrity: sha512-PNaGjoCnw9DBA2Kl8D+8po957z778q/HOPuY2u3Bkw/JO3eC8MDx7jn/PgMtSgpcBbs+6UOjDbwReGpXmRvs0g==}
engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0}
+ readdirp@4.1.2:
+ resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
+ engines: {node: '>= 14.18.0'}
+
readdirp@5.0.0:
resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==}
engines: {node: '>= 20.19.0'}
@@ -4057,6 +4180,16 @@ packages:
remark-stringify@11.0.0:
resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
+ request-light@0.5.8:
+ resolution: {integrity: sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg==}
+
+ request-light@0.7.0:
+ resolution: {integrity: sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q==}
+
+ require-from-string@2.0.2:
+ resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
+ engines: {node: '>=0.10.0'}
+
resolve-cwd@3.0.0:
resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==}
engines: {node: '>=8'}
@@ -4325,6 +4458,12 @@ packages:
resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==}
engines: {node: '>=10'}
+ typesafe-path@0.2.2:
+ resolution: {integrity: sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA==}
+
+ typescript-auto-import-cache@0.3.6:
+ resolution: {integrity: sha512-RpuHXrknHdVdK7wv/8ug3Fr0WNsNi5l5aB8MYYuXhq2UH5lnEB1htJ1smhtD5VeCsGr2p8mUDtd83LCQDFVgjQ==}
+
typescript@6.0.3:
resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==}
engines: {node: '>=14.17'}
@@ -4569,6 +4708,108 @@ packages:
jsdom:
optional: true
+ volar-service-css@0.0.71:
+ resolution: {integrity: sha512-wRRFt9BpjMKCazcgOh67MSjUjiWUCAh99DyYSDIOTuxaRjEtDC7PpB0k1Y1wbJIW/pVtMUSVbpPo3UGSm0Byxw==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ volar-service-emmet@0.0.71:
+ resolution: {integrity: sha512-zqjzt6bN95e3CUstBm0PBFAJnrfz0ZAARka87fart46/gNCLLuP3Vujy8V/J8HEziTFLnfkgIASLFYPUhonJcA==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ volar-service-html@0.0.71:
+ resolution: {integrity: sha512-e8tHPhgQ7ooLfudAEIku+kgd9pWkq3SSz8RbnQDI1+Eb8wbenkLGHqoirLqz5ORLV6wIMr2Iv08RWBG5eOcgpw==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ volar-service-prettier@0.0.71:
+ resolution: {integrity: sha512-Rz7JVH3qD108UCdmIEiZvOBNljMt2nLFdbN8AXcDfn7xD9F5I2aCIsDVqBbXw21PsnxG0b7MfwtNF+zPS/NKUg==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ prettier: ^2.2 || ^3.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+ prettier:
+ optional: true
+
+ volar-service-typescript-twoslash-queries@0.0.71:
+ resolution: {integrity: sha512-9K2k72s4n7rV9s4bX0MyjbX9iBribvKZbBJKuEmTCZfeWJXs6Yh7bGpY4eoc7UufAjvpheBqwyZCOIPBvxCv0A==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ volar-service-typescript@0.0.71:
+ resolution: {integrity: sha512-yTtM/BVT6hoyEYnDtaCyAtNhdNeS/mhTTABlBOdw3NNiRBUin3IznFJpgfjer4c6RYopiPjjQjc9VFhxVl1mLw==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ volar-service-yaml@0.0.71:
+ resolution: {integrity: sha512-qYGWGuVpUTnZGu5P/CR4KLK4aIR8RrcVnmfZ2eRcj9q/I8VZCoC5yy9FtEvfNvnDp4MU17yhdJcvpQPIqhJS2Q==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ vscode-css-languageservice@6.3.10:
+ resolution: {integrity: sha512-eq5N9Er3fC4vA9zd9EFhyBG90wtCCuXgRSpAndaOgXMh1Wgep5lBgRIeDgjZBW9pa+332yC9+49cZMW8jcL3MA==}
+
+ vscode-html-languageservice@5.6.2:
+ resolution: {integrity: sha512-ulCrSnFnfQ16YzvwnYUgEbUEl/ZG7u2eV27YhvLObSHKkb8fw1Z9cgsnUwjTEeDIdJDoTDTDpxuhQwoenoLNMg==}
+
+ vscode-json-languageservice@4.1.8:
+ resolution: {integrity: sha512-0vSpg6Xd9hfV+eZAaYN63xVVMOTmJ4GgHxXnkLCh+9RsQBkWKIghzLhW2B9ebfG+LQQg8uLtsQ2aUKjTgE+QOg==}
+ engines: {npm: '>=7.0.0'}
+
+ vscode-jsonrpc@8.2.0:
+ resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==}
+ engines: {node: '>=14.0.0'}
+
+ vscode-jsonrpc@9.0.2:
+ resolution: {integrity: sha512-SbQSV9yRemARxeXw6LU5sS6Zq0e9/DgCCX5yelH263ZQWukbTk8EF8fjTrr1dziasf4GwlJbvTwFnTrnQFWZXQ==}
+ engines: {node: '>=14.0.0'}
+
+ vscode-languageserver-protocol@3.17.5:
+ resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==}
+
+ vscode-languageserver-protocol@3.18.3:
+ resolution: {integrity: sha512-DF49+WeV5py4zO5hhobp60jjsDSK0lAqA0OuKBLBvp423HPWQcCbhZz3JgyfIewsEz2f8U+X75xNIFHdiXZm2w==}
+
+ vscode-languageserver-textdocument@1.0.14:
+ resolution: {integrity: sha512-EQyqJMi552E4ZTf46izQ4Fj6XquqxCySR3J5ZSD1SisMf6RfpeOWHxGBE8Gr6V0/3GHIGdAzDn8F8+1nTGCnoQ==}
+
+ vscode-languageserver-types@3.17.5:
+ resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==}
+
+ vscode-languageserver-types@3.18.3:
+ resolution: {integrity: sha512-XIlzJ7Qp/jzSI1ds7/FwPAWrPeTZA7pAtlW4hdJ1J6xXWJL6dR9QYnDhJOdLzdKhUQ5Mm6mvUMw+3DcOQQasPw==}
+
+ vscode-languageserver@9.0.1:
+ resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==}
+ hasBin: true
+
+ vscode-nls@5.2.0:
+ resolution: {integrity: sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==}
+
+ vscode-uri@3.2.0:
+ resolution: {integrity: sha512-m2gXo3bn0G1kT9InzMf07fTbqMbGtyckj3bH5ktLO+1Ssv+yiATZ4dhwaQv9UZWxJh6E9IFGnQyjgWVDWVBDrg==}
+
w3c-keyname@2.2.8:
resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==}
@@ -4646,6 +4887,15 @@ packages:
resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==}
engines: {node: '>=18'}
+ yaml-language-server@1.23.0:
+ resolution: {integrity: sha512-3qVyCOexLCWw06PQa5kRPwvMWMZ/eZeCRWUvgD6a0OkqL/4iCnxy2WumbWifa937Uo5xhyWJ0uxlU39ljhNh7A==}
+ hasBin: true
+
+ yaml@2.8.3:
+ resolution: {integrity: sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==}
+ engines: {node: '>= 14.6'}
+ hasBin: true
+
yaml@2.9.0:
resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==}
engines: {node: '>= 14.6'}
@@ -4704,6 +4954,17 @@ snapshots:
'@angular/core': 22.1.3(rxjs@7.8.2)
tslib: 2.6.3
+ '@astrojs/check@0.9.10(prettier@3.9.6)(typescript@6.0.3)':
+ dependencies:
+ '@astrojs/language-server': 2.16.16(prettier@3.9.6)(typescript@6.0.3)
+ chokidar: 4.0.3
+ kleur: 4.1.5
+ typescript: 6.0.3
+ yargs: 18.0.0
+ transitivePeerDependencies:
+ - prettier
+ - prettier-plugin-astro
+
'@astrojs/compiler-binding-darwin-arm64@0.3.2':
optional: true
@@ -4758,6 +5019,8 @@ snapshots:
- '@emnapi/core'
- '@emnapi/runtime'
+ '@astrojs/compiler@2.13.1': {}
+
'@astrojs/internal-helpers@0.10.4':
dependencies:
'@types/hast': 3.0.4
@@ -4769,6 +5032,31 @@ snapshots:
smol-toml: 1.6.1
unified: 11.0.5
+ '@astrojs/language-server@2.16.16(prettier@3.9.6)(typescript@6.0.3)':
+ dependencies:
+ '@astrojs/compiler': 2.13.1
+ '@astrojs/yaml2ts': 0.2.4
+ '@jridgewell/sourcemap-codec': 1.5.5
+ '@volar/kit': 2.4.28(typescript@6.0.3)
+ '@volar/language-core': 2.4.28
+ '@volar/language-server': 2.4.28
+ '@volar/language-service': 2.4.28
+ muggle-string: 0.4.1
+ tinyglobby: 0.2.17
+ volar-service-css: 0.0.71(@volar/language-service@2.4.28)
+ volar-service-emmet: 0.0.71(@volar/language-service@2.4.28)
+ volar-service-html: 0.0.71(@volar/language-service@2.4.28)
+ volar-service-prettier: 0.0.71(@volar/language-service@2.4.28)(prettier@3.9.6)
+ volar-service-typescript: 0.0.71(@volar/language-service@2.4.28)
+ volar-service-typescript-twoslash-queries: 0.0.71(@volar/language-service@2.4.28)
+ volar-service-yaml: 0.0.71(@volar/language-service@2.4.28)
+ vscode-html-languageservice: 5.6.2
+ vscode-uri: 3.2.0
+ optionalDependencies:
+ prettier: 3.9.6
+ transitivePeerDependencies:
+ - typescript
+
'@astrojs/markdown-remark@7.2.4':
dependencies:
'@astrojs/internal-helpers': 0.10.4
@@ -4875,6 +5163,10 @@ snapshots:
is-docker: 4.0.0
package-manager-detector: 1.6.0
+ '@astrojs/yaml2ts@0.2.4':
+ dependencies:
+ yaml: 2.9.0
+
'@avsystem/openapi-ng-darwin-arm64@0.5.1':
optional: true
@@ -5105,6 +5397,29 @@ snapshots:
'@ctrl/tinycolor@4.2.0': {}
+ '@emmetio/abbreviation@2.3.3':
+ dependencies:
+ '@emmetio/scanner': 1.0.4
+
+ '@emmetio/css-abbreviation@2.1.8':
+ dependencies:
+ '@emmetio/scanner': 1.0.4
+
+ '@emmetio/css-parser@0.4.1':
+ dependencies:
+ '@emmetio/stream-reader': 2.2.0
+ '@emmetio/stream-reader-utils': 0.1.0
+
+ '@emmetio/html-matcher@1.3.0':
+ dependencies:
+ '@emmetio/scanner': 1.0.4
+
+ '@emmetio/scanner@1.0.4': {}
+
+ '@emmetio/stream-reader-utils@0.1.0': {}
+
+ '@emmetio/stream-reader@2.2.0': {}
+
'@emnapi/core@1.11.3':
dependencies:
'@emnapi/wasi-threads': 1.2.3
@@ -6490,10 +6805,6 @@ snapshots:
'@types/js-yaml@4.0.9': {}
- '@types/lz-string@1.5.0':
- dependencies:
- lz-string: 1.5.0
-
'@types/mdast@4.0.4':
dependencies:
'@types/unist': 3.0.3
@@ -6554,6 +6865,56 @@ snapshots:
'@vitest/spy@5.0.0': {}
+ '@volar/kit@2.4.28(typescript@6.0.3)':
+ dependencies:
+ '@volar/language-service': 2.4.28
+ '@volar/typescript': 2.4.28
+ typesafe-path: 0.2.2
+ typescript: 6.0.3
+ vscode-languageserver-textdocument: 1.0.14
+ vscode-uri: 3.2.0
+
+ '@volar/language-core@2.4.28':
+ dependencies:
+ '@volar/source-map': 2.4.28
+
+ '@volar/language-server@2.4.28':
+ dependencies:
+ '@volar/language-core': 2.4.28
+ '@volar/language-service': 2.4.28
+ '@volar/typescript': 2.4.28
+ path-browserify: 1.0.1
+ request-light: 0.7.0
+ vscode-languageserver: 9.0.1
+ vscode-languageserver-protocol: 3.18.3
+ vscode-languageserver-textdocument: 1.0.14
+ vscode-uri: 3.2.0
+
+ '@volar/language-service@2.4.28':
+ dependencies:
+ '@volar/language-core': 2.4.28
+ vscode-languageserver-protocol: 3.18.3
+ vscode-languageserver-textdocument: 1.0.14
+ vscode-uri: 3.2.0
+
+ '@volar/source-map@2.4.28': {}
+
+ '@volar/typescript@2.4.28':
+ dependencies:
+ '@volar/language-core': 2.4.28
+ path-browserify: 1.0.1
+ vscode-uri: 3.2.0
+
+ '@vscode/emmet-helper@2.11.0':
+ dependencies:
+ emmet: 2.4.11
+ jsonc-parser: 2.3.1
+ vscode-languageserver-textdocument: 1.0.14
+ vscode-languageserver-types: 3.18.3
+ vscode-uri: 3.2.0
+
+ '@vscode/l10n@0.0.18': {}
+
abbrev@3.0.0: {}
acorn-import-attributes@1.9.5(acorn@8.16.0):
@@ -6572,6 +6933,21 @@ snapshots:
agent-base@7.1.3: {}
+ ajv-draft-04@1.0.0(ajv@8.20.0):
+ optionalDependencies:
+ ajv: 8.20.0
+
+ ajv-i18n@4.2.0(ajv@8.20.0):
+ dependencies:
+ ajv: 8.20.0
+
+ ajv@8.20.0:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-uri: 3.1.7
+ json-schema-traverse: 1.0.0
+ require-from-string: 2.0.2
+
am-i-vibing@0.4.0:
dependencies:
process-ancestry: 0.1.0
@@ -6821,6 +7197,10 @@ snapshots:
chardet@2.1.1: {}
+ chokidar@4.0.3:
+ dependencies:
+ readdirp: 4.1.2
+
chokidar@5.0.0:
dependencies:
readdirp: 5.0.0
@@ -7003,6 +7383,11 @@ snapshots:
emittery@2.0.0: {}
+ emmet@2.4.11:
+ dependencies:
+ '@emmetio/abbreviation': 2.3.3
+ '@emmetio/css-abbreviation': 2.1.8
+
emnapi@1.11.3: {}
emoji-regex@10.3.0: {}
@@ -7151,6 +7536,8 @@ snapshots:
fast-content-type-parse@3.0.0: {}
+ fast-deep-equal@3.1.3: {}
+
fast-diff@1.3.0: {}
fast-glob@3.3.3:
@@ -7167,6 +7554,8 @@ snapshots:
dependencies:
fast-string-truncated-width: 3.0.3
+ fast-uri@3.1.7: {}
+
fast-wrap-ansi@0.2.0:
dependencies:
fast-string-width: 3.0.2
@@ -7544,8 +7933,12 @@ snapshots:
json-parse-even-better-errors@6.0.0: {}
+ json-schema-traverse@1.0.0: {}
+
json-with-bigint@3.5.7: {}
+ jsonc-parser@2.3.1: {}
+
jsonc-parser@3.3.1: {}
kleur@4.1.5: {}
@@ -8153,6 +8546,8 @@ snapshots:
ms@2.1.3: {}
+ muggle-string@0.4.1: {}
+
mute-stream@3.0.0: {}
nanoid@3.3.12: {}
@@ -8319,6 +8714,8 @@ snapshots:
dependencies:
entities: 6.0.1
+ path-browserify@1.0.1: {}
+
path-key@3.1.1: {}
path-scurry@2.0.2:
@@ -8372,6 +8769,8 @@ snapshots:
picocolors: 1.1.1
source-map-js: 1.2.1
+ prettier@3.9.6: {}
+
pretty-ms@9.3.0:
dependencies:
parse-ms: 4.0.0
@@ -8391,6 +8790,8 @@ snapshots:
json-parse-even-better-errors: 6.0.0
npm-normalize-package-bin: 6.0.0
+ readdirp@4.1.2: {}
+
readdirp@5.0.0: {}
recma-build-jsx@1.0.0:
@@ -8531,6 +8932,12 @@ snapshots:
mdast-util-to-markdown: 2.1.2
unified: 11.0.5
+ request-light@0.5.8: {}
+
+ request-light@0.7.0: {}
+
+ require-from-string@2.0.2: {}
+
resolve-cwd@3.0.0:
dependencies:
resolve-from: 5.0.0
@@ -8904,6 +9311,12 @@ snapshots:
type-fest@0.13.1: {}
+ typesafe-path@0.2.2: {}
+
+ typescript-auto-import-cache@0.3.6:
+ dependencies:
+ semver: 7.8.5
+
typescript@6.0.3: {}
ufo@1.6.4: {}
@@ -9058,6 +9471,112 @@ snapshots:
transitivePeerDependencies:
- msw
+ volar-service-css@0.0.71(@volar/language-service@2.4.28):
+ dependencies:
+ vscode-css-languageservice: 6.3.10
+ vscode-languageserver-textdocument: 1.0.14
+ vscode-uri: 3.2.0
+ optionalDependencies:
+ '@volar/language-service': 2.4.28
+
+ volar-service-emmet@0.0.71(@volar/language-service@2.4.28):
+ dependencies:
+ '@emmetio/css-parser': 0.4.1
+ '@emmetio/html-matcher': 1.3.0
+ '@vscode/emmet-helper': 2.11.0
+ vscode-uri: 3.2.0
+ optionalDependencies:
+ '@volar/language-service': 2.4.28
+
+ volar-service-html@0.0.71(@volar/language-service@2.4.28):
+ dependencies:
+ vscode-html-languageservice: 5.6.2
+ vscode-languageserver-textdocument: 1.0.14
+ vscode-uri: 3.2.0
+ optionalDependencies:
+ '@volar/language-service': 2.4.28
+
+ volar-service-prettier@0.0.71(@volar/language-service@2.4.28)(prettier@3.9.6):
+ dependencies:
+ vscode-uri: 3.2.0
+ optionalDependencies:
+ '@volar/language-service': 2.4.28
+ prettier: 3.9.6
+
+ volar-service-typescript-twoslash-queries@0.0.71(@volar/language-service@2.4.28):
+ dependencies:
+ vscode-uri: 3.2.0
+ optionalDependencies:
+ '@volar/language-service': 2.4.28
+
+ volar-service-typescript@0.0.71(@volar/language-service@2.4.28):
+ dependencies:
+ path-browserify: 1.0.1
+ semver: 7.8.5
+ typescript-auto-import-cache: 0.3.6
+ vscode-languageserver-textdocument: 1.0.14
+ vscode-nls: 5.2.0
+ vscode-uri: 3.2.0
+ optionalDependencies:
+ '@volar/language-service': 2.4.28
+
+ volar-service-yaml@0.0.71(@volar/language-service@2.4.28):
+ dependencies:
+ vscode-uri: 3.2.0
+ yaml-language-server: 1.23.0
+ optionalDependencies:
+ '@volar/language-service': 2.4.28
+
+ vscode-css-languageservice@6.3.10:
+ dependencies:
+ '@vscode/l10n': 0.0.18
+ vscode-languageserver-textdocument: 1.0.14
+ vscode-languageserver-types: 3.17.5
+ vscode-uri: 3.2.0
+
+ vscode-html-languageservice@5.6.2:
+ dependencies:
+ '@vscode/l10n': 0.0.18
+ vscode-languageserver-textdocument: 1.0.14
+ vscode-languageserver-types: 3.18.3
+ vscode-uri: 3.2.0
+
+ vscode-json-languageservice@4.1.8:
+ dependencies:
+ jsonc-parser: 3.3.1
+ vscode-languageserver-textdocument: 1.0.14
+ vscode-languageserver-types: 3.18.3
+ vscode-nls: 5.2.0
+ vscode-uri: 3.2.0
+
+ vscode-jsonrpc@8.2.0: {}
+
+ vscode-jsonrpc@9.0.2: {}
+
+ vscode-languageserver-protocol@3.17.5:
+ dependencies:
+ vscode-jsonrpc: 8.2.0
+ vscode-languageserver-types: 3.17.5
+
+ vscode-languageserver-protocol@3.18.3:
+ dependencies:
+ vscode-jsonrpc: 9.0.2
+ vscode-languageserver-types: 3.18.3
+
+ vscode-languageserver-textdocument@1.0.14: {}
+
+ vscode-languageserver-types@3.17.5: {}
+
+ vscode-languageserver-types@3.18.3: {}
+
+ vscode-languageserver@9.0.1:
+ dependencies:
+ vscode-languageserver-protocol: 3.17.5
+
+ vscode-nls@5.2.0: {}
+
+ vscode-uri@3.2.0: {}
+
w3c-keyname@2.2.8: {}
web-namespaces@2.0.1: {}
@@ -9126,6 +9645,23 @@ snapshots:
yallist@5.0.0: {}
+ yaml-language-server@1.23.0:
+ dependencies:
+ '@vscode/l10n': 0.0.18
+ ajv: 8.20.0
+ ajv-draft-04: 1.0.0(ajv@8.20.0)
+ ajv-i18n: 4.2.0(ajv@8.20.0)
+ prettier: 3.9.6
+ request-light: 0.5.8
+ vscode-json-languageservice: 4.1.8
+ vscode-languageserver: 9.0.1
+ vscode-languageserver-textdocument: 1.0.14
+ vscode-languageserver-types: 3.18.3
+ vscode-uri: 3.2.0
+ yaml: 2.8.3
+
+ yaml@2.8.3: {}
+
yaml@2.9.0: {}
yargs-parser@22.0.0: {}
diff --git a/stackblitz/petstore.openapi.yaml b/stackblitz/petstore.openapi.yaml
new file mode 100644
index 0000000..7c39dae
--- /dev/null
+++ b/stackblitz/petstore.openapi.yaml
@@ -0,0 +1,146 @@
+openapi: 3.0.3
+info:
+ title: Petstore
+ version: 1.0.0
+paths:
+ /pets:
+ get:
+ operationId: listPets
+ tags:
+ - Pet
+ parameters:
+ - name: status
+ in: query
+ required: false
+ schema:
+ $ref: '#/components/schemas/PetStatus'
+ responses:
+ '200':
+ description: ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/PetList'
+ /pets/{petId}:
+ get:
+ operationId: getPet
+ tags:
+ - Pet
+ parameters:
+ - name: petId
+ in: path
+ required: true
+ schema:
+ $ref: '#/components/schemas/PetId'
+ responses:
+ '200':
+ description: ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Pet'
+ post:
+ operationId: updatePet
+ tags:
+ - Pet
+ parameters:
+ - name: petId
+ in: path
+ required: true
+ schema:
+ $ref: '#/components/schemas/PetId'
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UpdatePetRequest'
+ responses:
+ '200':
+ description: ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Pet'
+ /accounts/check-email:
+ get:
+ operationId: checkEmail
+ tags:
+ - Account
+ parameters:
+ - name: email
+ in: query
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ description: ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/EmailAvailability'
+components:
+ schemas:
+ PetId:
+ type: string
+ PetStatus:
+ type: string
+ enum:
+ - available
+ - pending
+ - sold
+ Tag:
+ type: object
+ required:
+ - id
+ - label
+ properties:
+ id:
+ type: integer
+ label:
+ type: string
+ Pet:
+ type: object
+ required:
+ - id
+ - name
+ - status
+ - tags
+ properties:
+ id:
+ $ref: '#/components/schemas/PetId'
+ name:
+ type: string
+ status:
+ $ref: '#/components/schemas/PetStatus'
+ tags:
+ type: array
+ items:
+ $ref: '#/components/schemas/Tag'
+ nickname:
+ type: string
+ nullable: true
+ PetList:
+ type: array
+ items:
+ $ref: '#/components/schemas/Pet'
+ UpdatePetRequest:
+ type: object
+ required:
+ - status
+ properties:
+ status:
+ $ref: '#/components/schemas/PetStatus'
+ nickname:
+ type: string
+ nullable: true
+ EmailAvailability:
+ type: object
+ required:
+ - available
+ properties:
+ available:
+ type: boolean
+ suggestion:
+ type: string
diff --git a/website/astro.config.mjs b/website/astro.config.mjs
index acfb070..949e0d0 100644
--- a/website/astro.config.mjs
+++ b/website/astro.config.mjs
@@ -1,6 +1,26 @@
import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';
+// `astro dev` ignores public/_headers; mirror its COOP/COEP scope so the
+// playground page is cross-origin isolated and its wasm worker inherits COEP.
+const playgroundHeaders = {
+ name: 'playground-headers',
+ configureServer(server) {
+ server.middlewares.use((req, res, next) => {
+ const pathname = req.url?.split('?')[0] ?? '';
+ if (
+ pathname === '/playground' ||
+ pathname.startsWith('/playground/') ||
+ pathname.startsWith('/playground-engine/')
+ ) {
+ res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
+ res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
+ }
+ next();
+ });
+ },
+};
+
export default defineConfig({
site: 'https://docs.openapi-ng.dev',
integrations: [
@@ -57,5 +77,20 @@ export default defineConfig({
vite: {
build: { target: 'es2022' },
server: { fs: { allow: ['..'] } },
+ plugins: [playgroundHeaders],
+ // The playground's imports are only reachable through src/playground/*.ts, so
+ // dev discovers them late and re-optimizes, which 504s already-served modules.
+ optimizeDeps: {
+ include: [
+ '@avsystem/openapi-ng/browser',
+ 'codemirror',
+ '@codemirror/state',
+ '@codemirror/lang-json',
+ '@codemirror/lang-yaml',
+ 'highlight.js/lib/core',
+ 'highlight.js/lib/languages/typescript',
+ 'lz-string',
+ ],
+ },
},
});
diff --git a/website/package.json b/website/package.json
index 937eaf9..a80924f 100644
--- a/website/package.json
+++ b/website/package.json
@@ -11,6 +11,7 @@
"build": "astro build",
"preview": "astro preview",
"astro": "astro",
+ "check": "astro check",
"test:unit": "vitest run"
},
"dependencies": {
@@ -19,6 +20,7 @@
"@avsystem/openapi-ng-wasm32-wasi": "0.5.1",
"@codemirror/lang-json": "6.0.2",
"@codemirror/lang-yaml": "6.1.3",
+ "@codemirror/state": "6.7.2",
"astro": "7.2.4",
"codemirror": "6.0.2",
"highlight.js": "11.12.0",
@@ -26,8 +28,9 @@
"sharp": "0.35.3"
},
"devDependencies": {
- "@types/lz-string": "1.5.0",
+ "@astrojs/check": "0.9.10",
"esbuild": "0.28.2",
+ "typescript": "6.0.3",
"vitest": "5.0.0",
"wrangler": "4.124.0"
},
diff --git a/website/src/pages/playground.astro b/website/src/pages/playground.astro
index aa359be..9bf6df9 100644
--- a/website/src/pages/playground.astro
+++ b/website/src/pages/playground.astro
@@ -1,6 +1,7 @@
---
import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
import '../playground/playground.css';
+import '../playground/hljs-theme.css';
---
void,
+): SpecEditor {
+ const language = new Compartment();
+ let format: SpecFormat = detectFormat(initial);
+
+ const view = new EditorView({
+ parent,
+ state: EditorState.create({
+ doc: initial,
+ extensions: [
+ basicSetup,
+ theme,
+ language.of(format === 'json' ? json() : yaml()),
+ EditorView.updateListener.of(update => {
+ if (!update.docChanged) return;
+ const value = update.state.doc.toString();
+ const next = detectFormat(value);
+ if (next !== format) {
+ format = next;
+ view.dispatch({ effects: language.reconfigure(next === 'json' ? json() : yaml()) });
+ }
+ onChange(value);
+ }),
+ ],
+ }),
+ });
+
+ return {
+ getValue: () => view.state.doc.toString(),
+ setValue: value =>
+ view.dispatch({ changes: { from: 0, to: view.state.doc.length, insert: value } }),
+ };
+}
diff --git a/website/src/playground/generator.ts b/website/src/playground/generator.ts
new file mode 100644
index 0000000..f14f755
--- /dev/null
+++ b/website/src/playground/generator.ts
@@ -0,0 +1,23 @@
+import { createGenerate, GenerateError } from '@avsystem/openapi-ng/browser';
+import type { GenerateOptions, GenerateResult } from '@avsystem/openapi-ng/browser';
+
+export type GenerateFn = (options: GenerateOptions) => Promise;
+export { GenerateError };
+
+// Pre-bundled by scripts/bundle-engine.mjs; kept out of Vite's graph so the
+// napi-rs loader's worker and wasm URLs resolve relative to this file.
+const ENGINE_URL = '/playground-engine/openapi-ng.wasi-browser.js';
+
+export function loadGenerate(): GenerateFn {
+ // An absolute URL keeps Vite's dev client from appending `?import`, which
+ // would route the request through its transform pipeline and reject a public/ file.
+ const url = new URL(ENGINE_URL, location.origin).href;
+ return createGenerate(() => import(/* @vite-ignore */ url));
+}
+
+export async function engineVersion(): Promise {
+ const response = await fetch('/playground-engine/version.json');
+ if (!response.ok) throw new Error(`engine version lookup failed (${response.status})`);
+ const { version } = (await response.json()) as { version: string };
+ return version;
+}
diff --git a/website/src/playground/hljs-theme.css b/website/src/playground/hljs-theme.css
new file mode 100644
index 0000000..e8bf8a6
--- /dev/null
+++ b/website/src/playground/hljs-theme.css
@@ -0,0 +1,236 @@
+/* Generated from highlight.js/styles/github.css and github-dark.css.
+ Each rule is prefixed with :root[data-theme='light'] / :root[data-theme='dark']. */
+:root[data-theme='light'] pre code.hljs {
+ display: block;
+ overflow-x: auto;
+ padding: 1em;
+}
+:root[data-theme='light'] code.hljs {
+ padding: 3px 5px;
+}
+:root[data-theme='light'] /*!
+ Theme: GitHub
+ Description: Light theme as seen on github.com
+ Author: github.com
+ Maintainer: @Hirse
+ Updated: 2021-05-15
+
+ Outdated base version: https://github.com/primer/github-syntax-light
+ Current colors taken from GitHub's CSS
+*/
+.hljs {
+ color: #24292e;
+ background: #ffffff;
+}
+:root[data-theme='light'] .hljs-doctag,
+:root[data-theme='light'] .hljs-keyword,
+:root[data-theme='light'] .hljs-meta .hljs-keyword,
+:root[data-theme='light'] .hljs-template-tag,
+:root[data-theme='light'] .hljs-template-variable,
+:root[data-theme='light'] .hljs-type,
+:root[data-theme='light'] .hljs-variable.language_ {
+ /* prettylights-syntax-keyword */
+ color: #d73a49;
+}
+:root[data-theme='light'] .hljs-title,
+:root[data-theme='light'] .hljs-title.class_,
+:root[data-theme='light'] .hljs-title.class_.inherited__,
+:root[data-theme='light'] .hljs-title.function_ {
+ /* prettylights-syntax-entity */
+ color: #6f42c1;
+}
+:root[data-theme='light'] .hljs-attr,
+:root[data-theme='light'] .hljs-attribute,
+:root[data-theme='light'] .hljs-literal,
+:root[data-theme='light'] .hljs-meta,
+:root[data-theme='light'] .hljs-number,
+:root[data-theme='light'] .hljs-operator,
+:root[data-theme='light'] .hljs-variable,
+:root[data-theme='light'] .hljs-selector-attr,
+:root[data-theme='light'] .hljs-selector-class,
+:root[data-theme='light'] .hljs-selector-id {
+ /* prettylights-syntax-constant */
+ color: #005cc5;
+}
+:root[data-theme='light'] .hljs-regexp,
+:root[data-theme='light'] .hljs-string,
+:root[data-theme='light'] .hljs-meta .hljs-string {
+ /* prettylights-syntax-string */
+ color: #032f62;
+}
+:root[data-theme='light'] .hljs-built_in,
+:root[data-theme='light'] .hljs-symbol {
+ /* prettylights-syntax-variable */
+ color: #e36209;
+}
+:root[data-theme='light'] .hljs-comment,
+:root[data-theme='light'] .hljs-code,
+:root[data-theme='light'] .hljs-formula {
+ /* prettylights-syntax-comment */
+ color: #6a737d;
+}
+:root[data-theme='light'] .hljs-name,
+:root[data-theme='light'] .hljs-quote,
+:root[data-theme='light'] .hljs-selector-tag,
+:root[data-theme='light'] .hljs-selector-pseudo {
+ /* prettylights-syntax-entity-tag */
+ color: #22863a;
+}
+:root[data-theme='light'] .hljs-subst {
+ /* prettylights-syntax-storage-modifier-import */
+ color: #24292e;
+}
+:root[data-theme='light'] .hljs-section {
+ /* prettylights-syntax-markup-heading */
+ color: #005cc5;
+ font-weight: bold;
+}
+:root[data-theme='light'] .hljs-bullet {
+ /* prettylights-syntax-markup-list */
+ color: #735c0f;
+}
+:root[data-theme='light'] .hljs-emphasis {
+ /* prettylights-syntax-markup-italic */
+ color: #24292e;
+ font-style: italic;
+}
+:root[data-theme='light'] .hljs-strong {
+ /* prettylights-syntax-markup-bold */
+ color: #24292e;
+ font-weight: bold;
+}
+:root[data-theme='light'] .hljs-addition {
+ /* prettylights-syntax-markup-inserted */
+ color: #22863a;
+ background-color: #f0fff4;
+}
+:root[data-theme='light'] .hljs-deletion {
+ /* prettylights-syntax-markup-deleted */
+ color: #b31d28;
+ background-color: #ffeef0;
+}
+:root[data-theme='light'] .hljs-char.escape_,
+:root[data-theme='light'] .hljs-link,
+:root[data-theme='light'] .hljs-params,
+:root[data-theme='light'] .hljs-property,
+:root[data-theme='light'] .hljs-punctuation,
+:root[data-theme='light'] .hljs-tag {
+ /* purposely ignored */
+}
+:root[data-theme='dark'] pre code.hljs {
+ display: block;
+ overflow-x: auto;
+ padding: 1em;
+}
+:root[data-theme='dark'] code.hljs {
+ padding: 3px 5px;
+}
+:root[data-theme='dark'] /*!
+ Theme: GitHub Dark
+ Description: Dark theme as seen on github.com
+ Author: github.com
+ Maintainer: @Hirse
+ Updated: 2021-05-15
+
+ Outdated base version: https://github.com/primer/github-syntax-dark
+ Current colors taken from GitHub's CSS
+*/
+.hljs {
+ color: #c9d1d9;
+ background: #0d1117;
+}
+:root[data-theme='dark'] .hljs-doctag,
+:root[data-theme='dark'] .hljs-keyword,
+:root[data-theme='dark'] .hljs-meta .hljs-keyword,
+:root[data-theme='dark'] .hljs-template-tag,
+:root[data-theme='dark'] .hljs-template-variable,
+:root[data-theme='dark'] .hljs-type,
+:root[data-theme='dark'] .hljs-variable.language_ {
+ /* prettylights-syntax-keyword */
+ color: #ff7b72;
+}
+:root[data-theme='dark'] .hljs-title,
+:root[data-theme='dark'] .hljs-title.class_,
+:root[data-theme='dark'] .hljs-title.class_.inherited__,
+:root[data-theme='dark'] .hljs-title.function_ {
+ /* prettylights-syntax-entity */
+ color: #d2a8ff;
+}
+:root[data-theme='dark'] .hljs-attr,
+:root[data-theme='dark'] .hljs-attribute,
+:root[data-theme='dark'] .hljs-literal,
+:root[data-theme='dark'] .hljs-meta,
+:root[data-theme='dark'] .hljs-number,
+:root[data-theme='dark'] .hljs-operator,
+:root[data-theme='dark'] .hljs-variable,
+:root[data-theme='dark'] .hljs-selector-attr,
+:root[data-theme='dark'] .hljs-selector-class,
+:root[data-theme='dark'] .hljs-selector-id {
+ /* prettylights-syntax-constant */
+ color: #79c0ff;
+}
+:root[data-theme='dark'] .hljs-regexp,
+:root[data-theme='dark'] .hljs-string,
+:root[data-theme='dark'] .hljs-meta .hljs-string {
+ /* prettylights-syntax-string */
+ color: #a5d6ff;
+}
+:root[data-theme='dark'] .hljs-built_in,
+:root[data-theme='dark'] .hljs-symbol {
+ /* prettylights-syntax-variable */
+ color: #ffa657;
+}
+:root[data-theme='dark'] .hljs-comment,
+:root[data-theme='dark'] .hljs-code,
+:root[data-theme='dark'] .hljs-formula {
+ /* prettylights-syntax-comment */
+ color: #8b949e;
+}
+:root[data-theme='dark'] .hljs-name,
+:root[data-theme='dark'] .hljs-quote,
+:root[data-theme='dark'] .hljs-selector-tag,
+:root[data-theme='dark'] .hljs-selector-pseudo {
+ /* prettylights-syntax-entity-tag */
+ color: #7ee787;
+}
+:root[data-theme='dark'] .hljs-subst {
+ /* prettylights-syntax-storage-modifier-import */
+ color: #c9d1d9;
+}
+:root[data-theme='dark'] .hljs-section {
+ /* prettylights-syntax-markup-heading */
+ color: #1f6feb;
+ font-weight: bold;
+}
+:root[data-theme='dark'] .hljs-bullet {
+ /* prettylights-syntax-markup-list */
+ color: #f2cc60;
+}
+:root[data-theme='dark'] .hljs-emphasis {
+ /* prettylights-syntax-markup-italic */
+ color: #c9d1d9;
+ font-style: italic;
+}
+:root[data-theme='dark'] .hljs-strong {
+ /* prettylights-syntax-markup-bold */
+ color: #c9d1d9;
+ font-weight: bold;
+}
+:root[data-theme='dark'] .hljs-addition {
+ /* prettylights-syntax-markup-inserted */
+ color: #aff5b4;
+ background-color: #033a16;
+}
+:root[data-theme='dark'] .hljs-deletion {
+ /* prettylights-syntax-markup-deleted */
+ color: #ffdcd7;
+ background-color: #67060c;
+}
+:root[data-theme='dark'] .hljs-char.escape_,
+:root[data-theme='dark'] .hljs-link,
+:root[data-theme='dark'] .hljs-params,
+:root[data-theme='dark'] .hljs-property,
+:root[data-theme='dark'] .hljs-punctuation,
+:root[data-theme='dark'] .hljs-tag {
+ /* purposely ignored */
+}
diff --git a/website/src/playground/main.ts b/website/src/playground/main.ts
index c827bbe..92ed1e7 100644
--- a/website/src/playground/main.ts
+++ b/website/src/playground/main.ts
@@ -1 +1,168 @@
-export function start(_doc: Document): void {}
+import petstoreSpec from '../../../stackblitz/petstore.openapi.yaml?raw';
+import type { GenerateResult, GeneratorDiagnostic } from '@avsystem/openapi-ng/browser';
+import { createEditor } from './editor';
+import { detectFormat, displayPathFor } from './format';
+import { engineVersion, GenerateError, loadGenerate, type GenerateFn } from './generator';
+import { copyText, renderOutput } from './output';
+import { decodeShareHash, encodeShareHash } from './share';
+import { buildTree, renderTree } from './tree';
+
+const DEBOUNCE_MS = 150;
+const STATUS_RESTORE_MS = 2000;
+const WARMUP_SPEC = 'openapi: 3.0.3\ninfo: {title: warmup, version: "1"}\npaths: {}';
+
+function byId(doc: Document, id: string): T {
+ const el = doc.getElementById(id);
+ if (!el) throw new Error(`playground: missing #${id}`);
+ return el as T;
+}
+
+export function start(doc: Document): void {
+ const root = doc.querySelector('.pg');
+ if (!root) return;
+
+ if (!globalThis.crossOriginIsolated) {
+ root.innerHTML =
+ 'The playground needs a cross-origin isolated page ' +
+ '(Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy headers). ' +
+ 'This host is not sending them, so the WebAssembly generator cannot start.
';
+ return;
+ }
+
+ const status = byId(doc, 'pg-status');
+ const treeEl = byId(doc, 'pg-tree');
+ const codeEl = byId(doc, 'pg-code');
+ const summaryEl = byId(doc, 'pg-summary');
+ const diagnosticsEl = byId(doc, 'pg-diagnostics');
+
+ let generate: GenerateFn | null = null;
+ let lastResult: GenerateResult | null = null;
+ let selectedPath: string | null = null;
+ let timer: ReturnType | undefined;
+ let runId = 0;
+ let readyStatus = '';
+
+ function announce(message: string): void {
+ status.textContent = message;
+ setTimeout(() => {
+ status.textContent = readyStatus;
+ }, STATUS_RESTORE_MS);
+ }
+
+ const initial = decodeShareHash(location.hash) ?? petstoreSpec;
+ const editor = createEditor(byId(doc, 'pg-editor'), initial, schedule);
+
+ function schedule(): void {
+ clearTimeout(timer);
+ timer = setTimeout(run, DEBOUNCE_MS);
+ }
+
+ function renderDiagnostics(items: GeneratorDiagnostic[], fatal?: GenerateError): void {
+ diagnosticsEl.replaceChildren();
+ if (fatal) {
+ const li = doc.createElement('li');
+ li.className = 'is-error';
+ li.textContent = `${fatal.code}${fatal.subcode ? ` (${fatal.subcode})` : ''}: ${fatal.message}`;
+ diagnosticsEl.append(li);
+ }
+ for (const item of items) {
+ const li = doc.createElement('li');
+ li.textContent = `${item.code}${item.subcode ? ` (${item.subcode})` : ''}: ${item.message}`;
+ diagnosticsEl.append(li);
+ }
+ }
+
+ function select(path: string): void {
+ selectedPath = path;
+ if (!lastResult) return;
+ const rows = buildTree(lastResult.artifacts);
+ renderTree(treeEl, rows, selectedPath, select);
+ const artifact = lastResult.artifacts.find(a => a.path === path);
+ if (artifact) renderOutput(codeEl, artifact.contents);
+ }
+
+ function showResult(result: GenerateResult, elapsedMs: number): void {
+ lastResult = result;
+ root!.classList.remove('is-stale');
+ const paths = result.artifacts.map(a => a.path);
+ if (!selectedPath || !paths.includes(selectedPath)) selectedPath = paths[0] ?? null;
+ renderTree(treeEl, buildTree(result.artifacts), selectedPath, select);
+ const current = result.artifacts.find(a => a.path === selectedPath);
+ renderOutput(codeEl, current ? current.contents : '');
+ summaryEl.textContent =
+ `${result.summary.operationCount} operations · ${result.summary.schemaCount} schemas · ` +
+ `${result.artifacts.length} files · ${elapsedMs.toFixed(0)} ms`;
+ renderDiagnostics(result.diagnostics);
+ }
+
+ async function run(): Promise {
+ if (!generate) return;
+ // Guards against out-of-order resolution: a later edit's generation can
+ // resolve before an earlier, slower one still in flight.
+ const id = ++runId;
+ const source = editor.getValue();
+ const started = performance.now();
+ try {
+ // No inputFormat: the /browser subpath's InputFormat is a const enum with no
+ // runtime export, and displayPath's extension already selects the decoder.
+ const result = await generate({
+ inputContents: source,
+ displayPath: displayPathFor(detectFormat(source)),
+ emit: ['models', 'angular'],
+ });
+ if (id !== runId) return;
+ showResult(result, performance.now() - started);
+ } catch (err) {
+ if (id !== runId) return;
+ root!.classList.add('is-stale');
+ if (err instanceof GenerateError) {
+ summaryEl.textContent = 'generation failed';
+ renderDiagnostics(err.warnings, err);
+ } else {
+ renderDiagnostics([]);
+ summaryEl.textContent = err instanceof Error ? err.message : String(err);
+ }
+ }
+ }
+
+ byId(doc, 'pg-reset').addEventListener('click', () => {
+ editor.setValue(petstoreSpec);
+ history.replaceState(null, '', location.pathname);
+ });
+ byId(doc, 'pg-share').addEventListener('click', async () => {
+ const hash = encodeShareHash(editor.getValue());
+ history.replaceState(null, '', location.pathname + hash);
+ try {
+ await copyText(location.href);
+ announce('Link copied');
+ } catch (err) {
+ announce(`Copy failed: ${err instanceof Error ? err.message : String(err)}`);
+ }
+ });
+ byId(doc, 'pg-copy').addEventListener('click', async () => {
+ const artifact = lastResult?.artifacts.find(a => a.path === selectedPath);
+ if (!artifact) return;
+ try {
+ await copyText(artifact.contents);
+ } catch (err) {
+ announce(`Copy failed: ${err instanceof Error ? err.message : String(err)}`);
+ }
+ });
+
+ const fn = loadGenerate();
+ fn({ inputContents: WARMUP_SPEC, displayPath: 'spec.yaml', emit: ['models'] })
+ .then(() => {
+ generate = fn;
+ return engineVersion()
+ .then(version => `openapi-ng v${version} · runs in your browser`)
+ .catch(() => 'openapi-ng · runs in your browser');
+ })
+ .then(text => {
+ readyStatus = text;
+ status.textContent = text;
+ return run();
+ })
+ .catch((err: unknown) => {
+ status.textContent = err instanceof Error ? err.message : String(err);
+ });
+}
diff --git a/website/src/playground/output.ts b/website/src/playground/output.ts
new file mode 100644
index 0000000..150b3f4
--- /dev/null
+++ b/website/src/playground/output.ts
@@ -0,0 +1,15 @@
+import hljs from 'highlight.js/lib/core';
+import typescript from 'highlight.js/lib/languages/typescript';
+
+hljs.registerLanguage('typescript', typescript);
+
+export function renderOutput(code: HTMLElement, contents: string): void {
+ code.textContent = contents;
+ code.className = 'language-typescript';
+ delete code.dataset.highlighted;
+ hljs.highlightElement(code);
+}
+
+export async function copyText(text: string): Promise {
+ await navigator.clipboard.writeText(text);
+}
diff --git a/website/src/playground/playground.css b/website/src/playground/playground.css
index c675a28..e1c0938 100644
--- a/website/src/playground/playground.css
+++ b/website/src/playground/playground.css
@@ -2,7 +2,7 @@
display: grid;
grid-template-rows: auto 1fr auto;
gap: 0.75rem;
- height: calc(100vh - var(--sl-nav-height) - 3rem);
+ height: calc(100dvh - var(--sl-nav-height) - 3rem);
min-height: 32rem;
}
.pg-toolbar,
@@ -48,23 +48,33 @@
margin: 0;
padding: 0.5rem 0;
}
-.pg-tree li {
+.pg-tree li.is-dir {
padding: 0.25rem 0.75rem;
font-family: var(--__sl-font-mono);
font-size: 0.75rem;
+ color: var(--sl-color-gray-3);
+}
+.pg-tree li.is-selected {
+ background: var(--sl-color-gray-6);
+}
+.pg .pg-tree button {
+ all: unset;
+ box-sizing: border-box;
display: flex;
justify-content: space-between;
+ width: 100%;
+ padding: 0.25rem 0.75rem;
cursor: pointer;
+ font-family: var(--__sl-font-mono);
+ font-size: 0.75rem;
+ text-align: left;
}
-.pg-tree li[data-depth='1'] {
+.pg-tree li[data-depth='1'] button {
padding-left: 1.75rem;
}
-.pg-tree li.is-dir {
- cursor: default;
- color: var(--sl-color-gray-3);
-}
-.pg-tree li.is-selected {
- background: var(--sl-color-gray-6);
+.pg .pg-tree button:focus-visible {
+ outline: 2px solid var(--sl-color-accent);
+ outline-offset: -2px;
}
.pg-tree .size {
color: var(--sl-color-gray-3);
@@ -105,6 +115,9 @@
padding: 2rem;
}
@media (max-width: 72rem) {
+ .pg {
+ height: auto;
+ }
.pg-panes {
grid-template-columns: 1fr;
grid-template-rows: 20rem auto 20rem;
diff --git a/website/src/playground/tree.ts b/website/src/playground/tree.ts
index 8ed1839..beba7ec 100644
--- a/website/src/playground/tree.ts
+++ b/website/src/playground/tree.ts
@@ -16,7 +16,13 @@ export function buildTree(artifacts: ReadonlyArray): TreeRow[] {
const slash = artifact.path.indexOf('/');
const bytes = encoder.encode(artifact.contents).length;
if (slash === -1) {
- root.push({ kind: 'file', path: artifact.path, name: artifact.path, depth: 0, bytes });
+ root.push({
+ kind: 'file',
+ path: artifact.path,
+ name: artifact.path,
+ depth: 0,
+ bytes,
+ });
continue;
}
const dir = artifact.path.slice(0, slash);
@@ -25,7 +31,8 @@ export function buildTree(artifacts: ReadonlyArray): TreeRow[] {
rows.push({ kind: 'file', path: artifact.path, name, depth: 1, bytes });
dirs.set(dir, rows);
}
- const byName = (a: { name: string }, b: { name: string }) => a.name.localeCompare(b.name);
+ const byName = (a: { name: string }, b: { name: string }) =>
+ a.name.localeCompare(b.name);
root.sort(byName);
for (const dir of [...dirs.keys()].sort()) {
root.push({ kind: 'dir', name: dir, depth: 0 });
@@ -44,9 +51,10 @@ export function renderTree(
selectedPath: string | null,
onSelect: (path: string) => void,
): void {
- const list = document.createElement('ul');
+ const doc = container.ownerDocument;
+ const list = doc.createElement('ul');
for (const row of rows) {
- const item = document.createElement('li');
+ const item = doc.createElement('li');
item.dataset.depth = String(row.depth);
if (row.kind === 'dir') {
item.className = 'is-dir';
@@ -54,13 +62,16 @@ export function renderTree(
} else {
item.dataset.path = row.path;
if (row.path === selectedPath) item.className = 'is-selected';
- const name = document.createElement('span');
+ const button = doc.createElement('button');
+ button.type = 'button';
+ const name = doc.createElement('span');
name.textContent = row.name;
- const size = document.createElement('span');
+ const size = doc.createElement('span');
size.className = 'size';
size.textContent = formatBytes(row.bytes);
- item.append(name, size);
- item.addEventListener('click', () => onSelect(row.path));
+ button.append(name, size);
+ button.addEventListener('click', () => onSelect(row.path));
+ item.append(button);
}
list.append(item);
}
diff --git a/website/tsconfig.json b/website/tsconfig.json
index 8bf91d3..36d027d 100644
--- a/website/tsconfig.json
+++ b/website/tsconfig.json
@@ -1,5 +1,5 @@
{
"extends": "astro/tsconfigs/strict",
"include": [".astro/types.d.ts", "**/*"],
- "exclude": ["dist"]
+ "exclude": ["dist", "public"]
}
From f6c5dfcac838b7d57af3cb5f61ddfe8fe0d4add9 Mon Sep 17 00:00:00 2001
From: pkurcx
Date: Thu, 3 Sep 2026 19:53:35 +0200
Subject: [PATCH 04/17] test(website): playground smoke test against wrangler
dev
Co-Authored-By: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_011t8uBVY6h4kfN5cXHXuCpR
---
.github/workflows/docs.yml | 12 ++++++++++
.gitignore | 2 ++
pnpm-lock.yaml | 38 ++++++++++++++++++++++++++++++++
website/package.json | 5 ++++-
website/playwright.config.ts | 14 ++++++++++++
website/tests/playground.spec.ts | 38 ++++++++++++++++++++++++++++++++
6 files changed, 108 insertions(+), 1 deletion(-)
create mode 100644 website/playwright.config.ts
create mode 100644 website/tests/playground.spec.ts
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index fd265cc..ebf4302 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -7,10 +7,16 @@ on:
paths:
- 'website/**'
- '.github/workflows/docs.yml'
+ - 'pnpm-lock.yaml'
+ - 'pnpm-workspace.yaml'
+ - 'stackblitz/petstore.openapi.yaml'
pull_request:
paths:
- 'website/**'
- '.github/workflows/docs.yml'
+ - 'pnpm-lock.yaml'
+ - 'pnpm-workspace.yaml'
+ - 'stackblitz/petstore.openapi.yaml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -43,6 +49,12 @@ jobs:
- name: Type-check
working-directory: website
run: pnpm check
+ - name: Install Playwright browser
+ working-directory: website
+ run: pnpm exec playwright install --with-deps chromium
+ - name: Test
+ working-directory: website
+ run: pnpm test
- name: Deploy to production
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
uses: cloudflare/wrangler-action@v3
diff --git a/.gitignore b/.gitignore
index d85cdec..c5737f2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -241,4 +241,6 @@ tmp/
*.bak
website/public/playground-engine/
+website/test-results/
+website/playwright-report/
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 3310fd0..3e704ee 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -134,6 +134,9 @@ importers:
'@astrojs/check':
specifier: 0.9.10
version: 0.9.10(prettier@3.9.6)(typescript@6.0.3)
+ '@playwright/test':
+ specifier: 1.62.1
+ version: 1.62.1
esbuild:
specifier: 0.28.2
version: 0.28.2
@@ -2258,6 +2261,11 @@ packages:
cpu: [x64]
os: [win32]
+ '@playwright/test@1.62.1':
+ resolution: {integrity: sha512-DTcUc8qii+cpHvtOwggMtBRMjKZHXYWdw8syRYu2vtzuq4Wxphqq4NfCs5Zt44L6mA8rfDfj+PHnxFc/FeK6mQ==}
+ engines: {node: '>=20'}
+ hasBin: true
+
'@poppinss/colors@4.1.6':
resolution: {integrity: sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==}
@@ -3258,6 +3266,11 @@ packages:
resolution: {integrity: sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw==}
engines: {node: '>=20'}
+ fsevents@2.3.2:
+ resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@@ -4054,6 +4067,16 @@ packages:
resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==}
engines: {node: '>= 6'}
+ playwright-core@1.62.1:
+ resolution: {integrity: sha512-wPYSwEBJY9GHraISXqyqtx0na0LpO3XEX7jNDhntbex7tzUS7kLnZsOlFruFJB4Hi/rhDMjXGqHewDZ68nYZVw==}
+ engines: {node: '>=20'}
+ hasBin: true
+
+ playwright@1.62.1:
+ resolution: {integrity: sha512-0M+L3LAD8/nm554LOla9Ayx0j0tmFZ0FBcoQ7F1VuVHpM/XpiC8RcDzBQB8W5+hA8L22THxELzeF+2WcUzvcLg==}
+ engines: {node: '>=20'}
+ hasBin: true
+
plur@6.0.0:
resolution: {integrity: sha512-Y9wXQivjRX0REtwpA9+n0bYYypWESn3cWtW2vazymw711qn+AQXxzZjRqhANYGBLIMC1UzVdpwe/1hHQwHfwng==}
engines: {node: '>=20'}
@@ -6582,6 +6605,10 @@ snapshots:
'@pagefind/windows-x64@1.5.2':
optional: true
+ '@playwright/test@1.62.1':
+ dependencies:
+ playwright: 1.62.1
+
'@poppinss/colors@4.1.6':
dependencies:
kleur: 4.1.5
@@ -7600,6 +7627,9 @@ snapshots:
dependencies:
tiny-inflate: 1.0.3
+ fsevents@2.3.2:
+ optional: true
+
fsevents@2.3.3:
optional: true
@@ -8743,6 +8773,14 @@ snapshots:
pirates@4.0.7: {}
+ playwright-core@1.62.1: {}
+
+ playwright@1.62.1:
+ dependencies:
+ playwright-core: 1.62.1
+ optionalDependencies:
+ fsevents: 2.3.2
+
plur@6.0.0:
dependencies:
irregular-plurals: 4.2.0
diff --git a/website/package.json b/website/package.json
index a80924f..a957c8b 100644
--- a/website/package.json
+++ b/website/package.json
@@ -12,7 +12,9 @@
"preview": "astro preview",
"astro": "astro",
"check": "astro check",
- "test:unit": "vitest run"
+ "test:unit": "vitest run",
+ "test:e2e": "playwright test",
+ "test": "pnpm test:unit && pnpm test:e2e"
},
"dependencies": {
"@astrojs/starlight": "0.41.7",
@@ -29,6 +31,7 @@
},
"devDependencies": {
"@astrojs/check": "0.9.10",
+ "@playwright/test": "1.62.1",
"esbuild": "0.28.2",
"typescript": "6.0.3",
"vitest": "5.0.0",
diff --git a/website/playwright.config.ts b/website/playwright.config.ts
new file mode 100644
index 0000000..f17c602
--- /dev/null
+++ b/website/playwright.config.ts
@@ -0,0 +1,14 @@
+import { defineConfig } from '@playwright/test';
+
+export default defineConfig({
+ testDir: './tests',
+ timeout: 60_000,
+ use: { baseURL: 'http://localhost:8788' },
+ // wrangler dev serves dist/ with the _headers file; astro preview does not.
+ webServer: {
+ command: 'pnpm exec wrangler dev --port 8788',
+ url: 'http://localhost:8788/playground/',
+ reuseExistingServer: !process.env.CI,
+ timeout: 120_000,
+ },
+});
diff --git a/website/tests/playground.spec.ts b/website/tests/playground.spec.ts
new file mode 100644
index 0000000..a94ead9
--- /dev/null
+++ b/website/tests/playground.spec.ts
@@ -0,0 +1,38 @@
+import { expect, test } from '@playwright/test';
+
+const INVALID_SPEC =
+ 'openapi: 3.0.3\ninfo: {title: x, version: "1"}\npaths: {/a: {get: {responses: {"200": {description: ok}}}}}';
+
+test('generates the petstore client in the browser', async ({ page }) => {
+ await page.goto('/playground/');
+ expect(await page.evaluate(() => globalThis.crossOriginIsolated)).toBe(true);
+ await expect(page.locator('#pg-status')).toContainText('runs in your browser');
+ await expect(page.locator('#pg-tree li[data-path]')).toHaveCount(6);
+ await page.locator('#pg-tree li[data-path="rest/pet.rest.generated.ts"]').click();
+ await expect(page.locator('#pg-code')).toContainText('listPets');
+});
+
+test('shows a typed diagnostic for an unsupported spec', async ({ page }) => {
+ await page.goto('/playground/');
+ await expect(page.locator('#pg-status')).toContainText('runs in your browser');
+ const editor = page.locator('#pg-editor .cm-content');
+ await editor.click();
+ await page.keyboard.press('ControlOrMeta+a');
+ await page.keyboard.insertText(INVALID_SPEC);
+ await expect(page.locator('#pg-diagnostics li.is-error')).toContainText('E_POLICY_VIOLATION');
+ await expect(page.locator('#pg-diagnostics li.is-error')).toContainText('missing-operation-id');
+});
+
+test('share link round-trips the spec', async ({ page, context }) => {
+ await context.grantPermissions(['clipboard-read', 'clipboard-write']);
+ await page.goto('/playground/');
+ await expect(page.locator('#pg-status')).toContainText('runs in your browser');
+ const editor = page.locator('#pg-editor .cm-content');
+ await editor.click();
+ await page.keyboard.press('ControlOrMeta+a');
+ await page.keyboard.insertText('openapi: 3.0.3\ninfo: {title: shared, version: "1"}\npaths: {}');
+ await page.locator('#pg-share').click();
+ await expect(page).toHaveURL(/#spec=/);
+ await page.reload();
+ await expect(page.locator('#pg-editor .cm-content')).toContainText('title: shared');
+});
From 74c1d60c4a148a0a6be2eff895bc190a626d92b6 Mon Sep 17 00:00:00 2001
From: pkurcx
Date: Thu, 3 Sep 2026 20:12:30 +0200
Subject: [PATCH 05/17] chore: track the StackBlitz demo app
Co-Authored-By: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_011t8uBVY6h4kfN5cXHXuCpR
---
stackblitz/.stackblitzrc | 4 +
stackblitz/angular.json | 47 +
stackblitz/package-lock.json | 7069 +++++++++++++++++
stackblitz/package.json | 25 +
stackblitz/src/app/app.ts | 26 +
stackblitz/src/app/mock-api.interceptor.ts | 68 +
stackblitz/src/app/pet-detail.ts | 77 +
stackblitz/src/app/pet-list.ts | 54 +
stackblitz/src/app/signup-form.ts | 74 +
stackblitz/src/generated/model.generated.ts | 32 +
stackblitz/src/generated/rest.model.ts | 82 +
stackblitz/src/generated/rest.util.ts | 335 +
stackblitz/src/generated/rest.validate.ts | 70 +
.../generated/rest/account.rest.generated.ts | 28 +
.../src/generated/rest/pet.rest.generated.ts | 58 +
stackblitz/src/index.html | 11 +
stackblitz/src/main.ts | 12 +
stackblitz/src/styles.css | 111 +
stackblitz/tsconfig.app.json | 9 +
stackblitz/tsconfig.json | 25 +
20 files changed, 8217 insertions(+)
create mode 100644 stackblitz/.stackblitzrc
create mode 100644 stackblitz/angular.json
create mode 100644 stackblitz/package-lock.json
create mode 100644 stackblitz/package.json
create mode 100644 stackblitz/src/app/app.ts
create mode 100644 stackblitz/src/app/mock-api.interceptor.ts
create mode 100644 stackblitz/src/app/pet-detail.ts
create mode 100644 stackblitz/src/app/pet-list.ts
create mode 100644 stackblitz/src/app/signup-form.ts
create mode 100644 stackblitz/src/generated/model.generated.ts
create mode 100644 stackblitz/src/generated/rest.model.ts
create mode 100644 stackblitz/src/generated/rest.util.ts
create mode 100644 stackblitz/src/generated/rest.validate.ts
create mode 100644 stackblitz/src/generated/rest/account.rest.generated.ts
create mode 100644 stackblitz/src/generated/rest/pet.rest.generated.ts
create mode 100644 stackblitz/src/index.html
create mode 100644 stackblitz/src/main.ts
create mode 100644 stackblitz/src/styles.css
create mode 100644 stackblitz/tsconfig.app.json
create mode 100644 stackblitz/tsconfig.json
diff --git a/stackblitz/.stackblitzrc b/stackblitz/.stackblitzrc
new file mode 100644
index 0000000..5490eb1
--- /dev/null
+++ b/stackblitz/.stackblitzrc
@@ -0,0 +1,4 @@
+{
+ "installDependencies": true,
+ "startCommand": "npm start"
+}
diff --git a/stackblitz/angular.json b/stackblitz/angular.json
new file mode 100644
index 0000000..8b4ade4
--- /dev/null
+++ b/stackblitz/angular.json
@@ -0,0 +1,47 @@
+{
+ "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
+ "version": 1,
+ "newProjectRoot": "projects",
+ "projects": {
+ "demo": {
+ "projectType": "application",
+ "root": "",
+ "sourceRoot": "src",
+ "prefix": "app",
+ "architect": {
+ "build": {
+ "builder": "@angular/build:application",
+ "options": {
+ "browser": "src/main.ts",
+ "index": "src/index.html",
+ "tsConfig": "tsconfig.app.json",
+ "styles": ["src/styles.css"]
+ },
+ "configurations": {
+ "production": {
+ "outputHashing": "all"
+ },
+ "development": {
+ "optimization": false,
+ "extractLicenses": false,
+ "sourceMap": true
+ }
+ },
+ "defaultConfiguration": "production"
+ },
+ "serve": {
+ "builder": "@angular/build:dev-server",
+ "configurations": {
+ "production": {
+ "buildTarget": "demo:build:production"
+ },
+ "development": {
+ "buildTarget": "demo:build:development"
+ }
+ },
+ "defaultConfiguration": "development"
+ }
+ }
+ }
+ }
+}
diff --git a/stackblitz/package-lock.json b/stackblitz/package-lock.json
new file mode 100644
index 0000000..5a2b013
--- /dev/null
+++ b/stackblitz/package-lock.json
@@ -0,0 +1,7069 @@
+{
+ "name": "openapi-ng-demo",
+ "version": "0.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "openapi-ng-demo",
+ "version": "0.0.0",
+ "dependencies": {
+ "@angular/common": "^22.1.3",
+ "@angular/compiler": "^22.1.3",
+ "@angular/core": "^22.1.3",
+ "@angular/forms": "^22.1.3",
+ "@angular/platform-browser": "^22.1.3",
+ "rxjs": "~7.8.2",
+ "tslib": "^2.8.1"
+ },
+ "devDependencies": {
+ "@angular/build": "^22.1.3",
+ "@angular/cli": "^22.1.3",
+ "@angular/compiler-cli": "^22.1.3",
+ "typescript": "~6.0.3"
+ }
+ },
+ "node_modules/@ampproject/remapping": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+ "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@angular-devkit/architect": {
+ "version": "0.2201.7",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2201.7.tgz",
+ "integrity": "sha512-qffChB0+3WuLcwDk9gx3p/Vl3zYJDomweui5zsLESDMzvJ8zsbKRkgohTieOngajx+XBsklp0gKcxjiVn4NvWQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@angular-devkit/core": "22.1.7",
+ "rxjs": "7.8.2"
+ },
+ "bin": {
+ "architect": "bin/cli.js"
+ },
+ "engines": {
+ "node": "^22.22.3 || ^24.15.0 || >=26.0.0",
+ "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+ "yarn": ">= 1.13.0"
+ }
+ },
+ "node_modules/@angular-devkit/core": {
+ "version": "22.1.7",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-22.1.7.tgz",
+ "integrity": "sha512-RKayeOOjhcIe/iBOM1fmtI5pjXwBEJh+u55VnSeIwYvFNXyxI0/jdRw4T6uhwusQ+1bzyya4d8q1mT9oaOQ/5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "8.20.0",
+ "ajv-formats": "3.0.1",
+ "jsonc-parser": "3.3.1",
+ "picomatch": "4.0.5",
+ "rxjs": "7.8.2",
+ "source-map": "0.7.6"
+ },
+ "engines": {
+ "node": "^22.22.3 || ^24.15.0 || >=26.0.0",
+ "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+ "yarn": ">= 1.13.0"
+ },
+ "peerDependencies": {
+ "chokidar": "^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "chokidar": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@angular-devkit/schematics": {
+ "version": "22.1.7",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-22.1.7.tgz",
+ "integrity": "sha512-KOcVeT4MCsoPt6AMnXH7AbWZnzlKXhMyua2ITWij4UbLaNWCDwfIug/xrZssYLHUFwebCIqsR8iuG/BPH8Cz2w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@angular-devkit/core": "22.1.7",
+ "jsonc-parser": "3.3.1",
+ "magic-string": "1.0.0",
+ "ora": "9.4.1",
+ "rxjs": "7.8.2"
+ },
+ "engines": {
+ "node": "^22.22.3 || ^24.15.0 || >=26.0.0",
+ "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+ "yarn": ">= 1.13.0"
+ }
+ },
+ "node_modules/@angular/build": {
+ "version": "22.1.7",
+ "resolved": "https://registry.npmjs.org/@angular/build/-/build-22.1.7.tgz",
+ "integrity": "sha512-YNZL3R2YS1qZud9zbJfW3ZSeEB0xAURBJEE0cf7WRCCwkn7NFlH7xXLW/zR+WRBwtcCBRsLrM2/ix3Y8FoKX9A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@ampproject/remapping": "2.3.0",
+ "@angular-devkit/architect": "0.2201.7",
+ "@babel/core": "8.0.1",
+ "@babel/helper-annotate-as-pure": "8.0.0",
+ "@babel/helper-split-export-declaration": "7.24.7",
+ "@inquirer/confirm": "6.1.1",
+ "@vitejs/plugin-basic-ssl": "2.3.0",
+ "beasties": "0.4.3",
+ "browserslist": "^4.26.0",
+ "esbuild": "0.28.2",
+ "https-proxy-agent": "9.1.0",
+ "jsonc-parser": "3.3.1",
+ "listr2": "11.0.0",
+ "magic-string": "1.0.0",
+ "mrmime": "2.0.1",
+ "oxc-parser": "0.142.0",
+ "parse5-html-rewriting-stream": "8.0.1",
+ "picomatch": "4.0.5",
+ "piscina": "5.2.0",
+ "rolldown": "1.2.0",
+ "sass": "1.101.0",
+ "semver": "7.8.5",
+ "source-map-support": "0.5.21",
+ "tinyglobby": "0.2.17",
+ "vite": "8.1.5",
+ "watchpack": "2.5.2"
+ },
+ "engines": {
+ "node": "^22.22.3 || ^24.15.0 || >=26.0.0",
+ "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+ "yarn": ">= 1.13.0"
+ },
+ "optionalDependencies": {
+ "lmdb": "3.5.6"
+ },
+ "peerDependencies": {
+ "@angular/compiler": "^22.0.0",
+ "@angular/compiler-cli": "^22.0.0",
+ "@angular/core": "^22.0.0",
+ "@angular/localize": "^22.0.0",
+ "@angular/platform-browser": "^22.0.0",
+ "@angular/platform-server": "^22.0.0",
+ "@angular/service-worker": "^22.0.0",
+ "@angular/ssr": "^22.1.7",
+ "istanbul-lib-instrument": "^6.0.0",
+ "karma": "^6.4.0",
+ "less": "^4.2.0",
+ "ng-packagr": "^22.0.0",
+ "postcss": "^8.4.0",
+ "rollup": "^4.0.0",
+ "tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0",
+ "tslib": "^2.3.0",
+ "typescript": ">=6.0 <6.1",
+ "vitest": "^4.0.8"
+ },
+ "peerDependenciesMeta": {
+ "@angular/core": {
+ "optional": true
+ },
+ "@angular/localize": {
+ "optional": true
+ },
+ "@angular/platform-browser": {
+ "optional": true
+ },
+ "@angular/platform-server": {
+ "optional": true
+ },
+ "@angular/service-worker": {
+ "optional": true
+ },
+ "@angular/ssr": {
+ "optional": true
+ },
+ "istanbul-lib-instrument": {
+ "optional": true
+ },
+ "karma": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "ng-packagr": {
+ "optional": true
+ },
+ "postcss": {
+ "optional": true
+ },
+ "rollup": {
+ "optional": true
+ },
+ "tailwindcss": {
+ "optional": true
+ },
+ "vitest": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@angular/cli": {
+ "version": "22.1.7",
+ "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-22.1.7.tgz",
+ "integrity": "sha512-dsOAAPHTXSrTvH5jIdZsFhqmcrTU9+aLXPSYSkQ1afMxPUT/JDjWH228xURYmCaM3ml0vVaT9R2p7/FrS7CJmg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@angular-devkit/architect": "0.2201.7",
+ "@angular-devkit/core": "22.1.7",
+ "@angular-devkit/schematics": "22.1.7",
+ "@inquirer/prompts": "8.5.2",
+ "@listr2/prompt-adapter-inquirer": "4.2.5",
+ "@modelcontextprotocol/sdk": "1.30.0",
+ "@schematics/angular": "22.1.7",
+ "jsonc-parser": "3.3.1",
+ "listr2": "11.0.0",
+ "npm-package-arg": "14.0.0",
+ "parse5-html-rewriting-stream": "8.0.1",
+ "semver": "7.8.5",
+ "yargs": "18.1.0",
+ "zod": "4.4.3"
+ },
+ "bin": {
+ "ng": "bin/ng.js"
+ },
+ "engines": {
+ "node": "^22.22.3 || ^24.15.0 || >=26.0.0",
+ "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+ "yarn": ">= 1.13.0"
+ }
+ },
+ "node_modules/@angular/common": {
+ "version": "22.1.5",
+ "resolved": "https://registry.npmjs.org/@angular/common/-/common-22.1.5.tgz",
+ "integrity": "sha512-KgB+MTDotlTn67YK4sCTNFLja+G+EMCqHo5bB1cvRKw7Gd9AtAi5kgDmYzMk7ftJ9qJ2O30zXR56Hpw37J2CTQ==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.3.0"
+ },
+ "engines": {
+ "node": "^22.22.3 || ^24.15.0 || >=26.0.0"
+ },
+ "peerDependencies": {
+ "@angular/core": "22.1.5",
+ "rxjs": "^6.5.3 || ^7.4.0"
+ }
+ },
+ "node_modules/@angular/compiler": {
+ "version": "22.1.5",
+ "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-22.1.5.tgz",
+ "integrity": "sha512-GvM0oNCuI09Up5Lk0ZQCX5yA2cGyHYB/rZsa/EGTnzwuxgLDlhOOa19QaVaoxDCo9vO43Ix9rG7SLppEv+qd1w==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.3.0"
+ },
+ "engines": {
+ "node": "^22.22.3 || ^24.15.0 || >=26.0.0"
+ }
+ },
+ "node_modules/@angular/compiler-cli": {
+ "version": "22.1.5",
+ "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-22.1.5.tgz",
+ "integrity": "sha512-XyeLlCqngUiZK8EMQo2DFfDxDoFdlsOe98eK7++N9Cs7qETTaMM3mu8iZbT2o6KhEwzjabW+mqipts1/ecEhyQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "8.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.14",
+ "chokidar": "^5.0.0",
+ "convert-source-map": "^1.5.1",
+ "reflect-metadata": "^0.2.0",
+ "semver": "^7.0.0",
+ "tslib": "^2.3.0",
+ "yargs": "^18.0.0"
+ },
+ "bin": {
+ "ng-xi18n": "bundles/src/bin/ng_xi18n.js",
+ "ngc": "bundles/src/bin/ngc.js"
+ },
+ "engines": {
+ "node": "^22.22.3 || ^24.15.0 || >=26.0.0"
+ },
+ "peerDependencies": {
+ "@angular/compiler": "22.1.5",
+ "typescript": ">=6.0 <6.1"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@angular/core": {
+ "version": "22.1.5",
+ "resolved": "https://registry.npmjs.org/@angular/core/-/core-22.1.5.tgz",
+ "integrity": "sha512-uiL+xVL4264NEuc3E5ILd6meSv9I4Xt82VQHvYlAVYlcjHlWY49yVe0/apzncUOGxUKzvK8/GDbyFEH7WfJYFw==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.3.0"
+ },
+ "engines": {
+ "node": "^22.22.3 || ^24.15.0 || >=26.0.0"
+ },
+ "peerDependencies": {
+ "@angular/compiler": "22.1.5",
+ "rxjs": "^6.5.3 || ^7.4.0",
+ "zone.js": "~0.15.0 || ~0.16.0"
+ },
+ "peerDependenciesMeta": {
+ "@angular/compiler": {
+ "optional": true
+ },
+ "zone.js": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@angular/forms": {
+ "version": "22.1.5",
+ "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-22.1.5.tgz",
+ "integrity": "sha512-E7pDEKtSvO1MNw222ZcvphzT4GAQ9D725v2Rq7ft8orT2qvHS6RlVnEc5ioPDhYTAD0HmbwDmutxkcuxqc16VA==",
+ "license": "MIT",
+ "dependencies": {
+ "@standard-schema/spec": "^1.0.0",
+ "tslib": "^2.3.0",
+ "zod": "^4.0.10"
+ },
+ "engines": {
+ "node": "^22.22.3 || ^24.15.0 || >=26.0.0"
+ },
+ "peerDependencies": {
+ "@angular/common": "22.1.5",
+ "@angular/core": "22.1.5",
+ "@angular/platform-browser": "22.1.5",
+ "rxjs": "^6.5.3 || ^7.4.0"
+ }
+ },
+ "node_modules/@angular/platform-browser": {
+ "version": "22.1.5",
+ "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-22.1.5.tgz",
+ "integrity": "sha512-xRX7TvHzFcur5bhZUqT7QPkezcSuWRzcltcsrqh3UsZnEJ2p+olilFyLq5yAneO13hffNifFkxngoSxVwKwnHw==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.3.0"
+ },
+ "engines": {
+ "node": "^22.22.3 || ^24.15.0 || >=26.0.0"
+ },
+ "peerDependencies": {
+ "@angular/animations": "22.1.5",
+ "@angular/common": "22.1.5",
+ "@angular/core": "22.1.5"
+ },
+ "peerDependenciesMeta": {
+ "@angular/animations": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-8.0.0.tgz",
+ "integrity": "sha512-dYYg153EyN2Ekbqw2zAsbd6/JR+9N2SEoC7YV2GyyqMM7x9bLDTjBD6XBhSMLH0wtIVyJj03jWNriQhaN+eoCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^8.0.0",
+ "js-tokens": "^10.0.0"
+ },
+ "engines": {
+ "node": "^22.18.0 || >=24.11.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-8.0.0.tgz",
+ "integrity": "sha512-DOjnob/cXOUgDOozCDeq/aK2p5y8dUIVdf6tNhEV1HQRd6I8aQ4f4fbtHRVEvb6lP3BGomrKHiS8ICAASSVQSw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^22.18.0 || >=24.11.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-8.0.1.tgz",
+ "integrity": "sha512-5FgxM4dLQpMJHSiVATk8foW263dVHQHBVpXYiimNECVWG01f4nFyEbQixeT6Mwvg7TayREJ2gpKl3o2RoMdnqw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^8.0.0",
+ "@babel/generator": "^8.0.0",
+ "@babel/helper-compilation-targets": "^8.0.0",
+ "@babel/helpers": "^8.0.0",
+ "@babel/parser": "^8.0.0",
+ "@babel/template": "^8.0.0",
+ "@babel/traverse": "^8.0.0",
+ "@babel/types": "^8.0.0",
+ "@types/gensync": "^1.0.5",
+ "convert-source-map": "^2.0.0",
+ "empathic": "^2.0.1",
+ "gensync": "^1.0.0-beta.2",
+ "import-meta-resolve": "^4.2.0",
+ "json5": "^2.2.3",
+ "obug": "^2.1.1",
+ "semver": "^7.7.3"
+ },
+ "engines": {
+ "node": "^22.18.0 || >=24.11.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/core/node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@babel/generator": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-8.0.0.tgz",
+ "integrity": "sha512-NT9NrVwJsbSV6Y2FSstWa71EETOnzrjkL5/wX3D2mYHtKM+qvqB1DvR4D0Setb/gDBsHzRICifwEWMO8CnTF6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^8.0.0",
+ "@babel/types": "^8.0.0",
+ "@jridgewell/gen-mapping": "^0.3.12",
+ "@jridgewell/trace-mapping": "^0.3.28",
+ "@types/jsesc": "^2.5.0",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": "^22.18.0 || >=24.11.0"
+ }
+ },
+ "node_modules/@babel/helper-annotate-as-pure": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-8.0.0.tgz",
+ "integrity": "sha512-NSpMkMsvvZqzThJ0p1B02cbtA2ObEyfBvq950bmNkyxsxvcxwhvvCB036rKhlEnuBBo30bOrk13u3FzlKSoRrw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^8.0.0"
+ },
+ "engines": {
+ "node": "^22.18.0 || >=24.11.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-8.0.0.tgz",
+ "integrity": "sha512-JwculLABZvyPvyLBpwU/E/IbH2uM3mnxNtIJpxnIfb24y1PrdVxK5Dqjle4DpgqpGRnwgC7G8IkzPdSXZrO1Ew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^8.0.0",
+ "@babel/helper-validator-option": "^8.0.0",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^11.0.0",
+ "semver": "^7.7.3"
+ },
+ "engines": {
+ "node": "^22.18.0 || >=24.11.0"
+ }
+ },
+ "node_modules/@babel/helper-globals": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-8.0.0.tgz",
+ "integrity": "sha512-lLozHOM6sWWlxNo8CYqHy4MBZeTvHXNgVPBfPOGsjPKUzHC2Az9QwB6gxdQmpwHl6GlQtbGgS+lj5887guDiLw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^22.18.0 || >=24.11.0"
+ }
+ },
+ "node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz",
+ "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-split-export-declaration/node_modules/@babel/helper-string-parser": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
+ "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-split-export-declaration/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
+ "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-split-export-declaration/node_modules/@babel/types": {
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz",
+ "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.29.7",
+ "@babel/helper-validator-identifier": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-8.0.0.tgz",
+ "integrity": "sha512-6mJgmFFFIIO82vvoLt9XtRC7/TkzXfts1t/SpRX4IHSzMgqoPYCWesVu1udUPUWioAE/2fcG6WuI8zrkE1gwrg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^22.18.0 || >=24.11.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "8.0.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-8.0.4.tgz",
+ "integrity": "sha512-4wFaiLd0bVo4cIoTXI3zKI038NIWE/cr3jvBjejOVYVxV/m8Ltav1USiGzG1fmS5J2RhgEOgXNNK46cRPnRsrg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^22.18.0 || >=24.11.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-8.0.0.tgz",
+ "integrity": "sha512-U4Dybxh4WESWHt5XhBeExi4DrY0/DNK1aHpQbsrQXCUbFHuMweT0TpLEWKvaraV2Y6fS+ZXunsZ8zIuZIgvF2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^22.18.0 || >=24.11.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-8.0.0.tgz",
+ "integrity": "sha512-wfbi91pM3py96oIiJEz7qIpyXDytgr9zQC1HEWwlGNVRAEmItuU/0a41ZUKu1sJGyhhOIpc4t5vk4PYzt8wpsg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^8.0.0",
+ "@babel/types": "^8.0.0"
+ },
+ "engines": {
+ "node": "^22.18.0 || >=24.11.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "8.0.4",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-8.0.4.tgz",
+ "integrity": "sha512-srpptsAkEbbNIC/q8nT7o+m6CQe8CJUTV/t7MYc9NnWlgYVtHOb7JH6SorxMhN0kuRJjVqXbKClG6xSbPtzz+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^8.0.4"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": "^22.18.0 || >=24.11.0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-8.0.0.tgz",
+ "integrity": "sha512-eAD0QW/AlbamBbw0FeGiwasbCVPq5ncW0HNVyLP3B9czqLyh4gvw+5JTSNt6le9+ziAU7mqDZsKTHf3jTb4chQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^8.0.0",
+ "@babel/parser": "^8.0.0",
+ "@babel/types": "^8.0.0"
+ },
+ "engines": {
+ "node": "^22.18.0 || >=24.11.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "8.0.4",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-8.0.4.tgz",
+ "integrity": "sha512-bZnmqzGG8UZneG1lLxBoWIH0G6Gr1D846Yu4/3XnY6FhCndMR49u26nTY08u/dAxWmLWF9vGQOuC+84FfIUoeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^8.0.0",
+ "@babel/generator": "^8.0.0",
+ "@babel/helper-globals": "^8.0.0",
+ "@babel/parser": "^8.0.4",
+ "@babel/template": "^8.0.0",
+ "@babel/types": "^8.0.4",
+ "obug": "^2.1.1"
+ },
+ "engines": {
+ "node": "^22.18.0 || >=24.11.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "8.0.4",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-8.0.4.tgz",
+ "integrity": "sha512-eY+Yn3dCqTGmyiq2QRU66lA5FL8lqqqvecHt0fF3uHONIa7ToYsaCiWV8lOKqAs0Rb2SjixiKFROngnulPtt2g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^8.0.0",
+ "@babel/helper-validator-identifier": "^8.0.4"
+ },
+ "engines": {
+ "node": "^22.18.0 || >=24.11.0"
+ }
+ },
+ "node_modules/@emnapi/core": {
+ "version": "1.11.2",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.2.tgz",
+ "integrity": "sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/wasi-threads": "1.2.2",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/runtime": {
+ "version": "1.11.2",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.2.tgz",
+ "integrity": "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/wasi-threads": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz",
+ "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz",
+ "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz",
+ "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz",
+ "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz",
+ "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz",
+ "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz",
+ "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz",
+ "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz",
+ "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz",
+ "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz",
+ "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz",
+ "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz",
+ "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz",
+ "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz",
+ "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz",
+ "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz",
+ "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz",
+ "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz",
+ "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz",
+ "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz",
+ "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz",
+ "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz",
+ "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz",
+ "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz",
+ "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz",
+ "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz",
+ "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@harperfast/extended-iterable": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@harperfast/extended-iterable/-/extended-iterable-1.0.3.tgz",
+ "integrity": "sha512-sSAYhQca3rDWtQUHSAPeO7axFIUJOI6hn1gjRC5APVE1a90tuyT8f5WIgRsFhhWA7htNkju2veB9eWL6YHi/Lw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true
+ },
+ "node_modules/@hono/node-server": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-2.1.1.tgz",
+ "integrity": "sha512-ELuehkj5VCBdgEw9zs+ivkKwyzzUCSQuE96YmiPvn1ECBoZCczbFXJLeEGMTYjphP6gydh4pHMqEYPVMYUVgQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=20"
+ },
+ "peerDependencies": {
+ "hono": "^4"
+ }
+ },
+ "node_modules/@inquirer/ansi": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.8.tgz",
+ "integrity": "sha512-WpQM+Ti6Z40EFwwt+uL2p4UabT+W179zHp6HhLVOzfbwnVn05IPO/eXIZXGNqcT1jbQ15SujNLzQ39k4QPPxBQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ }
+ },
+ "node_modules/@inquirer/checkbox": {
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-5.2.4.tgz",
+ "integrity": "sha512-oKT5RNeO9oKYizSyOxKb66IrKUsYVMQD2tnjllYW4wmSOe9WawfL3OE2p82JuvAyo+/nDIEem5P4Bm/ZIVYVew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/ansi": "^2.0.8",
+ "@inquirer/core": "^12.0.2",
+ "@inquirer/figures": "^2.0.9",
+ "@inquirer/type": "4.1.1"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/checkbox/node_modules/@inquirer/core": {
+ "version": "12.0.2",
+ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-12.0.2.tgz",
+ "integrity": "sha512-9pBhkxE14uUlnHhs8lOt7qVPtS4caRY6CjADl8COejl9Mf7w8i6Uoe3DrljCqYtmYM3Iv2Q6EmPxx/oTYbvTAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/ansi": "^2.0.8",
+ "@inquirer/figures": "^2.0.9",
+ "@inquirer/type": "4.1.1",
+ "cli-width": "^4.1.0",
+ "fast-wrap-ansi": "^0.2.0",
+ "mute-stream": "^3.0.0",
+ "signal-exit": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/confirm": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-6.1.1.tgz",
+ "integrity": "sha512-eb8DBZcz/2qHWQda4rk2JiQk5h9QV/cVHi1yjt0f69WFZMRFn0sJTye3EAP8icut8UDMjQPsaH5KbcOogefrFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/core": "^11.2.1",
+ "@inquirer/type": "^4.0.7"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/core": {
+ "version": "11.2.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-11.2.1.tgz",
+ "integrity": "sha512-Qd6GJT1yVyrZZCfN8W2qKF5ApmqryXRhRKCuip8h01x2w/esJQ2XIYc6f9abMIHgKQdBfFTSOdbHRLAhuM09UA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/ansi": "^2.0.7",
+ "@inquirer/figures": "^2.0.7",
+ "@inquirer/type": "^4.0.7",
+ "cli-width": "^4.1.0",
+ "fast-wrap-ansi": "^0.2.0",
+ "mute-stream": "^3.0.0",
+ "signal-exit": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/editor": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-5.3.2.tgz",
+ "integrity": "sha512-7ruKO5d/wxhGHxdCQ3eyP/aBNrPTZ+Ju7ERtnAwuIsu0RSLs6kotlTRkOxHatbD6sDaEEdwsD82pzFiT9ESIyQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/core": "^12.0.2",
+ "@inquirer/external-editor": "^3.0.5",
+ "@inquirer/type": "4.1.1"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/editor/node_modules/@inquirer/core": {
+ "version": "12.0.2",
+ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-12.0.2.tgz",
+ "integrity": "sha512-9pBhkxE14uUlnHhs8lOt7qVPtS4caRY6CjADl8COejl9Mf7w8i6Uoe3DrljCqYtmYM3Iv2Q6EmPxx/oTYbvTAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/ansi": "^2.0.8",
+ "@inquirer/figures": "^2.0.9",
+ "@inquirer/type": "4.1.1",
+ "cli-width": "^4.1.0",
+ "fast-wrap-ansi": "^0.2.0",
+ "mute-stream": "^3.0.0",
+ "signal-exit": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/expand": {
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-5.1.4.tgz",
+ "integrity": "sha512-12o4aYnjWouoq0fyVhYIL+hwXAaga+kntA/wrijFmVvn2heinkdvkbEXRt1Ob/9IOJ285US5tntjfI/Ukt2YkA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/core": "^12.0.2",
+ "@inquirer/type": "4.1.1"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/expand/node_modules/@inquirer/core": {
+ "version": "12.0.2",
+ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-12.0.2.tgz",
+ "integrity": "sha512-9pBhkxE14uUlnHhs8lOt7qVPtS4caRY6CjADl8COejl9Mf7w8i6Uoe3DrljCqYtmYM3Iv2Q6EmPxx/oTYbvTAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/ansi": "^2.0.8",
+ "@inquirer/figures": "^2.0.9",
+ "@inquirer/type": "4.1.1",
+ "cli-width": "^4.1.0",
+ "fast-wrap-ansi": "^0.2.0",
+ "mute-stream": "^3.0.0",
+ "signal-exit": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/external-editor": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-3.0.5.tgz",
+ "integrity": "sha512-f3QQJRIX5ZEneBHNUIuPjmbdzHnmRFJA8r2dkcb8q+OM5Uv5KtnuAttQumnrjcBVBM3mcTX1CkmtAkU58VRZxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chardet": "^2.1.1",
+ "iconv-lite": "^0.7.2"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/figures": {
+ "version": "2.0.9",
+ "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-2.0.9.tgz",
+ "integrity": "sha512-EAWgUTGQ/Umgga51dE3B2PUHbufuXarDfg86uVgoSgNHNNQnyFKcOrQLWVqYMghuSyHh8+2HUH0Js9cTC1WAdg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ }
+ },
+ "node_modules/@inquirer/input": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-5.1.5.tgz",
+ "integrity": "sha512-2MkYYFD1Owt1eRBwHhsLSutysRodWasA4DVpl42KJKGmzwBTXRYAIXujisrt0UW0UohUlMjNjLfMDbw4emRbfw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/core": "^12.0.2",
+ "@inquirer/type": "4.1.1"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/input/node_modules/@inquirer/core": {
+ "version": "12.0.2",
+ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-12.0.2.tgz",
+ "integrity": "sha512-9pBhkxE14uUlnHhs8lOt7qVPtS4caRY6CjADl8COejl9Mf7w8i6Uoe3DrljCqYtmYM3Iv2Q6EmPxx/oTYbvTAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/ansi": "^2.0.8",
+ "@inquirer/figures": "^2.0.9",
+ "@inquirer/type": "4.1.1",
+ "cli-width": "^4.1.0",
+ "fast-wrap-ansi": "^0.2.0",
+ "mute-stream": "^3.0.0",
+ "signal-exit": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/number": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-4.2.2.tgz",
+ "integrity": "sha512-tjW1gMIQsFb/9Ie11i8SpuPARBdyCVfC5XOeVugWovrdm8CpjzN+A1CBX5QwCCN2mtNmpgDDCnuLCCT94cQ5zA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/core": "^12.0.2",
+ "@inquirer/type": "4.1.1"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/number/node_modules/@inquirer/core": {
+ "version": "12.0.2",
+ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-12.0.2.tgz",
+ "integrity": "sha512-9pBhkxE14uUlnHhs8lOt7qVPtS4caRY6CjADl8COejl9Mf7w8i6Uoe3DrljCqYtmYM3Iv2Q6EmPxx/oTYbvTAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/ansi": "^2.0.8",
+ "@inquirer/figures": "^2.0.9",
+ "@inquirer/type": "4.1.1",
+ "cli-width": "^4.1.0",
+ "fast-wrap-ansi": "^0.2.0",
+ "mute-stream": "^3.0.0",
+ "signal-exit": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/password": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-5.2.1.tgz",
+ "integrity": "sha512-InA6nJxMCXPavPBiTKYHIsYiWz/mkIsk1rkI6pKp5w18gVawqrZOj7eSzSmPJa3j0pVxXm6RlrFP1BE9YeOixA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/ansi": "^2.0.8",
+ "@inquirer/core": "^12.0.2",
+ "@inquirer/type": "4.1.1"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/password/node_modules/@inquirer/core": {
+ "version": "12.0.2",
+ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-12.0.2.tgz",
+ "integrity": "sha512-9pBhkxE14uUlnHhs8lOt7qVPtS4caRY6CjADl8COejl9Mf7w8i6Uoe3DrljCqYtmYM3Iv2Q6EmPxx/oTYbvTAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/ansi": "^2.0.8",
+ "@inquirer/figures": "^2.0.9",
+ "@inquirer/type": "4.1.1",
+ "cli-width": "^4.1.0",
+ "fast-wrap-ansi": "^0.2.0",
+ "mute-stream": "^3.0.0",
+ "signal-exit": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/prompts": {
+ "version": "8.5.2",
+ "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-8.5.2.tgz",
+ "integrity": "sha512-IYR/3C/paEVVQYQvdDlFZVjRCJVYHHON0XXMH91KO9GSxs0TdKYWlUdvfQl2EfAHDxUaN3IBffkE/BDTh5nJ6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/checkbox": "^5.2.1",
+ "@inquirer/confirm": "^6.1.1",
+ "@inquirer/editor": "^5.2.2",
+ "@inquirer/expand": "^5.1.1",
+ "@inquirer/input": "^5.1.2",
+ "@inquirer/number": "^4.1.1",
+ "@inquirer/password": "^5.1.1",
+ "@inquirer/rawlist": "^5.3.1",
+ "@inquirer/search": "^4.2.1",
+ "@inquirer/select": "^5.2.1"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/rawlist": {
+ "version": "5.3.4",
+ "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-5.3.4.tgz",
+ "integrity": "sha512-c4fDwOpQsjJDHjXdHJE1/xXH6w9/BAiyu3QKzH9Ww5Xm1q37mzyUNa20L7qdtM1ECi4e+oUEKjhK8hR37OMAMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/core": "^12.0.2",
+ "@inquirer/type": "4.1.1"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/rawlist/node_modules/@inquirer/core": {
+ "version": "12.0.2",
+ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-12.0.2.tgz",
+ "integrity": "sha512-9pBhkxE14uUlnHhs8lOt7qVPtS4caRY6CjADl8COejl9Mf7w8i6Uoe3DrljCqYtmYM3Iv2Q6EmPxx/oTYbvTAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/ansi": "^2.0.8",
+ "@inquirer/figures": "^2.0.9",
+ "@inquirer/type": "4.1.1",
+ "cli-width": "^4.1.0",
+ "fast-wrap-ansi": "^0.2.0",
+ "mute-stream": "^3.0.0",
+ "signal-exit": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/search": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-4.3.2.tgz",
+ "integrity": "sha512-YIaEhWmfkdHEWOKwhF/oJar35FFTTrAdzNbJDo9lSsRT6E/obRPx9oVm4rkTMtlcJSqGYttNtLbcHQef9Qw2yw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/core": "^12.0.2",
+ "@inquirer/figures": "^2.0.9",
+ "@inquirer/type": "4.1.1"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/search/node_modules/@inquirer/core": {
+ "version": "12.0.2",
+ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-12.0.2.tgz",
+ "integrity": "sha512-9pBhkxE14uUlnHhs8lOt7qVPtS4caRY6CjADl8COejl9Mf7w8i6Uoe3DrljCqYtmYM3Iv2Q6EmPxx/oTYbvTAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/ansi": "^2.0.8",
+ "@inquirer/figures": "^2.0.9",
+ "@inquirer/type": "4.1.1",
+ "cli-width": "^4.1.0",
+ "fast-wrap-ansi": "^0.2.0",
+ "mute-stream": "^3.0.0",
+ "signal-exit": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/select": {
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-5.2.4.tgz",
+ "integrity": "sha512-L9ubNaJdoBsiom/AfPKq0QLHTkhhCFCtszzdVidGremrlJjPZfGlmvp+IULKIbnYjtVFWnvb4mhiEdNTZ12ugA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/ansi": "^2.0.8",
+ "@inquirer/core": "^12.0.2",
+ "@inquirer/figures": "^2.0.9",
+ "@inquirer/type": "4.1.1"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/select/node_modules/@inquirer/core": {
+ "version": "12.0.2",
+ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-12.0.2.tgz",
+ "integrity": "sha512-9pBhkxE14uUlnHhs8lOt7qVPtS4caRY6CjADl8COejl9Mf7w8i6Uoe3DrljCqYtmYM3Iv2Q6EmPxx/oTYbvTAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/ansi": "^2.0.8",
+ "@inquirer/figures": "^2.0.9",
+ "@inquirer/type": "4.1.1",
+ "cli-width": "^4.1.0",
+ "fast-wrap-ansi": "^0.2.0",
+ "mute-stream": "^3.0.0",
+ "signal-exit": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/type": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-4.1.1.tgz",
+ "integrity": "sha512-yJoHYrMnxIsJZCY+0Vb66Dy3he3kL3e2wOBKhoSwWWAzZAY82emlxwgprCtp6yRixvNRNq9ztfRWQYPNr3Go7A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz",
+ "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@listr2/prompt-adapter-inquirer": {
+ "version": "4.2.5",
+ "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-4.2.5.tgz",
+ "integrity": "sha512-pYGy9dTdTwXdasPgyohkr0HoQ4FrkAzFnsUZl/gcnadDArbpZ8e+fgr+F9WBdNEl2y00mb9bCM4WgmoBkZJ27A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/type": "^4.0.7"
+ },
+ "engines": {
+ "node": ">=22.13.0"
+ },
+ "peerDependencies": {
+ "@inquirer/prompts": ">= 3 < 9",
+ "listr2": "11.0.0"
+ }
+ },
+ "node_modules/@lmdb/lmdb-darwin-arm64": {
+ "version": "3.5.6",
+ "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.5.6.tgz",
+ "integrity": "sha512-mY5FG4TjPAkY4P0w+OhHaUka5mDh2TX2WKYIwuKzJ1zeW3VvRgxdam/lGJTquI+bthTx5CSHDW+BAQCnNAzkEA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@lmdb/lmdb-darwin-x64": {
+ "version": "3.5.6",
+ "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.5.6.tgz",
+ "integrity": "sha512-foa+pwitysO8k+xhs7psBFfTKnVgR69NlZRRTHaFVDqphh7AdGpLeyRzKw/ofatr/sN6TiHRRW6mmop0ZrrppQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@lmdb/lmdb-linux-arm": {
+ "version": "3.5.6",
+ "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.5.6.tgz",
+ "integrity": "sha512-QR4YRyR5h5Z8eGXrNQjiyo2NNDfqi3tCc9dQG5Is1blCt+qWw1ZoBWhlWAr5d+jshkifMIJjVHzHGKbkKzF8Tw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@lmdb/lmdb-linux-arm64": {
+ "version": "3.5.6",
+ "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.5.6.tgz",
+ "integrity": "sha512-HmiyFFdJa38s1heCMSooSPaBSFTHJ3C+ERPp28xAPlDX1YiALJVOgbry065nXd8Y7KISWjnw05zpG1RX8IfftA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@lmdb/lmdb-linux-x64": {
+ "version": "3.5.6",
+ "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.5.6.tgz",
+ "integrity": "sha512-ADzCuCF2cTNiX9kDScqcz1fjnAkxPpQNneV3KFTdV3wWtVlI2sTGzySoMTgDpinkMMFj1NTJlxA6XR8fwc4hlA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@lmdb/lmdb-win32-arm64": {
+ "version": "3.5.6",
+ "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-arm64/-/lmdb-win32-arm64-3.5.6.tgz",
+ "integrity": "sha512-J7A9aEQsQiv0TYtBGL7NDIPp2lOS8nnl+zm4sWZm1xlsTTaQ4PgD096Adzdrk27rw3UxCkDXdCUa4ax41oztBQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@lmdb/lmdb-win32-x64": {
+ "version": "3.5.6",
+ "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.5.6.tgz",
+ "integrity": "sha512-1g7G0knRX2iV/voDu54yxrGqw5Dk0w2oIYb7dgJq8IkOi+m7wbD8Q3QpPFjh0C01G58S88dqGn03len6UPCXsg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@modelcontextprotocol/sdk": {
+ "version": "1.30.0",
+ "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.30.0.tgz",
+ "integrity": "sha512-xKd8OIzlqNzcqcNumGAa6g+PW2kjD5vrpcKOnfldAUPP3j7lnqMPwlTXQm8gF+UwH72z0lqaRbjr9hqGz0eITA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@hono/node-server": "^1.19.9 || ^2.0.5",
+ "ajv": "^8.17.1",
+ "ajv-formats": "^3.0.1",
+ "content-type": "^1.0.5",
+ "cors": "^2.8.5",
+ "cross-spawn": "^7.0.5",
+ "eventsource": "^3.0.2",
+ "eventsource-parser": "^3.0.0",
+ "express": "^5.2.1",
+ "express-rate-limit": "^8.2.1",
+ "hono": "^4.11.4",
+ "jose": "^6.1.3",
+ "json-schema-typed": "^8.0.2",
+ "pkce-challenge": "^5.0.0",
+ "raw-body": "^3.0.0",
+ "zod": "^3.25 || ^4.0",
+ "zod-to-json-schema": "^3.25.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@cfworker/json-schema": "^4.1.1",
+ "zod": "^3.25 || ^4.0"
+ },
+ "peerDependenciesMeta": {
+ "@cfworker/json-schema": {
+ "optional": true
+ },
+ "zod": {
+ "optional": false
+ }
+ }
+ },
+ "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.4.tgz",
+ "integrity": "sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.4.tgz",
+ "integrity": "sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.4.tgz",
+ "integrity": "sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.4.tgz",
+ "integrity": "sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.4.tgz",
+ "integrity": "sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.4.tgz",
+ "integrity": "sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@napi-rs/nice": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/nice/-/nice-1.1.1.tgz",
+ "integrity": "sha512-xJIPs+bYuc9ASBl+cvGsKbGrJmS6fAKaSZCnT0lhahT5rhA2VVy9/EcIgd2JhtEuFOJNx7UHNn/qiTPTY4nrQw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 10"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ },
+ "optionalDependencies": {
+ "@napi-rs/nice-android-arm-eabi": "1.1.1",
+ "@napi-rs/nice-android-arm64": "1.1.1",
+ "@napi-rs/nice-darwin-arm64": "1.1.1",
+ "@napi-rs/nice-darwin-x64": "1.1.1",
+ "@napi-rs/nice-freebsd-x64": "1.1.1",
+ "@napi-rs/nice-linux-arm-gnueabihf": "1.1.1",
+ "@napi-rs/nice-linux-arm64-gnu": "1.1.1",
+ "@napi-rs/nice-linux-arm64-musl": "1.1.1",
+ "@napi-rs/nice-linux-ppc64-gnu": "1.1.1",
+ "@napi-rs/nice-linux-riscv64-gnu": "1.1.1",
+ "@napi-rs/nice-linux-s390x-gnu": "1.1.1",
+ "@napi-rs/nice-linux-x64-gnu": "1.1.1",
+ "@napi-rs/nice-linux-x64-musl": "1.1.1",
+ "@napi-rs/nice-openharmony-arm64": "1.1.1",
+ "@napi-rs/nice-win32-arm64-msvc": "1.1.1",
+ "@napi-rs/nice-win32-ia32-msvc": "1.1.1",
+ "@napi-rs/nice-win32-x64-msvc": "1.1.1"
+ }
+ },
+ "node_modules/@napi-rs/nice-android-arm-eabi": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.1.1.tgz",
+ "integrity": "sha512-kjirL3N6TnRPv5iuHw36wnucNqXAO46dzK9oPb0wj076R5Xm8PfUVA9nAFB5ZNMmfJQJVKACAPd/Z2KYMppthw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@napi-rs/nice-android-arm64": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.1.1.tgz",
+ "integrity": "sha512-blG0i7dXgbInN5urONoUCNf+DUEAavRffrO7fZSeoRMJc5qD+BJeNcpr54msPF6qfDD6kzs9AQJogZvT2KD5nw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@napi-rs/nice-darwin-arm64": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.1.1.tgz",
+ "integrity": "sha512-s/E7w45NaLqTGuOjC2p96pct4jRfo61xb9bU1unM/MJ/RFkKlJyJDx7OJI/O0ll/hrfpqKopuAFDV8yo0hfT7A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@napi-rs/nice-darwin-x64": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.1.1.tgz",
+ "integrity": "sha512-dGoEBnVpsdcC+oHHmW1LRK5eiyzLwdgNQq3BmZIav+9/5WTZwBYX7r5ZkQC07Nxd3KHOCkgbHSh4wPkH1N1LiQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@napi-rs/nice-freebsd-x64": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.1.1.tgz",
+ "integrity": "sha512-kHv4kEHAylMYmlNwcQcDtXjklYp4FCf0b05E+0h6nDHsZ+F0bDe04U/tXNOqrx5CmIAth4vwfkjjUmp4c4JktQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@napi-rs/nice-linux-arm-gnueabihf": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.1.1.tgz",
+ "integrity": "sha512-E1t7K0efyKXZDoZg1LzCOLxgolxV58HCkaEkEvIYQx12ht2pa8hoBo+4OB3qh7e+QiBlp1SRf+voWUZFxyhyqg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@napi-rs/nice-linux-arm64-gnu": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.1.1.tgz",
+ "integrity": "sha512-CIKLA12DTIZlmTaaKhQP88R3Xao+gyJxNWEn04wZwC2wmRapNnxCUZkVwggInMJvtVElA+D4ZzOU5sX4jV+SmQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@napi-rs/nice-linux-arm64-musl": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.1.1.tgz",
+ "integrity": "sha512-+2Rzdb3nTIYZ0YJF43qf2twhqOCkiSrHx2Pg6DJaCPYhhaxbLcdlV8hCRMHghQ+EtZQWGNcS2xF4KxBhSGeutg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@napi-rs/nice-linux-ppc64-gnu": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.1.1.tgz",
+ "integrity": "sha512-4FS8oc0GeHpwvv4tKciKkw3Y4jKsL7FRhaOeiPei0X9T4Jd619wHNe4xCLmN2EMgZoeGg+Q7GY7BsvwKpL22Tg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@napi-rs/nice-linux-riscv64-gnu": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.1.1.tgz",
+ "integrity": "sha512-HU0nw9uD4FO/oGCCk409tCi5IzIZpH2agE6nN4fqpwVlCn5BOq0MS1dXGjXaG17JaAvrlpV5ZeyZwSon10XOXw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@napi-rs/nice-linux-s390x-gnu": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.1.1.tgz",
+ "integrity": "sha512-2YqKJWWl24EwrX0DzCQgPLKQBxYDdBxOHot1KWEq7aY2uYeX+Uvtv4I8xFVVygJDgf6/92h9N3Y43WPx8+PAgQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@napi-rs/nice-linux-x64-gnu": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.1.1.tgz",
+ "integrity": "sha512-/gaNz3R92t+dcrfCw/96pDopcmec7oCcAQ3l/M+Zxr82KT4DljD37CpgrnXV+pJC263JkW572pdbP3hP+KjcIg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@napi-rs/nice-linux-x64-musl": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.1.1.tgz",
+ "integrity": "sha512-xScCGnyj/oppsNPMnevsBe3pvNaoK7FGvMjT35riz9YdhB2WtTG47ZlbxtOLpjeO9SqqQ2J2igCmz6IJOD5JYw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@napi-rs/nice-openharmony-arm64": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/nice-openharmony-arm64/-/nice-openharmony-arm64-1.1.1.tgz",
+ "integrity": "sha512-6uJPRVwVCLDeoOaNyeiW0gp2kFIM4r7PL2MczdZQHkFi9gVlgm+Vn+V6nTWRcu856mJ2WjYJiumEajfSm7arPQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@napi-rs/nice-win32-arm64-msvc": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.1.1.tgz",
+ "integrity": "sha512-uoTb4eAvM5B2aj/z8j+Nv8OttPf2m+HVx3UjA5jcFxASvNhQriyCQF1OB1lHL43ZhW+VwZlgvjmP5qF3+59atA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@napi-rs/nice-win32-ia32-msvc": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.1.1.tgz",
+ "integrity": "sha512-CNQqlQT9MwuCsg1Vd/oKXiuH+TcsSPJmlAFc5frFyX/KkOh0UpBLEj7aoY656d5UKZQMQFP7vJNa1DNUNORvug==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@napi-rs/nice-win32-x64-msvc": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.1.1.tgz",
+ "integrity": "sha512-vB+4G/jBQCAh0jelMTY3+kgFy00Hlx2f2/1zjMoH821IbplbWZOkLiTYXQkygNTzQJTq5cvwBDgn2ppHD+bglQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@napi-rs/wasm-runtime": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.3.tgz",
+ "integrity": "sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@tybys/wasm-util": "^0.10.3"
+ },
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=23.5.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ },
+ "peerDependencies": {
+ "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.4",
+ "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.4"
+ }
+ },
+ "node_modules/@oxc-parser/binding-android-arm-eabi": {
+ "version": "0.142.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm-eabi/-/binding-android-arm-eabi-0.142.0.tgz",
+ "integrity": "sha512-ZiRGDutGsv1G6bL/ozy/koC0Sv39T1DqyoC4KD1DOy9ZoACm1O5UWhEK2c02Qdk+4lfLVkvFa/mQ0fm/4h1BtQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-android-arm64": {
+ "version": "0.142.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.142.0.tgz",
+ "integrity": "sha512-WZkvGRLNQTz8lR9zP5nLjUdlroRCopBu3g9zF1p/laE6DzT1UbQo8Rdz5MWhaJUPYg/6gp+jo7HUgsyKaN1FtQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-darwin-arm64": {
+ "version": "0.142.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-arm64/-/binding-darwin-arm64-0.142.0.tgz",
+ "integrity": "sha512-l4khS8LQOOVYsGRVARo1gSaCT/aBSceUVXgtovWc2+drnxVuDr082WA3OCHVdVzIz5JIrP/y9CWsSKxBDNmYGg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-darwin-x64": {
+ "version": "0.142.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-x64/-/binding-darwin-x64-0.142.0.tgz",
+ "integrity": "sha512-QBsNF3nqlXmcH2B1YOPqQYmCJoy4HuIjUxGbBO/k5JAJUl68ghU2psRY2zPk+RyBaWqKP/qfL4oaFgEMCdwskA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-freebsd-x64": {
+ "version": "0.142.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-freebsd-x64/-/binding-freebsd-x64-0.142.0.tgz",
+ "integrity": "sha512-b7Q7m4Cqc6XqNhri3R+QhU+GVy646Pn+bkdhrDdWym/Fdi0ZUa+d73H9dm5H91JtbtAQ/z1d8XKMW3oOV8a4tQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-arm-gnueabihf": {
+ "version": "0.142.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.142.0.tgz",
+ "integrity": "sha512-3riVS5IhdH3uCZj1Y9ftDQlR0dvLsIlw/edrRqk8JhgNd5K0XSs+UBtgh50N13CAlW9/TXj6sVGXaKNBocd0Yg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-arm-musleabihf": {
+ "version": "0.142.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.142.0.tgz",
+ "integrity": "sha512-NmXUOpgpTSkhl795TiXmWppTwmSJ92RC1qvD6e4XOF+slgmo3e6Ah+kEu+6AN8s7NAOEwqGmir58MgSQSWmBSA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-arm64-gnu": {
+ "version": "0.142.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.142.0.tgz",
+ "integrity": "sha512-gc0EXsKtXgerujmU2Bql3u1L1HsSQ2774R83idq/FoNMPVV/RY/1ErFsvnit7KoiP/sLvzQixeUo4Ut0ic0wmw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-arm64-musl": {
+ "version": "0.142.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.142.0.tgz",
+ "integrity": "sha512-F2XvmWSE0uWpie+jHKKIFgdVOe9ypGhkEZxKx5DuW215K6cbAC274yYaPkcM7EqY4Df3Weyhpcz3lsURyH2LVg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-ppc64-gnu": {
+ "version": "0.142.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.142.0.tgz",
+ "integrity": "sha512-wLMbT21U/QxknQsk+VvNF0b9D2/aGWhcaQQQ+VYlE8FwD5+GoWZIPPXNzyHmkYyhm0KB3itL+TBavjMatqNnYA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-riscv64-gnu": {
+ "version": "0.142.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.142.0.tgz",
+ "integrity": "sha512-+G8F/4ckwT7FCJV4H2bt09xEzJbjNCfuL4Sp1AYNaFtFMVtgIGMuJlteT82U+K0UIZ/DzAR/LDlMFnEuajG7Kw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-riscv64-musl": {
+ "version": "0.142.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.142.0.tgz",
+ "integrity": "sha512-hTsHtTLxMAfCo+rpF5K3qZJKW2NpPN/CHd4mYB3y7XlSdspHkd2gehDIofP64AacA9nWQw2tY3O7wR6UY8IVOA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-s390x-gnu": {
+ "version": "0.142.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.142.0.tgz",
+ "integrity": "sha512-6y7qYY3TCUDYjqswImdTGl92y+KA/80twALegQPN27kfY+bG7Ib1+L3jbmrCZQx6wrVnai9IPsEZp07I0hx7JQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-x64-gnu": {
+ "version": "0.142.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.142.0.tgz",
+ "integrity": "sha512-i69kAWU+2LgoH5bR+zWiiu+UzAw7Oxkwv7COeJTeY19pn4e70nKQcr9Pm6cL2Z0Z54d+gl9qADlK/0yyuCPiBA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-x64-musl": {
+ "version": "0.142.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-musl/-/binding-linux-x64-musl-0.142.0.tgz",
+ "integrity": "sha512-4SQs678MmjYVrmhAgCWD4o0vpaFszXw9xLX5p2Z9MMFcltxiLkA88wQjh80YHjPrXtpyZ2CWI5m+1yNKM0m2Pw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-openharmony-arm64": {
+ "version": "0.142.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-openharmony-arm64/-/binding-openharmony-arm64-0.142.0.tgz",
+ "integrity": "sha512-YHpx9N7Ln3a++Tc8rv+H7mrK1zyJQOAwCFg8LZ3lTs1T5afGWeZrLPhPT9HLnIwSjCyJqPWVMIrMxbjcmBr2oQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-wasm32-wasi": {
+ "version": "0.142.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-wasm32-wasi/-/binding-wasm32-wasi-0.142.0.tgz",
+ "integrity": "sha512-3pLDyY3+oogW73RM5uehNgAiR/Xfb7fvO2Q1Z1gIqZ2+50XDVQmBVlRkHXZTU4gKnQHpwETNsYQVsJ3joVB2iA==",
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "1.11.2",
+ "@emnapi/runtime": "1.11.2",
+ "@napi-rs/wasm-runtime": "^1.1.6"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-win32-arm64-msvc": {
+ "version": "0.142.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.142.0.tgz",
+ "integrity": "sha512-Had/VeVY28Oyb0K+Q4FV8KCzoBycIh93oDK6pCbya9lkzdq+ikMHMgBubsdqqlybjJmQRawCQRrnBRHyQwYvcQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-win32-ia32-msvc": {
+ "version": "0.142.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.142.0.tgz",
+ "integrity": "sha512-GGi3+YphVHavvgs6gum2UXoNCqzHAmPt/nXkn8ZQZstV2Q1qZD1Mn8fz/nWrDkefHQtrG/+1/XrbMxsBTo6Svw==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-win32-x64-msvc": {
+ "version": "0.142.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.142.0.tgz",
+ "integrity": "sha512-Ny/Wv4Us1LGC/ljwNTp+Hx3r/pH15EFfeDF0p+n898gt+TtRd6C9SccHcuUhDiNTb8s5tt7jdeAMDRQZ4Vq6hg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-project/types": {
+ "version": "0.142.0",
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.142.0.tgz",
+ "integrity": "sha512-7W+2q5AKQVU36fkaryontrHn3YDt1RyUYXatw9i5H8ocYe2sPKSFB6eS8WNPeRKiN1qAWWZUPm7gwFzJGrccqQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/Boshen"
+ }
+ },
+ "node_modules/@parcel/watcher": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.6.0.tgz",
+ "integrity": "sha512-7FNeNl8NCE7aINx7WXiKQrPYZWC/hvrTsmk6zmxbI7LTXE7hVek/n8AfVgpe2y82zl3w0HvCHN0bVKMBoJcC0w==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "detect-libc": "^2.0.3",
+ "is-glob": "^4.0.3",
+ "node-addon-api": "^7.0.0",
+ "picomatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "@parcel/watcher-android-arm64": "2.6.0",
+ "@parcel/watcher-darwin-arm64": "2.6.0",
+ "@parcel/watcher-darwin-x64": "2.6.0",
+ "@parcel/watcher-freebsd-x64": "2.6.0",
+ "@parcel/watcher-linux-arm-glibc": "2.6.0",
+ "@parcel/watcher-linux-arm-musl": "2.6.0",
+ "@parcel/watcher-linux-arm64-glibc": "2.6.0",
+ "@parcel/watcher-linux-arm64-musl": "2.6.0",
+ "@parcel/watcher-linux-x64-glibc": "2.6.0",
+ "@parcel/watcher-linux-x64-musl": "2.6.0",
+ "@parcel/watcher-win32-arm64": "2.6.0",
+ "@parcel/watcher-win32-x64": "2.6.0"
+ }
+ },
+ "node_modules/@parcel/watcher-android-arm64": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.6.0.tgz",
+ "integrity": "sha512-trgpLSCKRC/huFjXX/Smh+0sWe4+YtKfktIToiMl59ghz7z+qkH6kMvNnUbLyRs9N11t8l4svSCs1+5B3rOAhA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-darwin-arm64": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.6.0.tgz",
+ "integrity": "sha512-Y3QV0gl7Q1zbfueunkWIERICbEojQFCgpyG7YqOGNFLsckXyI1xu9mAIUpKY9QBYzBtSkN8dBPwd3yiAO9ovMw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-darwin-x64": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.6.0.tgz",
+ "integrity": "sha512-Ohv6OpzhUfKYD7Beb8kDvG0jbIxORCYY1JRdZnaBtnjjkJxgD7ZVL0nw2sCYd0yTMKTvz3nnTnOF3cDifK+kvw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-freebsd-x64": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.6.0.tgz",
+ "integrity": "sha512-5HmXvDgs8VK+74jF9y9/2FE3/OnlcKmc56tjmSrEuZjpSZOGL+fvAu+HKJBdPs9uwoP2hE6TlSUpXZ/C5jUFmQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm-glibc": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.6.0.tgz",
+ "integrity": "sha512-Ps/hui3A+vMbjdqlqAowK2ZL8+BO8dBjxeWXj6npTBs3jx4wWmbPpaLuqwrQrSqIVMCnpWo238bJ1U37GhQOYg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm-musl": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.6.0.tgz",
+ "integrity": "sha512-9c6AUHgHoG+IY88MRIHupztQiQnrbqHYQjkM2btA+Bf/wQnQMuiD0Wfk1EVv3TlNT3x41uU71rn6E4xh/+zvkw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm64-glibc": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.6.0.tgz",
+ "integrity": "sha512-yHRqS2owEXe6Hic9z6Mh1ECsCd+ODVOGvZDyciqRd21+v+o+DnXMOrw50DSpIG2sb8GPEaPPmfeCAWKPJdq46g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm64-musl": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.6.0.tgz",
+ "integrity": "sha512-WhB2e/V7rqdHHWZusBSPuy5Ei8S6lSz6FE5TKKQz5h3a0O+C+mhY7vxU9b/stqvMb8beLnPY82ZrFTLKs+SrKA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-x64-glibc": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.6.0.tgz",
+ "integrity": "sha512-ulGE6x6Oz6iAwg75T8YQSoguBWasniIbX+QWpaYPcCnDOpdWX3k+4xbEYPZVLxOuoJI+svJJPD3sEj8G7lrQ3A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-x64-musl": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.6.0.tgz",
+ "integrity": "sha512-tkBYKt7YQrjIJWYDnto2YgO8MRkjlMTSNoRHzsXinBqbLdeOM3L32wPZJvIZxqaLMfSlS/4sUjH/6STVP/XDLw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-arm64": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.6.0.tgz",
+ "integrity": "sha512-gIZAP23jaHjGWasY/TY6yL7NHFClf0Ga7FN+iINvk+KN94rhm94lYZhFsbYFNcA04/onvGD9kKmiJLJB2HbNwQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-x64": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.6.0.tgz",
+ "integrity": "sha512-cA+/pXV2YkfxlIcXOQ5fSWqAzzPyD78/x5qbK/I0vUkrlYHA8TIz+MXjAbGouguKVSI4bOmkTSJ1/poVSsgt+A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher/node_modules/node-addon-api": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
+ "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/@rolldown/binding-android-arm64": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.0.tgz",
+ "integrity": "sha512-9yB1l95IrJuNGDFdOYe79vdApdz6WWBCObE+rQ2LUliYUlcyFwSYIb2xb5/Ifw7dAtMy2ZqNyd8QTSOc7duAKw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-darwin-arm64": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.0.tgz",
+ "integrity": "sha512-pexNaW9ACLUOaBITOpU6qVu4VrsOFIjTv6bzgu0YUATo4eUJx0V605PxwZfndpPOn0ilqGqvGQ0M8UW0IE24jg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-darwin-x64": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.0.tgz",
+ "integrity": "sha512-NqKYaq0355ZmNMG4QGpxtEDxsc7tGDhjhCm4PpE0cwnBW+5Il95LJyq414niEiaKLVjnVHBEjSo1wngKxJNiFw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-freebsd-x64": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.0.tgz",
+ "integrity": "sha512-3vPoHzh6eBTz9IbB0/qZdSr0Qeks2echn+I4cHu2joV74VriPDdldswksEDzrl1mBB+oPRi+67+3Ib59paxIPQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-arm-gnueabihf": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.0.tgz",
+ "integrity": "sha512-E6NNefZ1bUVmKJq2tJkf45J4Zyczj7qm9rUT7NY+Xo2474Y13qWAwc2tvBt0BAVbmtXR1llkxXg0Ou1jbDf2SQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-arm64-gnu": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.0.tgz",
+ "integrity": "sha512-D+TgkdgM1vu+7/Fpf8+v0ARW+RXEP9Ccazgm8zQ4JFFd9Q7SrYQ2TakU5S5ihazQDgpKyAgZDOcIFsvoHmTZ8w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-arm64-musl": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.0.tgz",
+ "integrity": "sha512-wUqdwJBbAv0APN87GecstdMUtLjjNTs0hBALpxETD73mccFxdmt/XeizXDtN5RAlBwNKmI+Tg+blect2G+8IeQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-ppc64-gnu": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.0.tgz",
+ "integrity": "sha512-9DtF35qR9/NrfhM4oxLplCzVVjE+KKm8Pjemi0i/sdhAWkUasjmSo8WTTubNJClhSHCfyk2yeyoXDQEDPtDAAw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-s390x-gnu": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.0.tgz",
+ "integrity": "sha512-RzuHrBh8X8Hntd2N4VR02QGEciq/9JhcZoTpR/Cee6otRrlILGCf3cg2ygHuih+ZebUnWmMrDX6ITI85btO6rQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-x64-gnu": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.0.tgz",
+ "integrity": "sha512-MK7L0018jjh1jR3mh21G2j1zAVcpscJBlPo2z19pRjv2XOYGRhaV4LyiD8HO6nCDdZln9IFgCMIV5yt4E3klGQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-x64-musl": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.0.tgz",
+ "integrity": "sha512-gyrxLQ9NfGb/9LoVnC4kb9miUghw1mghnkfYvNHSnVIXriabnfgGPUP4RLcJm87q3KgYz4FYUG8IDiWUT+CpSw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-openharmony-arm64": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.0.tgz",
+ "integrity": "sha512-/6VFMQGRmrhP77KXDC+StIxGzcNp5JOIyYtw0CQ8gPlzhpiIRucYfoM5FaFamHd5BJYIdH86yfP46l1p3WdrFA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-wasm32-wasi": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.2.0.tgz",
+ "integrity": "sha512-rwdbUL465kisF24WEJLvP3JrEG6E5GRuIHt5wpMwHGERtHe4Wm2CIvtf5gTBgr2tGOHKh5NdKEAFS2VkOPE91g==",
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "1.11.2",
+ "@emnapi/runtime": "1.11.2",
+ "@napi-rs/wasm-runtime": "^1.1.6"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-win32-arm64-msvc": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.0.tgz",
+ "integrity": "sha512-+5suHwRiKGmhwyUaNT8a5QbrBvLFh2DbO910TEmGRH1aSxwrCezodvGQnulv4uiWEIv1Kq4ypRsJ5+O+ry1DiA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-win32-x64-msvc": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.0.tgz",
+ "integrity": "sha512-WfFv6/qGufotqBSBzBYwgpCkJBk8Nj7697LL9vTz/XWc67e0r3oewu8iMRwQj3AUL45GVD7wVsPjCsAAtW66Wg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/pluginutils": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz",
+ "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@schematics/angular": {
+ "version": "22.1.7",
+ "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-22.1.7.tgz",
+ "integrity": "sha512-acBv147JjnwtWFgC8Af0KFBzPpb/TWaYxoWN/Ou3pXtUhYiEqnrdJeoFz3ssDw26eKFIdWnVBLB/dHORBykPBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@angular-devkit/core": "22.1.7",
+ "@angular-devkit/schematics": "22.1.7",
+ "jsonc-parser": "3.3.1",
+ "typescript": "6.0.3"
+ },
+ "engines": {
+ "node": "^22.22.3 || ^24.15.0 || >=26.0.0",
+ "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
+ "yarn": ">= 1.13.0"
+ }
+ },
+ "node_modules/@standard-schema/spec": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
+ "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
+ "license": "MIT"
+ },
+ "node_modules/@tybys/wasm-util": {
+ "version": "0.10.3",
+ "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz",
+ "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@types/gensync": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@types/gensync/-/gensync-1.0.5.tgz",
+ "integrity": "sha512-MbsRCT7mTikHwKZ0X+LVUTLRrZZRLipTuXEO9qOYO+zmjMVk81axyClMROf6uoPD9MRVu46bx8zoR0Ad9q3NAg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/jsesc": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@types/jsesc/-/jsesc-2.5.1.tgz",
+ "integrity": "sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@vitejs/plugin-basic-ssl": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-2.3.0.tgz",
+ "integrity": "sha512-bdyo8rB3NnQbikdMpHaML9Z1OZPBu6fFOBo+OtxsBlvMJtysWskmBcnbIDhUqgC8tcxNv/a+BcV5U+2nQMm1OQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/accepts": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
+ "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "^3.0.0",
+ "negotiator": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-9.0.0.tgz",
+ "integrity": "sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "8.20.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
+ "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ajv-formats": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz",
+ "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ansi-escapes": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz",
+ "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "environment": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz",
+ "integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.11.20",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.20.tgz",
+ "integrity": "sha512-H0ulySigv6icDJ1F7SjtdCD6PrhTpdYCmP0CactWy1+ekh0AFd0o1Wn5T8b+hnTmdBx19u9yhL6wvCylXMY7zw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.cjs"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/beasties": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/beasties/-/beasties-0.4.3.tgz",
+ "integrity": "sha512-fIIeLOcbAB/K1kb1HBVJoiq1alHL4RCYBSo5e7HzrNkkgMggXR1Vqt/Z9JWnkfe/qdCo66Ux3QRwZioAIBdWRA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "css-select": "^6.0.0",
+ "css-what": "^7.0.0",
+ "dom-serializer": "^2.0.0",
+ "domhandler": "^5.0.3",
+ "htmlparser2": "^10.0.0",
+ "picocolors": "^1.1.1",
+ "postcss": "^8.4.49",
+ "postcss-media-query-parser": "^0.2.3",
+ "postcss-safe-parser": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/body-parser": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz",
+ "integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "^3.1.2",
+ "content-type": "^2.0.0",
+ "debug": "^4.4.3",
+ "http-errors": "^2.0.1",
+ "iconv-lite": "^0.7.2",
+ "on-finished": "^2.4.1",
+ "qs": "^6.15.2",
+ "raw-body": "^3.0.2",
+ "type-is": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/body-parser/node_modules/content-type": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz",
+ "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/browserslist": {
+ "version": "4.28.8",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.8.tgz",
+ "integrity": "sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "baseline-browser-mapping": "^2.11.12",
+ "caniuse-lite": "^1.0.30001809",
+ "electron-to-chromium": "^1.5.402",
+ "node-releases": "^2.0.53",
+ "update-browserslist-db": "^1.3.0"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001810",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz",
+ "integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/chalk": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/chardet": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.2.0.tgz",
+ "integrity": "sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/chokidar": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz",
+ "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readdirp": "^5.0.0"
+ },
+ "engines": {
+ "node": ">= 20.19.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/cli-cursor": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz",
+ "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "restore-cursor": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-spinners": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.4.0.tgz",
+ "integrity": "sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-truncate": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-6.1.1.tgz",
+ "integrity": "sha512-06p9vyLahLa4zkGcgsGxU6iEkSOiuI4fhCH6Emhe2lPAcoUv73n72DnODsnHA+5wwXGnV0n9M9/qOQJSjYhFhw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "slice-ansi": "^9.0.0",
+ "string-width": "^8.2.0"
+ },
+ "engines": {
+ "node": ">=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-width": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz",
+ "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/cliui": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz",
+ "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^7.2.0",
+ "strip-ansi": "^7.1.0",
+ "wrap-ansi": "^9.0.0"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/cliui/node_modules/string-width": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cliui/node_modules/wrap-ansi": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
+ "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "string-width": "^7.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/content-disposition": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz",
+ "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/content-type": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/convert-source-map": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cookie": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
+ "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie-signature": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
+ "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.6.0"
+ }
+ },
+ "node_modules/cors": {
+ "version": "2.8.6",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz",
+ "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "object-assign": "^4",
+ "vary": "^1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/css-select": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-6.0.0.tgz",
+ "integrity": "sha512-rZZVSLle8v0+EY8QAkDWrKhpgt6SA5OtHsgBnsj6ZaLb5dmDVOWUDtQitd9ydxxvEjhewNudS6eTVU7uOyzvXw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^7.0.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.2.2",
+ "nth-check": "^2.1.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/css-what": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-7.0.0.tgz",
+ "integrity": "sha512-wD5oz5xibMOPHzy13CyGmogB3phdvcDaB5t0W/Nr5Z2O/agcB8YwOz6e2Lsp10pNDzBoDO9nVa3RGs/2BttpHQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/detect-libc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+ "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.420",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.420.tgz",
+ "integrity": "sha512-2yD6XreGusOfNV+dUcvipJEXc3n/n7fgr7996aszTG+YY5E4mqM4tOq/3uhP129cazL9YHbVWSpc79ePotWtPA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/emoji-regex": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
+ "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/empathic": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.1.tgz",
+ "integrity": "sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/encodeurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/environment": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz",
+ "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz",
+ "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz",
+ "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.28.2",
+ "@esbuild/android-arm": "0.28.2",
+ "@esbuild/android-arm64": "0.28.2",
+ "@esbuild/android-x64": "0.28.2",
+ "@esbuild/darwin-arm64": "0.28.2",
+ "@esbuild/darwin-x64": "0.28.2",
+ "@esbuild/freebsd-arm64": "0.28.2",
+ "@esbuild/freebsd-x64": "0.28.2",
+ "@esbuild/linux-arm": "0.28.2",
+ "@esbuild/linux-arm64": "0.28.2",
+ "@esbuild/linux-ia32": "0.28.2",
+ "@esbuild/linux-loong64": "0.28.2",
+ "@esbuild/linux-mips64el": "0.28.2",
+ "@esbuild/linux-ppc64": "0.28.2",
+ "@esbuild/linux-riscv64": "0.28.2",
+ "@esbuild/linux-s390x": "0.28.2",
+ "@esbuild/linux-x64": "0.28.2",
+ "@esbuild/netbsd-arm64": "0.28.2",
+ "@esbuild/netbsd-x64": "0.28.2",
+ "@esbuild/openbsd-arm64": "0.28.2",
+ "@esbuild/openbsd-x64": "0.28.2",
+ "@esbuild/openharmony-arm64": "0.28.2",
+ "@esbuild/sunos-x64": "0.28.2",
+ "@esbuild/win32-arm64": "0.28.2",
+ "@esbuild/win32-ia32": "0.28.2",
+ "@esbuild/win32-x64": "0.28.2"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/eventsource": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz",
+ "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eventsource-parser": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/eventsource-parser": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.1.1.tgz",
+ "integrity": "sha512-EKN1vKAMcZ8MlYMpaNuxN6R9yakzH6uajHcHVTqWJzvu5pWw9DyhbP35HH8MVBQ+dZjAfDxk+A8NiR9KWaXiyQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/express": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
+ "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "^2.0.0",
+ "body-parser": "^2.2.1",
+ "content-disposition": "^1.0.0",
+ "content-type": "^1.0.5",
+ "cookie": "^0.7.1",
+ "cookie-signature": "^1.2.1",
+ "debug": "^4.4.0",
+ "depd": "^2.0.0",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "finalhandler": "^2.1.0",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.0",
+ "merge-descriptors": "^2.0.0",
+ "mime-types": "^3.0.0",
+ "on-finished": "^2.4.1",
+ "once": "^1.4.0",
+ "parseurl": "^1.3.3",
+ "proxy-addr": "^2.0.7",
+ "qs": "^6.14.0",
+ "range-parser": "^1.2.1",
+ "router": "^2.2.0",
+ "send": "^1.1.0",
+ "serve-static": "^2.2.0",
+ "statuses": "^2.0.1",
+ "type-is": "^2.0.1",
+ "vary": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/express-rate-limit": {
+ "version": "8.7.0",
+ "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.7.0.tgz",
+ "integrity": "sha512-hOwV7WOxXfjRpAM1DSJWZDXx3GhplwD8IfwuwvogD8i1Qnkgosw/H45s4ZnFAUHDAhPjlY9hLBvJhKmGMyY26g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.3",
+ "ip-address": "^10.2.0"
+ },
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/express-rate-limit"
+ },
+ "peerDependencies": {
+ "express": ">= 4.11"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-string-truncated-width": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz",
+ "integrity": "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-string-width": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/fast-string-width/-/fast-string-width-3.0.2.tgz",
+ "integrity": "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-string-truncated-width": "^3.0.2"
+ }
+ },
+ "node_modules/fast-uri": {
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.7.tgz",
+ "integrity": "sha512-dOvZVzjdZdz7phd9v6jCbwxrBW3fK6n8Rc0CtdmM4bumzMnxywBYhuph6J819RRw/ku+rLbelwfMunktuzVVHg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/fast-wrap-ansi": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/fast-wrap-ansi/-/fast-wrap-ansi-0.2.2.tgz",
+ "integrity": "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-string-width": "^3.0.2"
+ }
+ },
+ "node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/finalhandler": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz",
+ "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.0",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "on-finished": "^2.4.1",
+ "parseurl": "^1.3.3",
+ "statuses": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
+ "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-east-asian-width": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz",
+ "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
+ "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/hono": {
+ "version": "4.13.5",
+ "resolved": "https://registry.npmjs.org/hono/-/hono-4.13.5.tgz",
+ "integrity": "sha512-O6+/eCYRkzzzy0rPWwKLiGBR1nFuUPZynnwjxN1MBA62NNqbT0wQEzQyK2gSO5yDIDB336sXQleAhOHrzlYyKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16.9.0"
+ }
+ },
+ "node_modules/hosted-git-info": {
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-10.1.1.tgz",
+ "integrity": "sha512-DeOnSPAvOndYKfw075gt8yZzQ7S2hNztw34zBTfhIzLhmBTswIBg5/y+pqu/VD5cYWm5goAFTusDmUEmKZ0PEQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "lru-cache": "^11.1.0"
+ },
+ "engines": {
+ "node": "^22.22.2 || ^24.15.0 || >=26.0.0"
+ }
+ },
+ "node_modules/htmlparser2": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz",
+ "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==",
+ "dev": true,
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.2.2",
+ "entities": "^7.0.1"
+ }
+ },
+ "node_modules/htmlparser2/node_modules/entities": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
+ "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/http-errors": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
+ "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "depd": "~2.0.0",
+ "inherits": "~2.0.4",
+ "setprototypeof": "~1.2.0",
+ "statuses": "~2.0.2",
+ "toidentifier": "~1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-9.1.0.tgz",
+ "integrity": "sha512-ag87y7cJJ9/3+GxFr8Oy4O5faDsGRGnBGsJj/YjOSsSx/5eadKLYTMPlzuR6obgoCDDm0abAAZitXXQkMOPSpA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "9.0.0",
+ "debug": "^4.3.4",
+ "proxy-agent-negotiate": "1.1.0"
+ },
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz",
+ "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/immutable": {
+ "version": "5.1.9",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.9.tgz",
+ "integrity": "sha512-m8nVez3rwrgmWxtLMt1ZYXB2Lv7OKYn/disyxAlSDYAlKSlFoPPfIAmAM/M5xqL4m4C/wAPw7S2/CNaUii1Hxg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/import-meta-resolve": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz",
+ "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ip-address": {
+ "version": "10.7.0",
+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.7.0.tgz",
+ "integrity": "sha512-BGFsyJd5mpXp3rK6jIdADLNgpJUK1jnjzvYF8lK+VyDab9JAmqN0YOKDdP17HlgKb2+ehPgDc8EtnRLbGCAMhA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz",
+ "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-east-asian-width": "^1.3.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-interactive": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz",
+ "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-promise": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
+ "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-unicode-supported": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz",
+ "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/jose": {
+ "version": "6.2.10",
+ "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.10.tgz",
+ "integrity": "sha512-iiW7J9qRFlGxvCOIBDBDxFePQSn7ZMAnrYGhrrOo6siO/MIqwfyilLR27pkfDgUk+raLuzADS8A3S/KLBisc0g==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/panva"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz",
+ "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-typed": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz",
+ "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/jsonc-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz",
+ "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lightningcss": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz",
+ "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "detect-libc": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "lightningcss-android-arm64": "1.33.0",
+ "lightningcss-darwin-arm64": "1.33.0",
+ "lightningcss-darwin-x64": "1.33.0",
+ "lightningcss-freebsd-x64": "1.33.0",
+ "lightningcss-linux-arm-gnueabihf": "1.33.0",
+ "lightningcss-linux-arm64-gnu": "1.33.0",
+ "lightningcss-linux-arm64-musl": "1.33.0",
+ "lightningcss-linux-x64-gnu": "1.33.0",
+ "lightningcss-linux-x64-musl": "1.33.0",
+ "lightningcss-win32-arm64-msvc": "1.33.0",
+ "lightningcss-win32-x64-msvc": "1.33.0"
+ }
+ },
+ "node_modules/lightningcss-android-arm64": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz",
+ "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-arm64": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz",
+ "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-x64": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz",
+ "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-freebsd-x64": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz",
+ "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm-gnueabihf": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz",
+ "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-gnu": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz",
+ "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-musl": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz",
+ "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-gnu": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz",
+ "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-musl": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz",
+ "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-arm64-msvc": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz",
+ "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-x64-msvc": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz",
+ "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/listr2": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/listr2/-/listr2-11.0.0.tgz",
+ "integrity": "sha512-8K88S0aSrcSXdJfiZtEy5BQMnR+TyjrCGLcgAvQs6ta0NEnIm0RJ72/Pv67Jvg07cfBhDbuN74V81lSSVYEFEw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cli-truncate": "^6.1.1",
+ "log-update": "^8.0.0",
+ "wrap-ansi": "^10.0.0"
+ },
+ "engines": {
+ "node": ">=22.13.0"
+ }
+ },
+ "node_modules/lmdb": {
+ "version": "3.5.6",
+ "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.5.6.tgz",
+ "integrity": "sha512-j3uE8ReKNyUWDjhfEFSJqE/1DLtfTR5Z8yFzVHvBjAk37wNg7HdScjcv8ttPHRvrdgPQMPWxFFI0SsdBzI5lBw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@harperfast/extended-iterable": "^1.0.3",
+ "msgpackr": "^1.11.2",
+ "node-addon-api": "^6.1.0",
+ "node-gyp-build-optional-packages": "5.2.2",
+ "ordered-binary": "^1.5.3",
+ "weak-lru-cache": "^1.2.2"
+ },
+ "bin": {
+ "download-lmdb-prebuilds": "bin/download-prebuilds.js"
+ },
+ "optionalDependencies": {
+ "@lmdb/lmdb-darwin-arm64": "3.5.6",
+ "@lmdb/lmdb-darwin-x64": "3.5.6",
+ "@lmdb/lmdb-linux-arm": "3.5.6",
+ "@lmdb/lmdb-linux-arm64": "3.5.6",
+ "@lmdb/lmdb-linux-x64": "3.5.6",
+ "@lmdb/lmdb-win32-arm64": "3.5.6",
+ "@lmdb/lmdb-win32-x64": "3.5.6"
+ }
+ },
+ "node_modules/log-symbols": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz",
+ "integrity": "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-unicode-supported": "^2.0.0",
+ "yoctocolors": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/log-update/-/log-update-8.0.0.tgz",
+ "integrity": "sha512-lddSgOt3bPASrylL54ZSpy8nBHns+vBVSoILlVOx+dei300pnLRN958rj/EdlVLKuWlSESU3qdnDZdAI7FXYGg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-escapes": "^7.3.0",
+ "cli-cursor": "^5.0.0",
+ "slice-ansi": "^9.0.0",
+ "string-width": "^8.2.0",
+ "strip-ansi": "^7.2.0",
+ "wrap-ansi": "^10.0.0"
+ },
+ "engines": {
+ "node": ">=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "11.5.2",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz",
+ "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.0.0.tgz",
+ "integrity": "sha512-CGvjzMN08iv6w1mm4/x3Gh1hLb4VnyRUA15FFpl6CsCIGGoe36k7kY5KNz9QDbSBN5I/fWHM6ZlIkUTa5xdUEA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/media-typer": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.1.tgz",
+ "integrity": "sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/merge-descriptors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
+ "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.54.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
+ "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
+ "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "^1.54.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/mimic-function": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz",
+ "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mrmime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
+ "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/msgpackr": {
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.12.1.tgz",
+ "integrity": "sha512-4EUH9tQHnMmEgzW/MdAP0KIfa1T9AF+htl0ffe2n5vb2EKn9y2co8ccpgWko6S52Jy1PQZKwRnx5/KkYjtd9MQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "optionalDependencies": {
+ "msgpackr-extract": "^3.0.2"
+ }
+ },
+ "node_modules/msgpackr-extract": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.4.tgz",
+ "integrity": "sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "node-gyp-build-optional-packages": "5.2.2"
+ },
+ "bin": {
+ "download-msgpackr-prebuilds": "bin/download-prebuilds.js"
+ },
+ "optionalDependencies": {
+ "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.4",
+ "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.4",
+ "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.4",
+ "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.4",
+ "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.4",
+ "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.4"
+ }
+ },
+ "node_modules/mute-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-3.0.0.tgz",
+ "integrity": "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.18",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz",
+ "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/negotiator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.1.0.tgz",
+ "integrity": "sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "content-type": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/negotiator/node_modules/content-type": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz",
+ "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/node-addon-api": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz",
+ "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/node-gyp-build-optional-packages": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz",
+ "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "detect-libc": "^2.0.1"
+ },
+ "bin": {
+ "node-gyp-build-optional-packages": "bin.js",
+ "node-gyp-build-optional-packages-optional": "optional.js",
+ "node-gyp-build-optional-packages-test": "build-test.js"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.54",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.54.tgz",
+ "integrity": "sha512-YHs7BmmcsdAI5Ozuf8JZo6PT0mv2GIWC9vMfvUC3dp65M8hn7Ux8CPL+2oBI7juNuj9d0ndhTcznq2ODBps9cQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/npm-package-arg": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-14.0.0.tgz",
+ "integrity": "sha512-69XQh3k+dtGa1p+7RaR57IuG3rCko96xr/nUfN4yDYBXbTYICiWcOpsFKLN2GtGE9cyIljE+f1exnaYt9MvM+Q==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "hosted-git-info": "^10.1.0",
+ "proc-log": "^7.0.0",
+ "semver": "^7.3.5",
+ "validate-npm-package-name": "^8.0.0"
+ },
+ "engines": {
+ "node": "^22.22.2 || ^24.15.0 || >=26.0.0"
+ }
+ },
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/obug": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz",
+ "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==",
+ "dev": true,
+ "funding": [
+ "https://github.com/sponsors/sxzz",
+ "https://opencollective.com/debug"
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.20.0"
+ }
+ },
+ "node_modules/on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz",
+ "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-function": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ora": {
+ "version": "9.4.1",
+ "resolved": "https://registry.npmjs.org/ora/-/ora-9.4.1.tgz",
+ "integrity": "sha512-6VlU9MLXbjVQD04AZCMX28hVtA5bUoadvUqO76MUCVA0ilwJbMiHsITRPfyVm6p/BC0Av/BXMujx39WCe1LEqw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^5.6.2",
+ "cli-cursor": "^5.0.0",
+ "cli-spinners": "^3.2.0",
+ "is-interactive": "^2.0.0",
+ "is-unicode-supported": "^2.1.0",
+ "log-symbols": "^7.0.1",
+ "stdin-discarder": "^0.3.2",
+ "string-width": "^8.1.0"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ordered-binary": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.6.1.tgz",
+ "integrity": "sha512-QkCdPooczexPLiXIrbVOPYkR3VO3T6v2OyKRkR1Xbhpy7/LAVXwahnRCgRp78Oe/Ehf0C/HATAxfSr6eA1oX+w==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/oxc-parser": {
+ "version": "0.142.0",
+ "resolved": "https://registry.npmjs.org/oxc-parser/-/oxc-parser-0.142.0.tgz",
+ "integrity": "sha512-kKR+jPiRJYJDexVoziIg/FVGvr1fT1FZSSJOk6tVoMKKSlsf1Cso+cgGCJkOEDWOP174vRntCPFKg+AS7InWvw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@oxc-project/types": "^0.142.0"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/Boshen"
+ },
+ "optionalDependencies": {
+ "@oxc-parser/binding-android-arm-eabi": "0.142.0",
+ "@oxc-parser/binding-android-arm64": "0.142.0",
+ "@oxc-parser/binding-darwin-arm64": "0.142.0",
+ "@oxc-parser/binding-darwin-x64": "0.142.0",
+ "@oxc-parser/binding-freebsd-x64": "0.142.0",
+ "@oxc-parser/binding-linux-arm-gnueabihf": "0.142.0",
+ "@oxc-parser/binding-linux-arm-musleabihf": "0.142.0",
+ "@oxc-parser/binding-linux-arm64-gnu": "0.142.0",
+ "@oxc-parser/binding-linux-arm64-musl": "0.142.0",
+ "@oxc-parser/binding-linux-ppc64-gnu": "0.142.0",
+ "@oxc-parser/binding-linux-riscv64-gnu": "0.142.0",
+ "@oxc-parser/binding-linux-riscv64-musl": "0.142.0",
+ "@oxc-parser/binding-linux-s390x-gnu": "0.142.0",
+ "@oxc-parser/binding-linux-x64-gnu": "0.142.0",
+ "@oxc-parser/binding-linux-x64-musl": "0.142.0",
+ "@oxc-parser/binding-openharmony-arm64": "0.142.0",
+ "@oxc-parser/binding-wasm32-wasi": "0.142.0",
+ "@oxc-parser/binding-win32-arm64-msvc": "0.142.0",
+ "@oxc-parser/binding-win32-ia32-msvc": "0.142.0",
+ "@oxc-parser/binding-win32-x64-msvc": "0.142.0"
+ }
+ },
+ "node_modules/parse5": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz",
+ "integrity": "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "entities": "^8.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5-html-rewriting-stream": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-8.0.1.tgz",
+ "integrity": "sha512-NaRku2aMpUN1Sh1Gyk1KWUh2A7EJx2c6qYzvwsPtqhoHoaURshdrceYK3LunVCm3WHhm6FS7Vcczbvdh3/UIVw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "entities": "^8.0.0",
+ "parse5": "^8.0.0",
+ "parse5-sax-parser": "^8.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5-html-rewriting-stream/node_modules/entities": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz",
+ "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/parse5-sax-parser": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-8.0.0.tgz",
+ "integrity": "sha512-/dQ8UzHZwnrzs3EvDj6IkKrD/jIZyTlB+8XrHJvcjNgRdmWruNdN9i9RK/JtxakmlUdPwKubKPTCqvbTgzGhrw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parse5": "^8.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5/node_modules/entities": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz",
+ "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-to-regexp": {
+ "version": "8.4.2",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz",
+ "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz",
+ "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/piscina": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/piscina/-/piscina-5.2.0.tgz",
+ "integrity": "sha512-DszUCKeVN/5G5QKo6jAVHL8fmKnkJvQ0ACiVgY7YGCq3TUB2oznAOayvZPIAdEThvhczkXR+qm3IHsNXpFCYfA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.x"
+ },
+ "optionalDependencies": {
+ "@napi-rs/nice": "^1.0.4"
+ }
+ },
+ "node_modules/pkce-challenge": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz",
+ "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16.20.0"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.27",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.27.tgz",
+ "integrity": "sha512-79Iho8QeYyooJ8e9lCRyTVlyTAkS/kXBYKff6TMzS3kEWGQ8Ds5UEtXpGrSUDLUWok6QTvxeYy0GO8fopHnaSA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.18",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-media-query-parser": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz",
+ "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/postcss-safe-parser": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz",
+ "integrity": "sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss-safe-parser"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4.31"
+ }
+ },
+ "node_modules/proc-log": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-7.0.0.tgz",
+ "integrity": "sha512-FYgfaA69XZ93zaXLoMNQ+ViDXGGBgR8aLh03txzcFhV+9xOXx7+8DLCULrKKpR9+GsH9ZfHm82aSUPpozX0Ztg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^22.22.2 || ^24.15.0 || >=26.0.0"
+ }
+ },
+ "node_modules/proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/proxy-agent-negotiate": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-agent-negotiate/-/proxy-agent-negotiate-1.1.0.tgz",
+ "integrity": "sha512-N8IBcM3UgCVzz2L2Lqv8DVntDnnC8/hiV4nEDUPkqq72TPUgYWjQc+bdZlBPZK9LzPAvOY//gAt0S0DApoOXWQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 20"
+ },
+ "peerDependencies": {
+ "kerberos": "^2.0.0"
+ },
+ "peerDependenciesMeta": {
+ "kerberos": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/qs": {
+ "version": "6.16.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.16.0.tgz",
+ "integrity": "sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "es-define-property": "^1.0.1",
+ "side-channel": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/range-parser": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.3.0.tgz",
+ "integrity": "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/raw-body": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz",
+ "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "~3.1.2",
+ "http-errors": "~2.0.1",
+ "iconv-lite": "~0.7.0",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.1.1.tgz",
+ "integrity": "sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 20.19.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/reflect-metadata": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz",
+ "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/restore-cursor": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz",
+ "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "onetime": "^7.0.0",
+ "signal-exit": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/rolldown": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.0.tgz",
+ "integrity": "sha512-u7tgm5l4Yw1iTqUL4EcYOAt7fFvCgQMLeidrnD4GALlC6aOznCjezYajgxeyKw27u0Q5N7fwgCzjVyPIWzwuBA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@oxc-project/types": "=0.140.0",
+ "@rolldown/pluginutils": "^1.0.0"
+ },
+ "bin": {
+ "rolldown": "bin/cli.mjs"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "optionalDependencies": {
+ "@rolldown/binding-android-arm64": "1.2.0",
+ "@rolldown/binding-darwin-arm64": "1.2.0",
+ "@rolldown/binding-darwin-x64": "1.2.0",
+ "@rolldown/binding-freebsd-x64": "1.2.0",
+ "@rolldown/binding-linux-arm-gnueabihf": "1.2.0",
+ "@rolldown/binding-linux-arm64-gnu": "1.2.0",
+ "@rolldown/binding-linux-arm64-musl": "1.2.0",
+ "@rolldown/binding-linux-ppc64-gnu": "1.2.0",
+ "@rolldown/binding-linux-s390x-gnu": "1.2.0",
+ "@rolldown/binding-linux-x64-gnu": "1.2.0",
+ "@rolldown/binding-linux-x64-musl": "1.2.0",
+ "@rolldown/binding-openharmony-arm64": "1.2.0",
+ "@rolldown/binding-wasm32-wasi": "1.2.0",
+ "@rolldown/binding-win32-arm64-msvc": "1.2.0",
+ "@rolldown/binding-win32-x64-msvc": "1.2.0"
+ }
+ },
+ "node_modules/rolldown/node_modules/@oxc-project/types": {
+ "version": "0.140.0",
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.140.0.tgz",
+ "integrity": "sha512-h5LUOzGArYemnW1NMz/DuuQhBi96J6JL2Bk8zE4kvqxB5Sg3jxmCiH4uyOWHDkiKSt5vWlG4FIwCR/DbstcNRQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/Boshen"
+ }
+ },
+ "node_modules/router": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
+ "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.0",
+ "depd": "^2.0.0",
+ "is-promise": "^4.0.0",
+ "parseurl": "^1.3.3",
+ "path-to-regexp": "^8.0.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/rxjs": {
+ "version": "7.8.2",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
+ "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/sass": {
+ "version": "1.101.0",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.101.0.tgz",
+ "integrity": "sha512-OL3GoQyoUdDt843DpVmDO6y2k1sc5IhUDSpu8XucEI+35neq5QivZ1iuegnpraEVTJXlQGK1gl27zKcTLEPbQw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chokidar": "^5.0.0",
+ "immutable": "^5.1.5",
+ "source-map-js": ">=0.6.2 <2.0.0"
+ },
+ "bin": {
+ "sass": "sass.js"
+ },
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "optionalDependencies": {
+ "@parcel/watcher": "^2.4.1"
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.8.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
+ "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/send": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz",
+ "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.3",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.1",
+ "mime-types": "^3.0.2",
+ "ms": "^2.1.3",
+ "on-finished": "^2.4.1",
+ "range-parser": "^1.2.1",
+ "statuses": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/serve-static": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz",
+ "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "parseurl": "^1.3.3",
+ "send": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz",
+ "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.4",
+ "side-channel-list": "^1.0.1",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz",
+ "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/slice-ansi": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-9.0.0.tgz",
+ "integrity": "sha512-SO/3iYL5S3W57LLEniscOGPZgOqZUPCx6d3dB+52B80yJ0XstzsC/eV8gnA4tM3MHDrKz+OCFSLNjswdSC+/bA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.2.3",
+ "is-fullwidth-code-point": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=22"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.7.6",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz",
+ "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/source-map-support/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/statuses": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
+ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/stdin-discarder": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.3.2.tgz",
+ "integrity": "sha512-eCPu1qRxPVkl5605OTWF8Wz40b4Mf45NY5LQmVPQ599knfs5QhASUm9GbJ5BDMDOXgrnh0wyEdvzmL//YMlw0A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "8.2.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.2.tgz",
+ "integrity": "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-east-asian-width": "^1.5.0",
+ "strip-ansi": "^7.1.2"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
+ "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.2.2"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.17",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
+ "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD"
+ },
+ "node_modules/type-is": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz",
+ "integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "content-type": "^2.0.0",
+ "media-typer": "^1.1.0",
+ "mime-types": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/type-is/node_modules/content-type": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz",
+ "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
+ "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.2.tgz",
+ "integrity": "sha512-UQ+MSxlhRm1bzjhU+DcuXfjFO1FzNtqhK5+9Yvlp90ItDLk5vT932A0rFu619nf7RVS+Y/VeaUW1jaRDqZ8VJw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/validate-npm-package-name": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-8.0.0.tgz",
+ "integrity": "sha512-SCv6OOV6Xj2/3cXy3dGmADluJTNcL3o7hZAglNPTe+WYuEuvxgJzxPrSDLZhF+CwyQOubqgecjMmTJGMVLWjYQ==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^22.22.2 || ^24.15.0 || >=26.0.0"
+ }
+ },
+ "node_modules/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/vite": {
+ "version": "8.1.5",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.5.tgz",
+ "integrity": "sha512-7ULLwsCdYx/nRyrpiEwvqb5TFHrMVZyBt+rg/OAXT7rgj/z+DtTDyKFeLAdDkubDVDKD8jOsndmy7m55XcfUsw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lightningcss": "^1.32.0",
+ "picomatch": "^4.0.5",
+ "postcss": "^8.5.17",
+ "rolldown": "~1.1.5",
+ "tinyglobby": "^0.2.17"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^20.19.0 || >=22.12.0",
+ "@vitejs/devtools": "^0.3.0",
+ "esbuild": "^0.27.0 || ^0.28.0",
+ "jiti": ">=1.21.0",
+ "less": "^4.0.0",
+ "sass": "^1.70.0",
+ "sass-embedded": "^1.70.0",
+ "stylus": ">=0.54.8",
+ "sugarss": "^5.0.0",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "@vitejs/devtools": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite/node_modules/@emnapi/core": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz",
+ "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/wasi-threads": "1.2.2",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/vite/node_modules/@emnapi/runtime": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz",
+ "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/vite/node_modules/@oxc-project/types": {
+ "version": "0.139.0",
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.139.0.tgz",
+ "integrity": "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/Boshen"
+ }
+ },
+ "node_modules/vite/node_modules/@rolldown/binding-android-arm64": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.5.tgz",
+ "integrity": "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/vite/node_modules/@rolldown/binding-darwin-arm64": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.5.tgz",
+ "integrity": "sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/vite/node_modules/@rolldown/binding-darwin-x64": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.5.tgz",
+ "integrity": "sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/vite/node_modules/@rolldown/binding-freebsd-x64": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.5.tgz",
+ "integrity": "sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/vite/node_modules/@rolldown/binding-linux-arm-gnueabihf": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.5.tgz",
+ "integrity": "sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/vite/node_modules/@rolldown/binding-linux-arm64-gnu": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.5.tgz",
+ "integrity": "sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/vite/node_modules/@rolldown/binding-linux-arm64-musl": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.5.tgz",
+ "integrity": "sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/vite/node_modules/@rolldown/binding-linux-ppc64-gnu": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.5.tgz",
+ "integrity": "sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/vite/node_modules/@rolldown/binding-linux-s390x-gnu": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.5.tgz",
+ "integrity": "sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/vite/node_modules/@rolldown/binding-linux-x64-gnu": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.5.tgz",
+ "integrity": "sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/vite/node_modules/@rolldown/binding-linux-x64-musl": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.5.tgz",
+ "integrity": "sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/vite/node_modules/@rolldown/binding-openharmony-arm64": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.5.tgz",
+ "integrity": "sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/vite/node_modules/@rolldown/binding-wasm32-wasi": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.5.tgz",
+ "integrity": "sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==",
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "1.11.1",
+ "@emnapi/runtime": "1.11.1",
+ "@napi-rs/wasm-runtime": "^1.1.6"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/vite/node_modules/@rolldown/binding-win32-arm64-msvc": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.5.tgz",
+ "integrity": "sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/vite/node_modules/@rolldown/binding-win32-x64-msvc": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.5.tgz",
+ "integrity": "sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/vite/node_modules/rolldown": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.5.tgz",
+ "integrity": "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@oxc-project/types": "=0.139.0",
+ "@rolldown/pluginutils": "^1.0.0"
+ },
+ "bin": {
+ "rolldown": "bin/cli.mjs"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "optionalDependencies": {
+ "@rolldown/binding-android-arm64": "1.1.5",
+ "@rolldown/binding-darwin-arm64": "1.1.5",
+ "@rolldown/binding-darwin-x64": "1.1.5",
+ "@rolldown/binding-freebsd-x64": "1.1.5",
+ "@rolldown/binding-linux-arm-gnueabihf": "1.1.5",
+ "@rolldown/binding-linux-arm64-gnu": "1.1.5",
+ "@rolldown/binding-linux-arm64-musl": "1.1.5",
+ "@rolldown/binding-linux-ppc64-gnu": "1.1.5",
+ "@rolldown/binding-linux-s390x-gnu": "1.1.5",
+ "@rolldown/binding-linux-x64-gnu": "1.1.5",
+ "@rolldown/binding-linux-x64-musl": "1.1.5",
+ "@rolldown/binding-openharmony-arm64": "1.1.5",
+ "@rolldown/binding-wasm32-wasi": "1.1.5",
+ "@rolldown/binding-win32-arm64-msvc": "1.1.5",
+ "@rolldown/binding-win32-x64-msvc": "1.1.5"
+ }
+ },
+ "node_modules/watchpack": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.2.tgz",
+ "integrity": "sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.1.2"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/weak-lru-cache": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz",
+ "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-10.0.1.tgz",
+ "integrity": "sha512-M0N4xzyzosiIok3svYlEo1sdLZts/8FPgYH/GPC3wvlmPoRvnoManGMrE54waYj3tISA8w6lsdesfVv67qSr8Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.2.3",
+ "string-width": "^8.2.0"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs": {
+ "version": "18.1.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.1.0.tgz",
+ "integrity": "sha512-2rAgRKu54VsHkqI0/tYkmluGXHD4KW7yZoycuqDQ15QOTnc2VVfy0nN/1eMhnQLO00A+dwtK20xuCnc1YGeUyg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^9.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "string-width": "^8.2.1",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^22.0.0"
+ },
+ "engines": {
+ "node": "^20.19.0 || ^22.12.0 || >=23"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "22.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz",
+ "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^20.19.0 || ^22.12.0 || >=23"
+ }
+ },
+ "node_modules/yoctocolors": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.2.0.tgz",
+ "integrity": "sha512-xYqdZFUK/VYazNl/oCDYN+3WloWQwMfZxBoiNt6qNyk+xfOdi598muWE42rNZFp1kNOiqW936q5RhUdnpqElSg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/zod": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz",
+ "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/zod-to-json-schema": {
+ "version": "3.25.2",
+ "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz",
+ "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==",
+ "dev": true,
+ "license": "ISC",
+ "peerDependencies": {
+ "zod": "^3.25.28 || ^4"
+ }
+ }
+ }
+}
diff --git a/stackblitz/package.json b/stackblitz/package.json
new file mode 100644
index 0000000..b8721c1
--- /dev/null
+++ b/stackblitz/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "openapi-ng-demo",
+ "version": "0.0.0",
+ "private": true,
+ "scripts": {
+ "start": "ng serve",
+ "build": "ng build",
+ "generate": "npx -y @avsystem/openapi-ng generate --input petstore.openapi.yaml --output src/generated"
+ },
+ "dependencies": {
+ "@angular/common": "^22.1.3",
+ "@angular/compiler": "^22.1.3",
+ "@angular/core": "^22.1.3",
+ "@angular/forms": "^22.1.3",
+ "@angular/platform-browser": "^22.1.3",
+ "rxjs": "~7.8.2",
+ "tslib": "^2.8.1"
+ },
+ "devDependencies": {
+ "@angular/build": "^22.1.3",
+ "@angular/cli": "^22.1.3",
+ "@angular/compiler-cli": "^22.1.3",
+ "typescript": "~6.0.3"
+ }
+}
diff --git a/stackblitz/src/app/app.ts b/stackblitz/src/app/app.ts
new file mode 100644
index 0000000..6b27b5f
--- /dev/null
+++ b/stackblitz/src/app/app.ts
@@ -0,0 +1,26 @@
+import { Component, signal } from '@angular/core';
+import type { PetId } from '../generated/model.generated';
+import { PetDetail } from './pet-detail';
+import { PetList } from './pet-list';
+import { SignupForm } from './signup-form';
+
+@Component({
+ selector: 'app-root',
+ imports: [PetList, PetDetail, SignupForm],
+ template: `
+ openapi-ng generated Angular client, mock backend via HttpInterceptor
+
+ Everything under src/generated/ came out of openapi-ng generate run on
+ petstore.openapi.yaml. The components in src/app/ consume it three ways:
+ .resource(), .observable(), and .request().
+
+
+ `,
+})
+export class App {
+ protected readonly selectedId = signal(undefined);
+}
diff --git a/stackblitz/src/app/mock-api.interceptor.ts b/stackblitz/src/app/mock-api.interceptor.ts
new file mode 100644
index 0000000..2791b05
--- /dev/null
+++ b/stackblitz/src/app/mock-api.interceptor.ts
@@ -0,0 +1,68 @@
+import { HttpErrorResponse, HttpHeaders, HttpInterceptorFn, HttpResponse } from '@angular/common/http';
+import { delay, mergeMap, of, throwError } from 'rxjs';
+import type { EmailAvailability, Pet, UpdatePetRequest } from '../generated/model.generated';
+
+// In-memory stand-in for the Petstore backend, so the demo runs with no server.
+const pets: Pet[] = [
+ { id: '1', name: 'Rex', status: 'available', tags: [{ id: 1, label: 'dog' }] },
+ { id: '2', name: 'Misha', status: 'pending', tags: [{ id: 2, label: 'cat' }], nickname: 'Mishka' },
+ { id: '3', name: 'Bubbles', status: 'available', tags: [{ id: 3, label: 'fish' }] },
+ { id: '4', name: 'Kiwi', status: 'sold', tags: [{ id: 4, label: 'bird' }], nickname: null },
+];
+
+const takenEmails = new Set(['taken@example.com', 'admin@example.com']);
+
+const LATENCY_MS = 500;
+
+export const mockApiInterceptor: HttpInterceptorFn = (req, next) => {
+ const url = new URL(req.urlWithParams, 'http://localhost');
+ if (!url.pathname.startsWith('/api/')) return next(req);
+
+ const route = `${req.method} ${url.pathname.slice('/api'.length)}`;
+ console.info('[mock-api]', route, url.search, req.body ?? '');
+ return of(null).pipe(
+ delay(LATENCY_MS),
+ mergeMap(() => {
+ const match = /^(GET|POST) \/pets\/([^/]+)$/.exec(route);
+ if (route === 'GET /pets') return ok(listPets(url.searchParams.get('status')));
+ if (match) {
+ const pet = pets.find((candidate) => candidate.id === match[2]);
+ if (!pet) return fail(404, `No pet with id ${match[2]}`);
+ return ok(match[1] === 'GET' ? pet : updatePet(pet, req.body as UpdatePetRequest));
+ }
+ if (route === 'GET /accounts/check-email') {
+ return ok(checkEmail(url.searchParams.get('email') ?? ''));
+ }
+ return fail(404, `Unhandled route ${route}`);
+ }),
+ );
+};
+
+function listPets(status: string | null): Pet[] {
+ return status ? pets.filter((pet) => pet.status === status) : pets;
+}
+
+function updatePet(pet: Pet, body: UpdatePetRequest): Pet {
+ pet.status = body.status;
+ if (body.nickname !== undefined) pet.nickname = body.nickname;
+ return pet;
+}
+
+function checkEmail(email: string): EmailAvailability {
+ const available = !takenEmails.has(email.toLowerCase());
+ return available ? { available } : { available, suggestion: email.replace('@', '.2026@') };
+}
+
+function ok(body: T) {
+ return of(
+ new HttpResponse({
+ status: 200,
+ body: structuredClone(body),
+ headers: new HttpHeaders({ 'x-mock-latency': `${LATENCY_MS}ms` }),
+ }),
+ );
+}
+
+function fail(status: number, message: string) {
+ return throwError(() => new HttpErrorResponse({ status, statusText: message, error: { message } }));
+}
diff --git a/stackblitz/src/app/pet-detail.ts b/stackblitz/src/app/pet-detail.ts
new file mode 100644
index 0000000..1a454b2
--- /dev/null
+++ b/stackblitz/src/app/pet-detail.ts
@@ -0,0 +1,77 @@
+import { JsonPipe } from '@angular/common';
+import { Component, computed, inject, input, output, signal } from '@angular/core';
+import type { Pet, PetId, PetStatus } from '../generated/model.generated';
+import { PetRest } from '../generated/rest/pet.rest.generated';
+
+@Component({
+ selector: 'app-pet-detail',
+ imports: [JsonPipe],
+ template: `
+ getPet.resource() and updatePet.observable()
+
+ @if (!petId()) {
+ Pick a pet on the left.
+ } @else if (pet.isLoading()) {
+ loading…
+ } @else if (pet.error()) {
+ {{ pet.error() }}
+ } @else if (pet.value(); as current) {
+
+ {{ current.name }}
+ #{{ current.id }}, {{ current.status }}
+ @if (current.nickname) {
+ aka {{ current.nickname }}
+ }
+
+
+ @for (option of statuses; track option) {
+
+ mark {{ option }}
+
+ }
+
+ }
+
+ @if (rawRequest(); as raw) {
+ .request() returns the plain request, if you want to send it yourself:
+ {{ raw | json }}
+ }
+ `,
+})
+export class PetDetail {
+ readonly #petRest = inject(PetRest);
+
+ readonly petId = input();
+ readonly updated = output();
+
+ protected readonly statuses: PetStatus[] = ['available', 'pending', 'sold'];
+ protected readonly saving = signal(false);
+
+ // Returning undefined from the callback keeps the resource idle until a pet is picked.
+ readonly pet = this.#petRest.getPet.resource(() => {
+ const petId = this.petId();
+ return petId ? { petId } : undefined;
+ });
+
+ protected readonly rawRequest = computed(() => {
+ const petId = this.petId();
+ return petId ? this.#petRest.getPet.request({ petId }) : undefined;
+ });
+
+ protected setStatus(status: PetStatus) {
+ const current = this.pet.value();
+ if (!current) return;
+ this.saving.set(true);
+ this.#petRest.updatePet
+ .observable({ petId: current.id, body: { status } }, { observe: 'response' })
+ .subscribe({
+ next: (response) => {
+ const saved = response.body!;
+ this.pet.set(saved);
+ this.updated.emit(saved);
+ },
+ error: () => this.saving.set(false),
+ complete: () => this.saving.set(false),
+ });
+ }
+}
diff --git a/stackblitz/src/app/pet-list.ts b/stackblitz/src/app/pet-list.ts
new file mode 100644
index 0000000..2bd4544
--- /dev/null
+++ b/stackblitz/src/app/pet-list.ts
@@ -0,0 +1,54 @@
+import { Component, inject, output, signal } from '@angular/core';
+import type { PetId, PetStatus } from '../generated/model.generated';
+import { PetRest } from '../generated/rest/pet.rest.generated';
+
+@Component({
+ selector: 'app-pet-list',
+ template: `
+ listPets.resource()
+ Status filter
+
+ all
+ @for (option of statuses; track option) {
+ {{ option }}
+ }
+
+
+
+ @if (pets.isLoading()) {
+ loading…
+ } @else {
+ {{ pets.value().length }} pets, HTTP {{ pets.statusCode() }},
+ server latency {{ pets.headers()?.get('x-mock-latency') }}
+ }
+ reload
+
+
+
+ @for (pet of pets.value(); track pet.id) {
+
+ {{ pet.name }}
+ {{ pet.status }}
+
+ }
+
+ `,
+})
+export class PetList {
+ readonly #petRest = inject(PetRest);
+
+ readonly selected = output();
+
+ protected readonly statuses: PetStatus[] = ['available', 'pending', 'sold'];
+ protected readonly status = signal(undefined);
+
+ // Re-fetches whenever the filter signal changes. Typed HttpResourceRef.
+ readonly pets = this.#petRest.listPets.resource(() => ({ status: this.status() }), {
+ defaultValue: [],
+ });
+
+ protected onStatusChange(event: Event) {
+ const value = (event.target as HTMLSelectElement).value as PetStatus | '';
+ this.status.set(value || undefined);
+ }
+}
diff --git a/stackblitz/src/app/signup-form.ts b/stackblitz/src/app/signup-form.ts
new file mode 100644
index 0000000..1a900ea
--- /dev/null
+++ b/stackblitz/src/app/signup-form.ts
@@ -0,0 +1,74 @@
+import { JsonPipe } from '@angular/common';
+import { Component, inject, signal } from '@angular/core';
+import { email, form, FormField, required } from '@angular/forms/signals';
+import { AccountRest } from '../generated/rest/account.rest.generated';
+import { validateRest } from '../generated/rest.validate';
+
+interface Signup {
+ name: string;
+ email: string;
+}
+
+@Component({
+ selector: 'app-signup-form',
+ imports: [FormField, JsonPipe],
+ template: `
+ Signal forms: validateRest()
+
+ The async validator reuses the generated AccountRest.checkEmail operation, so
+ request and response stay typed. Try taken@example.com.
+
+
+
+
+ @if (submitted()) {
+ {{ model() | json }}
+ }
+ `,
+})
+export class SignupForm {
+ readonly #accountRest = inject(AccountRest);
+
+ protected readonly model = signal({ name: '', email: '' });
+ protected readonly submitted = signal(false);
+
+ protected readonly signup = form(this.model, (path) => {
+ required(path.name);
+ required(path.email);
+ email(path.email);
+ validateRest(path.email, this.#accountRest.checkEmail, {
+ // typed as CheckEmailParams; a typo here is a compile error
+ request: (ctx) => ({ email: ctx.value() }),
+ debounce: 300,
+ when: (ctx) => ctx.value().includes('@'),
+ onSuccess: (result) =>
+ result.available
+ ? undefined
+ : { kind: 'email-taken', message: `Already taken. How about ${result.suggestion}?` },
+ onError: () => ({ kind: 'check-failed', message: 'Could not verify the address.' }),
+ });
+ });
+
+ protected onSubmit(event: Event) {
+ event.preventDefault();
+ this.submitted.set(true);
+ }
+}
diff --git a/stackblitz/src/generated/model.generated.ts b/stackblitz/src/generated/model.generated.ts
new file mode 100644
index 0000000..dae8b6a
--- /dev/null
+++ b/stackblitz/src/generated/model.generated.ts
@@ -0,0 +1,32 @@
+// Generated by openapi-ng v0.4.0
+// Source: petstore.openapi.yaml
+// DO NOT EDIT — regenerate with `openapi-ng generate`
+
+export interface EmailAvailability {
+ available: boolean;
+ suggestion?: string;
+}
+
+export interface Pet {
+ id: PetId;
+ name: string;
+ status: PetStatus;
+ tags: Tag[];
+ nickname?: string | null;
+}
+
+export type PetId = string;
+
+export type PetList = Pet[];
+
+export type PetStatus = 'available' | 'pending' | 'sold';
+
+export interface Tag {
+ id: number;
+ label: string;
+}
+
+export interface UpdatePetRequest {
+ status: PetStatus;
+ nickname?: string | null;
+}
diff --git a/stackblitz/src/generated/rest.model.ts b/stackblitz/src/generated/rest.model.ts
new file mode 100644
index 0000000..7b30adc
--- /dev/null
+++ b/stackblitz/src/generated/rest.model.ts
@@ -0,0 +1,82 @@
+// Generated by openapi-ng v0.4.0
+// Source: petstore.openapi.yaml
+// DO NOT EDIT — regenerate with `openapi-ng generate`
+
+import type {
+ HttpContext,
+ HttpHeaders,
+ HttpParams,
+ HttpResourceOptions,
+ HttpResourceRequest,
+} from '@angular/common/http';
+
+export type QueryParamValue =
+ | string
+ | number
+ | boolean
+ | ReadonlyArray;
+
+export interface CommonRequest extends Pick<
+ HttpResourceRequest,
+ 'body' | 'params' | 'headers'
+> {
+ method: string;
+ url: string;
+ body?: unknown;
+ params?: HttpParams | Record;
+ headers?: HttpHeaders | Record;
+}
+
+export interface WithDefault {
+ defaultValue: NoInfer;
+}
+
+export interface WithParse {
+ parse: (raw: TRaw) => TResult;
+}
+
+export type BaseHttpResourceOptions = Omit<
+ HttpResourceOptions,
+ 'parse' | 'defaultValue'
+>;
+
+export type BaseHttpResourceOptionsWithParse = BaseHttpResourceOptions<
+ TResult,
+ TRaw
+> &
+ WithParse;
+
+export type BaseHttpResourceOptionsWithDefault<
+ TResult,
+ TRaw = TResult,
+> = BaseHttpResourceOptions & WithDefault;
+
+export type BaseHttpResourceOptionsWithDefaultAndParse =
+ BaseHttpResourceOptions &
+ WithParse &
+ WithDefault;
+
+export type HttpResourceOptionsUnion =
+ | BaseHttpResourceOptions
+ | BaseHttpResourceOptionsWithParse
+ | BaseHttpResourceOptionsWithDefault
+ | BaseHttpResourceOptionsWithDefaultAndParse;
+
+// Omits body/params/headers (generator supplies them) and responseType
+// (fixed per requestFactory variant). Structurally compatible with
+// HttpClient.request(method, url, options) so the runtime spread doesn't
+// need a Parameters<…>[2] cast.
+export type ObservableOptions = {
+ context?: HttpContext;
+ observe?: 'body' | 'response' | 'events';
+ reportProgress?: boolean;
+ transferCache?: { includeHeaders?: string[] } | boolean;
+ withCredentials?: boolean;
+ keepalive?: boolean;
+ redirect?: RequestRedirect;
+ mode?: RequestMode;
+ credentials?: RequestCredentials;
+ priority?: RequestPriority;
+ cache?: RequestCache;
+ timeout?: number;
+};
diff --git a/stackblitz/src/generated/rest.util.ts b/stackblitz/src/generated/rest.util.ts
new file mode 100644
index 0000000..8640263
--- /dev/null
+++ b/stackblitz/src/generated/rest.util.ts
@@ -0,0 +1,335 @@
+// Generated by openapi-ng v0.4.0
+// Source: petstore.openapi.yaml
+// DO NOT EDIT — regenerate with `openapi-ng generate`
+
+import { HttpClient, HttpParams, httpResource } from '@angular/common/http';
+import type {
+ HttpEvent,
+ HttpResourceOptions,
+ HttpResourceRef,
+ HttpResponse,
+} from '@angular/common/http';
+import {
+ InjectionToken,
+ inject,
+ makeEnvironmentProviders,
+ type EnvironmentProviders,
+} from '@angular/core';
+import type { Observable } from 'rxjs';
+import type {
+ BaseHttpResourceOptionsWithDefault,
+ BaseHttpResourceOptionsWithDefaultAndParse,
+ BaseHttpResourceOptionsWithParse,
+ CommonRequest,
+ HttpResourceOptionsUnion,
+ ObservableOptions,
+ QueryParamValue,
+} from './rest.model';
+
+type QueryParamRecord = Record;
+type ResponseType = 'blob' | 'text' | 'arraybuffer';
+
+export const OPENAPI_NG_BASE_PATH = new InjectionToken('OPENAPI_NG_BASE_PATH');
+
+export function provideOpenapiNg(config: { basePath: string }): EnvironmentProviders {
+ return makeEnvironmentProviders([
+ { provide: OPENAPI_NG_BASE_PATH, useValue: config.basePath },
+ ]);
+}
+
+export function httpParams(params: QueryParamRecord): HttpParams {
+ let resolved = new HttpParams();
+ for (const [key, value] of Object.entries(params)) {
+ if (value !== undefined) {
+ if (Array.isArray(value)) {
+ for (const item of value) {
+ resolved = resolved.append(key, String(item));
+ }
+ } else {
+ resolved = resolved.set(key, String(value));
+ }
+ }
+ }
+ return resolved;
+}
+
+// Derived from httpResource itself so the template compiles on every supported
+// Angular version: ResourceParamsContext (chain) on 22+, unknown on 20/21 where
+// the callback is typed as zero-arg.
+export type ResourceRequestContext = Parameters[0] extends (
+ context: infer Context,
+) => unknown
+ ? Context
+ : unknown;
+
+export interface RequestFnValue {
+ request(request: Request): CommonRequest;
+ observable(
+ request: Request,
+ options: ObservableOptions & { observe: 'response' },
+ ): Observable>;
+ observable(
+ request: Request,
+ options: ObservableOptions & { observe: 'events' },
+ ): Observable>;
+ observable(request: Request, options?: ObservableOptions): Observable;
+ resource(
+ reactiveReq: (context: ResourceRequestContext) => Request | undefined,
+ options: BaseHttpResourceOptionsWithDefault,
+ ): HttpResourceRef;
+ resource(
+ reactiveReq: (context: ResourceRequestContext) => Request | undefined,
+ options: BaseHttpResourceOptionsWithDefaultAndParse,
+ ): HttpResourceRef;
+ resource(
+ reactiveReq: (context: ResourceRequestContext) => Request | undefined,
+ options?: HttpResourceOptionsUnion,
+ ): HttpResourceRef;
+ resource(
+ reactiveReq: (context: ResourceRequestContext) => Request | undefined,
+ options: BaseHttpResourceOptionsWithParse,
+ ): HttpResourceRef;
+}
+
+export interface RequestFnVoid {
+ request(request: Request): CommonRequest;
+ observable(
+ request: Request,
+ options: ObservableOptions & { observe: 'response' },
+ ): Observable>;
+ observable(
+ request: Request,
+ options: ObservableOptions & { observe: 'events' },
+ ): Observable>;
+ observable(request: Request, options?: ObservableOptions): Observable;
+ resource(
+ reactiveReq: (context: ResourceRequestContext) => Request | undefined,
+ options?: HttpResourceOptionsUnion,
+ ): HttpResourceRef;
+}
+
+export type RequestFn = [Response] extends [void]
+ ? RequestFnVoid
+ : RequestFnValue;
+
+export interface ZeroArgRequestFnValue {
+ request(): CommonRequest;
+ observable(
+ options: ObservableOptions & { observe: 'response' },
+ ): Observable>;
+ observable(
+ options: ObservableOptions & { observe: 'events' },
+ ): Observable>;
+ observable(options?: ObservableOptions): Observable;
+ resource(
+ options: BaseHttpResourceOptionsWithDefault,
+ ): HttpResourceRef;
+ resource(
+ options: BaseHttpResourceOptionsWithDefaultAndParse,
+ ): HttpResourceRef;
+ resource(
+ options?: HttpResourceOptionsUnion,
+ ): HttpResourceRef;
+ resource(
+ options: BaseHttpResourceOptionsWithParse,
+ ): HttpResourceRef;
+}
+
+export interface ZeroArgRequestFnVoid {
+ request(): CommonRequest;
+ observable(
+ options: ObservableOptions & { observe: 'response' },
+ ): Observable>;
+ observable(
+ options: ObservableOptions & { observe: 'events' },
+ ): Observable>;
+ observable(options?: ObservableOptions): Observable;
+ resource(options?: HttpResourceOptionsUnion): HttpResourceRef;
+}
+
+export type ZeroArgRequestFn = [Response] extends [void]
+ ? ZeroArgRequestFnVoid
+ : ZeroArgRequestFnValue;
+
+function joinBasePath(base: string, url: string): string {
+ // Absolute URLs (https://…, etc.) bypass the configured basePath.
+ if (/^[a-z][a-z0-9+.-]*:\/\//i.test(url)) return url;
+ const normalizedBase = base.endsWith('/') ? base.slice(0, -1) : base;
+ const normalizedUrl = url.startsWith('/') ? url : `/${url}`;
+ return normalizedBase + normalizedUrl;
+}
+
+function withBasePath(
+ reqFn: (...args: TArgs) => CommonRequest,
+): (...args: TArgs) => CommonRequest {
+ const basePath = inject(OPENAPI_NG_BASE_PATH, { optional: true });
+ if (!basePath) return reqFn;
+ return (...args: TArgs) => {
+ const common = reqFn(...args);
+ return { ...common, url: joinBasePath(basePath, common.url) };
+ };
+}
+
+type ObserveFn = (
+ request: CommonRequest,
+ options?: ObservableOptions,
+) => Observable;
+
+function makeObserveFn(
+ http: HttpClient,
+ responseType?: ResponseType,
+): ObserveFn {
+ return (request, options) => {
+ const merged = {
+ ...options,
+ body: request.body,
+ headers: request.headers,
+ params: request.params,
+ ...(responseType ? { responseType } : {}),
+ };
+ return http.request(request.method, request.url, merged) as Observable;
+ };
+}
+
+function makeRequestFn(
+ reqFn: (req: Request) => CommonRequest,
+ observe: ObserveFn,
+ resourceImpl: (
+ // Optional: on Angular 20/21 httpResource expects a zero-arg callback and
+ // invokes it with no context.
+ request: (context?: ResourceRequestContext) => CommonRequest | undefined,
+ options?: HttpResourceOptions,
+ ) => HttpResourceRef,
+): RequestFn {
+ const wrappedReqFn = withBasePath(reqFn);
+ return {
+ request: (req: Request): CommonRequest => wrappedReqFn(req),
+ observable: (req: Request, options?: ObservableOptions): Observable =>
+ observe(wrappedReqFn(req), options),
+ resource: (
+ reactiveReq: (context: ResourceRequestContext | undefined) => Request | undefined,
+ options?: HttpResourceOptionsUnion,
+ ): HttpResourceRef =>
+ resourceImpl(context => {
+ const request = reactiveReq(context);
+ return request === undefined ? undefined : wrappedReqFn(request);
+ }, options),
+ } as RequestFn;
+}
+
+function makeZeroArgRequestFn(
+ reqFn: () => CommonRequest,
+ observe: ObserveFn,
+ resourceImpl: (
+ // Optional: on Angular 20/21 httpResource expects a zero-arg callback and
+ // invokes it with no context.
+ request: (context?: ResourceRequestContext) => CommonRequest | undefined,
+ options?: HttpResourceOptions,
+ ) => HttpResourceRef,
+): ZeroArgRequestFn {
+ const wrappedReqFn = withBasePath(reqFn);
+ return {
+ request: (): CommonRequest => wrappedReqFn(),
+ observable: (options?: ObservableOptions): Observable =>
+ observe(wrappedReqFn(), options),
+ resource: (
+ options?: HttpResourceOptionsUnion,
+ ): HttpResourceRef =>
+ resourceImpl(() => wrappedReqFn(), options),
+ } as ZeroArgRequestFn;
+}
+
+function makeJsonRequestFn(
+ reqFn: (request: Request) => CommonRequest,
+): RequestFn {
+ const http = inject(HttpClient);
+ return makeRequestFn(
+ reqFn,
+ makeObserveFn(http),
+ (request, options) => httpResource(request, options),
+ );
+}
+
+function makeJsonZeroArg(
+ reqFn: () => CommonRequest,
+): ZeroArgRequestFn {
+ const http = inject(HttpClient);
+ return makeZeroArgRequestFn(
+ reqFn,
+ makeObserveFn(http),
+ (request, options) => httpResource(request, options),
+ );
+}
+
+function makeBlobRequestFn(
+ reqFn: (request: Request) => CommonRequest,
+): RequestFn {
+ const http = inject(HttpClient);
+ return makeRequestFn(
+ reqFn,
+ makeObserveFn(http, 'blob'),
+ (request, options) => httpResource.blob(request, options),
+ );
+}
+
+function makeBlobZeroArg(reqFn: () => CommonRequest): ZeroArgRequestFn {
+ const http = inject(HttpClient);
+ return makeZeroArgRequestFn(
+ reqFn,
+ makeObserveFn(http, 'blob'),
+ (request, options) => httpResource.blob(request, options),
+ );
+}
+
+function makeTextRequestFn(
+ reqFn: (request: Request) => CommonRequest,
+): RequestFn {
+ const http = inject(HttpClient);
+ return makeRequestFn(
+ reqFn,
+ makeObserveFn(http, 'text'),
+ (request, options) => httpResource.text(request, options),
+ );
+}
+
+function makeTextZeroArg(reqFn: () => CommonRequest): ZeroArgRequestFn {
+ const http = inject(HttpClient);
+ return makeZeroArgRequestFn(
+ reqFn,
+ makeObserveFn(http, 'text'),
+ (request, options) => httpResource.text(request, options),
+ );
+}
+
+function makeArrayBufferRequestFn(
+ reqFn: (request: Request) => CommonRequest,
+): RequestFn {
+ const http = inject(HttpClient);
+ return makeRequestFn(
+ reqFn,
+ makeObserveFn(http, 'arraybuffer'),
+ (request, options) => httpResource.arrayBuffer(request, options),
+ );
+}
+
+function makeArrayBufferZeroArg(
+ reqFn: () => CommonRequest,
+): ZeroArgRequestFn {
+ const http = inject(HttpClient);
+ return makeZeroArgRequestFn(
+ reqFn,
+ makeObserveFn(http, 'arraybuffer'),
+ (request, options) => httpResource.arrayBuffer(request, options),
+ );
+}
+
+export const requestFactory = Object.assign(makeJsonRequestFn, {
+ blob: makeBlobRequestFn,
+ text: makeTextRequestFn,
+ arrayBuffer: makeArrayBufferRequestFn,
+ zeroArg: Object.assign(makeJsonZeroArg, {
+ blob: makeBlobZeroArg,
+ text: makeTextZeroArg,
+ arrayBuffer: makeArrayBufferZeroArg,
+ }),
+});
diff --git a/stackblitz/src/generated/rest.validate.ts b/stackblitz/src/generated/rest.validate.ts
new file mode 100644
index 0000000..3aec75a
--- /dev/null
+++ b/stackblitz/src/generated/rest.validate.ts
@@ -0,0 +1,70 @@
+// Generated by openapi-ng v0.4.0
+// Source: petstore.openapi.yaml
+// DO NOT EDIT — regenerate with `openapi-ng generate`
+
+import type { Signal } from '@angular/core';
+import { validateAsync } from '@angular/forms/signals';
+import type {
+ AsyncValidatorOptions,
+ FieldContext,
+ MapToErrorsFn,
+ PathKind,
+ SchemaPath,
+ SchemaPathRules,
+ TreeValidationResult,
+} from '@angular/forms/signals';
+import type { BaseHttpResourceOptions } from './rest.model';
+import type { RequestFn, RequestFnValue } from './rest.util';
+
+export type { MapToErrorsFn } from '@angular/forms/signals';
+
+type AsyncOptions = AsyncValidatorOptions<
+ TValue,
+ TRequest | undefined,
+ unknown,
+ TPathKind
+>;
+
+// Everything `validateRest` does not supply itself passes through to
+// `validateAsync` — `debounce` and `when` on @angular/forms 22, nothing on 21.
+// `Omit` rather than `Pick` because `Pick` would demand the keys exist.
+type AsyncPassThrough = Omit<
+ AsyncOptions,
+ 'params' | 'factory' | 'onSuccess' | 'onError' | 'options'
+>;
+
+export interface RestValidatorOptions<
+ TRequest,
+ TResponse,
+ TValue,
+ TPathKind extends PathKind = PathKind.Root,
+> extends AsyncPassThrough {
+ request: (ctx: FieldContext) => TRequest | undefined;
+ onError: (error: unknown, ctx: FieldContext) => TreeValidationResult;
+ onSuccess?: MapToErrorsFn;
+ options?: BaseHttpResourceOptions;
+}
+
+export function validateRest<
+ TRequest,
+ TResponse,
+ TValue,
+ TPathKind extends PathKind = PathKind.Root,
+>(
+ path: SchemaPath,
+ requestFn: RequestFn,
+ opts: RestValidatorOptions,
+): void {
+ const { request, onSuccess, onError, options, ...passThrough } = opts;
+ validateAsync(path, {
+ params: request,
+ factory: (req: Signal) =>
+ (requestFn as RequestFnValue).resource(req, options),
+ onSuccess: (result, ctx) =>
+ result === undefined ? undefined : (onSuccess ?? (() => undefined))(result, ctx),
+ onError,
+ // Spread, not `debounce: opts.debounce` — on @angular/forms 21 those keys are
+ // absent from AsyncValidatorOptions and naming them is an excess-property error.
+ ...passThrough,
+ });
+}
diff --git a/stackblitz/src/generated/rest/account.rest.generated.ts b/stackblitz/src/generated/rest/account.rest.generated.ts
new file mode 100644
index 0000000..69f53d7
--- /dev/null
+++ b/stackblitz/src/generated/rest/account.rest.generated.ts
@@ -0,0 +1,28 @@
+// Generated by openapi-ng v0.4.0
+// Source: petstore.openapi.yaml
+// DO NOT EDIT — regenerate with `openapi-ng generate`
+
+import { Injectable } from '@angular/core';
+import { httpParams, requestFactory } from '../rest.util';
+import type { EmailAvailability } from '../model.generated';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class AccountRest {
+
+ readonly checkEmail = requestFactory(
+ (request: CheckEmailParams) => {
+ const { email } = request;
+ return {
+ method: 'GET',
+ url: `/accounts/check-email`,
+ params: httpParams({ email }),
+ };
+ },
+ );
+}
+
+export interface CheckEmailParams {
+ email: string;
+}
diff --git a/stackblitz/src/generated/rest/pet.rest.generated.ts b/stackblitz/src/generated/rest/pet.rest.generated.ts
new file mode 100644
index 0000000..fba8104
--- /dev/null
+++ b/stackblitz/src/generated/rest/pet.rest.generated.ts
@@ -0,0 +1,58 @@
+// Generated by openapi-ng v0.4.0
+// Source: petstore.openapi.yaml
+// DO NOT EDIT — regenerate with `openapi-ng generate`
+
+import { Injectable } from '@angular/core';
+import { httpParams, requestFactory } from '../rest.util';
+import type { Pet, PetId, PetList, PetStatus, UpdatePetRequest } from '../model.generated';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class PetRest {
+
+ readonly getPet = requestFactory(
+ (request: GetPetParams) => {
+ const { petId } = request;
+ return {
+ method: 'GET',
+ url: `/pets/${encodeURIComponent(petId)}`,
+ };
+ },
+ );
+
+ readonly listPets = requestFactory(
+ (request: ListPetsParams) => {
+ const { status } = request;
+ return {
+ method: 'GET',
+ url: `/pets`,
+ params: httpParams({ status }),
+ };
+ },
+ );
+
+ readonly updatePet = requestFactory(
+ (request: UpdatePetParams) => {
+ const { petId, body } = request;
+ return {
+ method: 'POST',
+ url: `/pets/${encodeURIComponent(petId)}`,
+ body: body,
+ };
+ },
+ );
+}
+
+export interface GetPetParams {
+ petId: PetId;
+}
+
+export interface ListPetsParams {
+ status?: PetStatus;
+}
+
+export interface UpdatePetParams {
+ petId: PetId;
+ body: UpdatePetRequest;
+}
diff --git a/stackblitz/src/index.html b/stackblitz/src/index.html
new file mode 100644
index 0000000..85b746d
--- /dev/null
+++ b/stackblitz/src/index.html
@@ -0,0 +1,11 @@
+
+
+
+
+ openapi-ng demo
+
+
+
+
+
+
diff --git a/stackblitz/src/main.ts b/stackblitz/src/main.ts
new file mode 100644
index 0000000..4444f93
--- /dev/null
+++ b/stackblitz/src/main.ts
@@ -0,0 +1,12 @@
+import { provideHttpClient, withInterceptors } from '@angular/common/http';
+import { bootstrapApplication } from '@angular/platform-browser';
+import { App } from './app/app';
+import { mockApiInterceptor } from './app/mock-api.interceptor';
+import { provideOpenapiNg } from './generated/rest.util';
+
+bootstrapApplication(App, {
+ providers: [
+ provideHttpClient(withInterceptors([mockApiInterceptor])),
+ provideOpenapiNg({ basePath: '/api' }),
+ ],
+}).catch((error) => console.error(error));
diff --git a/stackblitz/src/styles.css b/stackblitz/src/styles.css
new file mode 100644
index 0000000..37ec3c4
--- /dev/null
+++ b/stackblitz/src/styles.css
@@ -0,0 +1,111 @@
+:root {
+ color-scheme: light dark;
+ font-family: system-ui, sans-serif;
+ line-height: 1.4;
+}
+
+body {
+ margin: 0 auto;
+ max-width: 64rem;
+ padding: 1.5rem;
+}
+
+h1 {
+ font-size: 1.4rem;
+}
+
+h1 small {
+ font-weight: normal;
+ opacity: 0.7;
+}
+
+h2 {
+ font-size: 1rem;
+ margin: 0 0 0.75rem;
+}
+
+.grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
+ gap: 1rem;
+}
+
+section {
+ border: 1px solid color-mix(in srgb, currentColor 20%, transparent);
+ border-radius: 0.5rem;
+ padding: 1rem;
+}
+
+pre {
+ background: color-mix(in srgb, currentColor 8%, transparent);
+ border-radius: 0.375rem;
+ font-size: 0.8rem;
+ overflow-x: auto;
+ padding: 0.5rem 0.75rem;
+}
+
+ul {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+li {
+ padding: 0.25rem 0;
+}
+
+button,
+select,
+input {
+ font: inherit;
+}
+
+button {
+ border: 1px solid currentColor;
+ border-radius: 0.375rem;
+ background: transparent;
+ color: inherit;
+ cursor: pointer;
+ padding: 0.25rem 0.6rem;
+}
+
+button:disabled {
+ cursor: default;
+ opacity: 0.4;
+}
+
+button.link {
+ border: 0;
+ padding: 0;
+ text-decoration: underline;
+}
+
+label {
+ display: block;
+ margin: 0.5rem 0 0.25rem;
+}
+
+input {
+ width: 100%;
+ box-sizing: border-box;
+ padding: 0.35rem 0.5rem;
+}
+
+.muted {
+ opacity: 0.7;
+ font-size: 0.85rem;
+}
+
+li > .muted,
+strong + .muted,
+strong + .muted + .muted {
+ margin-left: 0.4rem;
+}
+
+.error {
+ color: #c62828;
+}
+
+.ok {
+ color: #2e7d32;
+}
diff --git a/stackblitz/tsconfig.app.json b/stackblitz/tsconfig.app.json
new file mode 100644
index 0000000..5b9d3c5
--- /dev/null
+++ b/stackblitz/tsconfig.app.json
@@ -0,0 +1,9 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "outDir": "./out-tsc/app",
+ "types": []
+ },
+ "files": ["src/main.ts"],
+ "include": ["src/**/*.d.ts"]
+}
diff --git a/stackblitz/tsconfig.json b/stackblitz/tsconfig.json
new file mode 100644
index 0000000..b1b0d29
--- /dev/null
+++ b/stackblitz/tsconfig.json
@@ -0,0 +1,25 @@
+{
+ "compileOnSave": false,
+ "compilerOptions": {
+ "strict": true,
+ "noImplicitOverride": true,
+ "noPropertyAccessFromIndexSignature": true,
+ "noImplicitReturns": true,
+ "noFallthroughCasesInSwitch": true,
+ "skipLibCheck": true,
+ "isolatedModules": true,
+ "experimentalDecorators": true,
+ "importHelpers": true,
+ "target": "ES2022",
+ "module": "preserve"
+ },
+ "angularCompilerOptions": {
+ "enableI18nLegacyMessageIdFormat": false,
+ "strictInjectionParameters": true,
+ "strictInputAccessModifiers": true,
+ "typeCheckHostBindings": true,
+ "strictTemplates": true
+ },
+ "files": [],
+ "references": [{ "path": "./tsconfig.app.json" }]
+}
From 30183b94814539b767d3c81c1b4bbb6e3b1ffe25 Mon Sep 17 00:00:00 2001
From: pkurcx
Date: Thu, 3 Sep 2026 19:59:21 +0200
Subject: [PATCH 06/17] docs: link the browser playground
Co-Authored-By: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_011t8uBVY6h4kfN5cXHXuCpR
---
README.md | 2 +
reddit-post.md | 122 ++++++++++++++++++
stackblitz/README.md | 23 ++++
website/src/content/docs/getting-started.md | 3 +
website/src/content/docs/index.mdx | 4 +
website/src/content/docs/reference/runtime.md | 2 +
6 files changed, 156 insertions(+)
create mode 100644 reddit-post.md
create mode 100644 stackblitz/README.md
diff --git a/README.md b/README.md
index d8c4ce7..a770277 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,8 @@
Generate TypeScript models and Angular services from OpenAPI 3.x specs — fast, deterministic, Rust-powered.
+Try it without installing anything: [playground](https://docs.openapi-ng.dev/playground/) (paste a spec, see the output) · [StackBlitz demo](https://stackblitz.com/github/AVSystem/openapi-ng/tree/main/stackblitz) (generated client used in an Angular app).
+
**[Documentation →](https://docs.openapi-ng.dev)** · [Getting started](https://docs.openapi-ng.dev/getting-started/) · [Angular guide](https://docs.openapi-ng.dev/guides/angular/) · [Node API](https://docs.openapi-ng.dev/reference/node-api/) · [Diagnostics](https://docs.openapi-ng.dev/reference/diagnostics/)
## Why openapi-ng
diff --git a/reddit-post.md b/reddit-post.md
new file mode 100644
index 0000000..1557b79
--- /dev/null
+++ b/reddit-post.md
@@ -0,0 +1,122 @@
+# Title options
+
+1. I built an open-source OpenAPI → Angular generator because none gave me httpResource and Observables on the same operation. Comparison inside.
+2. Yet another OpenAPI → Angular generator (MIT). Here's why I built one anyway, and how it compares.
+
+---
+
+I know. Another OpenAPI generator for Angular. Before you scroll past, here's the honest version of why I built one at work and open-sourced it, and how it compares to what already exists.
+
+**The problem I hit**
+
+I wanted three things from generated clients and couldn't get them from one tool:
+
+1. `httpResource()` and `HttpClient` Observables for the *same* operation, chosen at the call site, not at config time.
+2. Every `HttpClient.request` / `httpResource` option passed straight through (`withCredentials`, `transferCache`, `reportProgress`, `equal`, `injector`, `observe: 'events'`...), without the generator wrapping or hiding anything.
+3. Zero runtime dependency in the generated code. Just `@angular/common/http`.
+
+So: https://github.com/AVSystem/openapi-ng (MIT). Live demo, no install: Playground (paste your spec, runs as WASM in the browser): https://docs.openapi-ng.dev/playground/ · Angular app demo: https://stackblitz.com/github/AVSystem/openapi-ng/tree/main/stackblitz
+
+**Before / after**
+
+What I kept hand-writing:
+
+```ts
+readonly pets = httpResource(() => ({
+ url: `${this.basePath}/pets`,
+ params: this.status() ? { status: this.status()! } : {},
+}), { defaultValue: [] });
+```
+
+The URL, the query param and the `` are all promises I make to the compiler. Nothing checks them against the spec.
+
+Generated:
+
+```ts
+readonly #petRest = inject(PetRest);
+
+// signal-based, httpResource under the hood, typed HttpResourceRef
+readonly pets = this.#petRest.listPets.resource(() => ({ status: this.status() }), { defaultValue: [] });
+
+// same operation, classic Observable, HttpClient under the hood
+save(petId: PetId, body: UpdatePetRequest) {
+ return this.#petRest.updatePet.observable({ petId, body }, { observe: 'response' });
+}
+```
+
+Each tag becomes an `@Injectable` service, each operation a property with `.resource()`, `.observable()` and `.request()` (the raw `{ method, url, params, body }` if you want to send it yourself). `.resource()` returns a real `HttpResourceRef`, so `headers()`, `statusCode()` and `progress()` are there. Nothing is re-wrapped.
+
+**Signal forms: async validation against a generated operation**
+
+With signal forms in v22, the thing I kept hand-writing was the "is this email taken" validator with `validateHttp`: URL string by hand, response cast by hand.
+
+```ts
+validateHttp(path.email, {
+ request: (ctx) => `${base}/accounts/check-email?email=${encodeURIComponent(ctx.value())}`,
+ onSuccess: (result) => (result as EmailAvailability).available ? undefined : { kind: 'email-taken' },
+ onError: () => ({ kind: 'check-failed' }),
+});
+```
+
+The generator emits a `validateRest()` helper that wraps `validateAsync` and reuses the generated operation:
+
+```ts
+validateRest(path.email, accountRest.checkEmail, {
+ request: (ctx) => ({ email: ctx.value() }), // typed as CheckEmailParams
+ debounce: 300,
+ when: (ctx) => ctx.value().includes('@'),
+ onSuccess: (result) => result.available ? undefined : { kind: 'email-taken' }, // result: EmailAvailability
+ onError: () => ({ kind: 'check-failed' }),
+});
+```
+
+Omit `onSuccess` for the "200 means fine, 4xx means taken" shape. `debounce` and `when` go straight to Angular's `validateAsync`. `@angular/forms` is an optional peer; if you never import `rest.validate.ts`, it tree-shakes away.
+
+**How it compares (checked 2026-09-03, corrections welcome)**
+
+| | openapi-ng | openapi-generator | ng-openapi-gen | orval | ng-openapi |
+|---|---|---|---|---|---|
+| httpResource | every operation, per call | no ([#21263](https://github.com/OpenAPITools/openapi-generator/issues/21263) open) | no | GET only, config mode | GET only, plugin |
+| Observable and resource on one operation | yes | n/a | n/a | separate files | separate classes |
+| Signal-forms validation helper | yes | no | no | no | no |
+| Unsupported spec features | rejected with a diagnostic code | best-effort | best-effort | best-effort | best-effort |
+| Engine | Rust (napi-rs), ms per spec, also runs in the browser via WASM | Java | TS | TS | TS |
+
+Two takeaways:
+
+- If you're on openapi-generator today, the Java requirement and the lack of httpResource are probably the two things that sting. openapi-ng does both.
+- orval and ng-openapi both have httpResource now, but only for GET and the flavour is picked per config, not per call. I think the call site knows better (a `POST /search` is a perfectly good resource; a GET that fires a side effect isn't).
+
+**Where it's deliberately opinionated (read: limited)**
+
+This is the part most "yet another generator" posts skip. openapi-ng accepts a *strict* subset of OpenAPI 3.x and refuses anything outside it with a diagnostic code instead of guessing:
+
+- `operationId` and at least one `tag` are required on every operation
+- only `#/components/schemas/` refs, no external files
+- string enums only
+- one composition keyword per schema (`allOf` or `oneOf` or `anyOf`, not mixed)
+- only the lowest 2xx response is typed. 4xx/5xx types aren't generated at all
+- no Zod or other runtime validation, no Swagger 2.x
+
+If your spec is generated from a backend framework, you're probably fine. If it's a hand-written spec that leans on every corner of the standard, one of the other tools above will be a better fit and I'd rather tell you now.
+
+Escape hatches for the real-world stuff: mapped types (`--mapped-type GeoFeature:geojson:Feature` swaps a placeholder schema for a real npm type), naming rules with regex captures in `openapi-ng.config.ts`, and a `provideOpenapiNg({ basePath })` provider.
+
+**Links and bits**
+
+- Playground: https://docs.openapi-ng.dev/playground/
+- Demo: https://stackblitz.com/github/AVSystem/openapi-ng/tree/main/stackblitz (the spec, the committed generated output, and three components using it against a mock interceptor)
+- Docs: https://docs.openapi-ng.dev
+- `npm i -D @avsystem/openapi-ng`, then `openapi-ng generate --input api.yaml --output src/generated`
+- Node 22.12+, prebuilt binaries for macOS / Linux (glibc + musl) / Windows, x64 + arm64. Works under Bun and Deno too. Browser via WebAssembly (@avsystem/openapi-ng-wasm32-wasi).
+- Generated code targets Angular 20+. `validateRest` with `debounce` / `when` needs `@angular/forms` 22+.
+- v0.5.1. I use it in production at work but the public API isn't frozen yet.
+
+**What I'd like feedback on**
+
+Two design calls I'm least sure about:
+
+1. One service per tag with `.resource()` / `.observable()` / `.request()` on every operation, versus orval's approach of separate generated classes per flavour. Is the per-call choice worth the fatter service surface?
+2. Rejecting unsupported spec features with a diagnostic instead of emitting best-effort code. Has a strict generator ever made you *drop* a tool, or is it the right trade for deterministic output?
+
+Happy to answer anything else in the thread.
diff --git a/stackblitz/README.md b/stackblitz/README.md
new file mode 100644
index 0000000..766f680
--- /dev/null
+++ b/stackblitz/README.md
@@ -0,0 +1,23 @@
+# openapi-ng demo
+
+A small Angular app consuming a client generated by [openapi-ng](https://github.com/AVSystem/openapi-ng).
+No backend: an `HttpInterceptorFn` in `src/app/mock-api.interceptor.ts` answers the requests in memory.
+
+To experiment with a spec of your own without a workspace, use the
+[playground](https://docs.openapi-ng.dev/playground/).
+
+[Open in StackBlitz](https://stackblitz.com/github/AVSystem/openapi-ng/tree/main/stackblitz)
+
+| Path | What it is |
+| --- | --- |
+| `petstore.openapi.yaml` | the input spec |
+| `src/generated/` | output of `openapi-ng generate`, committed as-is |
+| `src/app/pet-list.ts` | `.resource()` driven by a filter signal |
+| `src/app/pet-detail.ts` | `.resource()` keyed on an input, `.observable()` mutation, `.request()` |
+| `src/app/signup-form.ts` | signal forms async validation with `validateRest()` |
+
+Regenerate after editing the spec:
+
+```sh
+npm run generate
+```
diff --git a/website/src/content/docs/getting-started.md b/website/src/content/docs/getting-started.md
index 4d0fd89..955e73a 100644
--- a/website/src/content/docs/getting-started.md
+++ b/website/src/content/docs/getting-started.md
@@ -3,6 +3,9 @@ title: Getting started
description: Install openapi-ng and generate your first TypeScript models and Angular services from an OpenAPI spec.
---
+Want to see the output first? Paste a spec into the
+[playground](/playground/); the generator runs in your browser.
+
## Install
```bash
diff --git a/website/src/content/docs/index.mdx b/website/src/content/docs/index.mdx
index 9450901..6e00267 100644
--- a/website/src/content/docs/index.mdx
+++ b/website/src/content/docs/index.mdx
@@ -8,6 +8,10 @@ hero:
- text: Get started
link: /getting-started/
icon: right-arrow
+ - text: Playground
+ link: /playground/
+ icon: laptop
+ variant: secondary
- text: View on GitHub
link: https://github.com/AVSystem/openapi-ng
icon: external
diff --git a/website/src/content/docs/reference/runtime.md b/website/src/content/docs/reference/runtime.md
index 3a14f99..70f3c53 100644
--- a/website/src/content/docs/reference/runtime.md
+++ b/website/src/content/docs/reference/runtime.md
@@ -76,6 +76,8 @@ WebAssembly binding cannot be loaded, `generate()` rejects with
`E_UNSUPPORTED_RUNTIME` and a message naming the missing package or
header.
+Try it without installing anything: [the playground](/playground/).
+
## Edge runtimes
Cloudflare Workers, Vercel Edge and Deno Deploy are not verified. The
From 1ee589e634325ffea3fecb831e12a2e9cbc12f62 Mon Sep 17 00:00:00 2001
From: pkurcx
Date: Thu, 3 Sep 2026 21:50:43 +0200
Subject: [PATCH 07/17] feat(website): configurable playground with a console
footer
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add a JSON config editor beside the spec: it takes an openapi-ng config
body (emit, mappedTypes, responseTypeMapping, naming), drops input and
output with a note, and lowers "/…/flags" strings into the {source,
flags} shape the wrapper needs, since JSON cannot carry a RegExp.
Diagnostics move into a scrolling console card under the panes, and the
page hands the viewport below the title to the panes so only they
scroll. Starlight's auto inline margins made the content container a
content-sized flex item, so its width tracked the widest generated
file; pin it to 100%. CodeMirror and the highlight.js theme each own
their scrolling, so drop the wrapper scrollers that fought them.
Remove the share link: it earned little next to the cost of carrying
lz-string and a hash codec.
Co-Authored-By: Claude Opus 5
Claude-Session: https://claude.ai/code/session_011t8uBVY6h4kfN5cXHXuCpR
---
pnpm-lock.yaml | 15 +-
website/astro.config.mjs | 2 +
website/package.json | 3 +-
website/src/pages/playground.astro | 26 ++-
website/src/playground/config.test.ts | 107 ++++++++++++
website/src/playground/config.ts | 66 +++++++
website/src/playground/editor.ts | 24 ++-
website/src/playground/hljs-theme.css | 236 --------------------------
website/src/playground/main.ts | 65 +++----
website/src/playground/playground.css | 132 ++++++++++++--
website/src/playground/share.test.ts | 17 --
website/src/playground/share.ts | 16 --
website/src/playground/tree.ts | 2 +
website/tests/playground.spec.ts | 150 +++++++++++++---
14 files changed, 506 insertions(+), 355 deletions(-)
create mode 100644 website/src/playground/config.test.ts
create mode 100644 website/src/playground/config.ts
delete mode 100644 website/src/playground/hljs-theme.css
delete mode 100644 website/src/playground/share.test.ts
delete mode 100644 website/src/playground/share.ts
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 3e704ee..96ad207 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -112,9 +112,15 @@ importers:
'@codemirror/lang-yaml':
specifier: 6.1.3
version: 6.1.3
+ '@codemirror/language':
+ specifier: 6.12.4
+ version: 6.12.4
'@codemirror/state':
specifier: 6.7.2
version: 6.7.2
+ '@lezer/highlight':
+ specifier: 1.2.3
+ version: 1.2.3
astro:
specifier: 7.2.4
version: 7.2.4(@astrojs/markdown-remark@7.2.4)(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)(@types/node@26.2.0)(yaml@2.9.0)
@@ -124,9 +130,6 @@ importers:
highlight.js:
specifier: 11.12.0
version: 11.12.0
- lz-string:
- specifier: 1.5.0
- version: 1.5.0
sharp:
specifier: 0.35.3
version: 0.35.3(@types/node@26.2.0)
@@ -3628,10 +3631,6 @@ packages:
resolution: {integrity: sha512-5YgH9UJd7wVb9hIouI2adWpgqrrICkt070Dnj8EUY1+B4B2P9eRLPAkAAo6NICA7CEhOIeBHl46u9zSNpNu7zA==}
engines: {node: 20 || >=22}
- lz-string@1.5.0:
- resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==}
- hasBin: true
-
magic-string@0.30.21:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
@@ -8042,8 +8041,6 @@ snapshots:
lru-cache@11.5.0: {}
- lz-string@1.5.0: {}
-
magic-string@0.30.21:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
diff --git a/website/astro.config.mjs b/website/astro.config.mjs
index 949e0d0..a472221 100644
--- a/website/astro.config.mjs
+++ b/website/astro.config.mjs
@@ -87,6 +87,8 @@ export default defineConfig({
'@codemirror/state',
'@codemirror/lang-json',
'@codemirror/lang-yaml',
+ '@codemirror/language',
+ '@lezer/highlight',
'highlight.js/lib/core',
'highlight.js/lib/languages/typescript',
'lz-string',
diff --git a/website/package.json b/website/package.json
index a957c8b..2e50e9f 100644
--- a/website/package.json
+++ b/website/package.json
@@ -22,11 +22,12 @@
"@avsystem/openapi-ng-wasm32-wasi": "0.5.1",
"@codemirror/lang-json": "6.0.2",
"@codemirror/lang-yaml": "6.1.3",
+ "@codemirror/language": "6.12.4",
"@codemirror/state": "6.7.2",
+ "@lezer/highlight": "1.2.3",
"astro": "7.2.4",
"codemirror": "6.0.2",
"highlight.js": "11.12.0",
- "lz-string": "1.5.0",
"sharp": "0.35.3"
},
"devDependencies": {
diff --git a/website/src/pages/playground.astro b/website/src/pages/playground.astro
index 9bf6df9..f51f3ea 100644
--- a/website/src/pages/playground.astro
+++ b/website/src/pages/playground.astro
@@ -1,30 +1,44 @@
---
import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
import '../playground/playground.css';
-import '../playground/hljs-theme.css';
+import hljsLight from 'highlight.js/styles/github.css?raw';
+import hljsDark from 'highlight.js/styles/github-dark.css?raw';
+
+// highlight.js ships light and dark as separate unscoped sheets; nesting them
+// under Starlight's theme attribute lets its toggle pick one.
+const hljsTheme =
+ `:root[data-theme='light'] { ${hljsLight} }\n` + `:root[data-theme='dark'] { ${hljsDark} }`;
---
-
+
+
diff --git a/website/src/playground/config.test.ts b/website/src/playground/config.test.ts
new file mode 100644
index 0000000..cd1344f
--- /dev/null
+++ b/website/src/playground/config.test.ts
@@ -0,0 +1,107 @@
+import { describe, expect, it } from 'vitest';
+import { DEFAULT_CONFIG, parseConfig } from './config';
+
+describe('parseConfig', () => {
+ it('passes generator options through', () => {
+ const text = JSON.stringify({
+ emit: ['models'],
+ mappedTypes: [{ schema: 'GeoJSON', import: 'geojson', type: 'GeoJSON', alias: 'NativeGeoJSON' }],
+ responseTypeMapping: [{ contentType: 'application/pdf', responseType: 'blob' }],
+ });
+ expect(parseConfig(text)).toEqual({
+ ok: true,
+ options: JSON.parse(text),
+ notes: [],
+ });
+ });
+
+ it('drops input and output with a note', () => {
+ const result = parseConfig('{"input": "./spec.yaml", "output": "./out", "emit": ["angular"]}');
+ expect(result).toEqual({
+ ok: true,
+ options: { emit: ['angular'] },
+ notes: ['input and output are ignored in the playground'],
+ });
+ });
+
+ it('lowers a regex literal string in a methodName rule to {source, flags}', () => {
+ const result = parseConfig(
+ JSON.stringify({
+ naming: {
+ methodName: {
+ from: '{operationId}',
+ parse: '/^(?:[^_]+_)+(?.+)$/i',
+ format: '{capture.rest}',
+ case: 'camel',
+ },
+ },
+ }),
+ );
+ expect(result).toMatchObject({
+ ok: true,
+ options: {
+ naming: {
+ methodName: {
+ from: '{operationId}',
+ parse: { source: '^(?:[^_]+_)+(?.+)$', flags: 'i' },
+ format: '{capture.rest}',
+ case: 'camel',
+ },
+ },
+ },
+ });
+ });
+
+ it('lowers parse inside a group chain and keeps string items', () => {
+ const result = parseConfig(
+ JSON.stringify({
+ naming: { group: ['{tags[0]}', { from: '{path}', parse: '/^\\/(?[^/]+)/', format: '{capture.seg}' }] },
+ }),
+ );
+ expect(result).toMatchObject({
+ ok: true,
+ options: {
+ naming: {
+ group: ['{tags[0]}', { from: '{path}', parse: { source: '^\\/(?[^/]+)', flags: '' }, format: '{capture.seg}' }],
+ },
+ },
+ });
+ });
+
+ it('keeps an explicit {source, flags} parse untouched', () => {
+ const result = parseConfig(
+ JSON.stringify({ naming: { methodName: { parse: { source: 'a', flags: 'g' }, format: 'x' } } }),
+ );
+ expect(result).toMatchObject({
+ ok: true,
+ options: { naming: { methodName: { parse: { source: 'a', flags: 'g' }, format: 'x' } } },
+ });
+ });
+
+ it('rejects a parse string that is not a regex literal', () => {
+ const result = parseConfig(JSON.stringify({ naming: { methodName: { parse: '^abc$' } } }));
+ expect(result).toEqual({
+ ok: false,
+ error: 'naming.methodName.parse: write the regex as a literal, e.g. "/^abc$/i"',
+ });
+ });
+
+ it('rejects invalid JSON', () => {
+ const result = parseConfig('{"emit": [');
+ expect(result.ok).toBe(false);
+ if (!result.ok) expect(result.error).toMatch(/^config is not valid JSON: /);
+ });
+
+ it('rejects a non-object document', () => {
+ expect(parseConfig('["models"]')).toEqual({ ok: false, error: 'config must be a JSON object' });
+ expect(parseConfig('null')).toEqual({ ok: false, error: 'config must be a JSON object' });
+ });
+
+ it('ships a default that parses to the default emit set', () => {
+ expect(parseConfig(DEFAULT_CONFIG)).toEqual({
+ ok: true,
+ options: { emit: ['models', 'angular'] },
+ notes: [],
+ });
+ });
+});
diff --git a/website/src/playground/config.ts b/website/src/playground/config.ts
new file mode 100644
index 0000000..d9ef93c
--- /dev/null
+++ b/website/src/playground/config.ts
@@ -0,0 +1,66 @@
+import type { GenerateOptions } from '@avsystem/openapi-ng/browser';
+
+export type ConfigOptions = Pick<
+ GenerateOptions,
+ 'emit' | 'mappedTypes' | 'responseTypeMapping' | 'naming'
+>;
+
+export type ParsedConfig =
+ | { ok: true; options: ConfigOptions; notes: string[] }
+ | { ok: false; error: string };
+
+export const DEFAULT_CONFIG = '{\n "emit": ["models", "angular"]\n}\n';
+
+const REGEX_LITERAL = /^\/(.*)\/([a-z]*)$/s;
+
+class ConfigError extends Error {}
+
+function isRecord(value: unknown): value is Record {
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
+}
+
+// JSON cannot carry a RegExp; accept the literal spelling from a TS config
+// as a string and lower it to the {source, flags} shape the wrapper takes.
+function lowerRule(rule: unknown, path: string): unknown {
+ if (!isRecord(rule) || typeof rule.parse !== 'string') return rule;
+ const match = REGEX_LITERAL.exec(rule.parse);
+ if (!match) {
+ throw new ConfigError(`${path}.parse: write the regex as a literal, e.g. "/^abc$/i"`);
+ }
+ return { ...rule, parse: { source: match[1], flags: match[2] } };
+}
+
+function lowerNaming(value: unknown, path: string): unknown {
+ if (Array.isArray(value)) return value.map((item, i) => lowerRule(item, `${path}[${i}]`));
+ return lowerRule(value, path);
+}
+
+export function parseConfig(text: string): ParsedConfig {
+ let doc: unknown;
+ try {
+ doc = JSON.parse(text);
+ } catch (err) {
+ return { ok: false, error: `config is not valid JSON: ${(err as Error).message}` };
+ }
+ if (!isRecord(doc)) return { ok: false, error: 'config must be a JSON object' };
+
+ const { input, output, ...options } = doc;
+ const notes: string[] = [];
+ if (input !== undefined || output !== undefined) {
+ notes.push('input and output are ignored in the playground');
+ }
+ try {
+ if (isRecord(options.naming)) {
+ options.naming = Object.fromEntries(
+ Object.entries(options.naming).map(([key, value]) => [
+ key,
+ lowerNaming(value, `naming.${key}`),
+ ]),
+ );
+ }
+ } catch (err) {
+ if (err instanceof ConfigError) return { ok: false, error: err.message };
+ throw err;
+ }
+ return { ok: true, options: options as ConfigOptions, notes };
+}
diff --git a/website/src/playground/editor.ts b/website/src/playground/editor.ts
index baf61b9..4a8d304 100644
--- a/website/src/playground/editor.ts
+++ b/website/src/playground/editor.ts
@@ -1,4 +1,6 @@
+import { HighlightStyle, syntaxHighlighting } from '@codemirror/language';
import { EditorState, Compartment } from '@codemirror/state';
+import { tags } from '@lezer/highlight';
import { EditorView, basicSetup } from 'codemirror';
import { json } from '@codemirror/lang-json';
import { yaml } from '@codemirror/lang-yaml';
@@ -9,13 +11,31 @@ export interface SpecEditor {
setValue(value: string): void;
}
+// The editor root carries the `hljs` class, so the highlight.js theme that
+// styles the output pane also supplies the editor's colors and background.
const theme = EditorView.theme({
- '&': { height: '100%', backgroundColor: 'var(--sl-color-bg)', color: 'var(--sl-color-text)' },
+ '&': { height: '100%' },
'.cm-gutters': { backgroundColor: 'var(--sl-color-bg-nav)', color: 'var(--sl-color-gray-3)', border: 'none' },
'.cm-activeLine, .cm-activeLineGutter': { backgroundColor: 'var(--sl-color-gray-6)' },
'.cm-content': { fontFamily: 'var(--__sl-font-mono)' },
+ '.cm-cursor': { borderLeftColor: 'currentColor' },
+ // Mirrors the base theme's own selector depth, which a shorter one loses to.
+ // Its default tint is invisible against the dark hljs background.
+ '.cm-selectionBackground, &.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, ::selection':
+ { backgroundColor: 'var(--sl-color-accent-low)' },
});
+// Token classes mirror what highlight.js emits for YAML and JSON.
+const highlight = HighlightStyle.define([
+ { tag: [tags.keyword, tags.typeName], class: 'hljs-keyword' },
+ { tag: [tags.bool, tags.null, tags.number], class: 'hljs-literal' },
+ { tag: [tags.propertyName, tags.definition(tags.propertyName)], class: 'hljs-attr' },
+ { tag: [tags.string, tags.special(tags.string)], class: 'hljs-string' },
+ { tag: tags.labelName, class: 'hljs-symbol' },
+ { tag: [tags.comment, tags.meta], class: 'hljs-comment' },
+ { tag: tags.invalid, class: 'hljs-deletion' },
+]);
+
export function createEditor(
parent: HTMLElement,
initial: string,
@@ -31,6 +51,8 @@ export function createEditor(
extensions: [
basicSetup,
theme,
+ syntaxHighlighting(highlight),
+ EditorView.editorAttributes.of({ class: 'hljs' }),
language.of(format === 'json' ? json() : yaml()),
EditorView.updateListener.of(update => {
if (!update.docChanged) return;
diff --git a/website/src/playground/hljs-theme.css b/website/src/playground/hljs-theme.css
deleted file mode 100644
index e8bf8a6..0000000
--- a/website/src/playground/hljs-theme.css
+++ /dev/null
@@ -1,236 +0,0 @@
-/* Generated from highlight.js/styles/github.css and github-dark.css.
- Each rule is prefixed with :root[data-theme='light'] / :root[data-theme='dark']. */
-:root[data-theme='light'] pre code.hljs {
- display: block;
- overflow-x: auto;
- padding: 1em;
-}
-:root[data-theme='light'] code.hljs {
- padding: 3px 5px;
-}
-:root[data-theme='light'] /*!
- Theme: GitHub
- Description: Light theme as seen on github.com
- Author: github.com
- Maintainer: @Hirse
- Updated: 2021-05-15
-
- Outdated base version: https://github.com/primer/github-syntax-light
- Current colors taken from GitHub's CSS
-*/
-.hljs {
- color: #24292e;
- background: #ffffff;
-}
-:root[data-theme='light'] .hljs-doctag,
-:root[data-theme='light'] .hljs-keyword,
-:root[data-theme='light'] .hljs-meta .hljs-keyword,
-:root[data-theme='light'] .hljs-template-tag,
-:root[data-theme='light'] .hljs-template-variable,
-:root[data-theme='light'] .hljs-type,
-:root[data-theme='light'] .hljs-variable.language_ {
- /* prettylights-syntax-keyword */
- color: #d73a49;
-}
-:root[data-theme='light'] .hljs-title,
-:root[data-theme='light'] .hljs-title.class_,
-:root[data-theme='light'] .hljs-title.class_.inherited__,
-:root[data-theme='light'] .hljs-title.function_ {
- /* prettylights-syntax-entity */
- color: #6f42c1;
-}
-:root[data-theme='light'] .hljs-attr,
-:root[data-theme='light'] .hljs-attribute,
-:root[data-theme='light'] .hljs-literal,
-:root[data-theme='light'] .hljs-meta,
-:root[data-theme='light'] .hljs-number,
-:root[data-theme='light'] .hljs-operator,
-:root[data-theme='light'] .hljs-variable,
-:root[data-theme='light'] .hljs-selector-attr,
-:root[data-theme='light'] .hljs-selector-class,
-:root[data-theme='light'] .hljs-selector-id {
- /* prettylights-syntax-constant */
- color: #005cc5;
-}
-:root[data-theme='light'] .hljs-regexp,
-:root[data-theme='light'] .hljs-string,
-:root[data-theme='light'] .hljs-meta .hljs-string {
- /* prettylights-syntax-string */
- color: #032f62;
-}
-:root[data-theme='light'] .hljs-built_in,
-:root[data-theme='light'] .hljs-symbol {
- /* prettylights-syntax-variable */
- color: #e36209;
-}
-:root[data-theme='light'] .hljs-comment,
-:root[data-theme='light'] .hljs-code,
-:root[data-theme='light'] .hljs-formula {
- /* prettylights-syntax-comment */
- color: #6a737d;
-}
-:root[data-theme='light'] .hljs-name,
-:root[data-theme='light'] .hljs-quote,
-:root[data-theme='light'] .hljs-selector-tag,
-:root[data-theme='light'] .hljs-selector-pseudo {
- /* prettylights-syntax-entity-tag */
- color: #22863a;
-}
-:root[data-theme='light'] .hljs-subst {
- /* prettylights-syntax-storage-modifier-import */
- color: #24292e;
-}
-:root[data-theme='light'] .hljs-section {
- /* prettylights-syntax-markup-heading */
- color: #005cc5;
- font-weight: bold;
-}
-:root[data-theme='light'] .hljs-bullet {
- /* prettylights-syntax-markup-list */
- color: #735c0f;
-}
-:root[data-theme='light'] .hljs-emphasis {
- /* prettylights-syntax-markup-italic */
- color: #24292e;
- font-style: italic;
-}
-:root[data-theme='light'] .hljs-strong {
- /* prettylights-syntax-markup-bold */
- color: #24292e;
- font-weight: bold;
-}
-:root[data-theme='light'] .hljs-addition {
- /* prettylights-syntax-markup-inserted */
- color: #22863a;
- background-color: #f0fff4;
-}
-:root[data-theme='light'] .hljs-deletion {
- /* prettylights-syntax-markup-deleted */
- color: #b31d28;
- background-color: #ffeef0;
-}
-:root[data-theme='light'] .hljs-char.escape_,
-:root[data-theme='light'] .hljs-link,
-:root[data-theme='light'] .hljs-params,
-:root[data-theme='light'] .hljs-property,
-:root[data-theme='light'] .hljs-punctuation,
-:root[data-theme='light'] .hljs-tag {
- /* purposely ignored */
-}
-:root[data-theme='dark'] pre code.hljs {
- display: block;
- overflow-x: auto;
- padding: 1em;
-}
-:root[data-theme='dark'] code.hljs {
- padding: 3px 5px;
-}
-:root[data-theme='dark'] /*!
- Theme: GitHub Dark
- Description: Dark theme as seen on github.com
- Author: github.com
- Maintainer: @Hirse
- Updated: 2021-05-15
-
- Outdated base version: https://github.com/primer/github-syntax-dark
- Current colors taken from GitHub's CSS
-*/
-.hljs {
- color: #c9d1d9;
- background: #0d1117;
-}
-:root[data-theme='dark'] .hljs-doctag,
-:root[data-theme='dark'] .hljs-keyword,
-:root[data-theme='dark'] .hljs-meta .hljs-keyword,
-:root[data-theme='dark'] .hljs-template-tag,
-:root[data-theme='dark'] .hljs-template-variable,
-:root[data-theme='dark'] .hljs-type,
-:root[data-theme='dark'] .hljs-variable.language_ {
- /* prettylights-syntax-keyword */
- color: #ff7b72;
-}
-:root[data-theme='dark'] .hljs-title,
-:root[data-theme='dark'] .hljs-title.class_,
-:root[data-theme='dark'] .hljs-title.class_.inherited__,
-:root[data-theme='dark'] .hljs-title.function_ {
- /* prettylights-syntax-entity */
- color: #d2a8ff;
-}
-:root[data-theme='dark'] .hljs-attr,
-:root[data-theme='dark'] .hljs-attribute,
-:root[data-theme='dark'] .hljs-literal,
-:root[data-theme='dark'] .hljs-meta,
-:root[data-theme='dark'] .hljs-number,
-:root[data-theme='dark'] .hljs-operator,
-:root[data-theme='dark'] .hljs-variable,
-:root[data-theme='dark'] .hljs-selector-attr,
-:root[data-theme='dark'] .hljs-selector-class,
-:root[data-theme='dark'] .hljs-selector-id {
- /* prettylights-syntax-constant */
- color: #79c0ff;
-}
-:root[data-theme='dark'] .hljs-regexp,
-:root[data-theme='dark'] .hljs-string,
-:root[data-theme='dark'] .hljs-meta .hljs-string {
- /* prettylights-syntax-string */
- color: #a5d6ff;
-}
-:root[data-theme='dark'] .hljs-built_in,
-:root[data-theme='dark'] .hljs-symbol {
- /* prettylights-syntax-variable */
- color: #ffa657;
-}
-:root[data-theme='dark'] .hljs-comment,
-:root[data-theme='dark'] .hljs-code,
-:root[data-theme='dark'] .hljs-formula {
- /* prettylights-syntax-comment */
- color: #8b949e;
-}
-:root[data-theme='dark'] .hljs-name,
-:root[data-theme='dark'] .hljs-quote,
-:root[data-theme='dark'] .hljs-selector-tag,
-:root[data-theme='dark'] .hljs-selector-pseudo {
- /* prettylights-syntax-entity-tag */
- color: #7ee787;
-}
-:root[data-theme='dark'] .hljs-subst {
- /* prettylights-syntax-storage-modifier-import */
- color: #c9d1d9;
-}
-:root[data-theme='dark'] .hljs-section {
- /* prettylights-syntax-markup-heading */
- color: #1f6feb;
- font-weight: bold;
-}
-:root[data-theme='dark'] .hljs-bullet {
- /* prettylights-syntax-markup-list */
- color: #f2cc60;
-}
-:root[data-theme='dark'] .hljs-emphasis {
- /* prettylights-syntax-markup-italic */
- color: #c9d1d9;
- font-style: italic;
-}
-:root[data-theme='dark'] .hljs-strong {
- /* prettylights-syntax-markup-bold */
- color: #c9d1d9;
- font-weight: bold;
-}
-:root[data-theme='dark'] .hljs-addition {
- /* prettylights-syntax-markup-inserted */
- color: #aff5b4;
- background-color: #033a16;
-}
-:root[data-theme='dark'] .hljs-deletion {
- /* prettylights-syntax-markup-deleted */
- color: #ffdcd7;
- background-color: #67060c;
-}
-:root[data-theme='dark'] .hljs-char.escape_,
-:root[data-theme='dark'] .hljs-link,
-:root[data-theme='dark'] .hljs-params,
-:root[data-theme='dark'] .hljs-property,
-:root[data-theme='dark'] .hljs-punctuation,
-:root[data-theme='dark'] .hljs-tag {
- /* purposely ignored */
-}
diff --git a/website/src/playground/main.ts b/website/src/playground/main.ts
index 92ed1e7..1b93590 100644
--- a/website/src/playground/main.ts
+++ b/website/src/playground/main.ts
@@ -1,22 +1,32 @@
import petstoreSpec from '../../../stackblitz/petstore.openapi.yaml?raw';
import type { GenerateResult, GeneratorDiagnostic } from '@avsystem/openapi-ng/browser';
+import { DEFAULT_CONFIG, parseConfig } from './config';
import { createEditor } from './editor';
import { detectFormat, displayPathFor } from './format';
import { engineVersion, GenerateError, loadGenerate, type GenerateFn } from './generator';
import { copyText, renderOutput } from './output';
-import { decodeShareHash, encodeShareHash } from './share';
import { buildTree, renderTree } from './tree';
const DEBOUNCE_MS = 150;
const STATUS_RESTORE_MS = 2000;
const WARMUP_SPEC = 'openapi: 3.0.3\ninfo: {title: warmup, version: "1"}\npaths: {}';
+interface ConsoleLines {
+ errors?: string[];
+ warnings?: GeneratorDiagnostic[];
+ notes?: string[];
+}
+
function byId(doc: Document, id: string): T {
const el = doc.getElementById(id);
if (!el) throw new Error(`playground: missing #${id}`);
return el as T;
}
+function describe(item: { code: string; subcode?: string | null; message: string }): string {
+ return `${item.code}${item.subcode ? ` (${item.subcode})` : ''}: ${item.message}`;
+}
+
export function start(doc: Document): void {
const root = doc.querySelector('.pg');
if (!root) return;
@@ -49,27 +59,25 @@ export function start(doc: Document): void {
}, STATUS_RESTORE_MS);
}
- const initial = decodeShareHash(location.hash) ?? petstoreSpec;
- const editor = createEditor(byId(doc, 'pg-editor'), initial, schedule);
+ const editor = createEditor(byId(doc, 'pg-editor'), petstoreSpec, schedule);
+ const configEditor = createEditor(byId(doc, 'pg-config'), DEFAULT_CONFIG, schedule);
function schedule(): void {
clearTimeout(timer);
timer = setTimeout(run, DEBOUNCE_MS);
}
- function renderDiagnostics(items: GeneratorDiagnostic[], fatal?: GenerateError): void {
+ function renderConsole({ errors = [], warnings = [], notes = [] }: ConsoleLines): void {
diagnosticsEl.replaceChildren();
- if (fatal) {
+ const append = (text: string, className?: string) => {
const li = doc.createElement('li');
- li.className = 'is-error';
- li.textContent = `${fatal.code}${fatal.subcode ? ` (${fatal.subcode})` : ''}: ${fatal.message}`;
+ if (className) li.className = className;
+ li.textContent = text;
diagnosticsEl.append(li);
- }
- for (const item of items) {
- const li = doc.createElement('li');
- li.textContent = `${item.code}${item.subcode ? ` (${item.subcode})` : ''}: ${item.message}`;
- diagnosticsEl.append(li);
- }
+ };
+ for (const error of errors) append(error, 'is-error');
+ for (const warning of warnings) append(describe(warning));
+ for (const note of notes) append(note, 'is-note');
}
function select(path: string): void {
@@ -81,7 +89,7 @@ export function start(doc: Document): void {
if (artifact) renderOutput(codeEl, artifact.contents);
}
- function showResult(result: GenerateResult, elapsedMs: number): void {
+ function showResult(result: GenerateResult, elapsedMs: number, notes: string[]): void {
lastResult = result;
root!.classList.remove('is-stale');
const paths = result.artifacts.map(a => a.path);
@@ -92,7 +100,7 @@ export function start(doc: Document): void {
summaryEl.textContent =
`${result.summary.operationCount} operations · ${result.summary.schemaCount} schemas · ` +
`${result.artifacts.length} files · ${elapsedMs.toFixed(0)} ms`;
- renderDiagnostics(result.diagnostics);
+ renderConsole({ warnings: result.diagnostics, notes });
}
async function run(): Promise {
@@ -101,6 +109,13 @@ export function start(doc: Document): void {
// resolve before an earlier, slower one still in flight.
const id = ++runId;
const source = editor.getValue();
+ const config = parseConfig(configEditor.getValue());
+ if (!config.ok) {
+ root!.classList.add('is-stale');
+ summaryEl.textContent = 'config error';
+ renderConsole({ errors: [config.error] });
+ return;
+ }
const started = performance.now();
try {
// No inputFormat: the /browser subpath's InputFormat is a const enum with no
@@ -108,36 +123,26 @@ export function start(doc: Document): void {
const result = await generate({
inputContents: source,
displayPath: displayPathFor(detectFormat(source)),
- emit: ['models', 'angular'],
+ ...config.options,
});
if (id !== runId) return;
- showResult(result, performance.now() - started);
+ showResult(result, performance.now() - started, config.notes);
} catch (err) {
if (id !== runId) return;
root!.classList.add('is-stale');
if (err instanceof GenerateError) {
summaryEl.textContent = 'generation failed';
- renderDiagnostics(err.warnings, err);
+ renderConsole({ errors: [describe(err)], warnings: err.warnings, notes: config.notes });
} else {
- renderDiagnostics([]);
summaryEl.textContent = err instanceof Error ? err.message : String(err);
+ renderConsole({ notes: config.notes });
}
}
}
byId(doc, 'pg-reset').addEventListener('click', () => {
editor.setValue(petstoreSpec);
- history.replaceState(null, '', location.pathname);
- });
- byId(doc, 'pg-share').addEventListener('click', async () => {
- const hash = encodeShareHash(editor.getValue());
- history.replaceState(null, '', location.pathname + hash);
- try {
- await copyText(location.href);
- announce('Link copied');
- } catch (err) {
- announce(`Copy failed: ${err instanceof Error ? err.message : String(err)}`);
- }
+ configEditor.setValue(DEFAULT_CONFIG);
});
byId(doc, 'pg-copy').addEventListener('click', async () => {
const artifact = lastResult?.artifacts.find(a => a.path === selectedPath);
diff --git a/website/src/playground/playground.css b/website/src/playground/playground.css
index e1c0938..73bc3bc 100644
--- a/website/src/playground/playground.css
+++ b/website/src/playground/playground.css
@@ -1,12 +1,52 @@
+/* Scoped below the header, whose grid also reads this width. */
+main {
+ --sl-content-width: 100%;
+}
+
+/* Hand the viewport below the title to the playground; only the panes scroll. */
+@media (min-width: 72rem) {
+ .main-frame {
+ height: 100dvh;
+ display: flex;
+ flex-direction: column;
+ }
+ .main-frame > div,
+ .main-pane,
+ main,
+ main > .content-panel:last-child,
+ .content-panel:last-child > .sl-container,
+ .sl-container > .sl-markdown-content {
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ min-height: 0;
+ }
+ /* Starlight's auto inline margins would make the container a content-sized
+ flex item, so its width would track the widest generated file. */
+ .content-panel:last-child > .sl-container {
+ width: 100%;
+ margin-inline: 0;
+ }
+ main {
+ padding-bottom: 0;
+ }
+ /* Pagination links would eat into the height the panes claim. */
+ .content-panel:last-child > .sl-container > footer {
+ display: none;
+ }
+ .pg {
+ flex: 1;
+ min-height: 0;
+ margin-top: 0;
+ }
+}
+
.pg {
display: grid;
- grid-template-rows: auto 1fr auto;
+ grid-template-rows: auto minmax(0, 1fr) auto;
gap: 0.75rem;
- height: calc(100dvh - var(--sl-nav-height) - 3rem);
- min-height: 32rem;
}
-.pg-toolbar,
-.pg-footer {
+.pg-toolbar {
display: flex;
justify-content: space-between;
align-items: center;
@@ -27,19 +67,49 @@
}
.pg-panes {
display: grid;
- grid-template-columns: minmax(0, 5fr) 14rem minmax(0, 6fr);
+ grid-template-columns: minmax(0, 5fr) 18rem minmax(0, 6fr);
+ gap: 0.75rem;
+ min-height: 0;
+}
+.pg-inputs {
+ display: grid;
+ grid-template-rows: minmax(0, 2fr) minmax(0, 1fr);
gap: 0.75rem;
min-height: 0;
}
+.pg-config-pane {
+ display: grid;
+ grid-template-rows: auto minmax(0, 1fr);
+ gap: 0.25rem;
+ min-height: 0;
+}
+.pg-pane-label {
+ font-size: var(--sl-text-xs);
+ color: var(--sl-color-gray-3);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+.pg-pane-label span {
+ margin-left: 0.5rem;
+}
.pg-editor,
+.pg-config,
.pg-tree,
-.pg-output {
+.pg-output,
+.pg-console {
border: 1px solid var(--sl-color-gray-5);
border-radius: 0.5rem;
overflow: auto;
min-height: 0;
}
-.pg-editor .cm-editor {
+/* CodeMirror scrolls itself; a second scroller here would fight its measuring. */
+.pg-editor,
+.pg-config {
+ overflow: hidden;
+}
+.pg-editor .cm-editor,
+.pg-config .cm-editor {
height: 100%;
font-size: 0.8rem;
}
@@ -62,12 +132,14 @@
box-sizing: border-box;
display: flex;
justify-content: space-between;
+ gap: 1rem;
width: 100%;
padding: 0.25rem 0.75rem;
cursor: pointer;
font-family: var(--__sl-font-mono);
font-size: 0.75rem;
text-align: left;
+ white-space: nowrap;
}
.pg-tree li[data-depth='1'] button {
padding-left: 1.75rem;
@@ -76,7 +148,13 @@
outline: 2px solid var(--sl-color-accent);
outline-offset: -2px;
}
+.pg-tree .name {
+ min-width: 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
.pg-tree .size {
+ flex-shrink: 0;
color: var(--sl-color-gray-3);
}
.pg-output {
@@ -87,26 +165,49 @@
height: 100%;
font-size: 0.75rem;
}
+/* The pane is the only scroller; the hljs theme's own overflow on `code`
+ would otherwise nest a second one and resize the pane as you scroll. The id
+ outranks that theme's `pre code.hljs`, which ties on specificity and is
+ injected later in the document. */
+#pg-code.hljs {
+ box-sizing: border-box;
+ min-height: 100%;
+ overflow: visible;
+ width: max-content;
+ min-width: 100%;
+}
.pg-copy {
position: absolute;
top: 0.5rem;
right: 0.5rem;
}
+.pg-console {
+ max-height: 9rem;
+ overflow-y: auto;
+ padding: 0.5rem 0.75rem;
+ background: var(--sl-color-bg-nav);
+ font-family: var(--__sl-font-mono);
+ font-size: 0.75rem;
+ line-height: 1.5;
+}
+.pg-summary {
+ color: var(--sl-color-gray-3);
+}
.pg-diagnostics {
list-style: none;
margin: 0;
padding: 0;
- display: flex;
- flex-wrap: wrap;
- gap: 0.5rem;
}
.pg-diagnostics li {
- font-family: var(--__sl-font-mono);
- font-size: 0.75rem;
+ white-space: pre-wrap;
+ overflow-wrap: anywhere;
}
.pg-diagnostics li.is-error {
color: var(--sl-color-red);
}
+.pg-diagnostics li.is-note {
+ color: var(--sl-color-gray-3);
+}
.pg.is-stale .pg-tree,
.pg.is-stale .pg-output {
opacity: 0.5;
@@ -115,11 +216,8 @@
padding: 2rem;
}
@media (max-width: 72rem) {
- .pg {
- height: auto;
- }
.pg-panes {
grid-template-columns: 1fr;
- grid-template-rows: 20rem auto 20rem;
+ grid-template-rows: 32rem auto 20rem;
}
}
diff --git a/website/src/playground/share.test.ts b/website/src/playground/share.test.ts
deleted file mode 100644
index 67689c0..0000000
--- a/website/src/playground/share.test.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { describe, expect, it } from 'vitest';
-import { decodeShareHash, encodeShareHash } from './share';
-
-describe('share hash', () => {
- it('round-trips a spec through the URL hash', () => {
- const spec = 'openapi: 3.0.3\ninfo:\n title: Ünïcode & spaces\n';
- const hash = encodeShareHash(spec);
- expect(hash.startsWith('#spec=')).toBe(true);
- expect(decodeShareHash(hash)).toBe(spec);
- });
- it('returns null for missing, foreign or corrupt hashes', () => {
- expect(decodeShareHash('')).toBeNull();
- expect(decodeShareHash('#section-anchor')).toBeNull();
- expect(decodeShareHash('#spec=')).toBeNull();
- expect(decodeShareHash('#spec=%%%not-lz%%%')).toBeNull();
- });
-});
diff --git a/website/src/playground/share.ts b/website/src/playground/share.ts
deleted file mode 100644
index c623587..0000000
--- a/website/src/playground/share.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import LZString from 'lz-string';
-
-const PREFIX = '#spec=';
-
-export function encodeShareHash(spec: string): string {
- return PREFIX + LZString.compressToEncodedURIComponent(spec);
-}
-
-// lz-string returns '' or null for input it cannot decode; both mean "no spec".
-export function decodeShareHash(hash: string): string | null {
- if (!hash.startsWith(PREFIX)) return null;
- const payload = hash.slice(PREFIX.length);
- if (payload === '') return null;
- const decoded = LZString.decompressFromEncodedURIComponent(payload);
- return decoded ? decoded : null;
-}
diff --git a/website/src/playground/tree.ts b/website/src/playground/tree.ts
index beba7ec..eab222f 100644
--- a/website/src/playground/tree.ts
+++ b/website/src/playground/tree.ts
@@ -64,7 +64,9 @@ export function renderTree(
if (row.path === selectedPath) item.className = 'is-selected';
const button = doc.createElement('button');
button.type = 'button';
+ button.title = row.path;
const name = doc.createElement('span');
+ name.className = 'name';
name.textContent = row.name;
const size = doc.createElement('span');
size.className = 'size';
diff --git a/website/tests/playground.spec.ts b/website/tests/playground.spec.ts
index a94ead9..a1f2709 100644
--- a/website/tests/playground.spec.ts
+++ b/website/tests/playground.spec.ts
@@ -1,38 +1,144 @@
-import { expect, test } from '@playwright/test';
+import { expect, test, type Page } from '@playwright/test';
const INVALID_SPEC =
'openapi: 3.0.3\ninfo: {title: x, version: "1"}\npaths: {/a: {get: {responses: {"200": {description: ok}}}}}';
-test('generates the petstore client in the browser', async ({ page }) => {
+const SNAKE_CASE_CONFIG = JSON.stringify({
+ input: './openapi/internal.json',
+ output: './libs/openapi-ng',
+ emit: ['models', 'angular'],
+ naming: { methodName: { from: '{operationId}', parse: '/^(?.+)$/', format: '{capture.all}', case: 'snake' } },
+});
+
+async function ready(page: Page): Promise {
await page.goto('/playground/');
- expect(await page.evaluate(() => globalThis.crossOriginIsolated)).toBe(true);
await expect(page.locator('#pg-status')).toContainText('runs in your browser');
+}
+
+async function replaceText(page: Page, selector: string, text: string): Promise {
+ await page.locator(`${selector} .cm-content`).click();
+ await page.keyboard.press('ControlOrMeta+a');
+ await page.keyboard.insertText(text);
+}
+
+test('generates the petstore client in the browser', async ({ page }) => {
+ await ready(page);
+ expect(await page.evaluate(() => globalThis.crossOriginIsolated)).toBe(true);
await expect(page.locator('#pg-tree li[data-path]')).toHaveCount(6);
- await page.locator('#pg-tree li[data-path="rest/pet.rest.generated.ts"]').click();
+ const petFile = page.locator('#pg-tree li[data-path="rest/pet.rest.generated.ts"] button');
+ await expect(petFile).toHaveAttribute('title', 'rest/pet.rest.generated.ts');
+ await petFile.click();
await expect(page.locator('#pg-code')).toContainText('listPets');
});
test('shows a typed diagnostic for an unsupported spec', async ({ page }) => {
- await page.goto('/playground/');
- await expect(page.locator('#pg-status')).toContainText('runs in your browser');
- const editor = page.locator('#pg-editor .cm-content');
- await editor.click();
- await page.keyboard.press('ControlOrMeta+a');
- await page.keyboard.insertText(INVALID_SPEC);
+ await ready(page);
+ await replaceText(page, '#pg-editor', INVALID_SPEC);
await expect(page.locator('#pg-diagnostics li.is-error')).toContainText('E_POLICY_VIOLATION');
await expect(page.locator('#pg-diagnostics li.is-error')).toContainText('missing-operation-id');
});
-test('share link round-trips the spec', async ({ page, context }) => {
- await context.grantPermissions(['clipboard-read', 'clipboard-write']);
- await page.goto('/playground/');
- await expect(page.locator('#pg-status')).toContainText('runs in your browser');
- const editor = page.locator('#pg-editor .cm-content');
- await editor.click();
- await page.keyboard.press('ControlOrMeta+a');
- await page.keyboard.insertText('openapi: 3.0.3\ninfo: {title: shared, version: "1"}\npaths: {}');
- await page.locator('#pg-share').click();
- await expect(page).toHaveURL(/#spec=/);
- await page.reload();
- await expect(page.locator('#pg-editor .cm-content')).toContainText('title: shared');
+test('applies a pasted project config to the generated names', async ({ page }) => {
+ await ready(page);
+ await page.locator('#pg-tree li[data-path="rest/pet.rest.generated.ts"] button').click();
+ await expect(page.locator('#pg-code')).toContainText('listPets');
+ await replaceText(page, '#pg-config', SNAKE_CASE_CONFIG);
+ await expect(page.locator('#pg-code')).toContainText('list_pets');
+ await expect(page.locator('#pg-diagnostics li.is-note')).toContainText('input and output are ignored');
+});
+
+test('reports a broken config in the console and keeps the last output', async ({ page }) => {
+ await ready(page);
+ await replaceText(page, '#pg-config', '{"emit": [');
+ await expect(page.locator('#pg-diagnostics li.is-error')).toContainText('config is not valid JSON');
+ await expect(page.locator('.pg')).toHaveClass(/is-stale/);
+ await replaceText(page, '#pg-config', '{"emit": ["models"], "typo": true}');
+ await expect(page.locator('#pg-diagnostics li.is-error')).toContainText('E_INVALID_OPTION');
+});
+
+test('lays the panes out untouched by the prose styles', async ({ page }) => {
+ await ready(page);
+ const paneTops = await page
+ .locator('.pg-panes > *')
+ .evaluateAll(els => els.map(el => el.getBoundingClientRect().top));
+ expect(new Set(paneTops).size).toBe(1);
+ const buttonHeights = await page
+ .locator('.pg-actions button')
+ .evaluateAll(els => els.map(el => el.getBoundingClientRect().height));
+ expect(new Set(buttonHeights).size).toBe(1);
+ await expect(page.locator('.cm-line').nth(1)).toHaveCSS('margin-top', '0px');
+ const [pgWidth, panelWidth] = await page.evaluate(() => {
+ const panel = document.querySelector('.content-panel') as HTMLElement;
+ const panelStyle = getComputedStyle(panel);
+ return [
+ document.querySelector('.pg')!.getBoundingClientRect().width,
+ panel.clientWidth - parseFloat(panelStyle.paddingLeft) - parseFloat(panelStyle.paddingRight),
+ ];
+ });
+ expect(pgWidth).toBeCloseTo(panelWidth, 0);
+ const tree = page.locator('#pg-tree');
+ const [treeScrollWidth, treeClientWidth] = await tree.evaluate(el => [el.scrollWidth, el.clientWidth]);
+ expect(treeScrollWidth).toBe(treeClientWidth);
+ const console = page.locator('#pg-console');
+ await expect(console).toHaveCSS('overflow-y', 'auto');
+ expect(await console.evaluate(el => parseFloat(getComputedStyle(el).maxHeight))).toBeGreaterThan(0);
+});
+
+test.describe('on a wide screen', () => {
+ test.use({ viewport: { width: 2560, height: 1300 } });
+
+ test('fills the width whatever file is selected', async ({ page }) => {
+ await ready(page);
+ const widthOf = () => page.locator('.pg').evaluate(el => el.getBoundingClientRect().width);
+ await page.locator('#pg-tree li[data-path="rest/pet.rest.generated.ts"] button').click();
+ const wide = await widthOf();
+ await page.locator('#pg-tree li[data-path="rest.util.ts"] button').click();
+ expect(await widthOf()).toBeCloseTo(wide, 0);
+ const panelWidth = await page.evaluate(() => {
+ const panel = document.querySelector('main > .content-panel:last-child') as HTMLElement;
+ const style = getComputedStyle(panel);
+ return panel.clientWidth - parseFloat(style.paddingLeft) - parseFloat(style.paddingRight);
+ });
+ expect(wide).toBeCloseTo(panelWidth, 0);
+ });
+});
+
+test('scrolls inside each pane, never in a nested wrapper', async ({ page }) => {
+ await ready(page);
+ await page.locator('#pg-tree li[data-path="rest/pet.rest.generated.ts"] button').click();
+ // CodeMirror owns its scrolling; an outer scroller would double up and re-measure.
+ for (const pane of ['#pg-editor', '#pg-config']) {
+ await expect(page.locator(pane)).toHaveCSS('overflow-x', 'hidden');
+ const [scrollWidth, clientWidth] = await page
+ .locator(pane)
+ .evaluate(el => [el.scrollWidth, el.clientWidth]);
+ expect(scrollWidth).toBe(clientWidth);
+ }
+ // The output pane is the single scroller: the code element must not scroll too.
+ await expect(page.locator('.pg-output pre code')).toHaveCSS('overflow-x', 'visible');
+ const stable = await page.locator('.pg-output').evaluate(async el => {
+ const before = el.scrollWidth;
+ el.scrollLeft = el.scrollWidth;
+ await new Promise(r => setTimeout(r, 200));
+ return [before, el.scrollWidth];
+ });
+ expect(stable[1]).toBe(stable[0]);
+});
+
+test('shows a themed selection in the config editor', async ({ page }) => {
+ await ready(page);
+ const selectionBackground = async (theme: 'light' | 'dark') => {
+ await page.evaluate(t => document.documentElement.dataset.theme = t, theme);
+ const box = (await page.locator('#pg-config .cm-content').boundingBox())!;
+ await page.mouse.move(box.x + 10, box.y + 8);
+ await page.mouse.down();
+ await page.mouse.move(box.x + 180, box.y + 34, { steps: 8 });
+ await page.mouse.up();
+ return page.locator('#pg-config .cm-selectionLayer .cm-selectionBackground').first().evaluate(
+ el => getComputedStyle(el).backgroundColor,
+ );
+ };
+ const light = await selectionBackground('light');
+ const dark = await selectionBackground('dark');
+ expect(light).not.toBe(dark);
});
From 3c3886aa62ae9bc28792965368c3c56cf597e142 Mon Sep 17 00:00:00 2001
From: pkurcx
Date: Thu, 3 Sep 2026 21:57:21 +0200
Subject: [PATCH 08/17] feat(website): colour playground diagnostics by
severity
Warnings were rendered in the body colour, so a dropped cookie
parameter read like ordinary chrome next to a red fatal. Colour each
line from the diagnostic's own `severity` instead of its position in
the list, and give notes their own hue.
Use the `-high` tints throughout: the mid-tone red and orange fall to
3.35:1 and 1.62:1 against the console background in the light theme,
which a new contrast test now guards.
Co-Authored-By: Claude Opus 5
Claude-Session: https://claude.ai/code/session_011t8uBVY6h4kfN5cXHXuCpR
---
website/src/playground/main.ts | 5 +-
website/src/playground/playground.css | 9 +++-
website/tests/playground.spec.ts | 68 +++++++++++++++++++++++++++
3 files changed, 79 insertions(+), 3 deletions(-)
diff --git a/website/src/playground/main.ts b/website/src/playground/main.ts
index 1b93590..44088d4 100644
--- a/website/src/playground/main.ts
+++ b/website/src/playground/main.ts
@@ -76,7 +76,10 @@ export function start(doc: Document): void {
diagnosticsEl.append(li);
};
for (const error of errors) append(error, 'is-error');
- for (const warning of warnings) append(describe(warning));
+ // A diagnostic list can carry either severity; colour by what it says.
+ for (const item of warnings) {
+ append(describe(item), item.severity === 'error' ? 'is-error' : 'is-warning');
+ }
for (const note of notes) append(note, 'is-note');
}
diff --git a/website/src/playground/playground.css b/website/src/playground/playground.css
index 73bc3bc..ad12551 100644
--- a/website/src/playground/playground.css
+++ b/website/src/playground/playground.css
@@ -202,11 +202,16 @@ main {
white-space: pre-wrap;
overflow-wrap: anywhere;
}
+/* The `-high` tints are the readable pair: the mid tones drop under 3.5:1
+ against the console background in the light theme. */
.pg-diagnostics li.is-error {
- color: var(--sl-color-red);
+ color: var(--sl-color-red-high);
+}
+.pg-diagnostics li.is-warning {
+ color: var(--sl-color-orange-high);
}
.pg-diagnostics li.is-note {
- color: var(--sl-color-gray-3);
+ color: var(--sl-color-blue-high);
}
.pg.is-stale .pg-tree,
.pg.is-stale .pg-output {
diff --git a/website/tests/playground.spec.ts b/website/tests/playground.spec.ts
index a1f2709..b5ffc38 100644
--- a/website/tests/playground.spec.ts
+++ b/website/tests/playground.spec.ts
@@ -3,6 +3,17 @@ import { expect, test, type Page } from '@playwright/test';
const INVALID_SPEC =
'openapi: 3.0.3\ninfo: {title: x, version: "1"}\npaths: {/a: {get: {responses: {"200": {description: ok}}}}}';
+const COOKIE_PARAM_SPEC = [
+ 'openapi: 3.0.3',
+ 'info: {title: cookies, version: "1"}',
+ 'paths:',
+ ' /a:',
+ ' get:',
+ ' operationId: getA',
+ ' parameters: [{name: sid, in: cookie, schema: {type: string}}]',
+ ' responses: {"200": {description: ok}}',
+].join('\n');
+
const SNAKE_CASE_CONFIG = JSON.stringify({
input: './openapi/internal.json',
output: './libs/openapi-ng',
@@ -38,6 +49,63 @@ test('shows a typed diagnostic for an unsupported spec', async ({ page }) => {
await expect(page.locator('#pg-diagnostics li.is-error')).toContainText('missing-operation-id');
});
+test('separates warnings from errors and notes by colour', async ({ page }) => {
+ await ready(page);
+ await replaceText(page, '#pg-editor', COOKIE_PARAM_SPEC);
+ const warning = page.locator('#pg-diagnostics li.is-warning');
+ await expect(warning).toContainText('unsupported-parameter-location');
+ await replaceText(page, '#pg-config', '{"emit": ["models"], "input": "./spec.yaml"}');
+ const note = page.locator('#pg-diagnostics li.is-note');
+ await expect(note).toContainText('input and output are ignored');
+ await replaceText(page, '#pg-config', '{"emit": [');
+ const error = page.locator('#pg-diagnostics li.is-error');
+ await expect(error).toContainText('not valid JSON');
+ const colours = await page.evaluate(() => {
+ const colourOf = (cls: string) => {
+ const el = document.createElement('li');
+ el.className = cls;
+ document.querySelector('#pg-diagnostics')!.append(el);
+ const colour = getComputedStyle(el).color;
+ el.remove();
+ return colour;
+ };
+ return ['is-warning', 'is-error', 'is-note', ''].map(colourOf);
+ });
+ expect(new Set(colours).size).toBe(4);
+});
+
+test('keeps diagnostic colours readable in both themes', async ({ page }) => {
+ await ready(page);
+ const contrasts = await page.evaluate(() => {
+ const luminance = (colour: string) => {
+ const [r, g, b] = colour.match(/\d+/g)!.map(Number).map(v => {
+ const channel = v / 255;
+ return channel <= 0.03928 ? channel / 12.92 : ((channel + 0.055) / 1.055) ** 2.4;
+ });
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b;
+ };
+ const ratio = (a: string, b: string) => {
+ const [hi, lo] = [luminance(a), luminance(b)].sort((x, y) => y - x);
+ return (hi + 0.05) / (lo + 0.05);
+ };
+ const consoleEl = document.querySelector('#pg-console')!;
+ const out: number[] = [];
+ for (const theme of ['light', 'dark']) {
+ document.documentElement.dataset.theme = theme;
+ const background = getComputedStyle(consoleEl).backgroundColor;
+ for (const className of ['is-warning', 'is-error', 'is-note']) {
+ const li = document.createElement('li');
+ li.className = className;
+ document.querySelector('#pg-diagnostics')!.append(li);
+ out.push(ratio(getComputedStyle(li).color, background));
+ li.remove();
+ }
+ }
+ return out;
+ });
+ for (const contrast of contrasts) expect(contrast).toBeGreaterThanOrEqual(4.5);
+});
+
test('applies a pasted project config to the generated names', async ({ page }) => {
await ready(page);
await page.locator('#pg-tree li[data-path="rest/pet.rest.generated.ts"] button').click();
From aab6ec814c0af4dd8bc015acfa2ded6ce78aa1d7 Mon Sep 17 00:00:00 2001
From: pkurcx
Date: Thu, 3 Sep 2026 22:38:07 +0200
Subject: [PATCH 09/17] feat(website): show generated files in a read-only
CodeMirror pane
The output pane rendered each file through highlight.js into a bare
, so it had no line numbers, no search, and re-highlighted the
whole file on every regeneration. Swap it for a read-only CodeMirror
view in TypeScript mode, which also renders only the viewport.
The theme and token mapping move to theme.ts and are shared by all
three panes; the highlight.js runtime is gone, its GitHub stylesheets
stay as the colour source. Non-editable content is not focusable by
default, so the view gets a tabindex for the search keymap to reach it.
Co-Authored-By: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_011t8uBVY6h4kfN5cXHXuCpR
---
pnpm-lock.yaml | 25 ++++++++++++++
website/astro.config.mjs | 3 +-
website/package.json | 1 +
website/src/pages/playground.astro | 2 +-
website/src/playground/editor.ts | 32 ++----------------
website/src/playground/main.ts | 8 ++---
website/src/playground/output.ts | 35 ++++++++++++++-----
website/src/playground/playground.css | 22 ++++--------
website/src/playground/theme.ts | 48 +++++++++++++++++++++++++++
website/tests/playground.spec.ts | 35 ++++++++++++++-----
10 files changed, 141 insertions(+), 70 deletions(-)
create mode 100644 website/src/playground/theme.ts
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 96ad207..3b003f7 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -106,6 +106,9 @@ importers:
'@avsystem/openapi-ng-wasm32-wasi':
specifier: 0.5.1
version: 0.5.1
+ '@codemirror/lang-javascript':
+ specifier: 6.2.5
+ version: 6.2.5
'@codemirror/lang-json':
specifier: 6.0.2
version: 6.0.2
@@ -574,6 +577,9 @@ packages:
'@codemirror/commands@6.11.0':
resolution: {integrity: sha512-/K4Rl5BN0OtTiPWmJCdqODu38XnDMsDxKY5rgrPnCkutPTJf2wVbkoixLfealF5Kwse/s8P8M5jAiURiwSwnFA==}
+ '@codemirror/lang-javascript@6.2.5':
+ resolution: {integrity: sha512-zD4e5mS+50htS7F+TYjBPsiIFGanfVqg4HyUz6WNFikgOPf2BgKlx+TQedI1w6n/IqRBVBbBWmGFdLB/7uxO4A==}
+
'@codemirror/lang-json@6.0.2':
resolution: {integrity: sha512-x2OtO+AvwEHrEwR0FyyPtfDUiloG3rnVTSZV1W8UteaLL8/MajQd8DpvUb2YVzC+/T18aSDv0H9mu+xw0EStoQ==}
@@ -1438,6 +1444,9 @@ packages:
'@lezer/highlight@1.2.3':
resolution: {integrity: sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g==}
+ '@lezer/javascript@1.5.4':
+ resolution: {integrity: sha512-vvYx3MhWqeZtGPwDStM2dwgljd5smolYD2lR2UyFcHfxbBQebqx8yjmFmxtJ/E6nN6u1D9srOiVWm3Rb4tmcUA==}
+
'@lezer/json@1.0.3':
resolution: {integrity: sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==}
@@ -5364,6 +5373,16 @@ snapshots:
'@codemirror/view': 6.43.11
'@lezer/common': 1.5.2
+ '@codemirror/lang-javascript@6.2.5':
+ dependencies:
+ '@codemirror/autocomplete': 6.20.3
+ '@codemirror/language': 6.12.4
+ '@codemirror/lint': 6.9.7
+ '@codemirror/state': 6.7.2
+ '@codemirror/view': 6.43.11
+ '@lezer/common': 1.5.2
+ '@lezer/javascript': 1.5.4
+
'@codemirror/lang-json@6.0.2':
dependencies:
'@codemirror/language': 6.12.4
@@ -5989,6 +6008,12 @@ snapshots:
dependencies:
'@lezer/common': 1.5.2
+ '@lezer/javascript@1.5.4':
+ dependencies:
+ '@lezer/common': 1.5.2
+ '@lezer/highlight': 1.2.3
+ '@lezer/lr': 1.4.10
+
'@lezer/json@1.0.3':
dependencies:
'@lezer/common': 1.5.2
diff --git a/website/astro.config.mjs b/website/astro.config.mjs
index a472221..7eb0ca3 100644
--- a/website/astro.config.mjs
+++ b/website/astro.config.mjs
@@ -85,12 +85,11 @@ export default defineConfig({
'@avsystem/openapi-ng/browser',
'codemirror',
'@codemirror/state',
+ '@codemirror/lang-javascript',
'@codemirror/lang-json',
'@codemirror/lang-yaml',
'@codemirror/language',
'@lezer/highlight',
- 'highlight.js/lib/core',
- 'highlight.js/lib/languages/typescript',
'lz-string',
],
},
diff --git a/website/package.json b/website/package.json
index 2e50e9f..8f917cf 100644
--- a/website/package.json
+++ b/website/package.json
@@ -20,6 +20,7 @@
"@astrojs/starlight": "0.41.7",
"@avsystem/openapi-ng": "0.5.1",
"@avsystem/openapi-ng-wasm32-wasi": "0.5.1",
+ "@codemirror/lang-javascript": "6.2.5",
"@codemirror/lang-json": "6.0.2",
"@codemirror/lang-yaml": "6.1.3",
"@codemirror/language": "6.12.4",
diff --git a/website/src/pages/playground.astro b/website/src/pages/playground.astro
index f51f3ea..c063e88 100644
--- a/website/src/pages/playground.astro
+++ b/website/src/pages/playground.astro
@@ -34,7 +34,7 @@ const hljsTheme =
diff --git a/website/src/playground/editor.ts b/website/src/playground/editor.ts
index 4a8d304..20c4d97 100644
--- a/website/src/playground/editor.ts
+++ b/website/src/playground/editor.ts
@@ -1,41 +1,15 @@
-import { HighlightStyle, syntaxHighlighting } from '@codemirror/language';
import { EditorState, Compartment } from '@codemirror/state';
-import { tags } from '@lezer/highlight';
import { EditorView, basicSetup } from 'codemirror';
import { json } from '@codemirror/lang-json';
import { yaml } from '@codemirror/lang-yaml';
import { detectFormat, type SpecFormat } from './format';
+import { chrome } from './theme';
export interface SpecEditor {
getValue(): string;
setValue(value: string): void;
}
-// The editor root carries the `hljs` class, so the highlight.js theme that
-// styles the output pane also supplies the editor's colors and background.
-const theme = EditorView.theme({
- '&': { height: '100%' },
- '.cm-gutters': { backgroundColor: 'var(--sl-color-bg-nav)', color: 'var(--sl-color-gray-3)', border: 'none' },
- '.cm-activeLine, .cm-activeLineGutter': { backgroundColor: 'var(--sl-color-gray-6)' },
- '.cm-content': { fontFamily: 'var(--__sl-font-mono)' },
- '.cm-cursor': { borderLeftColor: 'currentColor' },
- // Mirrors the base theme's own selector depth, which a shorter one loses to.
- // Its default tint is invisible against the dark hljs background.
- '.cm-selectionBackground, &.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, ::selection':
- { backgroundColor: 'var(--sl-color-accent-low)' },
-});
-
-// Token classes mirror what highlight.js emits for YAML and JSON.
-const highlight = HighlightStyle.define([
- { tag: [tags.keyword, tags.typeName], class: 'hljs-keyword' },
- { tag: [tags.bool, tags.null, tags.number], class: 'hljs-literal' },
- { tag: [tags.propertyName, tags.definition(tags.propertyName)], class: 'hljs-attr' },
- { tag: [tags.string, tags.special(tags.string)], class: 'hljs-string' },
- { tag: tags.labelName, class: 'hljs-symbol' },
- { tag: [tags.comment, tags.meta], class: 'hljs-comment' },
- { tag: tags.invalid, class: 'hljs-deletion' },
-]);
-
export function createEditor(
parent: HTMLElement,
initial: string,
@@ -50,9 +24,7 @@ export function createEditor(
doc: initial,
extensions: [
basicSetup,
- theme,
- syntaxHighlighting(highlight),
- EditorView.editorAttributes.of({ class: 'hljs' }),
+ chrome,
language.of(format === 'json' ? json() : yaml()),
EditorView.updateListener.of(update => {
if (!update.docChanged) return;
diff --git a/website/src/playground/main.ts b/website/src/playground/main.ts
index 44088d4..aa8cd7f 100644
--- a/website/src/playground/main.ts
+++ b/website/src/playground/main.ts
@@ -4,7 +4,7 @@ import { DEFAULT_CONFIG, parseConfig } from './config';
import { createEditor } from './editor';
import { detectFormat, displayPathFor } from './format';
import { engineVersion, GenerateError, loadGenerate, type GenerateFn } from './generator';
-import { copyText, renderOutput } from './output';
+import { copyText, createOutput } from './output';
import { buildTree, renderTree } from './tree';
const DEBOUNCE_MS = 150;
@@ -41,7 +41,6 @@ export function start(doc: Document): void {
const status = byId(doc, 'pg-status');
const treeEl = byId(doc, 'pg-tree');
- const codeEl = byId(doc, 'pg-code');
const summaryEl = byId(doc, 'pg-summary');
const diagnosticsEl = byId(doc, 'pg-diagnostics');
@@ -60,6 +59,7 @@ export function start(doc: Document): void {
}
const editor = createEditor(byId(doc, 'pg-editor'), petstoreSpec, schedule);
+ const output = createOutput(byId(doc, 'pg-code'));
const configEditor = createEditor(byId(doc, 'pg-config'), DEFAULT_CONFIG, schedule);
function schedule(): void {
@@ -89,7 +89,7 @@ export function start(doc: Document): void {
const rows = buildTree(lastResult.artifacts);
renderTree(treeEl, rows, selectedPath, select);
const artifact = lastResult.artifacts.find(a => a.path === path);
- if (artifact) renderOutput(codeEl, artifact.contents);
+ if (artifact) output.setValue(artifact.contents);
}
function showResult(result: GenerateResult, elapsedMs: number, notes: string[]): void {
@@ -99,7 +99,7 @@ export function start(doc: Document): void {
if (!selectedPath || !paths.includes(selectedPath)) selectedPath = paths[0] ?? null;
renderTree(treeEl, buildTree(result.artifacts), selectedPath, select);
const current = result.artifacts.find(a => a.path === selectedPath);
- renderOutput(codeEl, current ? current.contents : '');
+ output.setValue(current ? current.contents : '');
summaryEl.textContent =
`${result.summary.operationCount} operations · ${result.summary.schemaCount} schemas · ` +
`${result.artifacts.length} files · ${elapsedMs.toFixed(0)} ms`;
diff --git a/website/src/playground/output.ts b/website/src/playground/output.ts
index 150b3f4..c8fd051 100644
--- a/website/src/playground/output.ts
+++ b/website/src/playground/output.ts
@@ -1,13 +1,32 @@
-import hljs from 'highlight.js/lib/core';
-import typescript from 'highlight.js/lib/languages/typescript';
+import { javascript } from '@codemirror/lang-javascript';
+import { EditorState } from '@codemirror/state';
+import { EditorView, basicSetup } from 'codemirror';
+import { chrome } from './theme';
-hljs.registerLanguage('typescript', typescript);
+export interface OutputView {
+ setValue(contents: string): void;
+}
-export function renderOutput(code: HTMLElement, contents: string): void {
- code.textContent = contents;
- code.className = 'language-typescript';
- delete code.dataset.highlighted;
- hljs.highlightElement(code);
+export function createOutput(parent: HTMLElement): OutputView {
+ const view = new EditorView({
+ parent,
+ state: EditorState.create({
+ extensions: [
+ basicSetup,
+ chrome,
+ javascript({ typescript: true }),
+ EditorState.readOnly.of(true),
+ EditorView.editable.of(false),
+ // Non-editable content is not focusable by default, which would leave
+ // the search keymap unreachable.
+ EditorView.contentAttributes.of({ tabindex: '0' }),
+ ],
+ }),
+ });
+ return {
+ setValue: contents =>
+ view.dispatch({ changes: { from: 0, to: view.state.doc.length, insert: contents } }),
+ };
}
export async function copyText(text: string): Promise {
diff --git a/website/src/playground/playground.css b/website/src/playground/playground.css
index ad12551..360a11d 100644
--- a/website/src/playground/playground.css
+++ b/website/src/playground/playground.css
@@ -105,11 +105,13 @@ main {
}
/* CodeMirror scrolls itself; a second scroller here would fight its measuring. */
.pg-editor,
-.pg-config {
+.pg-config,
+.pg-output {
overflow: hidden;
}
.pg-editor .cm-editor,
-.pg-config .cm-editor {
+.pg-config .cm-editor,
+.pg-output .cm-editor {
height: 100%;
font-size: 0.8rem;
}
@@ -160,26 +162,14 @@ main {
.pg-output {
position: relative;
}
-.pg-output pre {
- margin: 0;
+.pg-code {
height: 100%;
- font-size: 0.75rem;
-}
-/* The pane is the only scroller; the hljs theme's own overflow on `code`
- would otherwise nest a second one and resize the pane as you scroll. The id
- outranks that theme's `pre code.hljs`, which ties on specificity and is
- injected later in the document. */
-#pg-code.hljs {
- box-sizing: border-box;
- min-height: 100%;
- overflow: visible;
- width: max-content;
- min-width: 100%;
}
.pg-copy {
position: absolute;
top: 0.5rem;
right: 0.5rem;
+ z-index: 1;
}
.pg-console {
max-height: 9rem;
diff --git a/website/src/playground/theme.ts b/website/src/playground/theme.ts
new file mode 100644
index 0000000..faf1641
--- /dev/null
+++ b/website/src/playground/theme.ts
@@ -0,0 +1,48 @@
+import { HighlightStyle, syntaxHighlighting } from '@codemirror/language';
+import type { Extension } from '@codemirror/state';
+import { tags } from '@lezer/highlight';
+import { EditorView } from 'codemirror';
+
+// Every editor root carries the `hljs` class, so the highlight.js theme
+// supplies the colors and background for all panes.
+const theme = EditorView.theme({
+ '&': { height: '100%' },
+ '.cm-gutters': { backgroundColor: 'var(--sl-color-bg-nav)', color: 'var(--sl-color-gray-3)', border: 'none' },
+ '.cm-activeLine, .cm-activeLineGutter': { backgroundColor: 'var(--sl-color-gray-6)' },
+ '.cm-content': { fontFamily: 'var(--__sl-font-mono)' },
+ '.cm-cursor': { borderLeftColor: 'currentColor' },
+ // Mirrors the base theme's own selector depth, which a shorter one loses to.
+ // Its default tint is invisible against the dark hljs background.
+ '.cm-selectionBackground, &.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, ::selection':
+ { backgroundColor: 'var(--sl-color-accent-low)' },
+ '.cm-panels': { backgroundColor: 'var(--sl-color-bg-nav)', color: 'var(--sl-color-white)' },
+ '.cm-panels.cm-panels-top': { borderBottom: '1px solid var(--sl-color-gray-5)' },
+ '.cm-panel input, .cm-panel button': {
+ background: 'var(--sl-color-bg)',
+ color: 'var(--sl-color-white)',
+ border: '1px solid var(--sl-color-gray-5)',
+ borderRadius: '0.25rem',
+ },
+ '.cm-searchMatch': { backgroundColor: 'var(--sl-color-orange-low)' },
+ '.cm-searchMatch.cm-searchMatch-selected': { backgroundColor: 'var(--sl-color-orange)' },
+});
+
+// Token classes mirror what highlight.js emits for YAML, JSON and TypeScript.
+const highlight = HighlightStyle.define([
+ { tag: tags.keyword, class: 'hljs-keyword' },
+ { tag: [tags.typeName, tags.className], class: 'hljs-title class_' },
+ { tag: [tags.function(tags.variableName), tags.function(tags.propertyName)], class: 'hljs-title function_' },
+ { tag: [tags.bool, tags.null], class: 'hljs-literal' },
+ { tag: tags.number, class: 'hljs-number' },
+ { tag: [tags.propertyName, tags.definition(tags.propertyName)], class: 'hljs-attr' },
+ { tag: [tags.string, tags.special(tags.string)], class: 'hljs-string' },
+ { tag: tags.labelName, class: 'hljs-symbol' },
+ { tag: [tags.comment, tags.meta], class: 'hljs-comment' },
+ { tag: tags.invalid, class: 'hljs-deletion' },
+]);
+
+export const chrome: Extension = [
+ theme,
+ syntaxHighlighting(highlight),
+ EditorView.editorAttributes.of({ class: 'hljs' }),
+];
diff --git a/website/tests/playground.spec.ts b/website/tests/playground.spec.ts
index b5ffc38..853731d 100644
--- a/website/tests/playground.spec.ts
+++ b/website/tests/playground.spec.ts
@@ -182,15 +182,32 @@ test('scrolls inside each pane, never in a nested wrapper', async ({ page }) =>
.evaluate(el => [el.scrollWidth, el.clientWidth]);
expect(scrollWidth).toBe(clientWidth);
}
- // The output pane is the single scroller: the code element must not scroll too.
- await expect(page.locator('.pg-output pre code')).toHaveCSS('overflow-x', 'visible');
- const stable = await page.locator('.pg-output').evaluate(async el => {
- const before = el.scrollWidth;
- el.scrollLeft = el.scrollWidth;
- await new Promise(r => setTimeout(r, 200));
- return [before, el.scrollWidth];
- });
- expect(stable[1]).toBe(stable[0]);
+ // The output editor scrolls inside its own scroller as well.
+ await expect(page.locator('.pg-output')).toHaveCSS('overflow-x', 'hidden');
+ const [outputScrollWidth, outputClientWidth] = await page
+ .locator('.pg-output')
+ .evaluate(el => [el.scrollWidth, el.clientWidth]);
+ expect(outputScrollWidth).toBe(outputClientWidth);
+});
+
+test('shows the generated file in a read-only editor with line numbers and search', async ({ page }) => {
+ await ready(page);
+ await page.locator('#pg-tree li[data-path="rest/pet.rest.generated.ts"] button').click();
+ const output = page.locator('#pg-code');
+ await expect(output.locator('.cm-content')).toHaveAttribute('contenteditable', 'false');
+ await expect(output.locator('.cm-lineNumbers .cm-gutterElement').nth(1)).toHaveText('1');
+ await expect(output.locator('.cm-content .hljs-keyword').first()).toBeVisible();
+ await output.locator('.cm-content').click();
+ await page.keyboard.press('ControlOrMeta+f');
+ const search = output.locator('.cm-search');
+ await expect(search).toBeVisible();
+ await search.locator('input[name="search"]').pressSequentially('listPets');
+ await page.keyboard.press('Enter');
+ await expect(output.locator('.cm-searchMatch-selected')).toHaveText('listPets');
+ await output.locator('.cm-content').click();
+ await page.keyboard.press('ControlOrMeta+a');
+ await page.keyboard.type('x');
+ await expect(output).toContainText('listPets');
});
test('shows a themed selection in the config editor', async ({ page }) => {
From b513691aa48f2f2082c68774e1e575ba1ba3c4fb Mon Sep 17 00:00:00 2001
From: pkurcx
Date: Thu, 3 Sep 2026 22:38:42 +0200
Subject: [PATCH 10/17] feat(website): open a spec file in the playground
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Pasting was the only way in. Add an "Open file…" button backed by a
hidden file input, and replace the document when a file is dropped on
an editor: CodeMirror's default handler would splice the file in at
the cursor and merge two specs.
Co-Authored-By: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_011t8uBVY6h4kfN5cXHXuCpR
---
website/src/pages/playground.astro | 2 ++
website/src/playground/editor.ts | 12 ++++++++++++
website/src/playground/main.ts | 8 ++++++++
website/tests/playground.spec.ts | 20 ++++++++++++++++++++
4 files changed, 42 insertions(+)
diff --git a/website/src/pages/playground.astro b/website/src/pages/playground.astro
index c063e88..06e4f0b 100644
--- a/website/src/pages/playground.astro
+++ b/website/src/pages/playground.astro
@@ -18,6 +18,8 @@ const hljsTheme =
diff --git a/website/src/playground/editor.ts b/website/src/playground/editor.ts
index 20c4d97..ae513c4 100644
--- a/website/src/playground/editor.ts
+++ b/website/src/playground/editor.ts
@@ -26,6 +26,18 @@ export function createEditor(
basicSetup,
chrome,
language.of(format === 'json' ? json() : yaml()),
+ // CodeMirror's own handler would splice the file in at the cursor.
+ EditorView.domEventHandlers({
+ drop(event, view) {
+ const file = event.dataTransfer?.files[0];
+ if (!file) return false;
+ event.preventDefault();
+ void file.text().then(text => {
+ view.dispatch({ changes: { from: 0, to: view.state.doc.length, insert: text } });
+ });
+ return true;
+ },
+ }),
EditorView.updateListener.of(update => {
if (!update.docChanged) return;
const value = update.state.doc.toString();
diff --git a/website/src/playground/main.ts b/website/src/playground/main.ts
index aa8cd7f..1e7b0dc 100644
--- a/website/src/playground/main.ts
+++ b/website/src/playground/main.ts
@@ -143,6 +143,14 @@ export function start(doc: Document): void {
}
}
+ const fileInput = byId(doc, 'pg-file');
+ byId(doc, 'pg-open').addEventListener('click', () => fileInput.click());
+ fileInput.addEventListener('change', async () => {
+ const file = fileInput.files?.[0];
+ // Cleared so picking the same file again still fires `change`.
+ fileInput.value = '';
+ if (file) editor.setValue(await file.text());
+ });
byId(doc, 'pg-reset').addEventListener('click', () => {
editor.setValue(petstoreSpec);
configEditor.setValue(DEFAULT_CONFIG);
diff --git a/website/tests/playground.spec.ts b/website/tests/playground.spec.ts
index 853731d..628da2d 100644
--- a/website/tests/playground.spec.ts
+++ b/website/tests/playground.spec.ts
@@ -190,6 +190,26 @@ test('scrolls inside each pane, never in a nested wrapper', async ({ page }) =>
expect(outputScrollWidth).toBe(outputClientWidth);
});
+test('opens a spec file from disk or by dropping it on the editor', async ({ page }) => {
+ await ready(page);
+ await page.locator('#pg-file').setInputFiles({
+ name: 'cookies.yaml',
+ mimeType: 'application/yaml',
+ buffer: Buffer.from(COOKIE_PARAM_SPEC),
+ });
+ await expect(page.locator('#pg-editor .cm-content')).toContainText('operationId: getA');
+ await expect(page.locator('#pg-diagnostics li.is-warning')).toContainText('unsupported-parameter-location');
+ // Dropping a file replaces the document instead of splicing it in at the cursor.
+ await page.locator('#pg-editor .cm-content').evaluate((el, spec) => {
+ const transfer = new DataTransfer();
+ transfer.items.add(new File([spec], 'invalid.yaml', { type: 'application/yaml' }));
+ el.dispatchEvent(new DragEvent('drop', { dataTransfer: transfer, bubbles: true, cancelable: true }));
+ }, INVALID_SPEC);
+ await expect(page.locator('#pg-editor .cm-content')).not.toContainText('getA');
+ await expect(page.locator('#pg-editor .cm-content')).toContainText('/a: {get:');
+ await expect(page.locator('#pg-diagnostics li.is-error')).toContainText('missing-operation-id');
+});
+
test('shows the generated file in a read-only editor with line numbers and search', async ({ page }) => {
await ready(page);
await page.locator('#pg-tree li[data-path="rest/pet.rest.generated.ts"] button').click();
From 626651406cff9349e264a4b394d392c8666b245e Mon Sep 17 00:00:00 2001
From: pkurcx
Date: Thu, 3 Sep 2026 22:39:19 +0200
Subject: [PATCH 11/17] feat(website): switch between docs and playground from
the header
The playground sat in the sidebar, so following that link dropped the
reader onto a splash page where the sidebar disappears. Override the
Starlight header with a Docs / Playground switch next to the site
title, marking the current section, and take the entry out of the
sidebar. Docs points at Getting started, the first page with a sidebar.
The playground page drops its own heading and the docs search box, both
redundant next to the switch. Below Starlight's mobile breakpoint the
header fits only the title and one link, so it shows the way out.
Co-Authored-By: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_011t8uBVY6h4kfN5cXHXuCpR
---
website/astro.config.mjs | 4 +-
website/src/components/Header.astro | 139 ++++++++++++++++++++++++++
website/src/playground/playground.css | 4 +
website/tests/playground.spec.ts | 18 +++-
4 files changed, 163 insertions(+), 2 deletions(-)
create mode 100644 website/src/components/Header.astro
diff --git a/website/astro.config.mjs b/website/astro.config.mjs
index 7eb0ca3..89cf18a 100644
--- a/website/astro.config.mjs
+++ b/website/astro.config.mjs
@@ -41,6 +41,9 @@ export default defineConfig({
href: 'https://www.npmjs.com/package/@avsystem/openapi-ng',
},
],
+ components: {
+ Header: './src/components/Header.astro',
+ },
editLink: {
baseUrl: 'https://github.com/AVSystem/openapi-ng/edit/main/website/',
},
@@ -50,7 +53,6 @@ export default defineConfig({
items: [
{ label: 'Introduction', slug: '' },
{ label: 'Getting started', slug: 'getting-started' },
- { label: 'Playground', link: '/playground/' },
],
},
{
diff --git a/website/src/components/Header.astro b/website/src/components/Header.astro
new file mode 100644
index 0000000..7d90c7d
--- /dev/null
+++ b/website/src/components/Header.astro
@@ -0,0 +1,139 @@
+---
+// Starlight's default header plus a Docs / Playground switch next to the title.
+import config from 'virtual:starlight/user-config';
+import LanguageSelect from '@astrojs/starlight/components/LanguageSelect.astro';
+import Search from '@astrojs/starlight/components/Search.astro';
+import SiteTitle from '@astrojs/starlight/components/SiteTitle.astro';
+import SocialIcons from '@astrojs/starlight/components/SocialIcons.astro';
+import ThemeSelect from '@astrojs/starlight/components/ThemeSelect.astro';
+
+const onPlayground = Astro.url.pathname.startsWith('/playground');
+// Site search indexes the docs; the playground has nothing to find in it.
+const shouldRenderSearch =
+ !onPlayground &&
+ (config.pagefind || config.components.Search !== '@astrojs/starlight/components/Search.astro');
+const sections = [
+ { label: 'Docs', href: '/getting-started/', current: !onPlayground },
+ { label: 'Playground', href: '/playground/', current: onPlayground },
+];
+---
+
+
+
+
diff --git a/website/src/playground/playground.css b/website/src/playground/playground.css
index 360a11d..173fcfe 100644
--- a/website/src/playground/playground.css
+++ b/website/src/playground/playground.css
@@ -2,6 +2,10 @@
main {
--sl-content-width: 100%;
}
+/* The header's section switch already names the page. */
+main > .content-panel:first-child {
+ display: none;
+}
/* Hand the viewport below the title to the playground; only the panes scroll. */
@media (min-width: 72rem) {
diff --git a/website/tests/playground.spec.ts b/website/tests/playground.spec.ts
index 628da2d..9a1c31e 100644
--- a/website/tests/playground.spec.ts
+++ b/website/tests/playground.spec.ts
@@ -136,7 +136,7 @@ test('lays the panes out untouched by the prose styles', async ({ page }) => {
expect(new Set(buttonHeights).size).toBe(1);
await expect(page.locator('.cm-line').nth(1)).toHaveCSS('margin-top', '0px');
const [pgWidth, panelWidth] = await page.evaluate(() => {
- const panel = document.querySelector('.content-panel') as HTMLElement;
+ const panel = document.querySelector('main > .content-panel:last-child') as HTMLElement;
const panelStyle = getComputedStyle(panel);
return [
document.querySelector('.pg')!.getBoundingClientRect().width,
@@ -210,6 +210,22 @@ test('opens a spec file from disk or by dropping it on the editor', async ({ pag
await expect(page.locator('#pg-diagnostics li.is-error')).toContainText('missing-operation-id');
});
+test('switches between docs and playground from the header', async ({ page }) => {
+ await ready(page);
+ const sections = page.locator('header nav[aria-label="Site sections"]');
+ await expect(sections.locator('a[aria-current="page"]')).toHaveText('Playground');
+ await expect(page.locator('main h1')).toBeHidden();
+ await expect(page.locator('header site-search')).toHaveCount(0);
+ await sections.getByRole('link', { name: 'Docs' }).click();
+ await expect(page).toHaveURL('/getting-started/');
+ await expect(page.locator('header site-search')).toHaveCount(1);
+ await expect(sections.locator('a[aria-current="page"]')).toHaveText('Docs');
+ await expect(page.locator('.sidebar-content')).toContainText('Getting started');
+ await expect(page.locator('.sidebar-content')).not.toContainText('Playground');
+ await sections.getByRole('link', { name: 'Playground' }).click();
+ await expect(page).toHaveURL('/playground/');
+});
+
test('shows the generated file in a read-only editor with line numbers and search', async ({ page }) => {
await ready(page);
await page.locator('#pg-tree li[data-path="rest/pet.rest.generated.ts"] button').click();
From 62672fffb0f318ba3e27c28a733b7290ba7ff878 Mon Sep 17 00:00:00 2001
From: pkurcx
Date: Thu, 3 Sep 2026 22:40:12 +0200
Subject: [PATCH 12/17] feat(website): JSONC playground config listing the
defaults
The config pane accepted plain JSON and a single live option, so every
other setting meant a trip to the docs. Parse the config as JSONC and
ship a template with mappedTypes, responseTypeMapping and naming
commented out at their default values, each with a one-line example of
the shape. Enabling all of them must not change the output, which an
e2e test checks on petstore and on a spec without tags.
The JSON grammar has no comments, so the config editor uses the
JavaScript mode. The root element now records the last settled
generation so tests can wait for a specific edit instead of the debounce.
Co-Authored-By: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_011t8uBVY6h4kfN5cXHXuCpR
---
pnpm-lock.yaml | 9 ++++++
website/package.json | 3 +-
website/src/pages/playground.astro | 2 +-
website/src/playground/config.test.ts | 33 +++++++++++++++++++-
website/src/playground/config.ts | 34 ++++++++++++++++++--
website/src/playground/editor.ts | 8 +++--
website/src/playground/main.ts | 7 ++++-
website/src/playground/playground.css | 2 +-
website/tests/playground.spec.ts | 45 ++++++++++++++++++++++++++-
website/tests/uncomment.ts | 6 ++++
10 files changed, 137 insertions(+), 12 deletions(-)
create mode 100644 website/tests/uncomment.ts
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 3b003f7..1d4f797 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -136,6 +136,9 @@ importers:
sharp:
specifier: 0.35.3
version: 0.35.3(@types/node@26.2.0)
+ strip-json-comments:
+ specifier: 5.0.3
+ version: 5.0.3
devDependencies:
'@astrojs/check':
specifier: 0.9.10
@@ -4393,6 +4396,10 @@ packages:
resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==}
engines: {node: '>=12'}
+ strip-json-comments@5.0.3:
+ resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==}
+ engines: {node: '>=14.16'}
+
style-mod@4.1.3:
resolution: {integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==}
@@ -9286,6 +9293,8 @@ snapshots:
dependencies:
ansi-regex: 6.2.2
+ strip-json-comments@5.0.3: {}
+
style-mod@4.1.3: {}
style-to-js@1.1.21:
diff --git a/website/package.json b/website/package.json
index 8f917cf..0d12325 100644
--- a/website/package.json
+++ b/website/package.json
@@ -29,7 +29,8 @@
"astro": "7.2.4",
"codemirror": "6.0.2",
"highlight.js": "11.12.0",
- "sharp": "0.35.3"
+ "sharp": "0.35.3",
+ "strip-json-comments": "5.0.3"
},
"devDependencies": {
"@astrojs/check": "0.9.10",
diff --git a/website/src/pages/playground.astro b/website/src/pages/playground.astro
index 06e4f0b..3101296 100644
--- a/website/src/pages/playground.astro
+++ b/website/src/pages/playground.astro
@@ -28,7 +28,7 @@ const hljsTheme =
- Config openapi-ng.config as JSON; write parse regexes as "/…/flags"
+ Config openapi-ng.config as JSONC; uncomment an option to change it
diff --git a/website/src/playground/config.test.ts b/website/src/playground/config.test.ts
index cd1344f..d511292 100644
--- a/website/src/playground/config.test.ts
+++ b/website/src/playground/config.test.ts
@@ -1,4 +1,5 @@
import { describe, expect, it } from 'vitest';
+import { uncommentConfig } from '../../tests/uncomment';
import { DEFAULT_CONFIG, parseConfig } from './config';
describe('parseConfig', () => {
@@ -89,7 +90,12 @@ describe('parseConfig', () => {
it('rejects invalid JSON', () => {
const result = parseConfig('{"emit": [');
expect(result.ok).toBe(false);
- if (!result.ok) expect(result.error).toMatch(/^config is not valid JSON: /);
+ if (!result.ok) expect(result.error).toMatch(/^config is not valid JSONC: /);
+ });
+
+ it('accepts comments and trailing commas', () => {
+ const text = '{\n // both\n "emit": ["models", /* inline */ "angular",],\n}\n';
+ expect(parseConfig(text)).toEqual({ ok: true, options: { emit: ['models', 'angular'] }, notes: [] });
});
it('rejects a non-object document', () => {
@@ -104,4 +110,29 @@ describe('parseConfig', () => {
notes: [],
});
});
+
+ it('ships a default whose commented-out options all parse once enabled', () => {
+ const enabled = uncommentConfig(DEFAULT_CONFIG);
+ expect(enabled).not.toContain('// ');
+ expect(parseConfig(enabled)).toEqual({
+ ok: true,
+ options: {
+ emit: ['models', 'angular'],
+ mappedTypes: [],
+ responseTypeMapping: [],
+ naming: {
+ methodName: [
+ { format: '{operationId}', case: 'camel' },
+ { format: '{method}_{path}', case: 'camel' },
+ ],
+ group: [
+ { format: '{tags[0]}', case: 'pascal' },
+ { format: '{pathSegments[0]}', case: 'pascal' },
+ { format: 'Default' },
+ ],
+ },
+ },
+ notes: [],
+ });
+ });
});
diff --git a/website/src/playground/config.ts b/website/src/playground/config.ts
index d9ef93c..b1377bf 100644
--- a/website/src/playground/config.ts
+++ b/website/src/playground/config.ts
@@ -1,4 +1,5 @@
import type { GenerateOptions } from '@avsystem/openapi-ng/browser';
+import stripJsonComments from 'strip-json-comments';
export type ConfigOptions = Pick<
GenerateOptions,
@@ -9,7 +10,34 @@ export type ParsedConfig =
| { ok: true; options: ConfigOptions; notes: string[] }
| { ok: false; error: string };
-export const DEFAULT_CONFIG = '{\n "emit": ["models", "angular"]\n}\n';
+// Commented-out options spell out the generator's defaults; enabling them
+// all must not change the output.
+export const DEFAULT_CONFIG = `{
+ "emit": ["models", "angular"],
+
+ // External TypeScript types standing in for schemas,
+ // e.g. { "schema": "GeoFeature", "import": "geojson", "type": "Feature", "alias": "Geo" }
+ // "mappedTypes": [],
+
+ // Decode a response content type as "json" | "blob" | "text" | "arrayBuffer",
+ // e.g. { "contentType": "application/pdf", "responseType": "blob" }
+ // "responseTypeMapping": [],
+
+ // Naming chains: each rule runs in turn until one succeeds.
+ // Write "parse" regexes as "/…/flags".
+ // "naming": {
+ // "methodName": [
+ // { "format": "{operationId}", "case": "camel" },
+ // { "format": "{method}_{path}", "case": "camel" }
+ // ],
+ // "group": [
+ // { "format": "{tags[0]}", "case": "pascal" },
+ // { "format": "{pathSegments[0]}", "case": "pascal" },
+ // { "format": "Default" }
+ // ]
+ // }
+}
+`;
const REGEX_LITERAL = /^\/(.*)\/([a-z]*)$/s;
@@ -38,9 +66,9 @@ function lowerNaming(value: unknown, path: string): unknown {
export function parseConfig(text: string): ParsedConfig {
let doc: unknown;
try {
- doc = JSON.parse(text);
+ doc = JSON.parse(stripJsonComments(text, { trailingCommas: true }));
} catch (err) {
- return { ok: false, error: `config is not valid JSON: ${(err as Error).message}` };
+ return { ok: false, error: `config is not valid JSONC: ${(err as Error).message}` };
}
if (!isRecord(doc)) return { ok: false, error: 'config must be a JSON object' };
diff --git a/website/src/playground/editor.ts b/website/src/playground/editor.ts
index ae513c4..9d96f24 100644
--- a/website/src/playground/editor.ts
+++ b/website/src/playground/editor.ts
@@ -1,4 +1,4 @@
-import { EditorState, Compartment } from '@codemirror/state';
+import { EditorState, Compartment, type Extension } from '@codemirror/state';
import { EditorView, basicSetup } from 'codemirror';
import { json } from '@codemirror/lang-json';
import { yaml } from '@codemirror/lang-yaml';
@@ -10,10 +10,12 @@ export interface SpecEditor {
setValue(value: string): void;
}
+// Without an explicit language the editor follows the document between YAML and JSON.
export function createEditor(
parent: HTMLElement,
initial: string,
onChange: (value: string) => void,
+ fixedLanguage?: Extension,
): SpecEditor {
const language = new Compartment();
let format: SpecFormat = detectFormat(initial);
@@ -25,7 +27,7 @@ export function createEditor(
extensions: [
basicSetup,
chrome,
- language.of(format === 'json' ? json() : yaml()),
+ fixedLanguage ?? language.of(format === 'json' ? json() : yaml()),
// CodeMirror's own handler would splice the file in at the cursor.
EditorView.domEventHandlers({
drop(event, view) {
@@ -42,7 +44,7 @@ export function createEditor(
if (!update.docChanged) return;
const value = update.state.doc.toString();
const next = detectFormat(value);
- if (next !== format) {
+ if (!fixedLanguage && next !== format) {
format = next;
view.dispatch({ effects: language.reconfigure(next === 'json' ? json() : yaml()) });
}
diff --git a/website/src/playground/main.ts b/website/src/playground/main.ts
index 1e7b0dc..9b3e233 100644
--- a/website/src/playground/main.ts
+++ b/website/src/playground/main.ts
@@ -1,4 +1,5 @@
import petstoreSpec from '../../../stackblitz/petstore.openapi.yaml?raw';
+import { javascript } from '@codemirror/lang-javascript';
import type { GenerateResult, GeneratorDiagnostic } from '@avsystem/openapi-ng/browser';
import { DEFAULT_CONFIG, parseConfig } from './config';
import { createEditor } from './editor';
@@ -60,7 +61,8 @@ export function start(doc: Document): void {
const editor = createEditor(byId(doc, 'pg-editor'), petstoreSpec, schedule);
const output = createOutput(byId(doc, 'pg-code'));
- const configEditor = createEditor(byId(doc, 'pg-config'), DEFAULT_CONFIG, schedule);
+ // The JSON grammar has no comments; the JavaScript one highlights JSONC fine.
+ const configEditor = createEditor(byId(doc, 'pg-config'), DEFAULT_CONFIG, schedule, javascript());
function schedule(): void {
clearTimeout(timer);
@@ -140,6 +142,9 @@ export function start(doc: Document): void {
summaryEl.textContent = err instanceof Error ? err.message : String(err);
renderConsole({ notes: config.notes });
}
+ } finally {
+ // Lets tests and tooling wait for a specific edit's generation to settle.
+ if (id === runId) root!.dataset.run = String(id);
}
}
diff --git a/website/src/playground/playground.css b/website/src/playground/playground.css
index 173fcfe..8ae09c1 100644
--- a/website/src/playground/playground.css
+++ b/website/src/playground/playground.css
@@ -77,7 +77,7 @@ main > .content-panel:first-child {
}
.pg-inputs {
display: grid;
- grid-template-rows: minmax(0, 2fr) minmax(0, 1fr);
+ grid-template-rows: minmax(0, 3fr) minmax(0, 2fr);
gap: 0.75rem;
min-height: 0;
}
diff --git a/website/tests/playground.spec.ts b/website/tests/playground.spec.ts
index 9a1c31e..1a950e7 100644
--- a/website/tests/playground.spec.ts
+++ b/website/tests/playground.spec.ts
@@ -1,4 +1,6 @@
import { expect, test, type Page } from '@playwright/test';
+import { DEFAULT_CONFIG } from '../src/playground/config';
+import { uncommentConfig } from './uncomment';
const INVALID_SPEC =
'openapi: 3.0.3\ninfo: {title: x, version: "1"}\npaths: {/a: {get: {responses: {"200": {description: ok}}}}}';
@@ -59,7 +61,7 @@ test('separates warnings from errors and notes by colour', async ({ page }) => {
await expect(note).toContainText('input and output are ignored');
await replaceText(page, '#pg-config', '{"emit": [');
const error = page.locator('#pg-diagnostics li.is-error');
- await expect(error).toContainText('not valid JSON');
+ await expect(error).toContainText('not valid JSONC');
const colours = await page.evaluate(() => {
const colourOf = (cls: string) => {
const el = document.createElement('li');
@@ -124,6 +126,47 @@ test('reports a broken config in the console and keeps the last output', async (
await expect(page.locator('#pg-diagnostics li.is-error')).toContainText('E_INVALID_OPTION');
});
+const NO_TAGS_SPEC = [
+ 'openapi: 3.0.3',
+ 'info: {title: untagged, version: "1"}',
+ 'paths:',
+ ' /store-items/{itemId}:',
+ ' get:',
+ ' operationId: fetch_storeItem',
+ ' parameters: [{name: itemId, in: path, required: true, schema: {type: string}}]',
+ ' responses: {"200": {description: ok}}',
+].join('\n');
+
+test('generates the same files with every default option enabled in the config', async ({ page }) => {
+ await ready(page);
+ const artifacts = () =>
+ page.locator('#pg-tree li[data-path]').evaluateAll(els => els.map(el => el.getAttribute('data-path')));
+ // The editor renders only the viewport, so the tree's byte size covers the rest.
+ const codeOf = async (path: string) => {
+ const row = page.locator(`#pg-tree li[data-path="${path}"]`);
+ await row.locator('button').click();
+ return `${await row.locator('.size').innerText()}\n${await page.locator('#pg-code .cm-content').innerText()}`;
+ };
+ const generated = async (edit: () => Promise) => {
+ const before = await page.locator('.pg').getAttribute('data-run');
+ await edit();
+ await expect(page.locator('.pg')).not.toHaveAttribute('data-run', before ?? '');
+ await expect(page.locator('#pg-diagnostics li.is-error')).toHaveCount(0);
+ };
+ for (const spec of [null, NO_TAGS_SPEC]) {
+ await generated(async () => {
+ if (spec) await replaceText(page, '#pg-editor', spec);
+ await replaceText(page, '#pg-config', DEFAULT_CONFIG);
+ });
+ const paths = await artifacts();
+ const expected = new Map();
+ for (const path of paths) expected.set(path!, await codeOf(path!));
+ await generated(() => replaceText(page, '#pg-config', uncommentConfig(DEFAULT_CONFIG)));
+ expect(await artifacts()).toEqual(paths);
+ for (const [path, code] of expected) expect(await codeOf(path)).toBe(code);
+ }
+});
+
test('lays the panes out untouched by the prose styles', async ({ page }) => {
await ready(page);
const paneTops = await page
diff --git a/website/tests/uncomment.ts b/website/tests/uncomment.ts
new file mode 100644
index 0000000..54f3f22
--- /dev/null
+++ b/website/tests/uncomment.ts
@@ -0,0 +1,6 @@
+// Enables every commented-out option in the default config template. Prose
+// comment lines start with a letter; option lines start with JSON punctuation
+// or deeper indentation.
+export function uncommentConfig(template: string): string {
+ return template.replace(/^(\s*)\/\/ (?=[\s"{}[\]])/gm, '$1');
+}
From b12afd44f9249bfb21283f7f773ae55f40ac20a8 Mon Sep 17 00:00:00 2001
From: pkurcx
Date: Thu, 3 Sep 2026 22:42:59 +0200
Subject: [PATCH 13/17] feat(website): paint the playground editors like the
docs code blocks
The editors wore highlight.js's GitHub theme while every snippet in the
docs is Night Owl on Starlight's grey. Colour the CodeMirror panes from
a --pg-* palette copied out of Starlight's bundled Night Owl themes,
on the same background tokens Starlight paints its code blocks with,
and drop highlight.js altogether.
Tokens get plain tok-* classes styled in CSS, so the theme toggle stays
a pure CSS switch. Property names share the JSON key colour across
YAML, JSON and TypeScript; Night Owl varies it per language, but
CodeMirror has a single tag for all three.
Co-Authored-By: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_011t8uBVY6h4kfN5cXHXuCpR
---
pnpm-lock.yaml | 9 ----
website/package.json | 1 -
website/src/pages/playground.astro | 8 ---
website/src/playground/playground.css | 71 +++++++++++++++++++++++++++
website/src/playground/theme.ts | 66 +++++++++++++++----------
website/tests/playground.spec.ts | 28 ++++++++++-
6 files changed, 137 insertions(+), 46 deletions(-)
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 1d4f797..60f8044 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -130,9 +130,6 @@ importers:
codemirror:
specifier: 6.0.2
version: 6.0.2
- highlight.js:
- specifier: 11.12.0
- version: 11.12.0
sharp:
specifier: 0.35.3
version: 0.35.3(@types/node@26.2.0)
@@ -3388,10 +3385,6 @@ packages:
hastscript@9.0.1:
resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==}
- highlight.js@11.12.0:
- resolution: {integrity: sha512-nbfWpyRMcMrPMmDwJB+dhX/eiaPKtc2RB+0QZskqJ3WjRA/FDS0e9hZrx8EC/lbEv8gXy98FcDbNa/dspAaJMg==}
- engines: {node: '>=12.0.0'}
-
html-escaper@3.0.3:
resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==}
@@ -7899,8 +7892,6 @@ snapshots:
property-information: 7.1.0
space-separated-tokens: 2.0.2
- highlight.js@11.12.0: {}
-
html-escaper@3.0.3: {}
html-void-elements@3.0.0: {}
diff --git a/website/package.json b/website/package.json
index 0d12325..959c12a 100644
--- a/website/package.json
+++ b/website/package.json
@@ -28,7 +28,6 @@
"@lezer/highlight": "1.2.3",
"astro": "7.2.4",
"codemirror": "6.0.2",
- "highlight.js": "11.12.0",
"sharp": "0.35.3",
"strip-json-comments": "5.0.3"
},
diff --git a/website/src/pages/playground.astro b/website/src/pages/playground.astro
index 3101296..2da7705 100644
--- a/website/src/pages/playground.astro
+++ b/website/src/pages/playground.astro
@@ -1,19 +1,11 @@
---
import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
import '../playground/playground.css';
-import hljsLight from 'highlight.js/styles/github.css?raw';
-import hljsDark from 'highlight.js/styles/github-dark.css?raw';
-
-// highlight.js ships light and dark as separate unscoped sheets; nesting them
-// under Starlight's theme attribute lets its toggle pick one.
-const hljsTheme =
- `:root[data-theme='light'] { ${hljsLight} }\n` + `:root[data-theme='dark'] { ${hljsDark} }`;
---
-
@for (option of statuses; track option) {
-
+
mark {{ option }}
}
@@ -33,7 +36,9 @@ import { PetRest } from '../generated/rest/pet.rest.generated';
}
@if (rawRequest(); as raw) {
- .request() returns the plain request, if you want to send it yourself:
+
+ .request() returns the plain request, if you want to send it yourself:
+
{{ raw | json }}
}
`,
@@ -65,7 +70,7 @@ export class PetDetail {
this.#petRest.updatePet
.observable({ petId: current.id, body: { status } }, { observe: 'response' })
.subscribe({
- next: (response) => {
+ next: response => {
const saved = response.body!;
this.pet.set(saved);
this.updated.emit(saved);
diff --git a/stackblitz/src/app/pet-list.ts b/stackblitz/src/app/pet-list.ts
index 2bd4544..7dd4fa5 100644
--- a/stackblitz/src/app/pet-list.ts
+++ b/stackblitz/src/app/pet-list.ts
@@ -18,8 +18,8 @@ import { PetRest } from '../generated/rest/pet.rest.generated';
@if (pets.isLoading()) {
loading…
} @else {
- {{ pets.value().length }} pets, HTTP {{ pets.statusCode() }},
- server latency {{ pets.headers()?.get('x-mock-latency') }}
+ {{ pets.value().length }} pets, HTTP {{ pets.statusCode() }}, server latency
+ {{ pets.headers()?.get('x-mock-latency') }}
}
reload
diff --git a/stackblitz/src/app/signup-form.ts b/stackblitz/src/app/signup-form.ts
index 1a900ea..a7c8cdb 100644
--- a/stackblitz/src/app/signup-form.ts
+++ b/stackblitz/src/app/signup-form.ts
@@ -15,8 +15,9 @@ interface Signup {
template: `
Signal forms: validateRest()
- The async validator reuses the generated AccountRest.checkEmail operation, so
- request and response stay typed. Try taken@example.com.
+ The async validator reuses the generated
+ AccountRest.checkEmail operation, so request and response stay typed.
+ Try taken@example.com.