Compare commits

..

3 Commits

Author SHA1 Message Date
conico974 d47b7df4ae Merge branch 'main' into conico/bump-on-next 2026-10-20 15:04:12 +02:00
Nicolas Dorseuil 45b38a2225 chore: update @opennextjs/aws to 4.1.11 and @opennextjs/cloudflare to 1.20.12 in gitbook package.json 2026-10-20 12:33:08 +02:00
Nicolas Dorseuil 1a9e8d635a chore(gitbook): update next dependency to version 16.4.2 2026-10-20 12:32:22 +02:00
62 changed files with 506 additions and 751 deletions
@@ -1,5 +0,0 @@
---
"gitbook": patch
---
Fix admin toolbar magnification, tooltip placement, title truncation and logo colour.
-5
View File
@@ -1,5 +0,0 @@
---
"gitbook": patch
---
Mark blocks, pages and titles so comments can target them on change request previews.
@@ -1,5 +0,0 @@
---
"gitbook": patch
---
Fix the double slash in the example page URLs of the MCP server's getPage and sendFeedback tools.
-5
View File
@@ -1,5 +0,0 @@
---
"gitbook": patch
---
Adjust tab panel and tab button padding so tabbed content has more breathing room.
-5
View File
@@ -1,5 +0,0 @@
---
"gitbook": patch
---
Track `ask_trigger_click` insights event when an Ask entry point is clicked.
+121 -118
View File
@@ -129,8 +129,8 @@
"@gitbook/react-openapi": "workspace:*", "@gitbook/react-openapi": "workspace:*",
"@mermaid-js/mermaid-zenuml": "^0.2.2", "@mermaid-js/mermaid-zenuml": "^0.2.2",
"@modelcontextprotocol/sdk": "1.17.5", "@modelcontextprotocol/sdk": "1.17.5",
"@opennextjs/aws": "4.1.7", "@opennextjs/aws": "4.1.11",
"@opennextjs/cloudflare": "1.20.8", "@opennextjs/cloudflare": "1.20.12",
"@panzoom/panzoom": "^4.6.1", "@panzoom/panzoom": "^4.6.1",
"@sindresorhus/fnv1a": "^3.1.0", "@sindresorhus/fnv1a": "^3.1.0",
"@tailwindcss/container-queries": "^0.1.1", "@tailwindcss/container-queries": "^0.1.1",
@@ -160,7 +160,7 @@
"micromark-extension-gfm": "^3.0.0", "micromark-extension-gfm": "^3.0.0",
"motion": "^12.23.24", "motion": "^12.23.24",
"negotiator": "^1.0.0", "negotiator": "^1.0.0",
"next": "^16.3.8", "next": "^16.4.2",
"next-themes": "^0.4.6", "next-themes": "^0.4.6",
"nuqs": "^2.2.3", "nuqs": "^2.2.3",
"object-hash": "^3.0.0", "object-hash": "^3.0.0",
@@ -342,7 +342,6 @@
}, },
"patchedDependencies": { "patchedDependencies": {
"decode-named-character-reference@1.0.2": "patches/decode-named-character-reference@1.0.2.patch", "decode-named-character-reference@1.0.2": "patches/decode-named-character-reference@1.0.2.patch",
"next@16.3.8": "patches/next@16.3.8.patch",
"mermaid@11.16.1": "patches/mermaid@11.16.1.patch", "mermaid@11.16.1": "patches/mermaid@11.16.1.patch",
}, },
"overrides": { "overrides": {
@@ -398,25 +397,25 @@
"@argos-ci/util": ["@argos-ci/util@4.0.0", "", {}, "sha512-2yrJr81OVpa2TkvSjzGZlGv6SVqZcxF62AVk6M79aZ7nXkwWFg3tjA8awbFwn2mODI67gkP5FarAD29bzx3P3w=="], "@argos-ci/util": ["@argos-ci/util@4.0.0", "", {}, "sha512-2yrJr81OVpa2TkvSjzGZlGv6SVqZcxF62AVk6M79aZ7nXkwWFg3tjA8awbFwn2mODI67gkP5FarAD29bzx3P3w=="],
"@ast-grep/napi": ["@ast-grep/napi@0.40.5", "", { "optionalDependencies": { "@ast-grep/napi-darwin-arm64": "0.40.5", "@ast-grep/napi-darwin-x64": "0.40.5", "@ast-grep/napi-linux-arm64-gnu": "0.40.5", "@ast-grep/napi-linux-arm64-musl": "0.40.5", "@ast-grep/napi-linux-x64-gnu": "0.40.5", "@ast-grep/napi-linux-x64-musl": "0.40.5", "@ast-grep/napi-win32-arm64-msvc": "0.40.5", "@ast-grep/napi-win32-ia32-msvc": "0.40.5", "@ast-grep/napi-win32-x64-msvc": "0.40.5" } }, "sha512-hJA62OeBKUQT68DD2gDyhOqJxZxycqg8wLxbqjgqSzYttCMSDL9tiAQ9abgekBYNHudbJosm9sWOEbmCDfpX2A=="], "@ast-grep/napi": ["@ast-grep/napi@0.45.3", "", { "optionalDependencies": { "@ast-grep/napi-darwin-arm64": "0.45.3", "@ast-grep/napi-darwin-x64": "0.45.3", "@ast-grep/napi-linux-arm64-gnu": "0.45.3", "@ast-grep/napi-linux-arm64-musl": "0.45.3", "@ast-grep/napi-linux-x64-gnu": "0.45.3", "@ast-grep/napi-linux-x64-musl": "0.45.3", "@ast-grep/napi-win32-arm64-msvc": "0.45.3", "@ast-grep/napi-win32-ia32-msvc": "0.45.3", "@ast-grep/napi-win32-x64-msvc": "0.45.3" } }, "sha512-bjJsUt0g3UCwbn9bjv7MnoR15rszSm79yPCXn4DWWK0NuYUUqBU/srtNMR4WnpfR7TnfBRdYFoqSNx0pGCNWJg=="],
"@ast-grep/napi-darwin-arm64": ["@ast-grep/napi-darwin-arm64@0.40.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-2F072fGN0WTq7KI3okuEnkGJVEHLbi56Bw1H6NAMf7j2mJJeQWsRyGOMcyNnUXZDeNdvoMH0OB2a5wwUegY/nQ=="], "@ast-grep/napi-darwin-arm64": ["@ast-grep/napi-darwin-arm64@0.45.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-rMZJ6frSpR/xSbeV4hiA9WR5hHqk3rVYX8lOqEoUCaUnjEuFXvHdGN4WawJ8pVDq/IqM1UnTtsDSYgUdVmO5DA=="],
"@ast-grep/napi-darwin-x64": ["@ast-grep/napi-darwin-x64@0.40.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-dJMidHZhhxuLBYNi6/FKI812jQ7wcFPSKkVPwviez2D+KvYagapUMAV/4dJ7FCORfguVk8Y0jpPAlYmWRT5nvA=="], "@ast-grep/napi-darwin-x64": ["@ast-grep/napi-darwin-x64@0.45.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-tIclZ5pM+YSgk8NNTBoTkaclbS39cU5lbVfSrFWX4LUnxXfUPG+F+ppxyFjKwJTBELsGHEO4LdX3/Lc+FDwPNA=="],
"@ast-grep/napi-linux-arm64-gnu": ["@ast-grep/napi-linux-arm64-gnu@0.40.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-nBRCbyoS87uqkaw4Oyfe5VO+SRm2B+0g0T8ME69Qry9ShMf41a2bTdpcQx9e8scZPogq+CTwDHo3THyBV71l9w=="], "@ast-grep/napi-linux-arm64-gnu": ["@ast-grep/napi-linux-arm64-gnu@0.45.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-Bm8F7/oRHQkDXbjH+gBi9oB5huJ0q12r/AIOMIypf5PWlAVvh206Tsw468phw4Oh6kd4Ad1Z+gflNW1MutgK2g=="],
"@ast-grep/napi-linux-arm64-musl": ["@ast-grep/napi-linux-arm64-musl@0.40.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-/qKsmds5FMoaEj6FdNzepbmLMtlFuBLdrAn9GIWCqOIcVcYvM1Nka8+mncfeXB/MFZKOrzQsQdPTWqrrQzXLrA=="], "@ast-grep/napi-linux-arm64-musl": ["@ast-grep/napi-linux-arm64-musl@0.45.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-yr5xcRerV41GeRxmZ8SKbfGeyZRhQePoNNCgTAb4OrWMelWwbMI80aY7/IlF2bo1sN40BSW4hZdGIO/akTd1RQ=="],
"@ast-grep/napi-linux-x64-gnu": ["@ast-grep/napi-linux-x64-gnu@0.40.5", "", { "os": "linux", "cpu": "x64" }, "sha512-DP4oDbq7f/1A2hRTFLhJfDFR6aI5mRWdEfKfHzRItmlKsR9WlcEl1qDJs/zX9R2EEtIDsSKRzuJNfJllY3/W8Q=="], "@ast-grep/napi-linux-x64-gnu": ["@ast-grep/napi-linux-x64-gnu@0.45.3", "", { "os": "linux", "cpu": "x64" }, "sha512-lluRK3hxfHMQdFuVID6seAKVx4FH0kEwF6rCh5/I40Sf3EtNR2UCBXAqd6RBA6hqlSckktvBxCfw+h4aescDmg=="],
"@ast-grep/napi-linux-x64-musl": ["@ast-grep/napi-linux-x64-musl@0.40.5", "", { "os": "linux", "cpu": "x64" }, "sha512-BRZUvVBPUNpWPo6Ns8chXVzxHPY+k9gpsubGTHy92Q26ecZULd/dTkWWdnvfhRqttsSQ9Pe/XQdi5+hDQ6RYcg=="], "@ast-grep/napi-linux-x64-musl": ["@ast-grep/napi-linux-x64-musl@0.45.3", "", { "os": "linux", "cpu": "x64" }, "sha512-09wJQKq86LqILqQtw0+X09SzhcPwUnMVFKyia7S3XLbLqSeQpAMF55Y+zll53JRQ1dCzFEZJyvTT/7j9vwfE3w=="],
"@ast-grep/napi-win32-arm64-msvc": ["@ast-grep/napi-win32-arm64-msvc@0.40.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-y95zSEwc7vhxmcrcH0GnK4ZHEBQrmrszRBNQovzaciF9GUqEcCACNLoBesn4V47IaOp4fYgD2/EhGRTIBFb2Ug=="], "@ast-grep/napi-win32-arm64-msvc": ["@ast-grep/napi-win32-arm64-msvc@0.45.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-/HiVgw2cdtzXLDLoG4eBBcauekNXewfagy7qiVbjkVu/KcCH8dJ9lpj8DzeWwuBNtZxuD8jpiwP0M1pz3Bc3uw=="],
"@ast-grep/napi-win32-ia32-msvc": ["@ast-grep/napi-win32-ia32-msvc@0.40.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-K/u8De62iUnFCzVUs7FBdTZ2Jrgc5/DLHqjpup66KxZ7GIM9/HGME/O8aSoPkpcAeCD4TiTZ11C1i5p5H98hTg=="], "@ast-grep/napi-win32-ia32-msvc": ["@ast-grep/napi-win32-ia32-msvc@0.45.3", "", { "os": "win32", "cpu": "ia32" }, "sha512-/gwJrJQUw65uNtAFcG2rtSTr117Gqqy3bfjaljCPKsa65dTeRcMMnjKLlZ6V9/g8z+4Xf78kdhp5ECbir4yfSw=="],
"@ast-grep/napi-win32-x64-msvc": ["@ast-grep/napi-win32-x64-msvc@0.40.5", "", { "os": "win32", "cpu": "x64" }, "sha512-dqm5zg/o4Nh4VOQPEpMS23ot8HVd22gG0eg01t4CFcZeuzyuSgBlOL3N7xLbz3iH2sVkk7keuBwAzOIpTqziNQ=="], "@ast-grep/napi-win32-x64-msvc": ["@ast-grep/napi-win32-x64-msvc@0.45.3", "", { "os": "win32", "cpu": "x64" }, "sha512-CEZAMAsaDoQoVE3MT2c/ry3/ydfyaqlTjxv8DK5PG355SrdAYPgevGC2Me6tz4dhphJin89Y20VsnrS5UrYV5Q=="],
"@aws-crypto/crc32": ["@aws-crypto/crc32@5.2.0", "", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg=="], "@aws-crypto/crc32": ["@aws-crypto/crc32@5.2.0", "", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg=="],
@@ -626,12 +625,16 @@
"@csstools/selector-specificity": ["@csstools/selector-specificity@5.0.0", "", { "peerDependencies": { "postcss-selector-parser": "^7.0.0" } }, "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw=="], "@csstools/selector-specificity": ["@csstools/selector-specificity@5.0.0", "", { "peerDependencies": { "postcss-selector-parser": "^7.0.0" } }, "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw=="],
"@dotenvx/dotenvx": ["@dotenvx/dotenvx@1.31.0", "", { "dependencies": { "commander": "^11.1.0", "dotenv": "^16.4.5", "eciesjs": "^0.4.10", "execa": "^5.1.1", "fdir": "^6.2.0", "ignore": "^5.3.0", "object-treeify": "1.1.33", "picomatch": "^4.0.2", "which": "^4.0.0" }, "bin": { "dotenvx": "src/cli/dotenvx.js", "git-dotenvx": "src/cli/dotenvx.js" } }, "sha512-GeDxvtjiRuoyWVU9nQneId879zIyNdL05bS7RKiqMkfBSKpHMWHLoRyRqjYWLaXmX/llKO1hTlqHDmatkQAjPA=="], "@dotenvx/dotenvx": ["@dotenvx/dotenvx@2.38.1", "", { "dependencies": { "@dotenvx/primitives": "^3.3.1", "@dotenvx/providers": "^0.3.11", "@dotenvx/tooling": "^1.0.5", "undici": "^6.28.1", "write-file-atomic": "^5.0.1", "yocto-spinner": "^1.2.1" }, "bin": { "dx": "src/cli/dotenvx.js", "dotenvx": "src/cli/dotenvx.js" } }, "sha512-/E1w1e5+XjX13+BsGAupICHNwGVbgcsSQ/+2bAUXWlovNAt567SNqfON8ATkF1jUD+5OuxOhez2dt+IBifHG8A=="],
"@dotenvx/primitives": ["@dotenvx/primitives@3.3.1", "", {}, "sha512-ykX29rVnHwwV6m3AMmvR+niFSwhOG2TYttJjURz3n/3iHtpWC8gEptojYY+eHgBAV4fkaGRM1Rf0wgQ6/DeUYQ=="],
"@dotenvx/providers": ["@dotenvx/providers@0.3.11", "", { "dependencies": { "@dotenvx/primitives": "^3.3.1", "@dotenvx/tooling": "^1.0.4" } }, "sha512-5H5kAr5ps4shR7ZtA3mtDphh9Fbhp21yY77jCBCJLX2pbdEse0bcCBn7M1Ex1YrKF2O9SLKJB8ttJ2P5JsPidQ=="],
"@dotenvx/tooling": ["@dotenvx/tooling@1.0.5", "", {}, "sha512-XMAwZpxIajWaP31zLl2GQS3grIQsRY4B4VMss8fDv70XbGF/9aXSMHc3v9iJNZZVX/i0Loz1MAn6oM8dycbN4A=="],
"@dual-bundle/import-meta-resolve": ["@dual-bundle/import-meta-resolve@4.1.0", "", {}, "sha512-+nxncfwHM5SgAtrVzgpzJOI1ol0PkumhVo469KCf9lUi21IGcY90G98VuHm9VRrUypmAzawAHO9bs6hqeADaVg=="], "@dual-bundle/import-meta-resolve": ["@dual-bundle/import-meta-resolve@4.1.0", "", {}, "sha512-+nxncfwHM5SgAtrVzgpzJOI1ol0PkumhVo469KCf9lUi21IGcY90G98VuHm9VRrUypmAzawAHO9bs6hqeADaVg=="],
"@ecies/ciphers": ["@ecies/ciphers@0.2.2", "", { "peerDependencies": { "@noble/ciphers": "^1.0.0" } }, "sha512-ylfGR7PyTd+Rm2PqQowG08BCKA22QuX8NzrL+LxAAvazN10DMwdJ2fWwAzRj05FI/M8vNFGm3cv9Wq/GFWCBLg=="],
"@edge-runtime/format": ["@edge-runtime/format@2.2.1", "", {}, "sha512-JQTRVuiusQLNNLe2W9tnzBlV/GvSVcozLl4XZHk5swnRZ/v6jp8TqR8P7sqmJsQqblDZ3EztcWmLDbhRje/+8g=="], "@edge-runtime/format": ["@edge-runtime/format@2.2.1", "", {}, "sha512-JQTRVuiusQLNNLe2W9tnzBlV/GvSVcozLl4XZHk5swnRZ/v6jp8TqR8P7sqmJsQqblDZ3EztcWmLDbhRje/+8g=="],
"@edge-runtime/node-utils": ["@edge-runtime/node-utils@2.3.0", "", {}, "sha512-uUtx8BFoO1hNxtHjp3eqVPC/mWImGb2exOfGjMLUoipuWgjej+f4o/VP4bUI8U40gu7Teogd5VTeZUkGvJSPOQ=="], "@edge-runtime/node-utils": ["@edge-runtime/node-utils@2.3.0", "", {}, "sha512-uUtx8BFoO1hNxtHjp3eqVPC/mWImGb2exOfGjMLUoipuWgjej+f4o/VP4bUI8U40gu7Teogd5VTeZUkGvJSPOQ=="],
@@ -772,57 +775,57 @@
"@img/colour": ["@img/colour@1.1.0", "", {}, "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ=="], "@img/colour": ["@img/colour@1.1.0", "", {}, "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ=="],
"@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.3.3" }, "os": "darwin", "cpu": "arm64" }, "sha512-Uhfl4V4lhP2nbUVF9+hyH1+luj86f1gUFeo8ALYxFoULoU+G87D43BfeMP8XHsk9boxAnCY/bf2EHwhA7MuGsA=="], "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.3.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-QRUlFQ0WxvdWyqqG/WtI3iupfD5rBzmCHXSdPsY91sAtVtTo7Q4cb6zOccZ3gqEqkr0f1As1ehLqmEpDsRf+lg=="],
"@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.3.3" }, "os": "darwin", "cpu": "x64" }, "sha512-hWniXY3bG5qKpkKrAwPe4y+VTPmf086YQAnkxWh7uA1YrlRouWGa0M0Mxj3ZjnXFkv7/TD1bTy9lGUK26vRvWw=="], "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.3.4" }, "os": "darwin", "cpu": "x64" }, "sha512-+BR255RhDlpygUpOc/Jdt1nT6DQ3XG/ERo5wbcdOf5Q320dKtPCKPLR1LJs9VGXRaMa8l1uUa0tkCNOXiAxZUw=="],
"@img/sharp-freebsd-wasm32": ["@img/sharp-freebsd-wasm32@0.35.4", "", { "dependencies": { "@img/sharp-wasm32": "0.35.4" }, "os": "freebsd" }, "sha512-lIsKw/BU+kjB4eZjxrYrZmwOJYi3Ajrv66iAlBmUPyKc3HpnloevB1g3wxGD9P/5BbQ1brBGl65VRRrCvQDEqA=="], "@img/sharp-freebsd-wasm32": ["@img/sharp-freebsd-wasm32@0.35.5", "", { "dependencies": { "@img/sharp-wasm32": "0.35.5" }, "os": "freebsd" }, "sha512-Y/z91nEZ4uIBX5X3nfTovjU9lHNKFYbL2lpHCLVNmXQK03VIZvXBBt0KxbPGp2SdGSF+2mQU4e+hQaWOt86iAw=="],
"@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.3.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-suTBPTDGrI9WodccaDdwZItTSaBYASlBk1NSfElSHrUfzu3szG6lvIF58+WiFvnfzuK8ZBFS5zE00PxqxnRiPg=="], "@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.3.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-5R89nBYiRdUlSWJxPhO+GVtaXzXSxKnRu/xqMn3KTA3L9EB9Oy/P+Nn2f2vlhPuUdy/Zusb2DarbyTpGCfEDuw=="],
"@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.3.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-FVJZ5mITMobmXIz/hPDTw0EintTW5H3WfrxwLqEqjiIihlu+hVRyGrFQ60xl0Lxn7Bt3zdpevPaQi0HEzqz9fw=="], "@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.3.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-iR2OKH80yi0U+dUplyh3/xdpFvps6YkCwsXenIJxqxR1v9o+xtKTGbS9H7cps+2Vxjc8B1j96p75NmTGjIhtpQ=="],
"@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.3.3", "", { "os": "linux", "cpu": "arm" }, "sha512-3rbU4vqXXc3hY/OiXdl52xZvT0F1yEngWfvqudtPJg/KkyiaQw2DRsFrNzpmLvfavbwOq3qXn36GP8obHRULQA=="], "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.3.4", "", { "os": "linux", "cpu": "arm" }, "sha512-LmRtTsOHuvM2+wlO2Db37dx5MiZhB0FvSunciw48YjdOkZz9KAiRbm8ujeMOA1INqmei5NapFxYEK1D1ZSidmw=="],
"@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-0DaL0A6Xu6sQSQFwe4iVCrKWU2cCTItnRsYsCdxAMm9NF6twAA9BKnoqy4hqz4+azQ0JHuA26qiUKsf1XJ/v5A=="], "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.3.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-Y3dgX/6lE2QhQb+Gxy0WZxfg9MEm/JBjamZpS2IklP7xIQoKN4hzAm7KcMVGtaVDt3neE9OKBC7vAfonA/Lr1A=="],
"@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.3.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-cdn1OvUBwsXhbC0zSzJnNzf5MZ/mTrobawDvNXBTxe8VtqKAm0sRuEY2Evzovb/w9JMk4TvRxqt1mekSuJz64w=="], "@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.3.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-Le6boB8Tai0Nis+gIxIpKx68UDVVIqdR8Tin5Yf1z2LJJQLDJvCDRqRu+jC2qCoD+eIomonmOwB4smBRxfVpYQ=="],
"@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.3.3", "", { "os": "linux", "cpu": "none" }, "sha512-HjPVx7yKz+0lqdhDlTw1tt90wamBoxhiXpvl1XZpJLiHH4RCJ5yDTqH+VlYPv2fwFs89JFw4c1IexYOcQUi4IQ=="], "@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.3.4", "", { "os": "linux", "cpu": "none" }, "sha512-aHkkIEHPRdQEegJN20MLmGtxYD9R2wQr3Cwpddnu5+YKMt6Uzax7S9h5gpZTo8wyrGuZSlfQ63OevL5mTyOC7Q=="],
"@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.3.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-neWLh+3yCNThxnfy3c4BbVBeGgt9aftno+XbT56iK28RgeDs3UOFWviLWlUu0bArYVYJaFDK+RRohbicUNCm8Q=="], "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.3.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-ra/mB6MikESDUO7Yg+Mi95bFBb9GsObURuhnOv3OqknjGe9sZrG8tCe9q0xSIGrtLgvgw0gKnFWcK4blSgQOuQ=="],
"@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-4vKmvAst9nrowcqquKFAyZJUDolUaIp8uRiN0mWFguJ1IplC9/pitXtlnnlU4aa/eJw3J7i67V+pwUL+wZGdsA=="], "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.3.4", "", { "os": "linux", "cpu": "x64" }, "sha512-GJ//SSXbnwSDes02umB3nDJLFcQzw8a18V8fyhqr6tV515tOEMdImjjxj1AoafMRz56F3PHgftnj1QEKSU1zkw=="],
"@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-Y9kQaLMuNoB0bPYOOdcZMaseNrFpPodIWWMrx+CZyydf2xn68j9WYc6sWWRrDwNkzCQjKYfc68L7jKjGlHMibw=="], "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.3.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-hvulFwtjUcagsis6BBxHwGFwWoNZjgYmULGVrZcyfNbjA8hKILbRxGg15/7w5HDyXHXUos/j6baAWqnCyQ2DWA=="],
"@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-fj8Mv0HHfD1Rr+4I68+3agJynxDWtBFgicTbSOb9Bke6pIwzGcJ+RX/yHjmiEGFMCavY/dxvem7MyNaJF+wDiw=="], "@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.3.4", "", { "os": "linux", "cpu": "x64" }, "sha512-6zXKeE/p39I1AmA3cJG35eyBGNqNddLnUXjhwBnsGjFPWqf5VKkDBEqaEkPDoTEtkxwi2vv8Tcr2mDyP4So7Fg=="],
"@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.3.3" }, "os": "linux", "cpu": "arm" }, "sha512-7OAS8gI0EReKGVN2HssHlM6umJgxF5VI3xN0p9FA91p/YO+ou5hiNghLdZ5BEHztwaaK5+bLKRf8x/o2L2nk9A=="], "@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.3.4" }, "os": "linux", "cpu": "arm" }, "sha512-LEaXK2WdXVK5ykcw0buWyPMsmLLL2vpHLD6yrNSW+JGEL3BZPA4tpKN6iaMc4AxTTAoaX/sU1rOL51lcIz48ZQ=="],
"@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.3.3" }, "os": "linux", "cpu": "arm64" }, "sha512-De4jpEnAU8Hd5oT0j1G3uL4ZvTuipVMn7YC6vPaJhy6/7EwEae0SVAoBrUMYQbkLGDm85taVWwuPc1a44LTzCQ=="], "@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.3.4" }, "os": "linux", "cpu": "arm64" }, "sha512-LYVx5JTsOM2CBzmxreh+nl64/3H6Xb09iSLknqH47z2T2DFFxDeFLP5y4dJwe6H7uGQlHPyEEtIqyo3DYsRwdQ=="],
"@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.3.3" }, "os": "linux", "cpu": "ppc64" }, "sha512-2oYZJeIl4kCcMGk4ouZVjnkCtFrpQFlNEtJ6GbxzhHQchwH0NH/qEb9ykmOl29dqwMq+JhFdZn+1ak2FKhI9fQ=="], "@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.3.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-QVxAAq8evVRI9ia2vqgwrmWucn5Dfv+JdWzj75pD8omHLPSP7f8p20O8jxzjCcuCEQEOtYOZUmX1hkiZ0kdevA=="],
"@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.3.3" }, "os": "linux", "cpu": "none" }, "sha512-cPbNChoRURAWdebDIHSenxRpgEdy7JkPydSnUxRm9VvKD7m0/xVaR/8Fzlu81pk5nHEvHH87UZUA7cTtwnbJSA=="], "@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.3.4" }, "os": "linux", "cpu": "none" }, "sha512-LtdreXguaavKODPIfzJ4kffx7UNt1omwtK0rch4EBbbSTXPnxWmYSayXdLJw0fJzQ97kHt1gL/yh4tvU+nCyRQ=="],
"@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.3.3" }, "os": "linux", "cpu": "s390x" }, "sha512-RY0JFY8Fd6RonCBtHz+DvadaPkXDSI1AUn6yWL9TipqkZ1vY8w8evqdgyDFnkm4/K1ve1TvZiaePP5oSd4+WVQ=="], "@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.3.4" }, "os": "linux", "cpu": "s390x" }, "sha512-UZasTOFiYzotTsGOCu42BfUzP6Tu6Do/947iRm1RsLKvlllxwGcn4RN27LibGWceix4Y+Pmw3jsnTcCQIgWjqA=="],
"@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.3.3" }, "os": "linux", "cpu": "x64" }, "sha512-9qvvEAuk8k89TfWUoX2htWjbAMX8p+NxCppjpcg5k6xMsjhBQPTsoIh36h9Qde4WRuGpJeYnOjdosDn/cnv+OA=="], "@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.3.4" }, "os": "linux", "cpu": "x64" }, "sha512-SxFtLTeJInhAA9Q836kux2vZNeOBQEx658qvbboZScr0wIARym3IcGmW7KpVD5sbVg0Ojy+udFQdayYIZyoNog=="],
"@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.3.3" }, "os": "linux", "cpu": "arm64" }, "sha512-KB5jxpfWQTr0nc3xdHtWChdbifHrBGsd2SM62Eyxrl8afikm+f5qGBU75SJIZBT/S1MC8XyacdlXBMSWq6OURA=="], "@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.3.4" }, "os": "linux", "cpu": "arm64" }, "sha512-9HbMclmI1zlNkFRs3z9/eBtDjfD0sGlrX1z6b1qwmiFY5ElDLh4BC0LPBdVp7z1DXFiKlIcznf+ZlsuZzLxQqg=="],
"@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.35.4", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.3.3" }, "os": "linux", "cpu": "x64" }, "sha512-f+eZJZIQNEEd26RPSW+76chwOf1XtA2Y/O+5ocVyLliHkeih3e+jhLVBdNTd2rS3IbNXK8+ug93Vf5ZXtF5Lxg=="], "@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.3.4" }, "os": "linux", "cpu": "x64" }, "sha512-4KOphqB035HrVdqLZfCgMzzERrQkkzOwRhl4OAkRO1YCldbaFjySXMaK534Mo0V+LndnlJk+sbUyLeU0ULyD1A=="],
"@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="], "@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="],
"@img/sharp-webcontainers-wasm32": ["@img/sharp-webcontainers-wasm32@0.35.4", "", { "dependencies": { "@img/sharp-wasm32": "0.35.4" }, "cpu": "none" }, "sha512-ESfNkywmCfPNyaZjxooddJQiQ+l/nTpGEOGthxiLnIHXC/CmcBixnfwUleX9mCz9ovrUUvKMap/pm8RYbzfwaA=="], "@img/sharp-webcontainers-wasm32": ["@img/sharp-webcontainers-wasm32@0.35.5", "", { "dependencies": { "@img/sharp-wasm32": "0.35.5" }, "cpu": "none" }, "sha512-hfhF/FmoQyTUkA0bIKFOtw536BQSeBMe6BF6QyWlrPxT754+TFLaZ7sKKTfvvM0yJgKgaYTwnFCIZ/GuDw5SUA=="],
"@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.35.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-iNdlBX9gLVvqe2I3uIJSIKTq6wckP/DYxZtcqxm09x5Gi24DnFBmPAWZmr60ZyYMG0xlzo6goG3670ar+RXvRw=="], "@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.35.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-X4t7g+7ZA5DKblCBEXGjUqqemj4vczING/5viFwAL8h4N3qYeyjwdCvRLHi4EdOUI+2Z7UFlp1VM+p/AuEtm6Q=="],
"@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.35.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-kqRsbaa5CS6KHlpxnN7WhE6vAAugXyZButpRdvDWetlv6Qv4N9WTcrWzF7tXfB9T7MsoadqdI8hmwLq6UlLvtw=="], "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.35.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-5Zm82LoBc43nhwNybZlG7Y1KO//Zhsn306fQl29ZOuStHLGTo3BWL83q3cznX0poxSAMuYL1On/BHBxkBeKr6A=="],
"@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.35.4", "", { "os": "win32", "cpu": "x64" }, "sha512-XtmnYhBcrORsJ4XJngyzr/EWP0hRZLAZRFaApdKuviyqF78+ylxh2y06ZmtULAMOnObJ3ucpN0AcwSWnMowTRg=="], "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.35.5", "", { "os": "win32", "cpu": "x64" }, "sha512-x76eH0vEiHlcMQu8Y8IenntaACtddpT6W0wmXtWrnKcnKI7ME5DdgqhAD6SEWOEl1v2zDvkZDhFA9KnURwpfqg=="],
"@inquirer/external-editor": ["@inquirer/external-editor@1.0.2", "", { "dependencies": { "chardet": "^2.1.0", "iconv-lite": "^0.7.0" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ=="], "@inquirer/external-editor": ["@inquirer/external-editor@1.0.2", "", { "dependencies": { "chardet": "^2.1.0", "iconv-lite": "^0.7.0" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ=="],
@@ -884,35 +887,29 @@
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.0.6", "", { "dependencies": { "@emnapi/core": "^1.5.0", "@emnapi/runtime": "^1.5.0", "@tybys/wasm-util": "^0.10.1" } }, "sha512-DXj75ewm11LIWUk198QSKUTxjyRjsBwk09MuMk5DGK+GDUtyPhhEHOGP/Xwwj3DjQXXkivoBirmOnKrLfc0+9g=="], "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.0.6", "", { "dependencies": { "@emnapi/core": "^1.5.0", "@emnapi/runtime": "^1.5.0", "@tybys/wasm-util": "^0.10.1" } }, "sha512-DXj75ewm11LIWUk198QSKUTxjyRjsBwk09MuMk5DGK+GDUtyPhhEHOGP/Xwwj3DjQXXkivoBirmOnKrLfc0+9g=="],
"@next/env": ["@next/env@16.3.8", "", {}, "sha512-Al9zqHVV7TJv0eFuOU4U7Lvv74PTih4Ch63sk2xCIpSTkE3udFnaOcnzP2lQVymiL7yS9Cj2iClUXlR3EQ5sEw=="], "@next/env": ["@next/env@16.4.2", "", {}, "sha512-nTUTFH7G5/J/fmpkjVLegOkqyKOP0CEsJcMsyO4UCYeN1su+YMW/MfaSErnJskL7XM+UDK6aTvslxsRCyya/sA=="],
"@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.3.8", "", { "os": "darwin", "cpu": "arm64" }, "sha512-2JPRMh2nmQG5CiL7cXGL9AGwnPWJQ//cTtAUCT+w511QHk79SYz3LGv/pc5X643B/WEO0rvu3Yww0hqwt3kgeA=="], "@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.4.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ONkhFvZNFWlsEHOM/81AtxdyuJP2KRYKYR0JxPwvcu1AuPMMMgcL+wW2luldJvMtZwKtUxoSkCychW5wIeoYSw=="],
"@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.3.8", "", { "os": "darwin", "cpu": "x64" }, "sha512-GZtCCOBKJ4leVIT/Th0llWKhD1ca92lzbQiS5R5ON9QkoiFnilFsebDae1JU2a3HWoKMEmEZWGs1AGLavVM72Q=="], "@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.4.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-luPCMbOsCoaF+kXJEUjmjmOZg1lC3BflhmUu+ZmW4tBu2vW/4AXak8JBFvePizGkxVmNiAw/r9ra+6UviCWtWQ=="],
"@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.3.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-O659ygeQYqneJ1fBKMpFxIFqYkYswu8IAS1OCKK/4f3ZgJJm1dRz4fVJZRi/kLLWjnBKnebOePA4WNv+sV1pVA=="], "@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.4.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-xhwFTAncJyaCNy5KqKKuKaIIdCy1/1ZV1s5S1G0hhT7wGMkDTlfJ6aQbfRFnIG/s3/kDrxQ8aycVe+c5QnP8ow=="],
"@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.3.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-dSjKSyWpzxoO1d3DIZZcP4XJcNaKeLmxQMFOiYl5vuBRMmweIqnAhty8tAmRsvTss779cK1FtYnDMj40e4TQlg=="], "@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.4.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-T1PNmfbPcxr5ndtWUL/3wQtLXsz808lq6sc2GrNT5k2oquF7UyqZddHSuAewHVsWsGXe6nsl9HoN1YNriVjuSg=="],
"@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.3.8", "", { "os": "linux", "cpu": "x64" }, "sha512-lbqOuz3RPRcv+o9msNsJw5x4+Y1ZwPTs6vmL6DCf7i0fZfvng/F59wyeDwqHIvV0mK//RBy/jJkZ+nCKsSMXjQ=="], "@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.4.2", "", { "os": "linux", "cpu": "x64" }, "sha512-N9cDUOCGtkJG5PNKDFZUF3xXndrJJcpLp121uAGjIGvO/U2p9tfdNOM9htj7+5f72l0m8rMw/cvYacUJBQoudg=="],
"@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.3.8", "", { "os": "linux", "cpu": "x64" }, "sha512-+316WswI8ScVgZeUd+1KGaXkHhaYQzCjvH/05TZSpJ8zBizb1a4G7DtO7F12jcBIqMOtsz9ji1t48fmKtzqsGA=="], "@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.4.2", "", { "os": "linux", "cpu": "x64" }, "sha512-yY2uh1YhX6ufuYy2FCbw1dqblbhI57GLYAJfCkqD9auTv6pLrH67Uccjc3QMKBeCYAG6lkgu08ExmX1bbjejjQ=="],
"@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.3.8", "", { "os": "win32", "cpu": "arm64" }, "sha512-ji0gd4kMYUxO+1fJBIbiBVRCjzG/lloiyCccnlebvb1ZJ5qXCPZqYg4Jl1DrrixnWNMKylzgpmMWx0yNDYXlzw=="], "@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.4.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-j/ArWRIHpMMB6wYLMhr2puTguBt70lNU/Cmjl9p6dTDE8DGknYJMP9PdwPk2dqpCNL/KIX9yfngDvIesxJPmsg=="],
"@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.3.8", "", { "os": "win32", "cpu": "x64" }, "sha512-WcTlaKt/TWkh5kUjdJcUmB1XgZ+1c6fz4Y9fDHL73YNSdGaUWjceeWrrlwF0nv19iABYWC4iAq1oX1w4Bn0vfg=="], "@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.4.2", "", { "os": "win32", "cpu": "x64" }, "sha512-AA4edyWHDko3NCSo0x6GomsdgFb0oR1J3MXU1b5xt6FRFg4AucrMPW3S0hCe/9onU0O1BbpGQBsqo1r0Gneu1g=="],
"@noble/ciphers": ["@noble/ciphers@1.2.1", "", {}, "sha512-rONPWMC7PeExE077uLE4oqWrZ1IvAfz3oH9LibVAcVCopJiA9R62uavnbEzdkVmJYI6M6Zgkbeb07+tWjlq2XA=="], "@node-minify/core": ["@node-minify/core@9.0.2", "", { "dependencies": { "@node-minify/utils": "9.0.1", "glob": "10.3.3", "mkdirp": "3.0.1" } }, "sha512-FNhv29Wom6wKrrFKaeAfmZqz7TX5A1E6P+bpd0VIc+DYWMLUIhAViS8riaZg3A1oD0s06s+5BG2Fg7RqMKiKHw=="],
"@noble/curves": ["@noble/curves@1.8.1", "", { "dependencies": { "@noble/hashes": "1.7.1" } }, "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ=="], "@node-minify/terser": ["@node-minify/terser@9.0.1", "", { "dependencies": { "@node-minify/utils": "9.0.1", "terser": "5.36.0" } }, "sha512-WF78Ex+/xNZZDYvzwB7+sLUYQbJzyyS36ZjMhVqhORejHOsoOcTjQ9TdOgKZoY7wlfxjnLxeMKkO8R/R1KL9aQ=="],
"@noble/hashes": ["@noble/hashes@1.7.1", "", {}, "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ=="], "@node-minify/utils": ["@node-minify/utils@9.0.1", "", { "dependencies": { "gzip-size": "6.0.0" } }, "sha512-aC1+mhKTP3IMa2VcuGl3ui92LO/7CPQWldNGzu3BVGKiMNJ70AKJW/R6huuYCSuQyHDGM9oFwiVClsZnFxn67g=="],
"@node-minify/core": ["@node-minify/core@8.0.6", "", { "dependencies": { "@node-minify/utils": "8.0.6", "glob": "9.3.5", "mkdirp": "1.0.4" } }, "sha512-/vxN46ieWDLU67CmgbArEvOb41zlYFOkOtr9QW9CnTrBLuTyGgkyNWC2y5+khvRw3Br58p2B5ZVSx/PxCTru6g=="],
"@node-minify/terser": ["@node-minify/terser@8.0.6", "", { "dependencies": { "@node-minify/utils": "8.0.6", "terser": "5.16.9" } }, "sha512-grQ1ipham743ch2c3++C8Isk6toJnxJSyDiwUI/IWUCh4CZFD6aYVw6UAY40IpCnjrq5aXGwiv5OZJn6Pr0hvg=="],
"@node-minify/utils": ["@node-minify/utils@8.0.6", "", { "dependencies": { "gzip-size": "6.0.0" } }, "sha512-csY4qcR7jUwiZmkreNTJhcypQfts2aY2CK+a+rXgXUImZiZiySh0FvwHjRnlqWKvg+y6ae9lHFzDRjBTmqlTIQ=="],
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
@@ -936,9 +933,9 @@
"@octokit/types": ["@octokit/types@14.1.0", "", { "dependencies": { "@octokit/openapi-types": "^25.1.0" } }, "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g=="], "@octokit/types": ["@octokit/types@14.1.0", "", { "dependencies": { "@octokit/openapi-types": "^25.1.0" } }, "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g=="],
"@opennextjs/aws": ["@opennextjs/aws@4.1.7", "", { "dependencies": { "@ast-grep/napi": "^0.40.5", "@aws-sdk/client-cloudfront": "3.984.0", "@aws-sdk/client-dynamodb": "3.984.0", "@aws-sdk/client-lambda": "3.984.0", "@aws-sdk/client-s3": "3.984.0", "@aws-sdk/client-sqs": "3.984.0", "@node-minify/core": "^8.0.6", "@node-minify/terser": "^8.0.6", "@tsconfig/node18": "^1.0.3", "aws4fetch": "^1.0.20", "chalk": "^5.6.2", "cookie": "^1.0.2", "esbuild": "0.25.4", "express": "^5.1.0", "path-to-regexp": "^6.3.0", "urlpattern-polyfill": "^10.1.0", "yaml": "^2.8.1" }, "peerDependencies": { "next": ">=15.5.27 <16 || >=16.3.8" }, "bin": { "open-next": "dist/index.js" } }, "sha512-ELezSARrTfxp/76cz41eQjki1AV0CuBUKOznU3w/tOk7i87x867RkkYho+gDkog9gpnGzefHdJu463o9VaabNQ=="], "@opennextjs/aws": ["@opennextjs/aws@4.1.11", "", { "dependencies": { "@ast-grep/napi": "^0.45.3", "@aws-sdk/client-cloudfront": "3.984.0", "@aws-sdk/client-dynamodb": "3.984.0", "@aws-sdk/client-lambda": "3.984.0", "@aws-sdk/client-s3": "3.984.0", "@aws-sdk/client-sqs": "3.984.0", "@node-minify/core": "^9.0.2", "@node-minify/terser": "^9.0.1", "@tsconfig/node18": "^18.2.7", "aws4fetch": "^1.0.20", "chalk": "^5.6.2", "cookie": "^1.1.1", "esbuild": "0.28.2", "express": "^5.2.1", "path-to-regexp": "^6.3.0", "urlpattern-polyfill": "^10.1.0", "yaml": "^2.9.1" }, "peerDependencies": { "next": ">=15.5.28 <16 || >=16.4.1" }, "bin": { "open-next": "dist/index.js" } }, "sha512-cew0cUgGZF/Kr/C+Z1qvmAdKj4Va5cRho+aB6Ci/5ILd+QDdrR2LVaC/6Qm12KVF37vSLDK7lPDd/KdvvCoNEw=="],
"@opennextjs/cloudflare": ["@opennextjs/cloudflare@1.20.8", "", { "dependencies": { "@ast-grep/napi": "^0.40.5", "@dotenvx/dotenvx": "1.31.0", "@opennextjs/aws": "4.1.7", "ci-info": "^4.2.0", "cloudflare": "^4.4.1", "comment-json": "^4.5.1", "enquirer": "^2.4.1", "glob": "^12.0.0", "ts-tqdm": "^0.8.6", "yargs": "^18.0.0" }, "peerDependencies": { "next": ">=15.5.27 <16 || >=16.3.8", "rclone.js": "^0.6.6", "wrangler": "^4.125.0" }, "optionalPeers": ["rclone.js"], "bin": { "opennextjs-cloudflare": "dist/cli/index.js" } }, "sha512-7rrsBqd234GBBnHITobS0gagT4/fSfHJwm+ogYTyUb7ubg3PGC06biJgL9l4DZabFeu/ucqvml80sBr5torBgg=="], "@opennextjs/cloudflare": ["@opennextjs/cloudflare@1.20.12", "", { "dependencies": { "@ast-grep/napi": "^0.45.3", "@dotenvx/dotenvx": "^2.33.0", "@opennextjs/aws": "4.1.11", "ci-info": "^4.2.0", "cloudflare": "^4.4.1", "comment-json": "^4.5.1", "enquirer": "^2.4.1", "glob": "^13.0.6", "ts-tqdm": "^0.8.6", "yargs": "^18.2.0" }, "peerDependencies": { "next": ">=15.5.28 <16 || >=16.4.1", "rclone.js": "^0.6.6", "wrangler": "^4.148.0" }, "optionalPeers": ["rclone.js"], "bin": { "opennextjs-cloudflare": "dist/cli/index.js" } }, "sha512-ZU1j7hMuOFaa0RHT/wrPXQKEEqzkkoc3fHaHy0Xrx4K0zZdSXGQbwbSHCnbjPRGXblCuWo+ur6UUkl0o9kVhrg=="],
"@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="], "@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="],
@@ -1354,7 +1351,7 @@
"@ts-morph/common": ["@ts-morph/common@0.11.1", "", { "dependencies": { "fast-glob": "^3.2.7", "minimatch": "^3.0.4", "mkdirp": "^1.0.4", "path-browserify": "^1.0.1" } }, "sha512-7hWZS0NRpEsNV8vWJzg7FEz6V8MaLNeJOmwmghqUXTpzk16V1LLZhdo+4QvE/+zv4cVci0OviuJFnqhEfoV3+g=="], "@ts-morph/common": ["@ts-morph/common@0.11.1", "", { "dependencies": { "fast-glob": "^3.2.7", "minimatch": "^3.0.4", "mkdirp": "^1.0.4", "path-browserify": "^1.0.1" } }, "sha512-7hWZS0NRpEsNV8vWJzg7FEz6V8MaLNeJOmwmghqUXTpzk16V1LLZhdo+4QvE/+zv4cVci0OviuJFnqhEfoV3+g=="],
"@tsconfig/node18": ["@tsconfig/node18@1.0.3", "", {}, "sha512-RbwvSJQsuN9TB04AQbGULYfOGE/RnSFk/FLQ5b0NmDf5Kx2q/lABZbHQPKCO1vZ6Fiwkplu+yb9pGdLy1iGseQ=="], "@tsconfig/node18": ["@tsconfig/node18@18.2.7", "", {}, "sha512-UyenTORreCUh8MKh2qbLGGHTRrxjBbSwvX0ZoWs6Jx1jrNS62PXEA3+VaLvmb0YDQrgGU3v3h7zB9Xs/BN1ozg=="],
"@tsconfig/node20": ["@tsconfig/node20@20.1.6", "", {}, "sha512-sz+Hqx9zwZDpZIV871WSbUzSqNIsXzghZydypnfgzPKLltVJfkINfUeTct31n/tTSa9ZE1ZOfKdRre1uHHquYQ=="], "@tsconfig/node20": ["@tsconfig/node20@20.1.6", "", {}, "sha512-sz+Hqx9zwZDpZIV871WSbUzSqNIsXzghZydypnfgzPKLltVJfkINfUeTct31n/tTSa9ZE1ZOfKdRre1uHHquYQ=="],
@@ -1698,7 +1695,7 @@
"bowser": ["bowser@2.11.0", "", {}, "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA=="], "bowser": ["bowser@2.11.0", "", {}, "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA=="],
"brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="], "brace-expansion": ["brace-expansion@5.0.12", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ=="],
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
@@ -1800,7 +1797,7 @@
"convict": ["convict@6.2.5", "", { "dependencies": { "lodash.clonedeep": "^4.5.0", "yargs-parser": "^20.2.7" } }, "sha512-JtXpxqDqJ8P0UwEHwhxLzCIXQy97vlYBZR222Sbzb1q1Erex9ASrztJ29SyhWFQjod1AeFBaPzEEC8YvtZMIYg=="], "convict": ["convict@6.2.5", "", { "dependencies": { "lodash.clonedeep": "^4.5.0", "yargs-parser": "^20.2.7" } }, "sha512-JtXpxqDqJ8P0UwEHwhxLzCIXQy97vlYBZR222Sbzb1q1Erex9ASrztJ29SyhWFQjod1AeFBaPzEEC8YvtZMIYg=="],
"cookie": ["cookie@1.0.2", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="], "cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="],
"cookie-es": ["cookie-es@2.0.0", "", {}, "sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg=="], "cookie-es": ["cookie-es@2.0.0", "", {}, "sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg=="],
@@ -1966,8 +1963,6 @@
"domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="], "domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="],
"dotenv": ["dotenv@16.4.7", "", {}, "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ=="],
"dts-resolver": ["dts-resolver@2.1.2", "", { "peerDependencies": { "oxc-resolver": ">=11.0.0" }, "optionalPeers": ["oxc-resolver"] }, "sha512-xeXHBQkn2ISSXxbJWD828PFjtyg+/UrMDo7W4Ffcs7+YWCquxU8YjV1KoxuiL+eJ5pg3ll+bC6flVv61L3LKZg=="], "dts-resolver": ["dts-resolver@2.1.2", "", { "peerDependencies": { "oxc-resolver": ">=11.0.0" }, "optionalPeers": ["oxc-resolver"] }, "sha512-xeXHBQkn2ISSXxbJWD828PFjtyg+/UrMDo7W4Ffcs7+YWCquxU8YjV1KoxuiL+eJ5pg3ll+bC6flVv61L3LKZg=="],
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
@@ -1980,8 +1975,6 @@
"ecdsa-sig-formatter": ["ecdsa-sig-formatter@1.0.11", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ=="], "ecdsa-sig-formatter": ["ecdsa-sig-formatter@1.0.11", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ=="],
"eciesjs": ["eciesjs@0.4.13", "", { "dependencies": { "@ecies/ciphers": "^0.2.2", "@noble/ciphers": "^1.0.0", "@noble/curves": "^1.6.0", "@noble/hashes": "^1.5.0" } }, "sha512-zBdtR4K+wbj10bWPpIOF9DW+eFYQu8miU5ypunh0t4Bvt83ZPlEWgT5Dq/0G6uwEXumZKjfb5BZxYUZQ2Hzn/Q=="],
"edge-runtime": ["edge-runtime@2.5.9", "", { "dependencies": { "@edge-runtime/format": "2.2.1", "@edge-runtime/ponyfill": "2.4.2", "@edge-runtime/vm": "3.2.0", "async-listen": "3.0.1", "mri": "1.2.0", "picocolors": "1.0.0", "pretty-ms": "7.0.1", "signal-exit": "4.0.2", "time-span": "4.0.0" }, "bin": { "edge-runtime": "dist/cli/index.js" } }, "sha512-pk+k0oK0PVXdlT4oRp4lwh+unuKB7Ng4iZ2HB+EZ7QCEQizX360Rp/F4aRpgpRgdP2ufB35N+1KppHmYjqIGSg=="], "edge-runtime": ["edge-runtime@2.5.9", "", { "dependencies": { "@edge-runtime/format": "2.2.1", "@edge-runtime/ponyfill": "2.4.2", "@edge-runtime/vm": "3.2.0", "async-listen": "3.0.1", "mri": "1.2.0", "picocolors": "1.0.0", "pretty-ms": "7.0.1", "signal-exit": "4.0.2", "time-span": "4.0.0" }, "bin": { "edge-runtime": "dist/cli/index.js" } }, "sha512-pk+k0oK0PVXdlT4oRp4lwh+unuKB7Ng4iZ2HB+EZ7QCEQizX360Rp/F4aRpgpRgdP2ufB35N+1KppHmYjqIGSg=="],
"ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="],
@@ -2144,8 +2137,6 @@
"fs-extra": ["fs-extra@7.0.1", "", { "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw=="], "fs-extra": ["fs-extra@7.0.1", "", { "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw=="],
"fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="],
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
@@ -2156,7 +2147,7 @@
"get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
"get-east-asian-width": ["get-east-asian-width@1.3.0", "", {}, "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ=="], "get-east-asian-width": ["get-east-asian-width@1.7.0", "", {}, "sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q=="],
"get-intrinsic": ["get-intrinsic@1.2.4", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" } }, "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ=="], "get-intrinsic": ["get-intrinsic@1.2.4", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" } }, "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ=="],
@@ -2174,7 +2165,7 @@
"github-slugger": ["github-slugger@2.0.0", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="], "github-slugger": ["github-slugger@2.0.0", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="],
"glob": ["glob@12.0.0", "", { "dependencies": { "foreground-child": "^3.3.1", "jackspeak": "^4.1.1", "minimatch": "^10.1.1", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^2.0.0" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-5Qcll1z7IKgHr5g485ePDdHcNQY0k2dtv/bjYy0iuyGxQw2qSOiiXUXJ+AYQpg3HNoUMHqAruX478Jeev7UULw=="], "glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="],
"glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], "glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
@@ -2340,7 +2331,7 @@
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
"jackspeak": ["jackspeak@4.1.1", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" } }, "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ=="], "jackspeak": ["jackspeak@2.3.6", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ=="],
"jiti": ["jiti@2.5.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w=="], "jiti": ["jiti@2.5.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w=="],
@@ -2604,15 +2595,15 @@
"miniflare": ["miniflare@4.20260401.0", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "sharp": "^0.34.5", "undici": "7.24.4", "workerd": "1.20260401.1", "ws": "8.18.0", "youch": "4.1.0-beta.10" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-lngHPzZFN9sxYG/mhzvnWiBMNVAN5MsO/7g32ttJ07rymtiK/ZBalODTKb8Od+BQdlU5DOR4CjVt9NydjnUyYg=="], "miniflare": ["miniflare@4.20260401.0", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "sharp": "^0.34.5", "undici": "7.24.4", "workerd": "1.20260401.1", "ws": "8.18.0", "youch": "4.1.0-beta.10" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-lngHPzZFN9sxYG/mhzvnWiBMNVAN5MsO/7g32ttJ07rymtiK/ZBalODTKb8Od+BQdlU5DOR4CjVt9NydjnUyYg=="],
"minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="], "minimatch": ["minimatch@10.2.6", "", { "dependencies": { "brace-expansion": "^5.0.8" } }, "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A=="],
"minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], "minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="],
"minizlib": ["minizlib@3.1.0", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw=="], "minizlib": ["minizlib@3.1.0", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw=="],
"mitt": ["mitt@3.0.1", "", {}, "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="], "mitt": ["mitt@3.0.1", "", {}, "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="],
"mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="], "mkdirp": ["mkdirp@3.0.1", "", { "bin": { "mkdirp": "dist/cjs/src/bin.js" } }, "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg=="],
"mlly": ["mlly@1.8.0", "", { "dependencies": { "acorn": "^8.15.0", "pathe": "^2.0.3", "pkg-types": "^1.3.1", "ufo": "^1.6.1" } }, "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g=="], "mlly": ["mlly@1.8.0", "", { "dependencies": { "acorn": "^8.15.0", "pathe": "^2.0.3", "pkg-types": "^1.3.1", "ufo": "^1.6.1" } }, "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g=="],
@@ -2638,7 +2629,7 @@
"netmask": ["netmask@2.0.2", "", {}, "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg=="], "netmask": ["netmask@2.0.2", "", {}, "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg=="],
"next": ["next@16.3.8", "", { "dependencies": { "@next/env": "16.3.8", "@swc/helpers": "0.5.23", "baseline-browser-mapping": "^2.9.19", "caniuse-lite": "^1.0.30001579", "postcss": "8.5.23", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.3.8", "@next/swc-darwin-x64": "16.3.8", "@next/swc-linux-arm64-gnu": "16.3.8", "@next/swc-linux-arm64-musl": "16.3.8", "@next/swc-linux-x64-gnu": "16.3.8", "@next/swc-linux-x64-musl": "16.3.8", "@next/swc-win32-arm64-msvc": "16.3.8", "@next/swc-win32-x64-msvc": "16.3.8", "sharp": "^0.35.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-U7QEZaTini6wKrb8A8hqLLqYQyCetegKjCpJOyxk642vWoMoU1x5PyZCJFvgYgiptA8xc5j/9xYlZFO7w9Sjmw=="], "next": ["next@16.4.2", "", { "dependencies": { "@next/env": "16.4.2", "@swc/helpers": "0.5.23", "baseline-browser-mapping": "^2.9.19", "caniuse-lite": "^1.0.30001579", "postcss": "8.5.23", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.4.2", "@next/swc-darwin-x64": "16.4.2", "@next/swc-linux-arm64-gnu": "16.4.2", "@next/swc-linux-arm64-musl": "16.4.2", "@next/swc-linux-x64-gnu": "16.4.2", "@next/swc-linux-x64-musl": "16.4.2", "@next/swc-win32-arm64-msvc": "16.4.2", "@next/swc-win32-x64-msvc": "16.4.2", "sharp": "^0.35.5" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-r+oBJojfefUjOiWkBhXgLS+igxX/7BWyK59uHnyOyplMSLtBZ+QLP3okrdYTbrfrbrmNTVWLBPaHDX9KRaIt3w=="],
"next-themes": ["next-themes@0.4.6", "", { "peerDependencies": { "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA=="], "next-themes": ["next-themes@0.4.6", "", { "peerDependencies": { "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA=="],
@@ -2670,8 +2661,6 @@
"object-inspect": ["object-inspect@1.13.2", "", {}, "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g=="], "object-inspect": ["object-inspect@1.13.2", "", {}, "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g=="],
"object-treeify": ["object-treeify@1.1.33", "", {}, "sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A=="],
"obliterator": ["obliterator@1.6.1", "", {}, "sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig=="], "obliterator": ["obliterator@1.6.1", "", {}, "sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig=="],
"on-exit-leak-free": ["on-exit-leak-free@2.1.2", "", {}, "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA=="], "on-exit-leak-free": ["on-exit-leak-free@2.1.2", "", {}, "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA=="],
@@ -2748,7 +2737,7 @@
"path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="], "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="],
"path-scurry": ["path-scurry@2.0.0", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg=="], "path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="],
"path-to-regexp": ["path-to-regexp@6.3.0", "", {}, "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ=="], "path-to-regexp": ["path-to-regexp@6.3.0", "", {}, "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ=="],
@@ -2956,7 +2945,7 @@
"setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="], "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="],
"sharp": ["sharp@0.35.4", "", { "dependencies": { "@img/colour": "^1.1.0", "detect-libc": "^2.1.2", "semver": "^7.8.5" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.35.4", "@img/sharp-darwin-x64": "0.35.4", "@img/sharp-freebsd-wasm32": "0.35.4", "@img/sharp-libvips-darwin-arm64": "1.3.3", "@img/sharp-libvips-darwin-x64": "1.3.3", "@img/sharp-libvips-linux-arm": "1.3.3", "@img/sharp-libvips-linux-arm64": "1.3.3", "@img/sharp-libvips-linux-ppc64": "1.3.3", "@img/sharp-libvips-linux-riscv64": "1.3.3", "@img/sharp-libvips-linux-s390x": "1.3.3", "@img/sharp-libvips-linux-x64": "1.3.3", "@img/sharp-libvips-linuxmusl-arm64": "1.3.3", "@img/sharp-libvips-linuxmusl-x64": "1.3.3", "@img/sharp-linux-arm": "0.35.4", "@img/sharp-linux-arm64": "0.35.4", "@img/sharp-linux-ppc64": "0.35.4", "@img/sharp-linux-riscv64": "0.35.4", "@img/sharp-linux-s390x": "0.35.4", "@img/sharp-linux-x64": "0.35.4", "@img/sharp-linuxmusl-arm64": "0.35.4", "@img/sharp-linuxmusl-x64": "0.35.4", "@img/sharp-webcontainers-wasm32": "0.35.4", "@img/sharp-win32-arm64": "0.35.4", "@img/sharp-win32-ia32": "0.35.4", "@img/sharp-win32-x64": "0.35.4" }, "peerDependencies": { "@types/node": "*" }, "optionalPeers": ["@types/node"] }, "sha512-n++8XWcj+jCOr2IOl7h8LbKnGBDY4aPbmprMONBNFdn0ImXqpGVv5zliDs0V9HbmbCQLpbuo2ej9rAoOQTvMDA=="], "sharp": ["sharp@0.35.5", "", { "dependencies": { "@img/colour": "^1.1.0", "detect-libc": "^2.1.2", "semver": "^7.8.5" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.35.5", "@img/sharp-darwin-x64": "0.35.5", "@img/sharp-freebsd-wasm32": "0.35.5", "@img/sharp-libvips-darwin-arm64": "1.3.4", "@img/sharp-libvips-darwin-x64": "1.3.4", "@img/sharp-libvips-linux-arm": "1.3.4", "@img/sharp-libvips-linux-arm64": "1.3.4", "@img/sharp-libvips-linux-ppc64": "1.3.4", "@img/sharp-libvips-linux-riscv64": "1.3.4", "@img/sharp-libvips-linux-s390x": "1.3.4", "@img/sharp-libvips-linux-x64": "1.3.4", "@img/sharp-libvips-linuxmusl-arm64": "1.3.4", "@img/sharp-libvips-linuxmusl-x64": "1.3.4", "@img/sharp-linux-arm": "0.35.5", "@img/sharp-linux-arm64": "0.35.5", "@img/sharp-linux-ppc64": "0.35.5", "@img/sharp-linux-riscv64": "0.35.5", "@img/sharp-linux-s390x": "0.35.5", "@img/sharp-linux-x64": "0.35.5", "@img/sharp-linuxmusl-arm64": "0.35.5", "@img/sharp-linuxmusl-x64": "0.35.5", "@img/sharp-webcontainers-wasm32": "0.35.5", "@img/sharp-win32-arm64": "0.35.5", "@img/sharp-win32-ia32": "0.35.5", "@img/sharp-win32-x64": "0.35.5" }, "peerDependencies": { "@types/node": "*" }, "optionalPeers": ["@types/node"] }, "sha512-Ywn4OnzGukp7CDMrp08RQ50YKmuwG47brZgIVPTvBaaAfQlRlygrRqSrxdCiL9M+LlzLBiJ68IR1QqvzHyjC7g=="],
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
@@ -3076,7 +3065,7 @@
"term-size": ["term-size@2.2.1", "", {}, "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg=="], "term-size": ["term-size@2.2.1", "", {}, "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg=="],
"terser": ["terser@5.16.9", "", { "dependencies": { "@jridgewell/source-map": "^0.3.2", "acorn": "^8.5.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" } }, "sha512-HPa/FdTB9XGI2H1/keLFZHxl6WNvAI4YalHGtDQTlMnJcoqSab1UwL4l1hGEhs6/GmLHBZIg/YgB++jcbzoOEg=="], "terser": ["terser@5.36.0", "", { "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" } }, "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w=="],
"thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="], "thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="],
@@ -3268,7 +3257,7 @@
"yaml": ["yaml@2.8.2", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A=="], "yaml": ["yaml@2.8.2", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A=="],
"yargs": ["yargs@18.0.0", "", { "dependencies": { "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "string-width": "^7.2.0", "y18n": "^5.0.5", "yargs-parser": "^22.0.0" } }, "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg=="], "yargs": ["yargs@18.2.0", "", { "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" } }, "sha512-9OpKOLeaoNFecEp7P6iYbzze/5CqWoH7N3SMs/6y1XF4nMvFMspEGZzJ6uFi9MmQwXhyzqYoSEKO3tvA3Z/o2w=="],
"yargs-parser": ["yargs-parser@22.0.0", "", {}, "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw=="], "yargs-parser": ["yargs-parser@22.0.0", "", {}, "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw=="],
@@ -3278,6 +3267,10 @@
"yauzl-promise": ["yauzl-promise@2.1.3", "", { "dependencies": { "yauzl": "^2.9.1", "yauzl-clone": "^1.0.4" } }, "sha512-A1pf6fzh6eYkK0L4Qp7g9jzJSDrM6nN0bOn5T0IbY4Yo3w+YkWlHFkJP7mzknMXjqusHFHlKsK2N+4OLsK2MRA=="], "yauzl-promise": ["yauzl-promise@2.1.3", "", { "dependencies": { "yauzl": "^2.9.1", "yauzl-clone": "^1.0.4" } }, "sha512-A1pf6fzh6eYkK0L4Qp7g9jzJSDrM6nN0bOn5T0IbY4Yo3w+YkWlHFkJP7mzknMXjqusHFHlKsK2N+4OLsK2MRA=="],
"yocto-spinner": ["yocto-spinner@1.2.2", "", { "dependencies": { "yoctocolors": "^2.1.1" } }, "sha512-DODGl1wJjA/s5pnJFKau9lIYHT81lnhob1i3e1TjxZRxEhWRKl74nTbWE6H5KlkViQQTo/Z29YFdxzTZAMY3ng=="],
"yoctocolors": ["yoctocolors@2.2.0", "", {}, "sha512-xYqdZFUK/VYazNl/oCDYN+3WloWQwMfZxBoiNt6qNyk+xfOdi598muWE42rNZFp1kNOiqW936q5RhUdnpqElSg=="],
"youch": ["youch@4.1.0-beta.10", "", { "dependencies": { "@poppinss/colors": "^4.1.5", "@poppinss/dumper": "^0.6.4", "@speed-highlight/core": "^1.2.7", "cookie": "^1.0.2", "youch-core": "^0.3.3" } }, "sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ=="], "youch": ["youch@4.1.0-beta.10", "", { "dependencies": { "@poppinss/colors": "^4.1.5", "@poppinss/dumper": "^0.6.4", "@speed-highlight/core": "^1.2.7", "cookie": "^1.0.2", "youch-core": "^0.3.3" } }, "sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ=="],
"youch-core": ["youch-core@0.3.3", "", { "dependencies": { "@poppinss/exception": "^1.2.2", "error-stack-parser-es": "^1.0.5" } }, "sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA=="], "youch-core": ["youch-core@0.3.3", "", { "dependencies": { "@poppinss/exception": "^1.2.2", "error-stack-parser-es": "^1.0.5" } }, "sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA=="],
@@ -3370,17 +3363,7 @@
"@cspotcode/source-map-support/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.9", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ=="], "@cspotcode/source-map-support/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.9", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ=="],
"@dotenvx/dotenvx/commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="], "@dotenvx/dotenvx/undici": ["undici@6.29.1", "", {}, "sha512-EvRlUt/QqAEvXdQeRMYUfwOQsfzpDztykrG2owGEE/rBOBoYv9uF39ZzsNDh4lTFHhTr2XOZjKkYgueD12ZmGA=="],
"@dotenvx/dotenvx/execa": ["execa@5.1.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg=="],
"@dotenvx/dotenvx/fdir": ["fdir@6.4.3", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw=="],
"@dotenvx/dotenvx/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
"@dotenvx/dotenvx/picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="],
"@dotenvx/dotenvx/which": ["which@4.0.0", "", { "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg=="],
"@floating-ui/react/@floating-ui/react-dom": ["@floating-ui/react-dom@2.1.7", "", { "dependencies": { "@floating-ui/dom": "^1.7.5" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-0tLRojf/1Go2JgEVm+3Frg9A3IW8bJgKgdO0BN5RkF//ufuz2joZM63Npau2ff3J6lUVYgDSNzNkR+aH3IVfjg=="], "@floating-ui/react/@floating-ui/react-dom": ["@floating-ui/react-dom@2.1.7", "", { "dependencies": { "@floating-ui/dom": "^1.7.5" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-0tLRojf/1Go2JgEVm+3Frg9A3IW8bJgKgdO0BN5RkF//ufuz2joZM63Npau2ff3J6lUVYgDSNzNkR+aH3IVfjg=="],
@@ -3394,11 +3377,11 @@
"@hyperjump/json-schema/uuid": ["uuid@9.0.1", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="], "@hyperjump/json-schema/uuid": ["uuid@9.0.1", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="],
"@img/sharp-freebsd-wasm32/@img/sharp-wasm32": ["@img/sharp-wasm32@0.35.4", "", { "dependencies": { "@emnapi/runtime": "^1.11.3" } }, "sha512-zQnl4Kwp7Q6NHsENtU2T/00Zi+w3AQNwz3+UaTyVBy2FpXrzXzGjndpK61onhZjRtRpQXxCTeqw19bVyXOh7jA=="], "@img/sharp-freebsd-wasm32/@img/sharp-wasm32": ["@img/sharp-wasm32@0.35.5", "", { "dependencies": { "@emnapi/runtime": "^1.11.3" } }, "sha512-Ptsga1su4tQx+LLF1ECS9U6nz5kmrXKo6XVbtR48Ke3ZRxxgaWBu7IDtEe1quo8hiupwm6WFqxVlXaSf7IINGQ=="],
"@img/sharp-wasm32/@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="], "@img/sharp-wasm32/@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="],
"@img/sharp-webcontainers-wasm32/@img/sharp-wasm32": ["@img/sharp-wasm32@0.35.4", "", { "dependencies": { "@emnapi/runtime": "^1.11.3" } }, "sha512-zQnl4Kwp7Q6NHsENtU2T/00Zi+w3AQNwz3+UaTyVBy2FpXrzXzGjndpK61onhZjRtRpQXxCTeqw19bVyXOh7jA=="], "@img/sharp-webcontainers-wasm32/@img/sharp-wasm32": ["@img/sharp-wasm32@0.35.5", "", { "dependencies": { "@emnapi/runtime": "^1.11.3" } }, "sha512-Ptsga1su4tQx+LLF1ECS9U6nz5kmrXKo6XVbtR48Ke3ZRxxgaWBu7IDtEe1quo8hiupwm6WFqxVlXaSf7IINGQ=="],
"@internationalized/date/@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="], "@internationalized/date/@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="],
@@ -3410,6 +3393,8 @@
"@isaacs/cliui/wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="], "@isaacs/cliui/wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="],
"@isaacs/fs-minipass/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
"@jridgewell/source-map/@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.5", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg=="], "@jridgewell/source-map/@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.5", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg=="],
"@jridgewell/source-map/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="], "@jridgewell/source-map/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="],
@@ -3452,10 +3437,12 @@
"@modelcontextprotocol/sdk/zod-to-json-schema": ["zod-to-json-schema@3.24.5", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g=="], "@modelcontextprotocol/sdk/zod-to-json-schema": ["zod-to-json-schema@3.24.5", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g=="],
"@node-minify/core/glob": ["glob@9.3.5", "", { "dependencies": { "fs.realpath": "^1.0.0", "minimatch": "^8.0.2", "minipass": "^4.2.4", "path-scurry": "^1.6.1" } }, "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q=="], "@node-minify/core/glob": ["glob@10.3.3", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^2.0.3", "minimatch": "^9.0.1", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", "path-scurry": "^1.10.1" }, "bin": { "glob": "dist/cjs/src/bin.js" } }, "sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw=="],
"@opennextjs/aws/express": ["express@5.2.1", "", { "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" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="], "@opennextjs/aws/express": ["express@5.2.1", "", { "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" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="],
"@opennextjs/aws/yaml": ["yaml@2.9.1", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw=="],
"@oxc-transform/binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.1", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" } }, "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A=="], "@oxc-transform/binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.1", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" } }, "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A=="],
"@playwright/test/playwright": ["playwright@1.61.1", "", { "dependencies": { "playwright-core": "1.61.1" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": { "playwright": "cli.js" } }, "sha512-DWnY5o3YbLWK4GovuAVwpqL+1VwGNdUGrRr++8j8PtQQzvAVZUIMjKQ90fY689sEJZJBbZVw1rXaOKSTitkzPQ=="], "@playwright/test/playwright": ["playwright@1.61.1", "", { "dependencies": { "playwright-core": "1.61.1" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": { "playwright": "cli.js" } }, "sha512-DWnY5o3YbLWK4GovuAVwpqL+1VwGNdUGrRr++8j8PtQQzvAVZUIMjKQ90fY689sEJZJBbZVw1rXaOKSTitkzPQ=="],
@@ -3596,6 +3583,8 @@
"@ts-morph/common/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], "@ts-morph/common/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"@ts-morph/common/mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="],
"@types/jsonwebtoken/@types/node": ["@types/node@20.16.11", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw=="], "@types/jsonwebtoken/@types/node": ["@types/node@20.16.11", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw=="],
"@types/swagger2openapi/@types/node": ["@types/node@20.16.11", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw=="], "@types/swagger2openapi/@types/node": ["@types/node@20.16.11", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw=="],
@@ -3650,6 +3639,8 @@
"@vercel/python-analysis/fs-extra": ["fs-extra@11.1.1", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ=="], "@vercel/python-analysis/fs-extra": ["fs-extra@11.1.1", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ=="],
"@vercel/python-analysis/minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="],
"@vercel/python-analysis/zod": ["zod@3.22.4", "", {}, "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg=="], "@vercel/python-analysis/zod": ["zod@3.22.4", "", {}, "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg=="],
"@vercel/redwood/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], "@vercel/redwood/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
@@ -3694,7 +3685,7 @@
"body-parser/type-is": ["type-is@1.6.18", "", { "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" } }, "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g=="], "body-parser/type-is": ["type-is@1.6.18", "", { "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" } }, "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g=="],
"brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], "brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
"bun-types/@types/node": ["@types/node@20.12.14", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg=="], "bun-types/@types/node": ["@types/node@20.12.14", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg=="],
@@ -3824,6 +3815,8 @@
"miniflare/undici": ["undici@7.24.4", "", {}, "sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w=="], "miniflare/undici": ["undici@7.24.4", "", {}, "sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w=="],
"minizlib/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
"mlly/pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], "mlly/pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="],
"multimatch/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], "multimatch/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
@@ -3906,7 +3899,7 @@
"swr/use-sync-external-store": ["use-sync-external-store@1.4.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw=="], "swr/use-sync-external-store": ["use-sync-external-store@1.4.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw=="],
"terser/acorn": ["acorn@8.14.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="], "tar/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
"terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], "terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="],
@@ -3924,7 +3917,9 @@
"wrap-ansi/strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="], "wrap-ansi/strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="],
"yargs/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], "yargs/string-width": ["string-width@8.3.0", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ=="],
"youch/cookie": ["cookie@1.0.2", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="],
"zod-to-json-schema/zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="], "zod-to-json-schema/zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="],
@@ -4018,14 +4013,6 @@
"@cspotcode/source-map-support/@jridgewell/trace-mapping/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="], "@cspotcode/source-map-support/@jridgewell/trace-mapping/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="],
"@dotenvx/dotenvx/execa/get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="],
"@dotenvx/dotenvx/execa/human-signals": ["human-signals@2.1.0", "", {}, "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="],
"@dotenvx/dotenvx/execa/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
"@dotenvx/dotenvx/which/isexe": ["isexe@3.1.1", "", {}, "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ=="],
"@floating-ui/react/@floating-ui/react-dom/@floating-ui/dom": ["@floating-ui/dom@1.7.5", "", { "dependencies": { "@floating-ui/core": "^1.7.4", "@floating-ui/utils": "^0.2.10" } }, "sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg=="], "@floating-ui/react/@floating-ui/react-dom/@floating-ui/dom": ["@floating-ui/dom@1.7.5", "", { "dependencies": { "@floating-ui/core": "^1.7.4", "@floating-ui/utils": "^0.2.10" } }, "sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg=="],
"@floating-ui/vue/@floating-ui/dom/@floating-ui/core": ["@floating-ui/core@1.7.3", "", { "dependencies": { "@floating-ui/utils": "^0.2.10" } }, "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w=="], "@floating-ui/vue/@floating-ui/dom/@floating-ui/core": ["@floating-ui/core@1.7.3", "", { "dependencies": { "@floating-ui/utils": "^0.2.10" } }, "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w=="],
@@ -4050,9 +4037,7 @@
"@modelcontextprotocol/sdk/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], "@modelcontextprotocol/sdk/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
"@node-minify/core/glob/minimatch": ["minimatch@8.0.4", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA=="], "@node-minify/core/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"@node-minify/core/glob/minipass": ["minipass@4.2.8", "", {}, "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ=="],
"@node-minify/core/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], "@node-minify/core/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
@@ -4162,12 +4147,14 @@
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime/@tybys/wasm-util": ["@tybys/wasm-util@0.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ=="], "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime/@tybys/wasm-util": ["@tybys/wasm-util@0.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ=="],
"@tailwindcss/oxide/tar/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
"@tailwindcss/oxide/tar/minizlib": ["minizlib@3.0.1", "", { "dependencies": { "minipass": "^7.0.4", "rimraf": "^5.0.5" } }, "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg=="], "@tailwindcss/oxide/tar/minizlib": ["minizlib@3.0.1", "", { "dependencies": { "minipass": "^7.0.4", "rimraf": "^5.0.5" } }, "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg=="],
"@tailwindcss/oxide/tar/mkdirp": ["mkdirp@3.0.1", "", { "bin": { "mkdirp": "dist/cjs/src/bin.js" } }, "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg=="],
"@tailwindcss/postcss/postcss/nanoid": ["nanoid@3.3.8", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w=="], "@tailwindcss/postcss/postcss/nanoid": ["nanoid@3.3.8", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w=="],
"@ts-morph/common/minimatch/brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="],
"@types/jsonwebtoken/@types/node/undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="], "@types/jsonwebtoken/@types/node/undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="],
"@types/swagger2openapi/@types/node/undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="], "@types/swagger2openapi/@types/node/undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="],
@@ -4226,6 +4213,10 @@
"@vercel/nft/glob/minimatch": ["minimatch@10.1.2", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.1" } }, "sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw=="], "@vercel/nft/glob/minimatch": ["minimatch@10.1.2", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.1" } }, "sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw=="],
"@vercel/nft/glob/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
"@vercel/nft/glob/path-scurry": ["path-scurry@2.0.0", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg=="],
"@vercel/node/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], "@vercel/node/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
"@vercel/python-analysis/fs-extra/jsonfile": ["jsonfile@6.1.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ=="], "@vercel/python-analysis/fs-extra/jsonfile": ["jsonfile@6.1.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ=="],
@@ -4272,6 +4263,8 @@
"cliui/string-width/emoji-regex": ["emoji-regex@10.4.0", "", {}, "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw=="], "cliui/string-width/emoji-regex": ["emoji-regex@10.4.0", "", {}, "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw=="],
"cliui/string-width/get-east-asian-width": ["get-east-asian-width@1.3.0", "", {}, "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ=="],
"cliui/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="], "cliui/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="],
"cloudflare/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], "cloudflare/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
@@ -4358,6 +4351,8 @@
"miniflare/sharp/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], "miniflare/sharp/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
"multimatch/minimatch/brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="],
"pino-abstract-transport/readable-stream/string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="], "pino-abstract-transport/readable-stream/string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="],
"radix-vue/@floating-ui/dom/@floating-ui/core": ["@floating-ui/core@1.6.8", "", { "dependencies": { "@floating-ui/utils": "^0.2.8" } }, "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA=="], "radix-vue/@floating-ui/dom/@floating-ui/core": ["@floating-ui/core@1.6.8", "", { "dependencies": { "@floating-ui/utils": "^0.2.8" } }, "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA=="],
@@ -4382,6 +4377,8 @@
"rimraf/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], "rimraf/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"rimraf/glob/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
"rimraf/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], "rimraf/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
"side-channel-map/get-intrinsic/es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], "side-channel-map/get-intrinsic/es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
@@ -4404,11 +4401,11 @@
"wrap-ansi/string-width/emoji-regex": ["emoji-regex@10.4.0", "", {}, "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw=="], "wrap-ansi/string-width/emoji-regex": ["emoji-regex@10.4.0", "", {}, "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw=="],
"wrap-ansi/string-width/get-east-asian-width": ["get-east-asian-width@1.3.0", "", {}, "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ=="],
"wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="], "wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="],
"yargs/string-width/emoji-regex": ["emoji-regex@10.4.0", "", {}, "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw=="], "yargs/string-width/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="],
"yargs/string-width/strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="],
"@argos-ci/core/sharp/@img/sharp-freebsd-wasm32/@img/sharp-wasm32": ["@img/sharp-wasm32@0.35.3", "", { "dependencies": { "@emnapi/runtime": "^1.11.1" } }, "sha512-cZ0XkcYGpHZkqW6iCkqTcmUC0CD9DhD5d/qeZlZkfRBn6GnHniZXLUo5+9xw8Iv76YE6LQFN9YNBlKREcCG76w=="], "@argos-ci/core/sharp/@img/sharp-freebsd-wasm32/@img/sharp-wasm32": ["@img/sharp-wasm32@0.35.3", "", { "dependencies": { "@emnapi/runtime": "^1.11.1" } }, "sha512-cZ0XkcYGpHZkqW6iCkqTcmUC0CD9DhD5d/qeZlZkfRBn6GnHniZXLUo5+9xw8Iv76YE6LQFN9YNBlKREcCG76w=="],
@@ -4470,12 +4467,16 @@
"@scalar/workspace-store/@scalar/openapi-upgrader/@scalar/openapi-types/zod": ["zod@4.1.11", "", {}, "sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg=="], "@scalar/workspace-store/@scalar/openapi-upgrader/@scalar/openapi-types/zod": ["zod@4.1.11", "", {}, "sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg=="],
"@ts-morph/common/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"@vercel/backends/rolldown/@rolldown/binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.1", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" } }, "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A=="], "@vercel/backends/rolldown/@rolldown/binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.1", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" } }, "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A=="],
"@vercel/fun/semver/lru-cache/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], "@vercel/fun/semver/lru-cache/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="],
"@vercel/nft/glob/minimatch/@isaacs/brace-expansion": ["@isaacs/brace-expansion@5.0.1", "", { "dependencies": { "@isaacs/balanced-match": "^4.0.1" } }, "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ=="], "@vercel/nft/glob/minimatch/@isaacs/brace-expansion": ["@isaacs/brace-expansion@5.0.1", "", { "dependencies": { "@isaacs/balanced-match": "^4.0.1" } }, "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ=="],
"@vercel/nft/glob/path-scurry/lru-cache": ["lru-cache@11.0.2", "", {}, "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA=="],
"@zenuml/core/tailwindcss/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], "@zenuml/core/tailwindcss/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
"@zenuml/core/tailwindcss/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], "@zenuml/core/tailwindcss/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
@@ -4492,11 +4493,13 @@
"micro/raw-body/http-errors/toidentifier": ["toidentifier@1.0.0", "", {}, "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="], "micro/raw-body/http-errors/toidentifier": ["toidentifier@1.0.0", "", {}, "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="],
"multimatch/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"rimraf/glob/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], "rimraf/glob/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
"rimraf/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], "rimraf/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
"yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="], "yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@6.4.0", "", {}, "sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw=="],
"@argos-ci/core/sharp/@img/sharp-freebsd-wasm32/@img/sharp-wasm32/@emnapi/runtime": ["@emnapi/runtime@1.11.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA=="], "@argos-ci/core/sharp/@img/sharp-freebsd-wasm32/@img/sharp-wasm32/@emnapi/runtime": ["@emnapi/runtime@1.11.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA=="],
+3 -3
View File
@@ -20,8 +20,8 @@
"@gitbook/react-openapi": "workspace:*", "@gitbook/react-openapi": "workspace:*",
"@mermaid-js/mermaid-zenuml": "^0.2.2", "@mermaid-js/mermaid-zenuml": "^0.2.2",
"@modelcontextprotocol/sdk": "1.17.5", "@modelcontextprotocol/sdk": "1.17.5",
"@opennextjs/aws": "4.1.7", "@opennextjs/aws": "4.1.11",
"@opennextjs/cloudflare": "1.20.8", "@opennextjs/cloudflare": "1.20.12",
"@panzoom/panzoom": "^4.6.1", "@panzoom/panzoom": "^4.6.1",
"@sindresorhus/fnv1a": "^3.1.0", "@sindresorhus/fnv1a": "^3.1.0",
"@tailwindcss/container-queries": "^0.1.1", "@tailwindcss/container-queries": "^0.1.1",
@@ -51,7 +51,7 @@
"micromark-extension-gfm": "^3.0.0", "micromark-extension-gfm": "^3.0.0",
"motion": "^12.23.24", "motion": "^12.23.24",
"negotiator": "^1.0.0", "negotiator": "^1.0.0",
"next": "^16.3.8", "next": "^16.4.2",
"next-themes": "^0.4.6", "next-themes": "^0.4.6",
"nuqs": "^2.2.3", "nuqs": "^2.2.3",
"object-hash": "^3.0.0", "object-hash": "^3.0.0",
@@ -1,7 +1,6 @@
'use client'; 'use client';
import type { Assistant } from '../AI'; import type { Assistant } from '../AI';
import { useIsMobile } from '../hooks/useIsMobile'; import { useIsMobile } from '../hooks/useIsMobile';
import { useTrackEvent } from '../Insights';
import { Button } from '../primitives'; import { Button } from '../primitives';
import { KeyboardShortcut } from '../primitives/KeyboardShortcut'; import { KeyboardShortcut } from '../primitives/KeyboardShortcut';
import { useLanguage } from '@/intl/client'; import { useLanguage } from '@/intl/client';
@@ -19,7 +18,6 @@ export function AIChatButton(props: {
}) { }) {
const { assistant, showLabel = true, withShortcut = true } = props; const { assistant, showLabel = true, withShortcut = true } = props;
const language = useLanguage(); const language = useLanguage();
const trackEvent = useTrackEvent();
const isMobile = useIsMobile(MOBILE_BREAKPOINT, '[data-gb-header-content]'); const isMobile = useIsMobile(MOBILE_BREAKPOINT, '[data-gb-header-content]');
return ( return (
@@ -41,12 +39,7 @@ export function AIChatButton(props: {
</div> </div>
} }
aria-label={tString(language, 'ai_chat_ask', assistant.label)} aria-label={tString(language, 'ai_chat_ask', assistant.label)}
onClick={() => { onClick={() => assistant.open(undefined, 'site')}
if (assistant.id === 'gitbook-assistant') {
trackEvent({ type: 'ask_trigger_click', trigger: 'site' });
}
assistant.open(undefined, 'site');
}}
> >
{showLabel ? t(language, 'ask') : null} {showLabel ? t(language, 'ask') : null}
</Button> </Button>
@@ -6,7 +6,6 @@ import { createPortal } from 'react-dom';
import { AIChatIcon } from '../AIChatIcon'; import { AIChatIcon } from '../AIChatIcon';
import { useAIChatController, useAIConfig } from '@/components/AI'; import { useAIChatController, useAIConfig } from '@/components/AI';
import { useTrackEvent } from '@/components/Insights';
import { Button } from '@/components/primitives'; import { Button } from '@/components/primitives';
import { isAIChatEnabled } from '@/components/utils/isAIChatEnabled'; import { isAIChatEnabled } from '@/components/utils/isAIChatEnabled';
import { t, tString, useLanguage } from '@/intl/client'; import { t, tString, useLanguage } from '@/intl/client';
@@ -25,7 +24,6 @@ export function AskAIParagraphButton() {
const config = useAIConfig(); const config = useAIConfig();
const language = useLanguage(); const language = useLanguage();
const chatController = useAIChatController(); const chatController = useAIChatController();
const trackEvent = useTrackEvent();
const [target, setTarget] = React.useState<HTMLElement | null>(null); const [target, setTarget] = React.useState<HTMLElement | null>(null);
const enabled = isAIChatEnabled(config.aiMode); const enabled = isAIChatEnabled(config.aiMode);
@@ -54,7 +52,6 @@ export function AskAIParagraphButton() {
} }
const onClick = () => { const onClick = () => {
trackEvent({ type: 'ask_trigger_click', trigger: 'hover' });
const text = getParagraphText(target).trim(); const text = getParagraphText(target).trim();
if (!text) { if (!text) {
return; return;
@@ -10,7 +10,6 @@ import { useStableTextSelection } from './useStableTextSelection';
import { useAIChatController, useAIConfig } from '@/components/AI'; import { useAIChatController, useAIConfig } from '@/components/AI';
import { useIsMobile } from '@/components/hooks/useIsMobile'; import { useIsMobile } from '@/components/hooks/useIsMobile';
import { useIsMounted } from '@/components/hooks/useIsMounted'; import { useIsMounted } from '@/components/hooks/useIsMounted';
import { useTrackEvent } from '@/components/Insights';
import { Button } from '@/components/primitives'; import { Button } from '@/components/primitives';
import { isAIChatEnabled } from '@/components/utils/isAIChatEnabled'; import { isAIChatEnabled } from '@/components/utils/isAIChatEnabled';
import { t, useLanguage } from '@/intl/client'; import { t, useLanguage } from '@/intl/client';
@@ -28,7 +27,6 @@ export function AskAITextSelection() {
const config = useAIConfig(); const config = useAIConfig();
const language = useLanguage(); const language = useLanguage();
const chatController = useAIChatController(); const chatController = useAIChatController();
const trackEvent = useTrackEvent();
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const isMounted = useIsMounted(); const isMounted = useIsMounted();
@@ -73,7 +71,6 @@ export function AskAITextSelection() {
}, [selection]); }, [selection]);
const onClick = () => { const onClick = () => {
trackEvent({ type: 'ask_trigger_click', trigger: 'selection' });
if (!selection) { if (!selection) {
return; return;
} }
@@ -15,6 +15,7 @@ import {
ToolbarBody, ToolbarBody,
ToolbarButton, ToolbarButton,
ToolbarButtonGroup, ToolbarButtonGroup,
type ToolbarButtonProps,
ToolbarSubtitle, ToolbarSubtitle,
ToolbarTitle, ToolbarTitle,
} from './Toolbar'; } from './Toolbar';
@@ -136,21 +137,14 @@ function ChangeRequestToolbar(props: ToolbarViewProps) {
<Toolbar minified={minified} onMinifiedChange={onMinifiedChange}> <Toolbar minified={minified} onMinifiedChange={onMinifiedChange}>
<ToolbarBody> <ToolbarBody>
<ToolbarTitle <ToolbarTitle
prefix={`#${changeRequest.number}`} prefix={`Change #${changeRequest.number}:`}
prefixLabel={`Change request #${changeRequest.number}`} suffix={`${changeRequest.subject || 'Untitled'}`}
suffix={changeRequest.subject || 'Untitled'}
/> />
<ToolbarSubtitle <ToolbarSubtitle
subtitle={ subtitle={
<> <>
<ToolbarDate value={changeRequest.updatedAt} />{' '} <ToolbarDate value={changeRequest.updatedAt} />{' '}
<motion.span <motion.span layout="position">by {author}</motion.span>
layout="position"
title={author}
className="min-w-0 truncate"
>
by {author}
</motion.span>
</> </>
} }
/> />
@@ -345,8 +339,12 @@ function ToolbarActions(props: { children: React.ReactNode }) {
); );
} }
function EditPageButton(props: { href: string; siteId: string }) { function EditPageButton(props: {
const { href, siteId } = props; href: string;
siteId: string;
motionValues?: ToolbarButtonProps['motionValues'];
}) {
const { href, motionValues, siteId } = props;
const pagePath = useCurrentPagePath(); const pagePath = useCurrentPagePath();
return ( return (
@@ -358,6 +356,7 @@ function EditPageButton(props: { href: string; siteId: string }) {
buttonId: 'edit', buttonId: 'edit',
})} })}
icon="pen-to-square" icon="pen-to-square"
motionValues={motionValues}
/> />
); );
} }
@@ -1,6 +1,5 @@
.svgLogo { .svgLogo {
/* The toolbar is always dark, so the logo is always light. */ --logo-fill: var(--color-neutral-100);
--logo-fill: rgb(255 255 255 / 0.92);
--seg-A-color: #2782c4; --seg-A-color: #2782c4;
--seg-B-color: #43b7f2; --seg-B-color: #43b7f2;
--seg-C-color: #8be2ff; --seg-C-color: #8be2ff;
@@ -11,14 +11,8 @@ export const AnimatedLogo: React.FC<AnimatedLogoProps> = (props) => {
const { shouldAnimate = true } = props; const { shouldAnimate = true } = props;
return ( return (
// Light even without the CSS module, which loads with the lazy toolbar chunk and can be
// missing (e.g. after a hot reload): an SVG path without a fill renders black.
<svg <svg
className={tcls( className={tcls(styles.svgLogo, shouldAnimate ? undefined : styles.static)}
'text-white/90',
styles.svgLogo,
shouldAnimate ? undefined : styles.static
)}
width="28" width="28"
height="28" height="28"
viewBox="0 0 28 28" viewBox="0 0 28 28"
@@ -28,7 +22,6 @@ export const AnimatedLogo: React.FC<AnimatedLogoProps> = (props) => {
<path <path
d={dPath} d={dPath}
transform="translate(14,14) scale(0.4)" transform="translate(14,14) scale(0.4)"
fill="currentColor"
strokeWidth={3} strokeWidth={3}
pathLength={1} pathLength={1}
strokeLinecap="round" strokeLinecap="round"
@@ -6,9 +6,8 @@ import type { SVGProps } from 'react';
import { Icon, type IconName, IconStyle } from '@gitbook/icons'; import { Icon, type IconName, IconStyle } from '@gitbook/icons';
import { DropdownMenu, DropdownMenuItem, DropdownMenuSeparator } from '../primitives'; import { DropdownMenu, DropdownMenuItem, DropdownMenuSeparator } from '../primitives';
import { useToolbarSlot } from './Toolbar'; import type { ToolbarButtonProps } from './Toolbar';
import type { MinimalChangedPage, MinimalChangedPages } from './types'; import type { MinimalChangedPage, MinimalChangedPages } from './types';
import { TOOLTIP_OFFSET } from './useMagnificationEffect';
import { tcls } from '@/lib/tailwind'; import { tcls } from '@/lib/tailwind';
const STATUS_ICON_STYLES: Record< const STATUS_ICON_STYLES: Record<
@@ -43,10 +42,12 @@ const STATUS_ICON_CHIP_CLASS = 'flex size-5 shrink-0 items-center justify-center
/** /**
* A button that opens a popover with quick links to the _changed_ pages. * A button that opens a popover with quick links to the _changed_ pages.
*/ */
export function ChangedPagesButton(props: { changedPages: MinimalChangedPages | null }) { export function ChangedPagesButton(props: {
const { changedPages } = props; changedPages: MinimalChangedPages | null;
motionValues?: ToolbarButtonProps['motionValues'];
}) {
const { changedPages, motionValues } = props;
const reduceMotion = useReducedMotion(); const reduceMotion = useReducedMotion();
const slot = useToolbarSlot();
if (!changedPages?.pages.length) { if (!changedPages?.pages.length) {
return null; return null;
@@ -58,19 +59,30 @@ export function ChangedPagesButton(props: { changedPages: MinimalChangedPages |
}`; }`;
const trigger = ( const trigger = (
<motion.button <button
type="button" type="button"
aria-label="View changed pages" aria-label="View changed pages"
style={
reduceMotion || !slot
? undefined
: { scale: slot.scale, x: slot.x, transformOrigin: 'bottom center' }
}
className="relative size-8 cursor-pointer border-0 bg-transparent p-0" className="relative size-8 cursor-pointer border-0 bg-transparent p-0"
> >
<span <motion.span
aria-hidden="true" aria-hidden="true"
style={
reduceMotion
? undefined
: {
scale: motionValues?.scale,
x: motionValues?.x,
transformOrigin: 'bottom center',
zIndex: motionValues?.scale ? 10 : 'auto',
}
}
transition={{
type: 'spring',
stiffness: 400,
damping: 30,
}}
className={tcls( className={tcls(
'toolbar-button',
'relative flex size-8 items-center justify-center gap-1 truncate rounded-full text-sm transition-colors', 'relative flex size-8 items-center justify-center gap-1 truncate rounded-full text-sm transition-colors',
'text-tint-7 hover:text-tint-1', 'text-tint-7 hover:text-tint-1',
'dark:text-tint-12', 'dark:text-tint-12',
@@ -79,18 +91,14 @@ export function ChangedPagesButton(props: { changedPages: MinimalChangedPages |
)} )}
> >
<DiffIcon className="size-4 shrink-0" /> <DiffIcon className="size-4 shrink-0" />
</span> </motion.span>
</motion.button> </button>
); );
return ( return (
<DropdownMenu <DropdownMenu
button={trigger} button={trigger}
buttonTooltip="View changed pages" buttonTooltip="View changed pages"
// Like the other toolbar buttons: against the unscaled slot, with room to magnify.
buttonTooltipProps={
slot ? { anchor: slot.anchorRef, sideOffset: TOOLTIP_OFFSET } : undefined
}
side="top" side="top"
align="end" align="end"
sideOffset={12} sideOffset={12}
@@ -5,7 +5,7 @@ import { useOnClickOutside } from 'usehooks-ts';
import { Icon, type IconName, IconStyle } from '@gitbook/icons'; import { Icon, type IconName, IconStyle } from '@gitbook/icons';
import { ToolbarButton, useToolbarSlot } from './Toolbar'; import { ToolbarButton, type ToolbarButtonProps } from './Toolbar';
import styles from './Toolbar.module.css'; import styles from './Toolbar.module.css';
import { useToolbarControls } from './ToolbarControlsContext'; import { useToolbarControls } from './ToolbarControlsContext';
import { tcls } from '@/lib/tailwind'; import { tcls } from '@/lib/tailwind';
@@ -26,11 +26,15 @@ const ARC_PARAMS = {
offsetAnchorY: 40, offsetAnchorY: 40,
} as const; } as const;
interface HideToolbarButtonProps {
motionValues?: ToolbarButtonProps['motionValues'];
}
/** /**
* Hide menu trigger. Expands a macOS Dock-like submenu with 3 labeled actions. * Hide menu trigger. Expands a macOS Dock-like submenu with 3 labeled actions.
*/ */
export function HideToolbarButton() { export function HideToolbarButton(props: HideToolbarButtonProps) {
const slot = useToolbarSlot(); const { motionValues } = props;
const [open, setOpen] = React.useState(false); const [open, setOpen] = React.useState(false);
const [closing, setClosing] = React.useState(false); const [closing, setClosing] = React.useState(false);
const controls = useToolbarControls(); const controls = useToolbarControls();
@@ -110,8 +114,11 @@ export function HideToolbarButton() {
: null, : null,
].filter(Boolean) as ArcMenuItem[]; ].filter(Boolean) as ArcMenuItem[];
// The arc follows the button's push, but not its scale. const sharedMotionStyle = motionValues
const sharedMotionStyle = slot ? { x: slot.x } : undefined; ? {
x: motionValues.x,
}
: undefined;
return ( return (
<ToolbarButton <ToolbarButton
@@ -129,6 +136,7 @@ export function HideToolbarButton() {
setOpen(true); setOpen(true);
} }
}} }}
motionValues={motionValues}
icon="gear" icon="gear"
> >
{/* Expanding arc menu */} {/* Expanding arc menu */}
@@ -1,13 +1,16 @@
'use client'; 'use client';
import React from 'react'; import React from 'react';
import { ToolbarButton } from './Toolbar'; import { ToolbarButton, type ToolbarButtonProps } from './Toolbar';
/** /**
* Button to refresh the page if the content has been updated. * Button to refresh the page if the content has been updated.
*/ */
export function RefreshContentButton(props: { refreshForUpdates: () => Promise<void> }) { export function RefreshContentButton(props: {
const { refreshForUpdates } = props; refreshForUpdates: () => Promise<void>;
motionValues?: ToolbarButtonProps['motionValues'];
}) {
const { refreshForUpdates, motionValues } = props;
const [loading, setLoading] = React.useState(false); const [loading, setLoading] = React.useState(false);
@@ -31,6 +34,7 @@ export function RefreshContentButton(props: { refreshForUpdates: () => Promise<v
refresh(); refresh();
}} }}
disabled={loading} disabled={loading}
motionValues={motionValues}
icon="rotate" icon="rotate"
iconClassName={loading ? 'animate-spin' : undefined} iconClassName={loading ? 'animate-spin' : undefined}
/> />
@@ -1,6 +1,12 @@
'use client'; 'use client';
import { type MotionValue, motion, useReducedMotion, useSpring } from 'motion/react'; import {
import React from 'react'; AnimatePresence,
type MotionValue,
motion,
useReducedMotion,
useSpring,
} from 'motion/react';
import React, { isValidElement } from 'react';
import { Icon, type IconName, IconStyle } from '@gitbook/icons'; import { Icon, type IconName, IconStyle } from '@gitbook/icons';
@@ -9,7 +15,7 @@ import { AnimatedLogo } from './AnimatedLogo';
import { useToolbarControls } from './ToolbarControlsContext'; import { useToolbarControls } from './ToolbarControlsContext';
import { ToolbarVisibilityHint } from './ToolbarVisibilityHint'; import { ToolbarVisibilityHint } from './ToolbarVisibilityHint';
import { getCopyVariants, toolbarEasings } from './transitions'; import { getCopyVariants, toolbarEasings } from './transitions';
import { TOOLTIP_OFFSET, useMagnificationEffect } from './useMagnificationEffect'; import { useMagnificationEffect } from './useMagnificationEffect';
import { tcls } from '@/lib/tailwind'; import { tcls } from '@/lib/tailwind';
const DURATION_LOGO_APPEARANCE = 2000; const DURATION_LOGO_APPEARANCE = 2000;
@@ -102,93 +108,63 @@ export function Toolbar(props: ToolbarProps) {
return ( return (
<motion.div <motion.div
data-testid="admin-toolbar" data-testid="admin-toolbar"
// Centered with `inset-x-0 mx-auto`: at `left-1/2` it could only grow to half the viewport, className="fixed bottom-5 left-1/2 z-40 w-auto max-w-xl -translate-x-1/2 transform px-4"
// which pushed the logo out of the pill.
className="fixed inset-x-0 bottom-5 z-40 mx-auto w-fit max-w-xl px-4"
> >
<ToolbarVisibilityHint show={showHint} /> <ToolbarVisibilityHint show={showHint} />
<motion.div <AnimatePresence mode="wait">
onClick={() => {
if (minified) {
setShouldAnimateLogo(false);
onMinifiedChange(false);
}
}}
// Only minifying and expanding animate: content width changes (e.g. the date
// format) would otherwise run a bouncy scale animation that stretches the content.
layout
layoutDependency={minified}
onLayoutAnimationComplete={() => {
if (!minified) {
setShowHint(true);
}
}}
transition={toolbarEasings.spring}
className={tcls(
minified ? 'cursor-pointer' : 'pr-2 pl-3.5',
'relative',
'flex',
'items-center',
'justify-center',
'min-h-11',
'min-w-12',
'h-12',
'py-2',
'origin-center',
'border-[0.5px] border-neutral-5 border-solid dark:border-neutral-8',
'bg-[var(--toolbar-bg)]'
)}
style={PILL_STYLE}
>
{/* Logo — double-click to minimize */}
<motion.div <motion.div
layout onClick={() => {
layoutDependency={minified} if (minified) {
onDoubleClick={(e) => { setShouldAnimateLogo(false);
if (minified) return; onMinifiedChange(false);
e.stopPropagation(); }
window.getSelection()?.removeAllRanges();
onMinifiedChange(true);
}} }}
layout
onLayoutAnimationComplete={() => {
if (!minified) {
setShowHint(true);
}
}}
transition={toolbarEasings.spring}
className={tcls(
minified ? 'cursor-pointer' : 'pr-2 pl-3.5',
'relative',
'flex',
'items-center',
'justify-center',
'min-h-11',
'min-w-12',
'h-12',
'py-2',
'origin-center',
'border-[0.5px] border-neutral-5 border-solid dark:border-neutral-8',
'bg-[var(--toolbar-bg)]'
)}
style={PILL_STYLE}
> >
<AnimatedLogo shouldAnimate={shouldAnimateLogo} /> {/* Logo — double-click to minimize */}
</motion.div>
{/* A layout child, so it's counter-scaled while the pill expands. */}
{!minified ? (
<motion.div <motion.div
layout layout
layoutDependency={minified} onDoubleClick={(e) => {
className="flex min-w-0 items-center" if (minified) return;
e.stopPropagation();
window.getSelection()?.removeAllRanges();
onMinifiedChange(true);
}}
> >
{children} <AnimatedLogo shouldAnimate={shouldAnimateLogo} />
</motion.div> </motion.div>
) : null}
</motion.div> {!minified ? children : null}
</motion.div>
</AnimatePresence>
</motion.div> </motion.div>
); );
} }
export function ToolbarBody(props: { children: React.ReactNode }) { export function ToolbarBody(props: { children: React.ReactNode }) {
// Shrinks so a long title truncates, but keeps room for the longest date format. return <div className="flex flex-col items-start px-3">{props.children}</div>;
return <div className="flex min-w-40 flex-col items-start px-3">{props.children}</div>;
}
const MAGNIFICATION_SPRING = { stiffness: 400, damping: 30 };
/** A button's magnification, and the unscaled box to place its tooltip against. */
type ToolbarSlot = {
scale: MotionValue<number>;
x: MotionValue<number>;
anchorRef: React.RefObject<HTMLDivElement | null>;
};
const ToolbarSlotContext = React.createContext<ToolbarSlot | null>(null);
/** The magnification of the toolbar button group slot this is rendered in, if any. */
export function useToolbarSlot() {
return React.useContext(ToolbarSlotContext);
} }
export function ToolbarButtonGroup(props: { children: React.ReactNode }) { export function ToolbarButtonGroup(props: { children: React.ReactNode }) {
@@ -196,8 +172,8 @@ export function ToolbarButtonGroup(props: { children: React.ReactNode }) {
const containerRef = React.useRef<HTMLDivElement>(null); const containerRef = React.useRef<HTMLDivElement>(null);
const buttonChildren = React.Children.toArray(children).filter((child) => !!child); const buttonChildren = React.Children.toArray(children).filter((child) => !!child);
const { motionValues } = useMagnificationEffect({ const { buttonMotionValues } = useMagnificationEffect({
slotCount: buttonChildren.length, childrenCount: buttonChildren.length,
containerRef, containerRef,
}); });
@@ -207,48 +183,28 @@ export function ToolbarButtonGroup(props: { children: React.ReactNode }) {
variants={toolbarEasings.parent} variants={toolbarEasings.parent}
initial="hidden" initial="hidden"
animate="show" animate="show"
// `relative`: the magnification measures slots by their `offsetLeft` in here. className="flex items-center gap-1 overflow-visible pl-4 pr-2"
className="relative flex items-center gap-1 overflow-visible pl-4 pr-2"
> >
{buttonChildren.map((child, index) => { {buttonChildren.map((child, index) => {
const values = motionValues[index]; const childEl = child as React.ReactElement;
return values ? ( const childKey = childEl.key ?? `toolbar-button-${index}`;
<ToolbarSlot return (
key={React.isValidElement(child) && child.key ? child.key : index} <ToolbarButtonWrapper
scale={values.scale} key={childKey}
x={values.x} child={childEl}
> rawMotionValues={buttonMotionValues[index]}
{child} />
</ToolbarSlot> );
) : null;
})} })}
</motion.div> </motion.div>
); );
} }
function ToolbarSlot(props: {
scale: MotionValue<number>;
x: MotionValue<number>;
children: React.ReactNode;
}) {
const anchorRef = React.useRef<HTMLDivElement>(null);
const scale = useSpring(props.scale, MAGNIFICATION_SPRING);
const x = useSpring(props.x, MAGNIFICATION_SPRING);
const slot = React.useMemo(() => ({ scale, x, anchorRef }), [scale, x]);
return (
<motion.div
ref={anchorRef}
variants={toolbarEasings.staggeringChild}
// Buttons can render null (e.g. no changed pages): don't leave a gap in the group.
className="relative empty:hidden"
>
<ToolbarSlotContext.Provider value={slot}>{props.children}</ToolbarSlotContext.Provider>
</motion.div>
);
}
export interface ToolbarButtonProps extends Omit<React.HTMLProps<HTMLAnchorElement>, 'title'> { export interface ToolbarButtonProps extends Omit<React.HTMLProps<HTMLAnchorElement>, 'title'> {
motionValues?: {
scale: MotionValue<number>;
x: MotionValue<number>;
};
icon: IconName; icon: IconName;
iconClassName?: string; iconClassName?: string;
title?: React.ReactNode; title?: React.ReactNode;
@@ -256,10 +212,19 @@ export interface ToolbarButtonProps extends Omit<React.HTMLProps<HTMLAnchorEleme
} }
export const ToolbarButton = React.forwardRef<HTMLDivElement, ToolbarButtonProps>((props, ref) => { export const ToolbarButton = React.forwardRef<HTMLDivElement, ToolbarButtonProps>((props, ref) => {
const { title, disabled, className, style, href, onClick, icon, iconClassName, children } = const {
props; title,
disabled,
motionValues,
className,
style,
href,
onClick,
icon,
iconClassName,
children,
} = props;
const reduceMotion = useReducedMotion(); const reduceMotion = useReducedMotion();
const slot = useToolbarSlot();
const anchor = ( const anchor = (
<motion.a <motion.a
@@ -268,11 +233,23 @@ export const ToolbarButton = React.forwardRef<HTMLDivElement, ToolbarButtonProps
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
style={ style={
reduceMotion || !slot reduceMotion
? style ? undefined
: { scale: slot.scale, x: slot.x, transformOrigin: 'bottom center', ...style } : {
scale: motionValues?.scale,
x: motionValues?.x,
transformOrigin: 'bottom center',
zIndex: motionValues?.scale ? 10 : 'auto',
...style,
}
} }
transition={{
type: 'spring',
stiffness: 400,
damping: 30,
}}
className={tcls( className={tcls(
'toolbar-button',
className, className,
'relative flex size-8 cursor-pointer items-center justify-center gap-1 truncate rounded-full text-sm transition-colors', 'relative flex size-8 cursor-pointer items-center justify-center gap-1 truncate rounded-full text-sm transition-colors',
'text-tint-7 hover:text-tint-1', 'text-tint-7 hover:text-tint-1',
@@ -285,68 +262,75 @@ export const ToolbarButton = React.forwardRef<HTMLDivElement, ToolbarButtonProps
<Icon <Icon
icon={icon} icon={icon}
iconStyle={IconStyle.Solid} iconStyle={IconStyle.Solid}
className={tcls('size-3.5 shrink-0', iconClassName)} className={tcls('size-3.5 shrink-0 group-hover:scale-110', iconClassName)}
/> />
</motion.a> </motion.a>
); );
return ( return (
<div className="relative" ref={ref}> <motion.div variants={toolbarEasings.staggeringChild} className="relative" ref={ref}>
{children ? children : null} {children ? children : null}
{/* Anchored to the unscaled slot with room for full magnification, so the gap doesn't {title ? <Tooltip label={title}>{anchor}</Tooltip> : anchor}
depend on how far the spring has grown when the tooltip opens. */} </motion.div>
{title ? (
<Tooltip
label={title}
anchor={slot?.anchorRef}
sideOffset={slot ? TOOLTIP_OFFSET : 4}
>
{anchor}
</Tooltip>
) : (
anchor
)}
</div>
); );
}); });
ToolbarButton.displayName = 'ToolbarButton'; ToolbarButton.displayName = 'ToolbarButton';
export function ToolbarTitle(props: { function ToolbarButtonWrapper(props: {
prefix?: string; child: React.ReactElement;
/** What a short prefix stands for, e.g. "Change request #54" for "#54". */ rawMotionValues?: { scale: MotionValue<number>; x: MotionValue<number> };
prefixLabel?: string;
suffix: string;
}) { }) {
const { prefix, prefixLabel, suffix } = props; const { child, rawMotionValues } = props;
// One tooltip for the whole title: the short prefix spelled out, and the full, often
// truncated, subject. // Convert the raw motion values to smooth spring easings
const label = prefixLabel ? ( const springScale = useSpring(rawMotionValues?.scale.get() ?? 1, {
<span className="flex flex-col"> stiffness: 400,
<span className="opacity-70 text-xxs">{prefixLabel}</span> damping: 30,
<span className="font-medium">{suffix}</span> });
</span> const springX = useSpring(rawMotionValues?.x.get() ?? 0, { stiffness: 400, damping: 30 });
) : prefix ? (
`${prefix}${suffix}` // Sync springs with raw motion values
) : ( React.useEffect(() => {
suffix if (!rawMotionValues) return;
);
const unsubScale = rawMotionValues.scale.on('change', (v) => springScale.set(v));
const unsubX = rawMotionValues.x.on('change', (v) => springX.set(v));
return () => {
unsubScale();
unsubX();
};
}, [rawMotionValues, springScale, springX]);
const motionValues = {
scale: springScale,
x: springX,
};
if (!isValidElement<{ motionValues: typeof motionValues }>(child)) {
return null;
}
return React.cloneElement(child, {
motionValues,
});
}
export function ToolbarTitle(props: { prefix?: string; suffix: string }) {
return ( return (
<Tooltip label={label}> <div className="flex items-center gap-1 text-xs">
<div className="flex min-w-0 max-w-full items-center gap-1 text-xs"> {props.prefix ? <ToolbarTitlePrefix title={props.prefix} /> : null}
{prefix ? <ToolbarTitlePrefix title={prefix} /> : null} <ToolbarTitleSuffix title={props.suffix} />
<ToolbarTitleSuffix title={suffix} /> </div>
</div>
</Tooltip>
); );
} }
function ToolbarTitlePrefix(props: { title: string }) { function ToolbarTitlePrefix(props: { title: string }) {
// Kept whole: prefixes are short, and the suffix is the one to truncate.
return ( return (
<motion.span <motion.span
{...getCopyVariants(0)} {...getCopyVariants(0)}
className="shrink-0 whitespace-nowrap font-medium text-neutral-1 dark:text-neutral-12" className="truncate font-medium text-neutral-1 dark:text-neutral-12"
> >
{props.title} {props.title}
</motion.span> </motion.span>
@@ -357,7 +341,7 @@ function ToolbarTitleSuffix(props: { title: string }) {
return ( return (
<motion.span <motion.span
{...getCopyVariants(1)} {...getCopyVariants(1)}
className="min-w-0 max-w-[28ch] truncate font-bold text-neutral-1 dark:text-neutral-12" className="max-w-[20ch] truncate font-bold text-neutral-1 dark:text-neutral-12"
> >
{props.title} {props.title}
</motion.span> </motion.span>
@@ -368,7 +352,7 @@ export function ToolbarSubtitle(props: { subtitle: React.ReactNode }) {
return ( return (
<motion.span <motion.span
{...getCopyVariants(1)} {...getCopyVariants(1)}
className="text-neutral-1/80 dark:text-neutral-12/80 flex min-w-0 max-w-full items-center gap-1 whitespace-nowrap text-xxs" className="text-neutral-1/80 dark:text-neutral-12/80 inline-flex items-center gap-1 text-xxs"
> >
{props.subtitle} {props.subtitle}
</motion.span> </motion.span>
@@ -35,8 +35,7 @@ export function ToolbarDate(props: { value: string }) {
return ( return (
<motion.div <motion.div
// Never wraps: the longer formats push the author's name to truncate instead. className="inline-flex items-center gap-1"
className="inline-flex shrink-0 items-center gap-1 whitespace-nowrap"
onMouseEnter={() => setHovered(true)} onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)} onMouseLeave={() => setHovered(false)}
> >
@@ -76,7 +75,7 @@ export function ToolbarDate(props: { value: string }) {
setFormatIndex((i) => (i + 1) % DATE_FORMATS.length); setFormatIndex((i) => (i + 1) % DATE_FORMATS.length);
}} }}
transition={{ type: 'spring', stiffness: 300, damping: 25 }} transition={{ type: 'spring', stiffness: 300, damping: 25 }}
className="relative inline-flex cursor-pointer select-none overflow-hidden whitespace-nowrap font-semibold transition-colors hover:text-white" // `text-white` is used insead of dark-mode adapting values because the date is always in a dark-tinted toolbar className="relative inline-flex cursor-pointer select-none overflow-hidden font-semibold transition-colors hover:text-white" // `text-white` is used insead of dark-mode adapting values because the date is always in a dark-tinted toolbar
> >
<AnimatePresence mode="popLayout" initial={false}> <AnimatePresence mode="popLayout" initial={false}>
<motion.span <motion.span
@@ -1,4 +1,4 @@
import { type MotionValue, motionValue, useReducedMotion } from 'motion/react'; import { type MotionValue, motionValue } from 'motion/react';
import React from 'react'; import React from 'react';
interface MagnificationConfig { interface MagnificationConfig {
@@ -16,29 +16,40 @@ interface MagnificationConfig {
padding?: number; padding?: number;
} }
export const BUTTON_SIZE = 32;
export const MAX_SCALE = 1.25;
/** Tooltip gap above a slot, with room for the button fully magnified (it grows from the bottom). */
export const TOOLTIP_OFFSET = 4 + BUTTON_SIZE * (MAX_SCALE - 1);
const defaultConfig: Required<MagnificationConfig> = { const defaultConfig: Required<MagnificationConfig> = {
buttonSize: BUTTON_SIZE, // Standard button size for 32px (size-8) buttons buttonSize: 32, // Standard button size for 32px (size-8) buttons
maxScale: MAX_SCALE, // 25% scale increase - noticeable but not overwhelming maxScale: 1.25, // 25% scale increase - noticeable but not overwhelming
influenceRadius: 80, // ~2.5 button widths of influence influenceRadius: 80, // ~2.5 button widths of influence
spacingMultiplier: 1.3, // Creates proportional spacing to scale increase spacingMultiplier: 1.3, // Creates proportional spacing to scale increase
scaleExponent: 2.5, // Exponential curve for dramatic close-range scaling scaleExponent: 2.5, // Exponential curve for dramatic close-range scaling
padding: 10, // Small buffer zone around container edges padding: 10, // Small buffer zone around container edges
}; };
type SlotMotionValues = { scale: MotionValue<number>; x: MotionValue<number> }; const resetMotionValues = (
motionValues: { scale: MotionValue<number>; x: MotionValue<number> }[]
const resetMotionValues = (motionValues: SlotMotionValues[]) => { ) => {
motionValues.forEach(({ scale, x }) => { motionValues.forEach(({ scale, x }) => {
scale.set(1); scale.set(1);
x.set(0); x.set(0);
}); });
}; };
const captureButtonPositions = (buttons: HTMLElement[]) => {
// Reset transforms to get original positions
buttons.forEach((button) => {
button.style.transform = '';
});
return buttons.map((button) => {
const rect = button.getBoundingClientRect();
return {
left: rect.left,
width: rect.width,
top: rect.top,
height: rect.height,
};
});
};
const calculateScale = ( const calculateScale = (
mouseX: number, mouseX: number,
buttonCenterX: number, buttonCenterX: number,
@@ -51,7 +62,8 @@ const calculateScale = (
if (distance > config.influenceRadius) return 1; if (distance > config.influenceRadius) return 1;
// Calculate distance from container edge (X-axis only) // Calculate distance from container edge (X-axis only)
const distanceFromEdge = Math.min(mouseX - containerRect.left, containerRect.right - mouseX); const distanceFromEdgeX = Math.min(mouseX - containerRect.left, containerRect.right - mouseX);
const distanceFromEdge = distanceFromEdgeX;
// Define the "heart" zone - 8px from center (16x16px total area) // Define the "heart" zone - 8px from center (16x16px total area)
const heartZoneRadius = 8; const heartZoneRadius = 8;
@@ -82,20 +94,24 @@ const calculateScale = (
const calculateSpacing = ( const calculateSpacing = (
buttonIndex: number, buttonIndex: number,
scales: number[], buttonEffects: { scale: number; translateX: number }[],
centers: (number | null)[], positions: { left: number; width: number; top: number; height: number }[],
config: Required<MagnificationConfig> config: Required<MagnificationConfig>
) => { ) => {
const buttonCenterX = centers[buttonIndex]; const currentPos = positions[buttonIndex];
if (buttonCenterX == null) return 0; if (!currentPos) return 0;
const buttonCenterX = currentPos.left + currentPos.width / 2;
let leftPush = 0; let leftPush = 0;
let rightPush = 0; let rightPush = 0;
scales.forEach((otherScale, otherIndex) => { buttonEffects.forEach((otherEffect, otherIndex) => {
const otherCenterX = centers[otherIndex]; if (otherIndex === buttonIndex) return;
if (otherIndex === buttonIndex || otherCenterX == null) return;
const otherPos = positions[otherIndex];
if (!otherPos) return;
const otherCenterX = otherPos.left + otherPos.width / 2;
const distanceBetween = Math.abs(buttonCenterX - otherCenterX); const distanceBetween = Math.abs(buttonCenterX - otherCenterX);
// Only apply influence if close enough // Only apply influence if close enough
@@ -104,7 +120,7 @@ const calculateSpacing = (
0, 0,
1 - distanceBetween / (config.influenceRadius * 1.5) 1 - distanceBetween / (config.influenceRadius * 1.5)
); );
const extraSpace = (otherScale - 1) * config.buttonSize; const extraSpace = (otherEffect.scale - 1) * config.buttonSize;
const pushAmount = (extraSpace / 2) * config.spacingMultiplier * influenceStrength; const pushAmount = (extraSpace / 2) * config.spacingMultiplier * influenceStrength;
if (otherCenterX < buttonCenterX) { if (otherCenterX < buttonCenterX) {
@@ -118,88 +134,104 @@ const calculateSpacing = (
return rightPush - leftPush; return rightPush - leftPush;
}; };
/**
* Dock-like magnification of the slots (direct children) of `containerRef`. Returns raw motion
* values per slot index, meant to be smoothed with springs by the slots.
*/
export function useMagnificationEffect(props: { export function useMagnificationEffect(props: {
slotCount: number; childrenCount: number;
containerRef: React.RefObject<HTMLElement | null>; containerRef: React.RefObject<HTMLElement | null>;
config?: MagnificationConfig; config?: MagnificationConfig;
}) { }) {
const { slotCount, containerRef, config } = props; const { childrenCount, containerRef, config } = props;
const reduceMotion = useReducedMotion(); const originalPositionsRef = React.useRef<
{ left: number; width: number; top: number; height: number }[]
>([]);
const finalConfig = React.useMemo(() => ({ ...defaultConfig, ...config }), [config]); const finalConfig = React.useMemo(() => ({ ...defaultConfig, ...config }), [config]);
// Stable across renders, grown as slots are added, so existing springs keep their source. // Create basic motion values that will be consumed by springs in the components
const motionValuesRef = React.useRef<SlotMotionValues[]>([]); const buttonMotionValues = React.useMemo(() => {
while (motionValuesRef.current.length < slotCount) { return Array.from({ length: childrenCount }, () => ({
motionValuesRef.current.push({ scale: motionValue(1), x: motionValue(0) }); scale: motionValue(1),
} x: motionValue(0),
const motionValues = motionValuesRef.current; }));
}, [childrenCount]);
React.useEffect(() => { React.useEffect(() => {
const container = containerRef.current; const container = containerRef.current;
if (!container || reduceMotion) { if (!container) return;
resetMotionValues(motionValues);
const buttons = Array.from(container.querySelectorAll('.toolbar-button')) as HTMLElement[];
if (buttons.length !== childrenCount) {
console.error(
`Button count (${buttons.length}) does not match children count (${childrenCount})`
);
return; return;
} }
let frame = 0; const handleMouseMove = (event: MouseEvent) => {
let pointer = { x: 0, y: 0 }; const buttons = Array.from(
container.querySelectorAll('.toolbar-button')
) as HTMLElement[];
// Measured every frame from layout positions (`offsetLeft`), which the slots' transforms // Capture positions if needed
// don't affect, so nothing goes stale when the toolbar resizes, re-centers or animates in. if (originalPositionsRef.current.length !== buttons.length) {
const update = () => { originalPositionsRef.current = captureButtonPositions(buttons);
frame = 0; }
const rect = container.getBoundingClientRect();
const inRange = const containerRect = container.getBoundingClientRect();
pointer.x >= rect.left - finalConfig.padding && const { clientX: mouseX, clientY: mouseY } = event;
pointer.x <= rect.right + finalConfig.padding &&
pointer.y >= rect.top - finalConfig.padding && // Check if mouse is in range
pointer.y <= rect.bottom + finalConfig.padding; const isInRange =
if (!inRange) { mouseX >= containerRect.left - finalConfig.padding &&
resetMotionValues(motionValues); mouseX <= containerRect.right + finalConfig.padding &&
mouseY >= containerRect.top - finalConfig.padding &&
mouseY <= containerRect.bottom + finalConfig.padding;
if (!isInRange) {
resetMotionValues(buttonMotionValues);
return; return;
} }
const slots = Array.from(container.children) as HTMLElement[]; // Calculate scales for all buttons
// Empty or hidden slots take no space and don't magnify. const buttonEffects = buttons.map((_, index) => {
const centers = slots.map((slot) => const pos = originalPositionsRef.current[index];
slot.offsetWidth > 0 ? rect.left + slot.offsetLeft + slot.offsetWidth / 2 : null if (!pos) return { scale: 1, translateX: 0 };
);
const scales = centers.map((center) => const buttonCenterX = pos.left + pos.width / 2;
center == null ? 1 : calculateScale(pointer.x, center, rect, finalConfig) const scale = calculateScale(mouseX, buttonCenterX, containerRect, finalConfig);
); return { scale, translateX: 0 };
motionValues.forEach((values, index) => { });
values.scale.set(scales[index] ?? 1);
values.x.set(calculateSpacing(index, scales, centers, finalConfig)); // Calculate spacing for all buttons
buttonEffects.forEach((effect, index) => {
effect.translateX = calculateSpacing(
index,
buttonEffects,
originalPositionsRef.current,
finalConfig
);
});
// Update motion values
buttonEffects.forEach((effect, index) => {
const motionValue = buttonMotionValues[index];
if (motionValue) {
motionValue.scale.set(effect.scale);
motionValue.x.set(effect.translateX);
}
}); });
}; };
const onPointerMove = (event: PointerEvent) => { const handleMouseLeave = () => resetMotionValues(buttonMotionValues);
if (event.pointerType !== 'mouse') {
return; container.addEventListener('mousemove', handleMouseMove);
} container.addEventListener('mouseleave', handleMouseLeave);
pointer = { x: event.clientX, y: event.clientY };
if (!frame) {
frame = requestAnimationFrame(update);
}
};
const onPointerLeave = () => {
cancelAnimationFrame(frame);
frame = 0;
resetMotionValues(motionValues);
};
container.addEventListener('pointermove', onPointerMove);
container.addEventListener('pointerleave', onPointerLeave);
return () => { return () => {
cancelAnimationFrame(frame); container.removeEventListener('mousemove', handleMouseMove);
container.removeEventListener('pointermove', onPointerMove); container.removeEventListener('mouseleave', handleMouseLeave);
container.removeEventListener('pointerleave', onPointerLeave);
}; };
}, [containerRef, finalConfig, motionValues, reduceMotion]); }, [finalConfig, containerRef, buttonMotionValues, childrenCount]);
return { motionValues }; return { buttonMotionValues };
} }
@@ -3,7 +3,6 @@ import type { DocumentInlineAnnotation } from '@gitbook/api';
import { Blocks } from '../Blocks'; import { Blocks } from '../Blocks';
import type { InlineProps } from '../Inline'; import type { InlineProps } from '../Inline';
import { Inlines } from '../Inlines'; import { Inlines } from '../Inlines';
import { getCommentMarkerProps } from '../utils';
import { AnnotationPopover } from './AnnotationPopover'; import { AnnotationPopover } from './AnnotationPopover';
import { getNodeFragmentByType } from '@/lib/document'; import { getNodeFragmentByType } from '@/lib/document';
@@ -22,19 +21,13 @@ export function Annotation(props: InlineProps<DocumentInlineAnnotation>) {
return ( return (
<AnnotationPopover <AnnotationPopover
body={ body={
// The app doesn't allow comments inside annotation bodies. <Blocks
<div document={document}
{...getCommentMarkerProps(context, 'data-comment-ignore')} ancestorBlocks={[]}
className="contents" context={context}
> nodes={fragment.nodes}
<Blocks style={['contents']}
document={document} />
ancestorBlocks={[]}
context={context}
nodes={fragment.nodes}
style={['contents']}
/>
</div>
} }
> >
{content} {content}
@@ -6,7 +6,6 @@ import {
import type { BlockProps } from './Block'; import type { BlockProps } from './Block';
import { NotFoundRefHoverCard } from './NotFoundRefHoverCard'; import { NotFoundRefHoverCard } from './NotFoundRefHoverCard';
import { getCommentAnchorProps } from './utils';
import { Card, type CardProps } from '@/components/primitives'; import { Card, type CardProps } from '@/components/primitives';
import { import {
type ResolvedContentRef, type ResolvedContentRef,
@@ -32,7 +31,6 @@ export async function BlockContentRef(props: BlockProps<DocumentBlockContentRef>
return ( return (
<NotFoundRefHoverCard context={context}> <NotFoundRefHoverCard context={context}>
<BlockContentRefCard <BlockContentRefCard
{...getCommentAnchorProps(context, block.key)}
contentRef={block.data.ref} contentRef={block.data.ref}
resolved={fallback} resolved={fallback}
style={style} style={style}
@@ -41,14 +39,7 @@ export async function BlockContentRef(props: BlockProps<DocumentBlockContentRef>
); );
} }
return ( return <BlockContentRefCard contentRef={block.data.ref} resolved={resolved} style={style} />;
<BlockContentRefCard
{...getCommentAnchorProps(context, block.key)}
contentRef={block.data.ref}
resolved={resolved}
style={style}
/>
);
} }
function BlockContentRefCard( function BlockContentRefCard(
@@ -9,7 +9,6 @@ import type {
import type { DocumentContextProps } from './DocumentView'; import type { DocumentContextProps } from './DocumentView';
import { Inlines } from './Inlines'; import { Inlines } from './Inlines';
import { getCommentAnchorProps } from './utils';
import { getNodeFragmentByName, isNodeEmpty } from '@/lib/document'; import { getNodeFragmentByName, isNodeEmpty } from '@/lib/document';
import { type ClassValue, tcls } from '@/lib/tailwind'; import { type ClassValue, tcls } from '@/lib/tailwind';
@@ -35,11 +34,6 @@ export function Caption(
block: DocumentBlockImage | DocumentBlockDrawing | DocumentBlockEmbed | DocumentBlockFile; block: DocumentBlockImage | DocumentBlockDrawing | DocumentBlockEmbed | DocumentBlockFile;
withBorder?: boolean; withBorder?: boolean;
withFrame?: boolean; withFrame?: boolean;
/**
* Expose the block key for commenting; off inside an `images` block, which carries the key
* itself since its images aren't comment targets.
*/
withBlockKey?: boolean;
} & DocumentContextProps } & DocumentContextProps
) { ) {
const { const {
@@ -65,11 +59,8 @@ export function Caption(
], ],
style, style,
align = 'center', align = 'center',
withBlockKey = false,
} = props; } = props;
const anchorProps = withBlockKey ? getCommentAnchorProps(context, block.key) : {};
const caption = getNodeFragmentByName(block, 'caption'); const caption = getNodeFragmentByName(block, 'caption');
const captionParagraph = caption?.nodes[0]; const captionParagraph = caption?.nodes[0];
@@ -78,15 +69,11 @@ export function Caption(
captionParagraph.type !== 'paragraph' || captionParagraph.type !== 'paragraph' ||
isNodeEmpty(captionParagraph) isNodeEmpty(captionParagraph)
) { ) {
return ( return <div className={tcls(style, wrapperStyle)}>{children}</div>;
<div {...anchorProps} className={tcls(style, wrapperStyle)}>
{children}
</div>
);
} }
return ( return (
<picture {...anchorProps} className={tcls('relative', style)}> <picture className={tcls('relative', style)}>
<div className={tcls(wrapperStyle, captionAlignStyles[align])}>{children}</div> <div className={tcls(wrapperStyle, captionAlignStyles[align])}>{children}</div>
<figcaption <figcaption
className={tcls( className={tcls(
@@ -3,7 +3,6 @@
import { getCodeTextFromId } from './utils'; import { getCodeTextFromId } from './utils';
import { useAIChatController, useAIConfig } from '@/components/AI'; import { useAIChatController, useAIConfig } from '@/components/AI';
import { AIChatIcon } from '@/components/AIChat'; import { AIChatIcon } from '@/components/AIChat';
import { useTrackEvent } from '@/components/Insights';
import { Button } from '@/components/primitives'; import { Button } from '@/components/primitives';
import { isAIChatEnabled } from '@/components/utils/isAIChatEnabled'; import { isAIChatEnabled } from '@/components/utils/isAIChatEnabled';
import { t, useLanguage } from '@/intl/client'; import { t, useLanguage } from '@/intl/client';
@@ -20,14 +19,12 @@ export function AskAICodeButton(props: {
const language = useLanguage(); const language = useLanguage();
const config = useAIConfig(); const config = useAIConfig();
const chatController = useAIChatController(); const chatController = useAIChatController();
const trackEvent = useTrackEvent();
if (!isAIChatEnabled(config.aiMode)) { if (!isAIChatEnabled(config.aiMode)) {
return null; return null;
} }
const onClick = () => { const onClick = () => {
trackEvent({ type: 'ask_trigger_click', trigger: 'code' });
const codeText = getCodeTextFromId(codeId); const codeText = getCodeTextFromId(codeId);
if (!codeText?.trim()) { if (!codeText?.trim()) {
return; return;
@@ -40,7 +37,7 @@ export function AskAICodeButton(props: {
content: codeText, content: codeText,
syntax, syntax,
}); });
chatController.open('code'); chatController.open();
chatController.focus(); chatController.focus();
}; };
@@ -23,8 +23,6 @@ export type ClientBlockProps = Pick<BlockProps<DocumentBlockCode>, 'block' | 'st
mode: BlockProps<DocumentBlockCode>['context']['mode']; mode: BlockProps<DocumentBlockCode>['context']['mode'];
themes?: CustomizationThemedCodeTheme; themes?: CustomizationThemedCodeTheme;
embedded?: boolean; embedded?: boolean;
/** Node key for comments, set only where commenting is possible. */
commentKey?: string;
}; };
export const CODE_BLOCK_DEFAULT_COLLAPSED_LINE_COUNT = 10; export const CODE_BLOCK_DEFAULT_COLLAPSED_LINE_COUNT = 10;
@@ -34,8 +32,7 @@ export const CODE_BLOCK_DEFAULT_COLLAPSED_LINE_COUNT = 10;
* It allows us to defer some load to avoid blocking the rendering of the whole page with block highlighting. * It allows us to defer some load to avoid blocking the rendering of the whole page with block highlighting.
*/ */
export function ClientCodeBlock(props: ClientBlockProps) { export function ClientCodeBlock(props: ClientBlockProps) {
const { block, mode, style, inlines, inlineExprVariables, themes, embedded, commentKey } = const { block, mode, style, inlines, inlineExprVariables, themes, embedded } = props;
props;
const blockRef = useRef<HTMLDivElement>(null); const blockRef = useRef<HTMLDivElement>(null);
const isInViewportRef = useRef(false); const isInViewportRef = useRef(false);
const [isInViewport, setIsInViewport] = useState(false); const [isInViewport, setIsInViewport] = useState(false);
@@ -148,7 +145,6 @@ export function ClientCodeBlock(props: ClientBlockProps) {
id={codeBlockBodyId} id={codeBlockBodyId}
isPrint={mode === 'print'} isPrint={mode === 'print'}
embedded={embedded} embedded={embedded}
commentKey={commentKey}
/> />
); );
@@ -8,7 +8,6 @@ import type {
import type { BlockProps } from '../Block'; import type { BlockProps } from '../Block';
import { Blocks } from '../Blocks'; import { Blocks } from '../Blocks';
import { getCommentKeyProp, getCommentMarkerProps } from '../utils';
import { ClientCodeBlock } from './ClientCodeBlock'; import { ClientCodeBlock } from './ClientCodeBlock';
import { CodeBlockRenderer } from './CodeBlockRenderer'; import { CodeBlockRenderer } from './CodeBlockRenderer';
import { highlight } from './highlight'; import { highlight } from './highlight';
@@ -60,20 +59,14 @@ export async function CodeBlock(
return null; return null;
} }
return ( return (
// The app doesn't allow comments inside annotation bodies. <Blocks
<div
key={index} key={index}
{...getCommentMarkerProps(context, 'data-comment-ignore')} document={document}
className="contents" ancestorBlocks={[]}
> context={context}
<Blocks nodes={fragment.nodes}
document={document} style="space-y-4"
ancestorBlocks={[]} />
context={context}
nodes={fragment.nodes}
style="space-y-4"
/>
</div>
); );
})(); })();
@@ -99,7 +92,6 @@ export async function CodeBlock(
theme={theme} theme={theme}
isPrint={context.mode === 'print'} isPrint={context.mode === 'print'}
embedded={embedded} embedded={embedded}
{...getCommentKeyProp(context, block.key)}
/> />
); );
} }
@@ -122,7 +114,6 @@ export async function CodeBlock(
mode: context.mode, mode: context.mode,
themes, themes,
embedded, embedded,
...getCommentKeyProp(context, block.key),
}; };
return ( return (
@@ -5,7 +5,6 @@ import type { DocumentBlockCode } from '@gitbook/api';
import { AnnotationPopover } from '../Annotation/AnnotationPopover'; import { AnnotationPopover } from '../Annotation/AnnotationPopover';
import type { BlockProps } from '../Block'; import type { BlockProps } from '../Block';
import { getCommentKeyAttributes } from '../utils/commentAnchors';
import { AskAICodeButton } from './AskAICodeButton'; import { AskAICodeButton } from './AskAICodeButton';
import { CopyCodeButton } from './CopyCodeButton'; import { CopyCodeButton } from './CopyCodeButton';
import type { HighlightLine, HighlightTheme, HighlightToken } from './highlight-tokens'; import type { HighlightLine, HighlightTheme, HighlightToken } from './highlight-tokens';
@@ -13,8 +12,6 @@ import { tcls } from '@/lib/tailwind';
type CodeBlockRendererProps = Pick<BlockProps<DocumentBlockCode>, 'block' | 'style'> & { type CodeBlockRendererProps = Pick<BlockProps<DocumentBlockCode>, 'block' | 'style'> & {
theme: HighlightTheme; theme: HighlightTheme;
/** Node key for comments, set only where commenting is possible. */
commentKey?: string;
'aria-busy'?: boolean; 'aria-busy'?: boolean;
id?: string; id?: string;
/** /**
@@ -32,7 +29,7 @@ export const CodeBlockRenderer = forwardRef(function CodeBlockRenderer(
props: CodeBlockRendererProps, props: CodeBlockRendererProps,
ref: React.ForwardedRef<HTMLDivElement> ref: React.ForwardedRef<HTMLDivElement>
) { ) {
const { block, style, theme, 'aria-busy': ariaBusy, isPrint, embedded, commentKey } = props; const { block, style, theme, 'aria-busy': ariaBusy, isPrint, embedded } = props;
const withLineNumbers = Boolean(block.data.lineNumbers) && block.nodes.length > 1; const withLineNumbers = Boolean(block.data.lineNumbers) && block.nodes.length > 1;
const withWrap = block.data.overflow === 'wrap'; const withWrap = block.data.overflow === 'wrap';
@@ -53,7 +50,6 @@ export const CodeBlockRenderer = forwardRef(function CodeBlockRenderer(
<div <div
ref={ref} ref={ref}
id={codeId} id={codeId}
{...getCommentKeyAttributes(commentKey)}
aria-busy={ariaBusy} aria-busy={ariaBusy}
className={tcls( className={tcls(
'group/codeblock shiki relative flex shrink flex-col overflow-hidden print:overflow-visible', 'group/codeblock shiki relative flex shrink flex-col overflow-hidden print:overflow-visible',
@@ -218,12 +218,7 @@ export function MermaidCodeBlock(
return ( return (
<> <>
{/* Inline slot: hosts the diagram in the document flow until it goes fullscreen. */} {/* Inline slot: hosts the diagram in the document flow until it goes fullscreen. */}
<div <div ref={rootRef} className={tcls('relative', style)} contentEditable={false} />
ref={rootRef}
data-block-key={props.commentKey}
className={tcls('relative', style)}
contentEditable={false}
/>
{diagramHostRef.current ? createPortal(diagram, diagramHostRef.current) : null} {diagramHostRef.current ? createPortal(diagram, diagramHostRef.current) : null}
<Dialog.Root <Dialog.Root
open={isFullscreen} open={isFullscreen}
@@ -4,7 +4,6 @@ import { type DocumentBlockColumns, type Length, VerticalAlignment } from '@gitb
import type { BlockProps } from '../Block'; import type { BlockProps } from '../Block';
import { Blocks } from '../Blocks'; import { Blocks } from '../Blocks';
import { getCommentMarkerProps } from '../utils';
import { tcls } from '@/lib/tailwind'; import { tcls } from '@/lib/tailwind';
export function Columns(props: BlockProps<DocumentBlockColumns>) { export function Columns(props: BlockProps<DocumentBlockColumns>) {
@@ -38,8 +37,6 @@ export function Columns(props: BlockProps<DocumentBlockColumns>) {
return ( return (
<div <div
// The app doesn't allow comments inside columns.
{...getCommentMarkerProps(context, 'data-comment-ignore')}
className={tcls( className={tcls(
'grid w-full @2xl:grid-flow-col @2xl:grid-cols-[repeat(var(--grid-slices),minmax(0,1fr))] grid-cols-1 @2xl:grid-rows-1 gap-x-8 gap-y-4', 'grid w-full @2xl:grid-flow-col @2xl:grid-cols-[repeat(var(--grid-slices),minmax(0,1fr))] grid-cols-1 @2xl:grid-rows-1 gap-x-8 gap-y-4',
style style
@@ -37,12 +37,6 @@ export interface DocumentContext {
*/ */
withLinkPreviews?: boolean; withLinkPreviews?: boolean;
/**
* Render the markers comments anchor to (block keys, table cells). Only where commenting is
* possible, so public pages don't carry them.
*/
withCommentAnchors?: boolean;
/** /**
* True when this document is the main page body — the only place a background page cover is * True when this document is the main page body — the only place a background page cover is
* shown behind the content. Cover-aware text styling (contrast over the cover) is scoped to it * shown behind the content. Cover-aware text styling (contrast over the cover) is scoped to it
@@ -18,7 +18,7 @@ export async function Drawing(props: BlockProps<DocumentBlockDrawing>) {
} }
return ( return (
<Caption {...props} withBlockKey> <Caption {...props}>
<Image <Image
sources={{ sources={{
light: { light: {
@@ -32,7 +32,7 @@ export async function Embed(props: BlockProps<gitbookAPI.DocumentBlockEmbed>) {
} }
return ( return (
<Caption {...props} withBorder withBlockKey> <Caption {...props} withBorder>
{embed.type === 'rich' ? ( {embed.type === 'rich' ? (
<> <>
<div <div
@@ -14,8 +14,6 @@ export function Details(props: {
contentIds?: string[]; contentIds?: string[];
open?: boolean; open?: boolean;
className?: ClassValue; className?: ClassValue;
/** Node key of the expandable, so comments can anchor to it. */
commentKey?: string;
}) { }) {
const { children, id, className } = props; const { children, id, className } = props;
@@ -48,7 +46,6 @@ export function Details(props: {
<details <details
ref={ref} ref={ref}
id={id} id={id}
data-block-key={props.commentKey}
open={props.open || openFromHash} open={props.open || openFromHash}
className={tcls( className={tcls(
className, className,
@@ -5,7 +5,6 @@ import type { BlockProps } from '../Block';
import { Blocks } from '../Blocks'; import { Blocks } from '../Blocks';
import { shouldShowHashLinks } from '../HashLinkButton'; import { shouldShowHashLinks } from '../HashLinkButton';
import { Inlines } from '../Inlines'; import { Inlines } from '../Inlines';
import { getCommentAnchorProps, getCommentKeyProp } from '../utils';
import { Details } from './Details'; import { Details } from './Details';
import { ToggleChevron } from '@/components/primitives'; import { ToggleChevron } from '@/components/primitives';
import { getSpaceLanguage, tString } from '@/intl/server'; import { getSpaceLanguage, tString } from '@/intl/server';
@@ -38,12 +37,10 @@ export async function Expandable(props: BlockProps<DocumentBlockExpandable>) {
return ( return (
<Details <Details
id={id} id={id}
{...getCommentKeyProp(context, block.key)}
open={context.mode === 'print' || isDefaultExpanded} open={context.mode === 'print' || isDefaultExpanded}
className={tcls('scroll-mt-(--content-scroll-margin)', style)} className={tcls('scroll-mt-(--content-scroll-margin)', style)}
> >
<summary <summary
{...getCommentAnchorProps(context, titleParagraph.key)}
className={tcls( className={tcls(
'cursor-pointer', 'cursor-pointer',
'px-4', 'px-4',
@@ -40,7 +40,7 @@ export async function File(props: BlockProps<DocumentBlockFile>) {
}; };
return ( return (
<Caption {...props} withBorder withBlockKey> <Caption {...props} withBorder>
<div className="flex flex-wrap items-center gap-5 px-5 py-3"> <div className="flex flex-wrap items-center gap-5 px-5 py-3">
<div className="flex min-h-8 min-w-14 flex-col items-center justify-center gap-1 border-r border-tint-subtle pr-4"> <div className="flex min-h-8 min-w-14 flex-col items-center justify-center gap-1 border-r border-tint-subtle pr-4">
{contentType === 'image' ? ( {contentType === 'image' ? (
@@ -5,7 +5,7 @@ import { HashLinkButton, hashLinkButtonWrapperStyles, shouldShowHashLinks } from
import { HeadingRevealWrapper } from './HeadingRevealWrapper'; import { HeadingRevealWrapper } from './HeadingRevealWrapper';
import { Inlines } from './Inlines'; import { Inlines } from './Inlines';
import { getBlockTextStyle } from './spacing'; import { getBlockTextStyle } from './spacing';
import { getCommentAnchorProps, getTextAlignment } from './utils'; import { getTextAlignment } from './utils';
import { getSpaceLanguage, tString } from '@/intl/server'; import { getSpaceLanguage, tString } from '@/intl/server';
import { defaultLanguage } from '@/intl/translations'; import { defaultLanguage } from '@/intl/translations';
import { tcls } from '@/lib/tailwind'; import { tcls } from '@/lib/tailwind';
@@ -30,7 +30,6 @@ export async function Heading(props: BlockProps<DocumentBlockHeading>) {
<HeadingRevealWrapper <HeadingRevealWrapper
as={Tag} as={Tag}
id={id} id={id}
{...getCommentAnchorProps(context, block.key)}
className={tcls( className={tcls(
textStyle.textSize, textStyle.textSize,
'heading', 'heading',
@@ -3,7 +3,6 @@ import type { DocumentBlockImage, DocumentBlockImages, JSONDocument, Length } fr
import type { BlockProps } from './Block'; import type { BlockProps } from './Block';
import { Caption, type CaptionAlign } from './Caption'; import { Caption, type CaptionAlign } from './Caption';
import type { DocumentContext } from './DocumentView'; import type { DocumentContext } from './DocumentView';
import { getCommentAnchorProps } from './utils';
import { Image, type ImageResponsiveSize } from '@/components/utils'; import { Image, type ImageResponsiveSize } from '@/components/utils';
import { resolveContentRefInDocument } from '@/lib/references'; import { resolveContentRefInDocument } from '@/lib/references';
import { type ClassValue, tcls } from '@/lib/tailwind'; import { type ClassValue, tcls } from '@/lib/tailwind';
@@ -16,7 +15,6 @@ export function Images(props: BlockProps<DocumentBlockImages>) {
return ( return (
<div <div
{...getCommentAnchorProps(context, block.key)}
className={tcls( className={tcls(
style, style,
'flex', 'flex',
@@ -2,10 +2,9 @@ import type { DocumentBlockIntegration, RenderIntegrationUI } from '@gitbook/api
import { ContentKitOutput } from '@gitbook/react-contentkit'; import { ContentKitOutput } from '@gitbook/react-contentkit';
import type { BlockProps } from '../Block'; import type { BlockProps } from '../Block';
import { getCommentAnchorProps, getCommentMarkerProps } from '../utils';
import { getWebframePageContext } from './adaptive'; import { getWebframePageContext } from './adaptive';
import './contentkit.css';
import { contentKitServerContext } from './contentkit'; import { contentKitServerContext } from './contentkit';
import './contentkit.css';
import { import {
ContentKitWithClientContext, ContentKitWithClientContext,
type WebframeLinkerData, type WebframeLinkerData,
@@ -62,12 +61,7 @@ export async function IntegrationBlock(props: BlockProps<DocumentBlockIntegratio
} }
return ( return (
<div <div className={tcls(style)}>
// Integration output can render blocks with generated keys.
{...getCommentAnchorProps(context, block.key)}
{...getCommentMarkerProps(context, 'data-comment-block')}
className={tcls(style)}
>
<pre> <pre>
Unexpected error with integration {block.data.integration}:{' '} Unexpected error with integration {block.data.integration}:{' '}
{initialResponse.error.message} {initialResponse.error.message}
@@ -105,12 +99,7 @@ export async function IntegrationBlock(props: BlockProps<DocumentBlockIntegratio
}; };
return ( return (
<div <div className={tcls(style)}>
// Integration output can render blocks with generated keys.
{...getCommentAnchorProps(context, block.key)}
{...getCommentMarkerProps(context, 'data-comment-block')}
className={tcls(style)}
>
<ContentKitWithClientContext <ContentKitWithClientContext
{...contentKitProps} {...contentKitProps}
canAccessVisitorClaims={canAccessVisitorClaims} canAccessVisitorClaims={canAccessVisitorClaims}
@@ -11,13 +11,11 @@ import type {
import type { BlockProps } from './Block'; import type { BlockProps } from './Block';
import { Blocks } from './Blocks'; import { Blocks } from './Blocks';
import { getBlockTextStyle } from './spacing'; import { getBlockTextStyle } from './spacing';
import { getCommentAnchorProps } from './utils';
import { Checkbox } from '@/components/primitives'; import { Checkbox } from '@/components/primitives';
import { tcls } from '@/lib/tailwind'; import { tcls } from '@/lib/tailwind';
export function ListItem(props: BlockProps<DocumentBlockListItem>) { export function ListItem(props: BlockProps<DocumentBlockListItem>) {
const { block, ancestorBlocks, ...contextProps } = props; const { block, ancestorBlocks, ...contextProps } = props;
const { context } = contextProps;
const parent = ancestorBlocks[ancestorBlocks.length - 1]; const parent = ancestorBlocks[ancestorBlocks.length - 1];
assert( assert(
@@ -48,7 +46,7 @@ export function ListItem(props: BlockProps<DocumentBlockListItem>) {
switch (parent.type) { switch (parent.type) {
case 'list-tasks': case 'list-tasks':
return ( return (
<ListItemLI block={block} anchorProps={getCommentAnchorProps(context, block.key)}> <ListItemLI block={block}>
<ListItemPrefix block={block}> <ListItemPrefix block={block}>
<Checkbox <Checkbox
id={block.key!} id={block.key!}
@@ -66,7 +64,7 @@ export function ListItem(props: BlockProps<DocumentBlockListItem>) {
); );
case 'list-ordered': case 'list-ordered':
return ( return (
<ListItemLI block={block} anchorProps={getCommentAnchorProps(context, block.key)}> <ListItemLI block={block}>
<ListItemPrefix block={block}> <ListItemPrefix block={block}>
<PseudoBefore <PseudoBefore
content={getOrderedListItemPrefixContent({ content={getOrderedListItemPrefixContent({
@@ -84,7 +82,7 @@ export function ListItem(props: BlockProps<DocumentBlockListItem>) {
); );
case 'list-unordered': case 'list-unordered':
return ( return (
<ListItemLI block={block} anchorProps={getCommentAnchorProps(context, block.key)}> <ListItemLI block={block}>
<ListItemPrefix block={block}> <ListItemPrefix block={block}>
<PseudoBefore <PseudoBefore
content={getUnorderedListItemsPrefixContent({ content={getUnorderedListItemsPrefixContent({
@@ -125,17 +123,9 @@ function getListItemDepth(input: {
return depth; return depth;
} }
function ListItemLI(props: { function ListItemLI(props: { block: DocumentBlockListItem; children: React.ReactNode }) {
block: DocumentBlockListItem;
anchorProps: ReturnType<typeof getCommentAnchorProps>;
children: React.ReactNode;
}) {
const textStyle = getBlockTextStyle(props.block); const textStyle = getBlockTextStyle(props.block);
return ( return <li className={tcls(textStyle.lineHeight, 'flex items-start')}>{props.children}</li>;
<li {...props.anchorProps} className={tcls(textStyle.lineHeight, 'flex items-start')}>
{props.children}
</li>
);
} }
function ListItemPrefix(props: { block: DocumentBlockListItem; children: React.ReactNode }) { function ListItemPrefix(props: { block: DocumentBlockListItem; children: React.ReactNode }) {
@@ -3,25 +3,21 @@ import { MathFormula } from '@gitbook/react-math';
import type { BlockProps } from './Block'; import type { BlockProps } from './Block';
import type { InlineProps } from './Inline'; import type { InlineProps } from './Inline';
import { getCommentAnchorProps } from './utils';
import { getAssetURL } from '@/lib/assets'; import { getAssetURL } from '@/lib/assets';
import { tcls } from '@/lib/tailwind'; import { tcls } from '@/lib/tailwind';
const assetsUrl = getAssetURL('math'); const assetsUrl = getAssetURL('math');
export async function BlockMath(props: BlockProps<DocumentBlockMath>) { export async function BlockMath(props: BlockProps<DocumentBlockMath>) {
const { block, style, context } = props; const { block, style } = props;
// `MathFormula` only forwards `className`, so the comment anchor needs its own wrapper.
return ( return (
<div {...getCommentAnchorProps(context, block.key)} className={tcls(style)}> <MathFormula
<MathFormula formula={block.data.formula}
formula={block.data.formula} inline={false}
inline={false} className={tcls(style, 'overflow-x-auto')}
className="overflow-x-auto" assetsUrl={assetsUrl}
assetsUrl={assetsUrl} />
/>
</div>
); );
} }
@@ -1,5 +1,4 @@
import type { BlockProps } from '../Block'; import type { BlockProps } from '../Block';
import { getCommentAnchorProps, getCommentMarkerProps } from '../utils';
import { getOpenAPIBlockClientProps } from './context'; import { getOpenAPIBlockClientProps } from './context';
import { OpenAPIBlockLazy } from './OpenAPIBlockLazy'; import { OpenAPIBlockLazy } from './OpenAPIBlockLazy';
import { resolveOpenAPIOperationBlock } from '@/lib/openapi/resolveOpenAPIOperationBlock'; import { resolveOpenAPIOperationBlock } from '@/lib/openapi/resolveOpenAPIOperationBlock';
@@ -10,14 +9,9 @@ import { tcls } from '@/lib/tailwind';
* Render an openapi block or an openapi-operation block. * Render an openapi block or an openapi-operation block.
*/ */
export async function OpenAPIOperation(props: BlockProps<AnyOpenAPIOperationsBlock>) { export async function OpenAPIOperation(props: BlockProps<AnyOpenAPIOperationsBlock>) {
const { style, block, context } = props; const { style } = props;
return ( return (
<div <div className={tcls('flex w-full min-w-0', style, 'max-w-full')}>
{...getCommentAnchorProps(context, block.key)}
// Its generated headings and descriptions carry keys that aren't page nodes.
{...getCommentMarkerProps(context, 'data-comment-block')}
className={tcls('flex w-full min-w-0', style, 'max-w-full')}
>
<OpenAPIOperationBody {...props} /> <OpenAPIOperationBody {...props} />
</div> </div>
); );
@@ -1,5 +1,4 @@
import type { BlockProps } from '../Block'; import type { BlockProps } from '../Block';
import { getCommentAnchorProps, getCommentMarkerProps } from '../utils';
import { getOpenAPIBlockClientProps } from './context'; import { getOpenAPIBlockClientProps } from './context';
import { OpenAPIBlockLazy } from './OpenAPIBlockLazy'; import { OpenAPIBlockLazy } from './OpenAPIBlockLazy';
import { resolveOpenAPISchemasBlock } from '@/lib/openapi/resolveOpenAPISchemasBlock'; import { resolveOpenAPISchemasBlock } from '@/lib/openapi/resolveOpenAPISchemasBlock';
@@ -10,14 +9,9 @@ import { tcls } from '@/lib/tailwind';
* Render an openapi-schemas block. * Render an openapi-schemas block.
*/ */
export async function OpenAPISchemas(props: BlockProps<OpenAPISchemasBlock>) { export async function OpenAPISchemas(props: BlockProps<OpenAPISchemasBlock>) {
const { style, block, context } = props; const { style } = props;
return ( return (
<div <div className={tcls('flex w-full', style, 'max-w-full')}>
{...getCommentAnchorProps(context, block.key)}
// Its generated headings and descriptions carry keys that aren't page nodes.
{...getCommentMarkerProps(context, 'data-comment-block')}
className={tcls('flex w-full', style, 'max-w-full')}
>
<OpenAPISchemasBody {...props} /> <OpenAPISchemasBody {...props} />
</div> </div>
); );
@@ -1,5 +1,4 @@
import type { BlockProps } from '../Block'; import type { BlockProps } from '../Block';
import { getCommentAnchorProps, getCommentMarkerProps } from '../utils';
import { getOpenAPIBlockClientProps } from './context'; import { getOpenAPIBlockClientProps } from './context';
import { OpenAPIBlockLazy } from './OpenAPIBlockLazy'; import { OpenAPIBlockLazy } from './OpenAPIBlockLazy';
import { resolveOpenAPIWebhookBlock } from '@/lib/openapi/resolveOpenAPIWebhookBlock'; import { resolveOpenAPIWebhookBlock } from '@/lib/openapi/resolveOpenAPIWebhookBlock';
@@ -10,14 +9,9 @@ import { tcls } from '@/lib/tailwind';
* Render an openapi block or an openapi-webhook block. * Render an openapi block or an openapi-webhook block.
*/ */
export async function OpenAPIWebhook(props: BlockProps<OpenAPIWebhookBlock>) { export async function OpenAPIWebhook(props: BlockProps<OpenAPIWebhookBlock>) {
const { style, block, context } = props; const { style } = props;
return ( return (
<div <div className={tcls('flex w-full min-w-0', style, 'max-w-full')}>
{...getCommentAnchorProps(context, block.key)}
// Its generated headings and descriptions carry keys that aren't page nodes.
{...getCommentMarkerProps(context, 'data-comment-block')}
className={tcls('flex w-full min-w-0', style, 'max-w-full')}
>
<OpenAPIWebhookBody {...props} /> <OpenAPIWebhookBody {...props} />
</div> </div>
); );
@@ -4,19 +4,15 @@ import { CustomizationAIMode } from '@gitbook/api';
import type { BlockProps } from './Block'; import type { BlockProps } from './Block';
import { Inlines } from './Inlines'; import { Inlines } from './Inlines';
import { getTextAlignment } from './utils'; import { getTextAlignment } from './utils';
import { getCommentAnchorProps } from './utils';
import { getNodeText } from '@/lib/document'; import { getNodeText } from '@/lib/document';
import { tcls } from '@/lib/tailwind'; import { tcls } from '@/lib/tailwind';
export function Paragraph(props: BlockProps<DocumentBlockParagraph>) { export function Paragraph(props: BlockProps<DocumentBlockParagraph>) {
const { block, style, ancestorBlocks, ...contextProps } = props; const { block, style, ancestorBlocks, ...contextProps } = props;
const { context } = contextProps; const { context } = contextProps;
// Like the app, a list item owns the comments on its direct paragraph.
const isCommentTarget = ancestorBlocks.at(-1)?.type !== 'list-item';
const paragraph = ( const paragraph = (
<p <p
{...(isCommentTarget ? getCommentAnchorProps(context, block.key) : {})}
// Cover-aware contrast text applies only to the page body, not to documents // Cover-aware contrast text applies only to the page body, not to documents
// rendered in overlays (search answers, AI chat) on a background-cover page. // rendered in overlays (search answers, AI chat) on a background-cover page.
data-cover-aware-text={context.isPageBody ? '' : undefined} data-cover-aware-text={context.isPageBody ? '' : undefined}
@@ -9,14 +9,12 @@ import { validateIconName } from '@gitbook/icons/icons';
import type { BlockProps } from '../Block'; import type { BlockProps } from '../Block';
import { CodeBlock } from '../CodeBlock'; import { CodeBlock } from '../CodeBlock';
import { getPlainCodeBlock } from '../CodeBlock/highlight-tokens'; import { getPlainCodeBlock } from '../CodeBlock/highlight-tokens';
import { COMMENT_IGNORE_CLASSNAME, getCommentKeyProp } from '../utils';
import { PromptClient } from './PromptClient'; import { PromptClient } from './PromptClient';
import { tcls } from '@/lib/tailwind';
const PROMPT_COLLAPSED_LINE_COUNT = 10; const PROMPT_COLLAPSED_LINE_COUNT = 10;
export function Prompt(props: BlockProps<DocumentBlockPrompt>) { export function Prompt(props: BlockProps<DocumentBlockPrompt>) {
const { block, document, ancestorBlocks, context, isEstimatedOffscreen, style } = props; const { block, document, ancestorBlocks, context, isEstimatedOffscreen } = props;
const contentIcon = const contentIcon =
block.data.icon && validateIconName(block.data.icon) ? block.data.icon : null; block.data.icon && validateIconName(block.data.icon) ? block.data.icon : null;
const prompt = getPromptText(block); const prompt = getPromptText(block);
@@ -41,13 +39,6 @@ export function Prompt(props: BlockProps<DocumentBlockPrompt>) {
defaultExpanded={defaultExpanded} defaultExpanded={defaultExpanded}
openInAIProviders={getOpenInAIProviders(props)} openInAIProviders={getOpenInAIProviders(props)}
prompt={prompt} prompt={prompt}
{...getCommentKeyProp(context, block.key)}
// Only the comment marker: the prompt keeps its own width rather than the block styles.
className={
tcls(style).split(' ').includes(COMMENT_IGNORE_CLASSNAME)
? COMMENT_IGNORE_CLASSNAME
: undefined
}
> >
{promptContent} {promptContent}
</PromptClient> </PromptClient>
@@ -13,9 +13,6 @@ import { tcls } from '@/lib/tailwind';
type PromptClientProps = DocumentBlockPrompt['data'] & { type PromptClientProps = DocumentBlockPrompt['data'] & {
contentIcon: IconName | null; contentIcon: IconName | null;
prompt: string; prompt: string;
/** Comment target: its code nodes aren't, so the prompt owns clicks inside it. */
commentKey?: string;
className?: string;
children?: React.ReactNode; children?: React.ReactNode;
}; };
@@ -26,8 +23,6 @@ export function PromptClient(props: PromptClientProps) {
openInAIProviders = false, openInAIProviders = false,
defaultExpanded = 'hidden', defaultExpanded = 'hidden',
prompt, prompt,
commentKey,
className,
children, children,
} = props; } = props;
const language = useLanguage(); const language = useLanguage();
@@ -42,14 +37,11 @@ export function PromptClient(props: PromptClientProps) {
return ( return (
<div <div
data-block-key={commentKey}
data-comment-block={commentKey ? '' : undefined}
className={tcls( className={tcls(
'relative flex w-full flex-col overflow-hidden circular-corners:rounded-2xl rounded-corners:rounded-xl straight-corners:rounded-xs text-tint-strong', 'relative flex w-full flex-col overflow-hidden circular-corners:rounded-2xl rounded-corners:rounded-xl straight-corners:rounded-xs text-tint-strong',
'border border-tint-subtle contrast-more:border-tint', 'border border-tint-subtle contrast-more:border-tint',
'transition', 'transition',
expanded ? 'bg-tint depth-subtle:shadow-xs' : 'bg-tint-base', expanded ? 'bg-tint depth-subtle:shadow-xs' : 'bg-tint-base'
className
)} )}
> >
<div <div
@@ -2,7 +2,6 @@ import type { DocumentBlockReusableContent } from '@gitbook/api';
import type { BlockProps } from './Block'; import type { BlockProps } from './Block';
import { UnwrappedBlocks } from './Blocks'; import { UnwrappedBlocks } from './Blocks';
import { COMMENT_IGNORE_CLASSNAME } from './utils';
import { getDataOrNull } from '@/lib/data'; import { getDataOrNull } from '@/lib/data';
import { resolveContentRefInDocument } from '@/lib/references'; import { resolveContentRefInDocument } from '@/lib/references';
@@ -51,9 +50,6 @@ export async function ReusableContent(props: BlockProps<DocumentBlockReusableCon
nodes={reusableContentDocument.nodes} nodes={reusableContentDocument.nodes}
document={reusableContentDocument} document={reusableContentDocument}
ancestorBlocks={[...ancestorBlocks, block]} ancestorBlocks={[...ancestorBlocks, block]}
// Its blocks carry keys of the reusable content's own document, which comments on the
// page can't anchor to. A class, not a wrapper, which would break the page's spacing.
blockStyle={context.withCommentAnchors ? COMMENT_IGNORE_CLASSNAME : undefined}
context={{ context={{
...context, ...context,
contentContext: reusableContent.context, contentContext: reusableContent.context,
@@ -4,12 +4,10 @@ import type { DocumentBlockStepperStep } from '@gitbook/api';
import type { BlockProps } from './Block'; import type { BlockProps } from './Block';
import { Blocks } from './Blocks'; import { Blocks } from './Blocks';
import { getCommentAnchorProps } from './utils';
import { tcls } from '@/lib/tailwind'; import { tcls } from '@/lib/tailwind';
export function StepperStep(props: BlockProps<DocumentBlockStepperStep>) { export function StepperStep(props: BlockProps<DocumentBlockStepperStep>) {
const { block, style, ancestorBlocks, ...contextProps } = props; const { block, style, ancestorBlocks, ...contextProps } = props;
const { context } = contextProps;
const ancestor = ancestorBlocks[ancestorBlocks.length - 1]; const ancestor = ancestorBlocks[ancestorBlocks.length - 1];
assert(ancestor?.type === 'stepper', 'Ancestor block must be a stepper'); assert(ancestor?.type === 'stepper', 'Ancestor block must be a stepper');
@@ -34,10 +32,7 @@ export function StepperStep(props: BlockProps<DocumentBlockStepperStep>) {
})(); })();
return ( return (
<div <div className={tcls('flex flex-row gap-4 md:gap-8', style)}>
{...getCommentAnchorProps(context, block.key)}
className={tcls('flex flex-row gap-4 md:gap-8', style)}
>
<div className="relative select-none"> <div className="relative select-none">
<div <div
className={tcls( className={tcls(
@@ -1,4 +1,3 @@
import { getCommentCellProps } from '../utils';
import { getTableCellMerge } from './cellMerges'; import { getTableCellMerge } from './cellMerges';
import { getColumnWidth, getViewGridLayout, hasVisibleHeader } from './layout'; import { getColumnWidth, getViewGridLayout, hasVisibleHeader } from './layout';
import { RecordColumnValue } from './RecordColumnValue'; import { RecordColumnValue } from './RecordColumnValue';
@@ -6,7 +5,7 @@ import { StickyViewGrid } from './StickyViewGrid';
import type { TableGridViewProps } from './Table'; import type { TableGridViewProps } from './Table';
import { TableHoverTable } from './TableHoverTable'; import { TableHoverTable } from './TableHoverTable';
import { TableSearchTableBody } from './TableSearch'; import { TableSearchTableBody } from './TableSearch';
import { getColumnAlignment, getColumnVerticalAlignment, type VerticalAlignment } from './utils'; import { type VerticalAlignment, getColumnAlignment, getColumnVerticalAlignment } from './utils';
import { tcls } from '@/lib/tailwind'; import { tcls } from '@/lib/tailwind';
/** Semantic table renderer used when a cell spans multiple records. */ /** Semantic table renderer used when a cell spans multiple records. */
@@ -142,7 +141,7 @@ function NativeViewGridBody(
stickyFirstColumn: boolean; stickyFirstColumn: boolean;
} }
) { ) {
const { block, view, records, withHeader, stickyFirstColumn, cellMergeLayout, context } = props; const { block, view, records, withHeader, stickyFirstColumn, cellMergeLayout } = props;
const firstVisibleColumn = view.columns[0]; const firstVisibleColumn = view.columns[0];
const lastVisibleColumn = view.columns.at(-1); const lastVisibleColumn = view.columns.at(-1);
const recordsById = new Map(records.map((record) => [record[0], record] as const)); const recordsById = new Map(records.map((record) => [record[0], record] as const));
@@ -220,7 +219,6 @@ function NativeViewGridBody(
colSpan={colSpan} colSpan={colSpan}
aria-rowspan={rowSpan} aria-rowspan={rowSpan}
aria-colspan={colSpan} aria-colspan={colSpan}
{...getCommentCellProps(context, recordId, column)}
data-table-row-start={recordIndex} data-table-row-start={recordIndex}
data-table-row-end={ data-table-row-end={
recordIndex + (cellMerge?.merge.rowSpan ?? 1) - 1 recordIndex + (cellMerge?.merge.rowSpan ?? 1) - 1
@@ -1,4 +1,3 @@
import { getCommentCellProps } from '../utils';
import { getMergedCellWidth, getTableCellMerge } from './cellMerges'; import { getMergedCellWidth, getTableCellMerge } from './cellMerges';
import { getColumnWidth } from './layout'; import { getColumnWidth } from './layout';
import { RecordColumnValue } from './RecordColumnValue'; import { RecordColumnValue } from './RecordColumnValue';
@@ -55,7 +54,6 @@ export function RecordRow(
<div <div
key={column} key={column}
role="cell" role="cell"
{...getCommentCellProps(context, record[0], column)}
aria-colspan={cellMerge?.merge.colSpan} aria-colspan={cellMerge?.merge.colSpan}
className={tcls( className={tcls(
'relative flex flex-1 border-r px-3 py-2 align-middle text-sm last:border-r-0', 'relative flex flex-1 border-r px-3 py-2 align-middle text-sm last:border-r-0',
@@ -3,7 +3,7 @@ import assertNever from 'assert-never';
import type { DocumentBlockTable, DocumentTableViewGrid } from '@gitbook/api'; import type { DocumentBlockTable, DocumentTableViewGrid } from '@gitbook/api';
import type { BlockProps } from '../Block'; import type { BlockProps } from '../Block';
import { getCommentAnchorProps, getCommentMarkerProps, isBlockOffscreen } from '../utils'; import { isBlockOffscreen } from '../utils';
import { type TableCellMergeLayout, createTableCellMergeLayout } from './cellMerges'; import { type TableCellMergeLayout, createTableCellMergeLayout } from './cellMerges';
import { getViewGridLayout, hasVisibleHeader } from './layout'; import { getViewGridLayout, hasVisibleHeader } from './layout';
import { NativeViewGrid } from './NativeViewGrid'; import { NativeViewGrid } from './NativeViewGrid';
@@ -74,12 +74,7 @@ export function Table(props: BlockProps<DocumentBlockTable>) {
block.data.view.type === 'grid' ? cellMergeLayout.recordGroups : undefined block.data.view.type === 'grid' ? cellMergeLayout.recordGroups : undefined
} }
> >
<div <div className={tcls(style, 'flex flex-col gap-3')}>
{...getCommentAnchorProps(context, block.key)}
// Owns clicks inside, e.g. on blocks of a record's own document; cells still win.
{...getCommentMarkerProps(context, 'data-comment-block')}
className={tcls(style, 'flex flex-col gap-3')}
>
{showSearch ? ( {showSearch ? (
<TableSearchInput <TableSearchInput
selectColumns={selectColumns} selectColumns={selectColumns}
@@ -130,7 +130,7 @@ const TabPanel = memo(function TabPanel(props: {
aria-labelledby={getTabButtonId(tab.id)} aria-labelledby={getTabButtonId(tab.id)}
className="scroll-mt-[calc(var(--content-scroll-margin)+var(--spacing)*20)]" className="scroll-mt-[calc(var(--content-scroll-margin)+var(--spacing)*20)]"
> >
<div className="px-8 py-6">{tab.body}</div> <div className="p-4">{tab.body}</div>
</div> </div>
); );
}); });
@@ -317,7 +317,7 @@ function TabButton(
{...rest} {...rest}
type="button" type="button"
className={tcls( className={tcls(
'relative inline-flex max-w-full items-center gap-1.5 px-4 py-2.5 font-medium text-sm transition-[color]', 'relative inline-flex max-w-full items-center gap-1.5 px-3.5 py-2 font-medium text-sm transition-[color]',
props.className props.className
)} )}
/> />
@@ -1,49 +0,0 @@
import type { DocumentContext } from '../DocumentView';
// Spread rather than set to `undefined`: an `undefined` prop is still written to the RSC payload,
// so public pages would keep paying for the attribute names.
/** Marks blocks comments can't anchor to, passed down as their `style` (see `ReusableContent`). */
export const COMMENT_IGNORE_CLASSNAME = 'comment-ignore';
/** The node key comments anchor to, only where commenting is possible. */
export function getCommentAnchorProps(
context: DocumentContext,
key: string | undefined
): { 'data-block-key'?: string } {
return context.withCommentAnchors && key ? { 'data-block-key': key } : {};
}
/** A table cell's record and column, only where commenting is possible. */
export function getCommentCellProps(
context: DocumentContext,
record: string,
column: string
): { 'data-table-record'?: string; 'data-table-column'?: string } {
return context.withCommentAnchors
? { 'data-table-record': record, 'data-table-column': column }
: {};
}
/** A boolean comment marker, only where commenting is possible. */
export function getCommentMarkerProps(
context: DocumentContext,
name: 'data-comment-block' | 'data-comment-ignore'
): Partial<Record<typeof name, ''>> {
return context.withCommentAnchors ? { [name]: '' } : {};
}
/** The node key as a `commentKey` prop for components rendering it themselves (e.g. client ones). */
export function getCommentKeyProp(
context: DocumentContext,
key: string | undefined
): { commentKey?: string } {
return context.withCommentAnchors && key ? { commentKey: key } : {};
}
/** The anchor attribute for a `commentKey` prop, when set. */
export function getCommentKeyAttributes(commentKey: string | undefined): {
'data-block-key'?: string;
} {
return commentKey ? { 'data-block-key': commentKey } : {};
}
@@ -1,3 +1,2 @@
export * from './isBlockOffscreen'; export * from './isBlockOffscreen';
export * from './textAlignment'; export * from './textAlignment';
export * from './commentAnchors';
@@ -10,7 +10,6 @@ import { Icon, type IconName, IconStyle } from '@gitbook/icons';
import { useAIChatController, useAIChatState } from '@/components/AI'; import { useAIChatController, useAIChatState } from '@/components/AI';
import type { Assistant } from '@/components/AI'; import type { Assistant } from '@/components/AI';
import { useTrackEvent } from '@/components/Insights';
import { Button } from '@/components/primitives/Button'; import { Button } from '@/components/primitives/Button';
import { DropdownMenuItem, useDropdownMenuClose } from '@/components/primitives/DropdownMenu'; import { DropdownMenuItem, useDropdownMenuClose } from '@/components/primitives/DropdownMenu';
import { getURLForLLM } from '@/components/utils'; import { getURLForLLM } from '@/components/utils';
@@ -40,7 +39,6 @@ export function ActionOpenAssistant(props: {
const { assistant, type, page } = props; const { assistant, type, page } = props;
const chat = useAIChatState(); const chat = useAIChatState();
const chatController = useAIChatController(); const chatController = useAIChatController();
const trackEvent = useTrackEvent();
const language = useLanguage(); const language = useLanguage();
return ( return (
@@ -57,7 +55,6 @@ export function ActionOpenAssistant(props: {
)} )}
disabled={chat.responding} disabled={chat.responding}
onClick={() => { onClick={() => {
trackEvent({ type: 'ask_trigger_click', trigger: 'page' });
// Stage a reference to the current page so the assistant is informed about // Stage a reference to the current page so the assistant is informed about
// the context the user is asking from. Only the sidebar GitBook Assistant // the context the user is asking from. Only the sidebar GitBook Assistant
// uses the chat reference system. // uses the chat reference system.
@@ -58,9 +58,6 @@ export async function PageBody(props: {
? hasTopLevelBlock(document, (block) => block.type === 'updates') ? hasTopLevelBlock(document, (block) => block.type === 'updates')
: false; : false;
// Comments can only be made on change request previews, so public pages skip their markers.
const withCommentAnchors = Boolean(context.changeRequest);
// Render link previews only if there are less than LINK_PREVIEW_MAX_COUNT links in the document. // Render link previews only if there are less than LINK_PREVIEW_MAX_COUNT links in the document.
const withLinkPreviews = document const withLinkPreviews = document
? !hasMoreThan( ? !hasMoreThan(
@@ -103,8 +100,6 @@ export async function PageBody(props: {
/> />
) : null} ) : null}
<main <main
// Comments on the whole page target anywhere in it that isn't a block.
{...(withCommentAnchors ? { 'data-comment-page': '' } : {})}
className={tcls( className={tcls(
'relative min-w-0 flex-1', 'relative min-w-0 flex-1',
'break-anywhere', // Allow words to break if they are too long. 'break-anywhere', // Allow words to break if they are too long.
@@ -155,7 +150,6 @@ export async function PageBody(props: {
page, page,
}, },
withLinkPreviews, withLinkPreviews,
withCommentAnchors,
isPageBody: true, isPageBody: true,
}} }}
/> />
@@ -255,8 +255,6 @@ export async function PageHeader(props: {
<PageTags page={page} revision={revision} /> <PageTags page={page} revision={revision} />
{page.layout.title ? ( {page.layout.title ? (
<h1 <h1
// Comments on the whole page get their pin next to the title.
{...(context.changeRequest ? { 'data-comment-page-title': '' } : {})}
data-cover-aware-text data-cover-aware-text
data-over-cover data-over-cover
className={tcls( className={tcls(
@@ -9,7 +9,7 @@ import { Icon, type IconName } from '@gitbook/icons';
import { Link, type LinkInsightsProps } from '.'; import { Link, type LinkInsightsProps } from '.';
import { ToggleChevron } from './ToggleChevron'; import { ToggleChevron } from './ToggleChevron';
import { Tooltip, type TooltipProps } from './Tooltip'; import { Tooltip } from './Tooltip';
import { type ClassValue, tcls } from '@/lib/tailwind'; import { type ClassValue, tcls } from '@/lib/tailwind';
export type DropdownButtonProps<E extends HTMLElement = HTMLElement> = Omit< export type DropdownButtonProps<E extends HTMLElement = HTMLElement> = Omit<
@@ -41,8 +41,6 @@ export function DropdownMenu(props: {
button: React.ReactElement<Record<string, unknown>>; button: React.ReactElement<Record<string, unknown>>;
/** Tooltip label for the button */ /** Tooltip label for the button */
buttonTooltip?: React.ReactNode; buttonTooltip?: React.ReactNode;
/** Placement of the button's tooltip. */
buttonTooltipProps?: Pick<TooltipProps, 'side' | 'sideOffset' | 'anchor'>;
/** Content of the dropdown */ /** Content of the dropdown */
children: React.ReactNode; children: React.ReactNode;
/** Custom styles */ /** Custom styles */
@@ -74,7 +72,6 @@ export function DropdownMenu(props: {
const { const {
button, button,
buttonTooltip, buttonTooltip,
buttonTooltipProps,
children, children,
className, className,
openOnHover = false, openOnHover = false,
@@ -101,7 +98,7 @@ export function DropdownMenu(props: {
<DropdownMenuContext.Provider value={{ open, setOpen }}> <DropdownMenuContext.Provider value={{ open, setOpen }}>
<Menu.Root modal={false} open={open} onOpenChange={setOpen}> <Menu.Root modal={false} open={open} onOpenChange={setOpen}>
{buttonTooltip ? ( {buttonTooltip ? (
<Tooltip label={buttonTooltip} disableHoverablePopup {...buttonTooltipProps}> <Tooltip label={buttonTooltip} disableHoverablePopup>
{trigger} {trigger}
</Tooltip> </Tooltip>
) : ( ) : (
@@ -10,8 +10,6 @@ export type TooltipProps = {
side?: BaseTooltip.Positioner.Props['side']; side?: BaseTooltip.Positioner.Props['side'];
align?: BaseTooltip.Positioner.Props['align']; align?: BaseTooltip.Positioner.Props['align'];
sideOffset?: number; sideOffset?: number;
/** Positions against this element instead of the trigger, e.g. when the trigger is transformed. */
anchor?: BaseTooltip.Positioner.Props['anchor'];
delay?: number; delay?: number;
disabled?: boolean; disabled?: boolean;
disableHoverablePopup?: boolean; disableHoverablePopup?: boolean;
@@ -33,7 +31,6 @@ export function Tooltip(
side, side,
align, align,
sideOffset = 4, sideOffset = 4,
anchor,
delay, delay,
disabled, disabled,
disableHoverablePopup, disableHoverablePopup,
@@ -72,7 +69,6 @@ export function Tooltip(
side={side} side={side}
align={align} align={align}
sideOffset={sideOffset} sideOffset={sideOffset}
anchor={anchor}
collisionPadding={8} collisionPadding={8}
> >
<BaseTooltip.Popup <BaseTooltip.Popup
@@ -1,4 +1,3 @@
import { joinPathWithBaseURL } from '../paths';
import { checkIsHttpURL } from '../urls'; import { checkIsHttpURL } from '../urls';
/** Matches the `feedback` length accepted by `submitSiteAgentFeedback`. */ /** Matches the `feedback` length accepted by `submitSiteAgentFeedback`. */
@@ -14,7 +13,7 @@ export const agentFeedbackDescriptions = {
goal: 'The broader end goal you were ultimately trying to accomplish (as/on behalf of the user) when you hit this issue. Gives the team the context you were working towards. Optional.', goal: 'The broader end goal you were ultimately trying to accomplish (as/on behalf of the user) when you hit this issue. Gives the team the context you were working towards. Optional.',
pageURL: (siteURL: string | undefined) => pageURL: (siteURL: string | undefined) =>
`The full URL of the page the issue is about${siteURL ? ` (e.g. ${joinPathWithBaseURL(siteURL, 'getting-started')})` : ''}, so the finding is linked to the exact page.`, `The full URL of the page the issue is about${siteURL ? ` (e.g. ${siteURL}/getting-started)` : ''}, so the finding is linked to the exact page.`,
pageReference: pageReference:
'The URL of the page the issue is about, so the finding is linked to the exact page. Omit it to report about the page the user is currently viewing.', 'The URL of the page the issue is about, so the finding is linked to the exact page. Omit it to report about the page the user is currently viewing.',
@@ -334,18 +334,6 @@ describe('buildSiteMcpServerCard', () => {
expect(search).not.toHaveProperty('inputSchema'); expect(search).not.toHaveProperty('inputSchema');
}); });
it('gives example page URLs under the path of a subpath site', () => {
const context = makeContext({ host: 'docs.example.com', siteBasePath: '/product/' });
const tools = createSiteMcpTools(context, { request });
const getPage = tools.find((tool) => tool.name === 'getPage');
const pageUrl = tools.find((tool) => tool.name === 'sendFeedback')?.inputSchema.pageUrl;
const example = 'https://docs.example.com/product/getting-started';
expect(getPage?.description).toContain(`(e.g. ${example})`);
expect(pageUrl?.description).toContain(`(e.g. ${example})`);
expect(pageUrl?.parse('getting-started')).toBe(example);
});
it('omits askQuestion when the site has no AI mode', () => { it('omits askQuestion when the site has no AI mode', () => {
const withAI = buildCard({ aiMode: CustomizationAIMode.Assistant }); const withAI = buildCard({ aiMode: CustomizationAIMode.Assistant });
const withoutAI = buildCard({ aiMode: CustomizationAIMode.None }); const withoutAI = buildCard({ aiMode: CustomizationAIMode.None });
+3 -4
View File
@@ -51,7 +51,6 @@ export function createSiteMcpTools(
const { request } = options; const { request } = options;
const { dataFetcher, linker, site } = context; const { dataFetcher, linker, site } = context;
const siteUrl = context.siteSpace.urls.published; const siteUrl = context.siteSpace.urls.published;
const examplePageURL = siteUrl ? joinPathWithBaseURL(siteUrl, 'getting-started') : undefined;
const tools: SiteMcpTool[] = [ const tools: SiteMcpTool[] = [
defineTool({ defineTool({
@@ -147,7 +146,7 @@ export function createSiteMcpTools(
defineTool({ defineTool({
name: 'getPage', name: 'getPage',
description: `Fetch the full markdown content of a specific documentation page from ${site.title}. Use this when you have a page URL and want to read its content. Accepts full URLs (e.g. ${examplePageURL}). Since \`searchDocumentation\` returns partial content, use \`getPage\` to retrieve the complete page when you need more details. The content includes links you can follow to navigate to related pages.`, description: `Fetch the full markdown content of a specific documentation page from ${site.title}. Use this when you have a page URL and want to read its content. Accepts full URLs (e.g. ${siteUrl}/getting-started). Since \`searchDocumentation\` returns partial content, use \`getPage\` to retrieve the complete page when you need more details. The content includes links you can follow to navigate to related pages.`,
inputSchema: { inputSchema: {
url: z url: z
.string() .string()
@@ -161,7 +160,7 @@ export function createSiteMcpTools(
} }
ctx.addIssue({ ctx.addIssue({
code: z.ZodIssueCode.custom, code: z.ZodIssueCode.custom,
message: `"${value}" is not a valid URL. Expected a full URL like ${examplePageURL}`, message: `"${value}" is not a valid URL. Expected a full URL like ${siteUrl}/getting-started`,
}); });
return z.NEVER; return z.NEVER;
}), }),
@@ -357,7 +356,7 @@ export function createSiteMcpTools(
if (!url) { if (!url) {
ctx.addIssue({ ctx.addIssue({
code: z.ZodIssueCode.custom, code: z.ZodIssueCode.custom,
message: `"${value}" is not a valid URL on this site. Expected a full URL like ${examplePageURL}`, message: `"${value}" is not a valid URL on this site. Expected a full URL like ${siteUrl}/getting-started`,
}); });
return z.NEVER; return z.NEVER;
} }
+1 -1
View File
@@ -579,7 +579,7 @@ async function serveSiteRoutes(requestURL: URL, request: NextRequest) {
// noindex search/assistant deep links, kept crawlable so Google sees the directive. // noindex search/assistant deep links, kept crawlable so Google sees the directive.
if (rewrittenURL.searchParams.has('ask') || rewrittenURL.searchParams.has('q')) { if (rewrittenURL.searchParams.has('ask') || rewrittenURL.searchParams.has('q')) {
response.headers.set('x-robots-tag', 'none'); response.headers.set('x-robots-tag', 'noindex');
} }
// Allow cross-origin requests from the same parent domain as the site. // Allow cross-origin requests from the same parent domain as the site.