mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-12 22:09:04 +00:00
Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7b34537bbe | |||
| 145f385fdb | |||
| 360aa1c6d6 | |||
| ccc0975240 | |||
| 791135040a | |||
| 12c9d765ff | |||
| 45207288a1 | |||
| 177afa5828 | |||
| d51b79edbb | |||
| a2720ac49d | |||
| 5f6853d812 | |||
| 17dd382dc3 | |||
| 98e42cfe79 | |||
| c890e01004 | |||
| 659be551bb | |||
| 78a632b7fe | |||
| 4927e964b7 | |||
| 262a9b198b | |||
| 4f3588240c | |||
| abbae3ec4d | |||
| 1b8609ac60 | |||
| 193d591e9f | |||
| 1edc5d622a | |||
| 61b8507996 | |||
| 6f368b5cf3 | |||
| 9201e2cf52 | |||
| 2e0d706d43 | |||
| 7fefe4919c | |||
| 729921f338 | |||
| 1839ea2678 | |||
| f08dd29364 | |||
| ca2dfa3065 | |||
| 10ded437f0 | |||
| d1fdc13441 | |||
| a8fca0e033 |
@@ -12,7 +12,7 @@
|
||||
},
|
||||
"packages/browser-types": {
|
||||
"name": "@gitbook/browser-types",
|
||||
"version": "0.0.0",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@gitbook/api": "catalog:",
|
||||
"@gitbook/icons": "workspace:",
|
||||
@@ -41,7 +41,7 @@
|
||||
},
|
||||
"packages/embed": {
|
||||
"name": "@gitbook/embed",
|
||||
"version": "0.0.0",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@gitbook/api": "catalog:",
|
||||
"@gitbook/icons": "workspace:",
|
||||
@@ -64,7 +64,7 @@
|
||||
},
|
||||
"packages/expr": {
|
||||
"name": "@gitbook/expr",
|
||||
"version": "0.0.1",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"acorn": "^8.14.0",
|
||||
"acorn-loose": "8.4.0",
|
||||
@@ -92,20 +92,21 @@
|
||||
},
|
||||
"packages/gitbook": {
|
||||
"name": "gitbook",
|
||||
"version": "0.15.0",
|
||||
"version": "0.16.0",
|
||||
"dependencies": {
|
||||
"@gitbook/api": "catalog:",
|
||||
"@gitbook/browser-types": "workspace:*",
|
||||
"@gitbook/cache-tags": "workspace:*",
|
||||
"@gitbook/colors": "workspace:*",
|
||||
"@gitbook/emoji-codepoints": "workspace:*",
|
||||
"@gitbook/expr": "workspace:*",
|
||||
"@gitbook/fonts": "workspace:*",
|
||||
"@gitbook/icons": "workspace:*",
|
||||
"@gitbook/openapi-parser": "workspace:*",
|
||||
"@gitbook/react-contentkit": "workspace:*",
|
||||
"@gitbook/react-math": "workspace:*",
|
||||
"@gitbook/react-openapi": "workspace:*",
|
||||
"@opennextjs/cloudflare": "^1.6.4",
|
||||
"@opennextjs/cloudflare": "^1.7.1",
|
||||
"@radix-ui/react-checkbox": "^1.0.4",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.12",
|
||||
"@radix-ui/react-hover-card": "^1.1.15",
|
||||
@@ -137,7 +138,7 @@
|
||||
"memoizee": "^0.4.17",
|
||||
"micromark-extension-frontmatter": "^2.0.0",
|
||||
"micromark-extension-gfm": "^3.0.0",
|
||||
"next": "^15.5.0",
|
||||
"next": "15.3.5",
|
||||
"next-themes": "^0.2.1",
|
||||
"nuqs": "^2.2.3",
|
||||
"object-hash": "^3.0.0",
|
||||
@@ -193,7 +194,7 @@
|
||||
},
|
||||
"packages/icons": {
|
||||
"name": "@gitbook/icons",
|
||||
"version": "0.2.2",
|
||||
"version": "0.3.0",
|
||||
"bin": {
|
||||
"gitbook-icons": "./bin/gitbook-icons.js",
|
||||
},
|
||||
@@ -213,10 +214,11 @@
|
||||
},
|
||||
"packages/openapi-parser": {
|
||||
"name": "@gitbook/openapi-parser",
|
||||
"version": "3.0.0",
|
||||
"version": "3.0.1",
|
||||
"dependencies": {
|
||||
"@scalar/openapi-parser": "^0.18.0",
|
||||
"@scalar/openapi-types": "^0.1.9",
|
||||
"@scalar/json-magic": "^0.3.1",
|
||||
"@scalar/openapi-parser": "^0.20.1",
|
||||
"@scalar/openapi-types": "^0.3.7",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tsconfig/node20": "^20.1.4",
|
||||
@@ -228,7 +230,7 @@
|
||||
},
|
||||
"packages/react-contentkit": {
|
||||
"name": "@gitbook/react-contentkit",
|
||||
"version": "0.7.3",
|
||||
"version": "0.7.4",
|
||||
"dependencies": {
|
||||
"@gitbook/api": "catalog:",
|
||||
"@gitbook/icons": "workspace:*",
|
||||
@@ -260,13 +262,16 @@
|
||||
},
|
||||
"packages/react-openapi": {
|
||||
"name": "@gitbook/react-openapi",
|
||||
"version": "1.3.5",
|
||||
"version": "1.3.6",
|
||||
"dependencies": {
|
||||
"@gitbook/expr": "workspace:*",
|
||||
"@gitbook/openapi-parser": "workspace:*",
|
||||
"@scalar/api-client-react": "^1.3.16",
|
||||
"@scalar/oas-utils": "^0.2.130",
|
||||
"@scalar/types": "^0.1.9",
|
||||
"clsx": "^2.1.1",
|
||||
"flatted": "^3.2.9",
|
||||
"js-yaml": "^4.1.0",
|
||||
"json-xml-parse": "^1.3.0",
|
||||
"react-aria": "^3.37.0",
|
||||
"react-aria-components": "^1.6.0",
|
||||
@@ -274,6 +279,7 @@
|
||||
"zustand": "^5.0.3",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
"bun-types": "^1.1.20",
|
||||
"typescript": "^5.5.3",
|
||||
},
|
||||
@@ -293,7 +299,7 @@
|
||||
"react-dom": "^19.0.0",
|
||||
},
|
||||
"catalog": {
|
||||
"@gitbook/api": "^0.136.0",
|
||||
"@gitbook/api": "^0.139.0",
|
||||
"bidc": "^0.0.2",
|
||||
},
|
||||
"packages": {
|
||||
@@ -447,7 +453,7 @@
|
||||
|
||||
"@babel/highlight": ["@babel/highlight@7.25.7", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.25.7", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" } }, "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw=="],
|
||||
|
||||
"@babel/parser": ["@babel/parser@7.25.8", "", { "dependencies": { "@babel/types": "^7.25.8" }, "bin": "./bin/babel-parser.js" }, "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ=="],
|
||||
"@babel/parser": ["@babel/parser@7.28.3", "", { "dependencies": { "@babel/types": "^7.28.2" }, "bin": "./bin/babel-parser.js" }, "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA=="],
|
||||
|
||||
"@babel/runtime": ["@babel/runtime@7.25.7", "", { "dependencies": { "regenerator-runtime": "^0.14.0" } }, "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w=="],
|
||||
|
||||
@@ -659,7 +665,7 @@
|
||||
|
||||
"@fortawesome/fontawesome-svg-core": ["@fortawesome/fontawesome-svg-core@6.6.0", "", { "dependencies": { "@fortawesome/fontawesome-common-types": "6.6.0" } }, "sha512-KHwPkCk6oRT4HADE7smhfsKudt9N/9lm6EJ5BVg0tD1yPA5hht837fB87F8pn15D8JfTqQOjhKTktwmLMiD7Kg=="],
|
||||
|
||||
"@gitbook/api": ["@gitbook/api@0.136.0", "", { "dependencies": { "event-iterator": "^2.0.0", "eventsource-parser": "^3.0.0" } }, "sha512-IxNqmXE6yUEUq0IzbenN8S/PcMfgxr4+akY8xh6V5ShI/+U37ixujJHZp2zJq6NdZOdBQoR3UQmhPnvtWrkF7g=="],
|
||||
"@gitbook/api": ["@gitbook/api@0.139.0", "", { "dependencies": { "event-iterator": "^2.0.0", "eventsource-parser": "^3.0.0" } }, "sha512-6VqN4BVvOdaRng2xz5wh0gj6NJmJJZwtswKZ6g9RMWedp2UkeMXi+kcO3fBo2VYJsxhIgbtWikqGEePgHTx67g=="],
|
||||
|
||||
"@gitbook/browser-types": ["@gitbook/browser-types@workspace:packages/browser-types"],
|
||||
|
||||
@@ -795,23 +801,23 @@
|
||||
|
||||
"@mapbox/node-pre-gyp": ["@mapbox/node-pre-gyp@2.0.0-rc.0", "", { "dependencies": { "consola": "^3.2.3", "detect-libc": "^2.0.0", "https-proxy-agent": "^7.0.5", "node-fetch": "^2.6.7", "nopt": "^8.0.0", "semver": "^7.5.3", "tar": "^7.4.0" }, "bin": { "node-pre-gyp": "bin/node-pre-gyp" } }, "sha512-nhSMNprz3WmeRvd8iUs5JqkKr0Ncx46JtPxM3AhXes84XpSJfmIwKeWXRpsr53S7kqPkQfPhzrMFUxSNb23qSA=="],
|
||||
|
||||
"@next/env": ["@next/env@15.5.0", "", {}, "sha512-sDaprBAfzCQiOgo2pO+LhnV0Wt2wBgartjrr+dpcTORYVnnXD0gwhHhiiyIih9hQbq+JnbqH4odgcFWhqCGidw=="],
|
||||
"@next/env": ["@next/env@15.3.5", "", {}, "sha512-7g06v8BUVtN2njAX/r8gheoVffhiKFVt4nx74Tt6G4Hqw9HCLYQVx/GkH2qHvPtAHZaUNZ0VXAa0pQP6v1wk7g=="],
|
||||
|
||||
"@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@15.5.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-v7Jj9iqC6enxIRBIScD/o0lH7QKvSxq2LM8UTyqJi+S2w2QzhMYjven4vgu/RzgsdtdbpkyCxBTzHl/gN5rTRg=="],
|
||||
"@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@15.3.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-lM/8tilIsqBq+2nq9kbTW19vfwFve0NR7MxfkuSUbRSgXlMQoJYg+31+++XwKVSXk4uT23G2eF/7BRIKdn8t8w=="],
|
||||
|
||||
"@next/swc-darwin-x64": ["@next/swc-darwin-x64@15.5.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-s2Nk6ec+pmYmAb/utawuURy7uvyYKDk+TRE5aqLRsdnj3AhwC9IKUBmhfnLmY/+P+DnwqpeXEFIKe9tlG0p6CA=="],
|
||||
"@next/swc-darwin-x64": ["@next/swc-darwin-x64@15.3.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-WhwegPQJ5IfoUNZUVsI9TRAlKpjGVK0tpJTL6KeiC4cux9774NYE9Wu/iCfIkL/5J8rPAkqZpG7n+EfiAfidXA=="],
|
||||
|
||||
"@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@15.5.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-mGlPJMZReU4yP5fSHjOxiTYvZmwPSWn/eF/dcg21pwfmiUCKS1amFvf1F1RkLHPIMPfocxLViNWFvkvDB14Isg=="],
|
||||
"@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@15.3.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-LVD6uMOZ7XePg3KWYdGuzuvVboxujGjbcuP2jsPAN3MnLdLoZUXKRc6ixxfs03RH7qBdEHCZjyLP/jBdCJVRJQ=="],
|
||||
|
||||
"@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@15.5.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-biWqIOE17OW/6S34t1X8K/3vb1+svp5ji5QQT/IKR+VfM3B7GvlCwmz5XtlEan2ukOUf9tj2vJJBffaGH4fGRw=="],
|
||||
"@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@15.3.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-k8aVScYZ++BnS2P69ClK7v4nOu702jcF9AIHKu6llhHEtBSmM2zkPGl9yoqbSU/657IIIb0QHpdxEr0iW9z53A=="],
|
||||
|
||||
"@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@15.5.0", "", { "os": "linux", "cpu": "x64" }, "sha512-zPisT+obYypM/l6EZ0yRkK3LEuoZqHaSoYKj+5jiD9ESHwdr6QhnabnNxYkdy34uCigNlWIaCbjFmQ8FY5AlxA=="],
|
||||
"@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@15.3.5", "", { "os": "linux", "cpu": "x64" }, "sha512-2xYU0DI9DGN/bAHzVwADid22ba5d/xrbrQlr2U+/Q5WkFUzeL0TDR963BdrtLS/4bMmKZGptLeg6282H/S2i8A=="],
|
||||
|
||||
"@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@15.5.0", "", { "os": "linux", "cpu": "x64" }, "sha512-+t3+7GoU9IYmk+N+FHKBNFdahaReoAktdOpXHFIPOU1ixxtdge26NgQEEkJkCw2dHT9UwwK5zw4mAsURw4E8jA=="],
|
||||
"@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@15.3.5", "", { "os": "linux", "cpu": "x64" }, "sha512-TRYIqAGf1KCbuAB0gjhdn5Ytd8fV+wJSM2Nh2is/xEqR8PZHxfQuaiNhoF50XfY90sNpaRMaGhF6E+qjV1b9Tg=="],
|
||||
|
||||
"@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@15.5.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-d8MrXKh0A+c9DLiy1BUFwtg3Hu90Lucj3k6iKTUdPOv42Ve2UiIG8HYi3UAb8kFVluXxEfdpCoPPCSODk5fDcw=="],
|
||||
"@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@15.3.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-h04/7iMEUSMY6fDGCvdanKqlO1qYvzNxntZlCzfE8i5P0uqzVQWQquU1TIhlz0VqGQGXLrFDuTJVONpqGqjGKQ=="],
|
||||
|
||||
"@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@15.5.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Fe1tGHxOWEyQjmygWkkXSwhFcTJuimrNu52JEuwItrKJVV4iRjbWp9I7zZjwqtiNnQmxoEvoisn8wueFLrNpvQ=="],
|
||||
"@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@15.3.5", "", { "os": "win32", "cpu": "x64" }, "sha512-5fhH6fccXxnX2KhllnGhkYMndhOiLOLEiVGYjP2nizqeGWkN10sA9taATlXwake2E2XMvYZjjz0Uj7T0y+z1yw=="],
|
||||
|
||||
"@noble/ciphers": ["@noble/ciphers@1.2.1", "", {}, "sha512-rONPWMC7PeExE077uLE4oqWrZ1IvAfz3oH9LibVAcVCopJiA9R62uavnbEzdkVmJYI6M6Zgkbeb07+tWjlq2XA=="],
|
||||
|
||||
@@ -847,9 +853,9 @@
|
||||
|
||||
"@octokit/types": ["@octokit/types@14.1.0", "", { "dependencies": { "@octokit/openapi-types": "^25.1.0" } }, "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g=="],
|
||||
|
||||
"@opennextjs/aws": ["@opennextjs/aws@3.7.4", "", { "dependencies": { "@ast-grep/napi": "^0.35.0", "@aws-sdk/client-cloudfront": "3.398.0", "@aws-sdk/client-dynamodb": "^3.398.0", "@aws-sdk/client-lambda": "^3.398.0", "@aws-sdk/client-s3": "^3.398.0", "@aws-sdk/client-sqs": "^3.398.0", "@node-minify/core": "^8.0.6", "@node-minify/terser": "^8.0.6", "@tsconfig/node18": "^1.0.1", "aws4fetch": "^1.0.18", "chalk": "^5.3.0", "cookie": "^1.0.2", "esbuild": "0.25.4", "express": "5.0.1", "path-to-regexp": "^6.3.0", "urlpattern-polyfill": "^10.0.0", "yaml": "^2.7.0" }, "bin": { "open-next": "dist/index.js" } }, "sha512-s50dmKrgQ62GliffoI/hGGQVb3q/7ZN5VRa4jJw0ZsEGLfk25XuAulO/ySCYeE7/A23KoAYuhafnKr/h+vxOeQ=="],
|
||||
"@opennextjs/aws": ["@opennextjs/aws@3.7.6", "", { "dependencies": { "@ast-grep/napi": "^0.35.0", "@aws-sdk/client-cloudfront": "3.398.0", "@aws-sdk/client-dynamodb": "^3.398.0", "@aws-sdk/client-lambda": "^3.398.0", "@aws-sdk/client-s3": "^3.398.0", "@aws-sdk/client-sqs": "^3.398.0", "@node-minify/core": "^8.0.6", "@node-minify/terser": "^8.0.6", "@tsconfig/node18": "^1.0.1", "aws4fetch": "^1.0.18", "chalk": "^5.3.0", "cookie": "^1.0.2", "esbuild": "0.25.4", "express": "5.0.1", "path-to-regexp": "^6.3.0", "urlpattern-polyfill": "^10.0.0", "yaml": "^2.7.0" }, "bin": { "open-next": "dist/index.js" } }, "sha512-l4UGkmaZaAjWER+PuZ/zNziMnrbf6oA9B1RUDKcyKsX+hEES1b7h6kLgpo4a4maf01M+k0yJUZQyF4sf+vI+Iw=="],
|
||||
|
||||
"@opennextjs/cloudflare": ["@opennextjs/cloudflare@1.6.4", "", { "dependencies": { "@dotenvx/dotenvx": "1.31.0", "@opennextjs/aws": "3.7.4", "cloudflare": "^4.4.1", "enquirer": "^2.4.1", "glob": "^11.0.0", "ts-tqdm": "^0.8.6", "yargs": "^18.0.0" }, "peerDependencies": { "wrangler": "^4.24.4" }, "bin": { "opennextjs-cloudflare": "dist/cli/index.js" } }, "sha512-vGEHr1+Dli4BSrs+CM+b2bnXoUdY/GUFiLfdH28UTRHggLMG7cL49M39LtzIVR5D8eqzZ38PDB2CZMn1LJ2gSw=="],
|
||||
"@opennextjs/cloudflare": ["@opennextjs/cloudflare@1.7.1", "", { "dependencies": { "@dotenvx/dotenvx": "1.31.0", "@opennextjs/aws": "3.7.6", "cloudflare": "^4.4.1", "enquirer": "^2.4.1", "glob": "^11.0.0", "ts-tqdm": "^0.8.6", "yargs": "^18.0.0" }, "peerDependencies": { "wrangler": "^4.24.4" }, "bin": { "opennextjs-cloudflare": "dist/cli/index.js" } }, "sha512-g3d8LSpGGJzuCLuLYHAs7nGWFKK57qSOgxhpn3wwk6t/tXxsneXA3D5nbf6zLsAQQo8b6A8LDcT732U3rUXUeA=="],
|
||||
|
||||
"@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="],
|
||||
|
||||
@@ -1151,19 +1157,21 @@
|
||||
|
||||
"@scalar/draggable": ["@scalar/draggable@0.2.0", "", { "dependencies": { "vue": "^3.5.12" } }, "sha512-UetHRB5Bqo5egVYlS21roWBcICmyk8CKh2htsidO+bFGAjl2e7Te+rY0borhNrMclr0xezHlPuLpEs1dvgLS2g=="],
|
||||
|
||||
"@scalar/helpers": ["@scalar/helpers@0.0.4", "", {}, "sha512-AkWdiU8zhztb4bJ0U2LHgCtJs+kwWB5UFXebfy9QCLwCP0guhhFR2UJtRCU3QZ8xmZnI0AX0i7BjrxU/MN1roQ=="],
|
||||
"@scalar/helpers": ["@scalar/helpers@0.0.8", "", {}, "sha512-9A1CxL3jV7Kl9wGu86/cR/wiJN6J+3tK4WuW3252s2gF+upXsgQRx9WLhFF3xifOP1irIGusitZBiojiKmUSVg=="],
|
||||
|
||||
"@scalar/icons": ["@scalar/icons@0.4.4", "", { "dependencies": { "@phosphor-icons/core": "^2.1.1", "@types/node": "^20.17.10", "chalk": "^5.4.1", "vue": "^3.5.12" } }, "sha512-622QsIkRPw5UG4IU4QzcTUV1UHEw7aBaZMu6QYEHPO0Wn3ue1lfFIqLZOKsoXxvDuuXGvZUqyoZahkXdRHccmQ=="],
|
||||
|
||||
"@scalar/import": ["@scalar/import@0.4.11", "", { "dependencies": { "@scalar/helpers": "0.0.4", "@scalar/openapi-parser": "0.18.0", "yaml": "^2.4.5" } }, "sha512-s8GRknImMjevimqv+jLkW+7LsBuOWgQPv/p29dukLqPtCGddIyNoWgVot6/IaREEXXeu5m/PmoG+uN58AVN4Vg=="],
|
||||
|
||||
"@scalar/json-magic": ["@scalar/json-magic@0.3.1", "", { "dependencies": { "@scalar/helpers": "0.0.8", "vue": "^3.5.17", "yaml": "2.8.0" } }, "sha512-vQvl4TckiMT8Txo6S82ETJ4OI+K6iSxLZsjPaq4cEqY+9zVfmIMALFGPj/X5BB8tU3FdluV2yEa8LswsMQ68IA=="],
|
||||
|
||||
"@scalar/oas-utils": ["@scalar/oas-utils@0.2.130", "", { "dependencies": { "@hyperjump/json-schema": "^1.9.6", "@scalar/object-utils": "1.1.13", "@scalar/openapi-types": "0.2.0", "@scalar/themes": "0.9.86", "@scalar/types": "0.1.7", "flatted": "^3.3.1", "microdiff": "^1.4.0", "nanoid": "^5.1.5", "type-fest": "^4.20.0", "yaml": "^2.4.5", "zod": "^3.23.8" } }, "sha512-sVpdc3+3c/WiNrKEIwzJ+ml2ZQBjarMOTDJCM/IrvYhrJE0nHrdkzxlJgNPi++vJbVl0saYt8LhEItALv7NziA=="],
|
||||
|
||||
"@scalar/object-utils": ["@scalar/object-utils@1.1.13", "", { "dependencies": { "flatted": "^3.3.1", "just-clone": "^6.2.0", "ts-deepmerge": "^7.0.1" } }, "sha512-311eTykIXgOtjCs4VTELj9UMT97jHTWc5qkGNoIzZ5nxjCcvOVe7kDQobIkE8dGT+ybOgHz5qly02Eu7nVHeZQ=="],
|
||||
|
||||
"@scalar/openapi-parser": ["@scalar/openapi-parser@0.18.0", "", { "dependencies": { "ajv": "^8.17.1", "ajv-draft-04": "^1.0.0", "ajv-formats": "^3.0.1", "jsonpointer": "^5.0.1", "leven": "^4.0.0", "yaml": "^2.4.5" } }, "sha512-qAWEfJR5f/LwSFULFeSkD56LHgU9ovyj+e1uqy9XaW9Hb9P0ewIGKi+Gd4wTyxfFkdPLXTFYXApjviP6jV+new=="],
|
||||
"@scalar/openapi-parser": ["@scalar/openapi-parser@0.20.1", "", { "dependencies": { "@scalar/json-magic": "0.3.1", "@scalar/openapi-types": "0.3.7", "ajv": "^8.17.1", "ajv-draft-04": "^1.0.0", "ajv-formats": "^3.0.1", "jsonpointer": "^5.0.1", "leven": "^4.0.0", "yaml": "2.8.0" } }, "sha512-rxtuBQ90YsUEDefWU3GAEmvjYr1CvGO6nkDVzbjmWv2aPB3mtK80bCRBgQGTdIdW5XQEWAAmflSKEhcj2Xo5QA=="],
|
||||
|
||||
"@scalar/openapi-types": ["@scalar/openapi-types@0.1.9", "", {}, "sha512-HQQudOSQBU7ewzfnBW9LhDmBE2XOJgSfwrh5PlUB7zJup/kaRkBGNgV2wMjNz9Af/uztiU/xNrO179FysmUT+g=="],
|
||||
"@scalar/openapi-types": ["@scalar/openapi-types@0.3.7", "", { "dependencies": { "zod": "3.24.1" } }, "sha512-QHSvHBVDze3+dUwAhIGq6l1iOev4jdoqdBK7QpfeN1Q4h+6qpVEw3EEqBiH0AXUSh/iWwObBv4uMgfIx0aNZ5g=="],
|
||||
|
||||
"@scalar/postman-to-openapi": ["@scalar/postman-to-openapi@0.3.10", "", { "dependencies": { "@scalar/helpers": "0.0.4", "@scalar/oas-utils": "0.4.7", "@scalar/openapi-types": "0.3.3" } }, "sha512-Jg+uJg56VASihtfL0sOzB8onyt7lfz/8Ztwo57WIAxUTvLcwBeCBgdTvUIw+Z4h7E2KfmKQY9HdDP/GHWMv6DQ=="],
|
||||
|
||||
@@ -1171,7 +1179,7 @@
|
||||
|
||||
"@scalar/themes": ["@scalar/themes@0.9.86", "", { "dependencies": { "@scalar/types": "0.1.7" } }, "sha512-QUHo9g5oSWi+0Lm1vJY9TaMZRau8LHg+vte7q5BVTBnu6NuQfigCaN+ouQ73FqIVd96TwMO6Db+dilK1B+9row=="],
|
||||
|
||||
"@scalar/types": ["@scalar/types@0.2.3", "", { "dependencies": { "@scalar/openapi-types": "0.3.3", "nanoid": "^5.1.5", "zod": "3.24.1" } }, "sha512-K1/Vp5xaQ8TEGDYwHg88OBuQWJRWrE3ToZ0Z2LJwskcY1Eg+uDiRQXKF4QPngZzu5rrWgRErAq4yte4Y7omqgA=="],
|
||||
"@scalar/types": ["@scalar/types@0.1.16", "", { "dependencies": { "@scalar/openapi-types": "0.2.3", "nanoid": "^5.1.5", "zod": "3.24.1" } }, "sha512-v1L96F8Inn27NUw5Xcl0iifw3SOX0R9WBV6GeswR23s8i1SJz7UiLEi8rLOqOB5DiLtC8hDK0kNl4TKn7MNJWQ=="],
|
||||
|
||||
"@scalar/use-codemirror": ["@scalar/use-codemirror@0.12.13", "", { "dependencies": { "@codemirror/autocomplete": "^6.18.3", "@codemirror/commands": "^6.7.1", "@codemirror/lang-css": "^6.3.1", "@codemirror/lang-html": "^6.4.8", "@codemirror/lang-json": "^6.0.0", "@codemirror/lang-xml": "^6.0.0", "@codemirror/lang-yaml": "^6.1.2", "@codemirror/language": "^6.10.7", "@codemirror/lint": "^6.8.4", "@codemirror/state": "^6.5.0", "@codemirror/view": "^6.35.3", "@lezer/common": "^1.2.3", "@lezer/highlight": "^1.2.1", "@replit/codemirror-css-color-picker": "^6.3.0", "@scalar/components": "0.14.12", "codemirror": "^6.0.0", "vue": "^3.5.12" } }, "sha512-XOXCUT3b1l0gkp4CY51e7xMgR6IP/AMpYIZ97fBOOjnrUIJ8B/J+U/BMS6+lPKiN0hexaSALRWlVBf90txdT8w=="],
|
||||
|
||||
@@ -1301,6 +1309,8 @@
|
||||
|
||||
"@smithy/util-waiter": ["@smithy/util-waiter@2.2.0", "", { "dependencies": { "@smithy/abort-controller": "^2.2.0", "@smithy/types": "^2.12.0", "tslib": "^2.6.2" } }, "sha512-IHk53BVw6MPMi2Gsn+hCng8rFA3ZmR3Rk7GllxDUW9qFJl/hiSvskn7XldkECapQVkIg/1dHpMAxI9xSTaLLSA=="],
|
||||
|
||||
"@swc/counter": ["@swc/counter@0.1.3", "", {}, "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="],
|
||||
|
||||
"@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="],
|
||||
|
||||
"@szmarczak/http-timer": ["@szmarczak/http-timer@1.1.2", "", { "dependencies": { "defer-to-connect": "^1.0.1" } }, "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA=="],
|
||||
@@ -1375,6 +1385,8 @@
|
||||
|
||||
"@types/js-cookie": ["@types/js-cookie@3.0.6", "", {}, "sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ=="],
|
||||
|
||||
"@types/js-yaml": ["@types/js-yaml@4.0.9", "", {}, "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg=="],
|
||||
|
||||
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
||||
|
||||
"@types/jsontoxml": ["@types/jsontoxml@1.0.6", "", {}, "sha512-SoeEpHuqdZcpLxZr5uzpB6A/ICmzBOfluwMm59Bm6vDuiSRSv4M/z8hvS+YCRw4ZyGO5BhJ5oeJnrurSigg3Vw=="],
|
||||
@@ -1457,25 +1469,25 @@
|
||||
|
||||
"@vercel/static-config": ["@vercel/static-config@3.0.0", "", { "dependencies": { "ajv": "8.6.3", "json-schema-to-ts": "1.6.4", "ts-morph": "12.0.0" } }, "sha512-2qtvcBJ1bGY0dYGYh3iM7yGKkk971FujLEDXzuW5wcZsPr1GSEjO/w2iSr3qve6nDDtBImsGoDEnus5FI4+fIw=="],
|
||||
|
||||
"@vue/compiler-core": ["@vue/compiler-core@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/shared": "3.5.12", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw=="],
|
||||
"@vue/compiler-core": ["@vue/compiler-core@3.5.21", "", { "dependencies": { "@babel/parser": "^7.28.3", "@vue/shared": "3.5.21", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-8i+LZ0vf6ZgII5Z9XmUvrCyEzocvWT+TeR2VBUVlzIH6Tyv57E20mPZ1bCS+tbejgUgmjrEh7q/0F0bibskAmw=="],
|
||||
|
||||
"@vue/compiler-dom": ["@vue/compiler-dom@3.5.12", "", { "dependencies": { "@vue/compiler-core": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg=="],
|
||||
"@vue/compiler-dom": ["@vue/compiler-dom@3.5.21", "", { "dependencies": { "@vue/compiler-core": "3.5.21", "@vue/shared": "3.5.21" } }, "sha512-jNtbu/u97wiyEBJlJ9kmdw7tAr5Vy0Aj5CgQmo+6pxWNQhXZDPsRr1UWPN4v3Zf82s2H3kF51IbzZ4jMWAgPlQ=="],
|
||||
|
||||
"@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/compiler-core": "3.5.12", "@vue/compiler-dom": "3.5.12", "@vue/compiler-ssr": "3.5.12", "@vue/shared": "3.5.12", "estree-walker": "^2.0.2", "magic-string": "^0.30.11", "postcss": "^8.4.47", "source-map-js": "^1.2.0" } }, "sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw=="],
|
||||
"@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.21", "", { "dependencies": { "@babel/parser": "^7.28.3", "@vue/compiler-core": "3.5.21", "@vue/compiler-dom": "3.5.21", "@vue/compiler-ssr": "3.5.21", "@vue/shared": "3.5.21", "estree-walker": "^2.0.2", "magic-string": "^0.30.18", "postcss": "^8.5.6", "source-map-js": "^1.2.1" } }, "sha512-SXlyk6I5eUGBd2v8Ie7tF6ADHE9kCR6mBEuPyH1nUZ0h6Xx6nZI29i12sJKQmzbDyr2tUHMhhTt51Z6blbkTTQ=="],
|
||||
|
||||
"@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA=="],
|
||||
"@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.21", "", { "dependencies": { "@vue/compiler-dom": "3.5.21", "@vue/shared": "3.5.21" } }, "sha512-vKQ5olH5edFZdf5ZrlEgSO1j1DMA4u23TVK5XR1uMhvwnYvVdDF0nHXJUblL/GvzlShQbjhZZ2uvYmDlAbgo9w=="],
|
||||
|
||||
"@vue/devtools-api": ["@vue/devtools-api@6.6.4", "", {}, "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g=="],
|
||||
|
||||
"@vue/reactivity": ["@vue/reactivity@3.5.12", "", { "dependencies": { "@vue/shared": "3.5.12" } }, "sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg=="],
|
||||
"@vue/reactivity": ["@vue/reactivity@3.5.21", "", { "dependencies": { "@vue/shared": "3.5.21" } }, "sha512-3ah7sa+Cwr9iiYEERt9JfZKPw4A2UlbY8RbbnH2mGCE8NwHkhmlZt2VsH0oDA3P08X3jJd29ohBDtX+TbD9AsA=="],
|
||||
|
||||
"@vue/runtime-core": ["@vue/runtime-core@3.5.12", "", { "dependencies": { "@vue/reactivity": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw=="],
|
||||
"@vue/runtime-core": ["@vue/runtime-core@3.5.21", "", { "dependencies": { "@vue/reactivity": "3.5.21", "@vue/shared": "3.5.21" } }, "sha512-+DplQlRS4MXfIf9gfD1BOJpk5RSyGgGXD/R+cumhe8jdjUcq/qlxDawQlSI8hCKupBlvM+3eS1se5xW+SuNAwA=="],
|
||||
|
||||
"@vue/runtime-dom": ["@vue/runtime-dom@3.5.12", "", { "dependencies": { "@vue/reactivity": "3.5.12", "@vue/runtime-core": "3.5.12", "@vue/shared": "3.5.12", "csstype": "^3.1.3" } }, "sha512-q8VFxR9A2MRfBr6/55Q3umyoN7ya836FzRXajPB6/Vvuv0zOPL+qltd9rIMzG/DbRLAIlREmnLsplEF/kotXKA=="],
|
||||
"@vue/runtime-dom": ["@vue/runtime-dom@3.5.21", "", { "dependencies": { "@vue/reactivity": "3.5.21", "@vue/runtime-core": "3.5.21", "@vue/shared": "3.5.21", "csstype": "^3.1.3" } }, "sha512-3M2DZsOFwM5qI15wrMmNF5RJe1+ARijt2HM3TbzBbPSuBHOQpoidE+Pa+XEaVN+czbHf81ETRoG1ltztP2em8w=="],
|
||||
|
||||
"@vue/server-renderer": ["@vue/server-renderer@3.5.12", "", { "dependencies": { "@vue/compiler-ssr": "3.5.12", "@vue/shared": "3.5.12" }, "peerDependencies": { "vue": "3.5.12" } }, "sha512-I3QoeDDeEPZm8yR28JtY+rk880Oqmj43hreIBVTicisFTx/Dl7JpG72g/X7YF8hnQD3IFhkky5i2bPonwrTVPg=="],
|
||||
"@vue/server-renderer": ["@vue/server-renderer@3.5.21", "", { "dependencies": { "@vue/compiler-ssr": "3.5.21", "@vue/shared": "3.5.21" }, "peerDependencies": { "vue": "3.5.21" } }, "sha512-qr8AqgD3DJPJcGvLcJKQo2tAc8OnXRcfxhOJCPF+fcfn5bBGz7VCcO7t+qETOPxpWK1mgysXvVT/j+xWaHeMWA=="],
|
||||
|
||||
"@vue/shared": ["@vue/shared@3.5.12", "", {}, "sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg=="],
|
||||
"@vue/shared": ["@vue/shared@3.5.21", "", {}, "sha512-+2k1EQpnYuVuu3N7atWyG3/xoFWIVJZq4Mz8XNOdScFI0etES75fbny/oU4lKWk/577P1zmg0ioYvpGEDZ3DLw=="],
|
||||
|
||||
"@vueuse/core": ["@vueuse/core@10.11.1", "", { "dependencies": { "@types/web-bluetooth": "^0.0.20", "@vueuse/metadata": "10.11.1", "@vueuse/shared": "10.11.1", "vue-demi": ">=0.14.8" } }, "sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww=="],
|
||||
|
||||
@@ -1595,6 +1607,8 @@
|
||||
|
||||
"bun-types": ["bun-types@1.1.30", "", { "dependencies": { "@types/node": "~20.12.8", "@types/ws": "~8.5.10" } }, "sha512-mGh7NLisOXskBU62DxLS+/nwmLlCYHYAkCzdo4DZ9+fzrpP41hAdOqaN4DO6tQfenHb4pYb0/shw29k4/6I2yQ=="],
|
||||
|
||||
"busboy": ["busboy@1.6.0", "", { "dependencies": { "streamsearch": "^1.1.0" } }, "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA=="],
|
||||
|
||||
"bytes": ["bytes@3.1.0", "", {}, "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="],
|
||||
|
||||
"cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="],
|
||||
@@ -2453,7 +2467,7 @@
|
||||
|
||||
"negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
|
||||
|
||||
"next": ["next@15.5.0", "", { "dependencies": { "@next/env": "15.5.0", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "15.5.0", "@next/swc-darwin-x64": "15.5.0", "@next/swc-linux-arm64-gnu": "15.5.0", "@next/swc-linux-arm64-musl": "15.5.0", "@next/swc-linux-x64-gnu": "15.5.0", "@next/swc-linux-x64-musl": "15.5.0", "@next/swc-win32-arm64-msvc": "15.5.0", "@next/swc-win32-x64-msvc": "15.5.0", "sharp": "^0.34.3" }, "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-N1lp9Hatw3a9XLt0307lGB4uTKsXDhyOKQo7uYMzX4i0nF/c27grcGXkLdb7VcT8QPYLBa8ouIyEoUQJ2OyeNQ=="],
|
||||
"next": ["next@15.3.5", "", { "dependencies": { "@next/env": "15.3.5", "@swc/counter": "0.1.3", "@swc/helpers": "0.5.15", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "15.3.5", "@next/swc-darwin-x64": "15.3.5", "@next/swc-linux-arm64-gnu": "15.3.5", "@next/swc-linux-arm64-musl": "15.3.5", "@next/swc-linux-x64-gnu": "15.3.5", "@next/swc-linux-x64-musl": "15.3.5", "@next/swc-win32-arm64-msvc": "15.3.5", "@next/swc-win32-x64-msvc": "15.3.5", "sharp": "^0.34.1" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.41.2", "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-RkazLBMMDJSJ4XZQ81kolSpwiCt907l0xcgcpF4xC2Vml6QVcPNXW0NQRwQ80FFtSn7UM52XN0anaw8TEJXaiw=="],
|
||||
|
||||
"next-themes": ["next-themes@0.2.1", "", { "peerDependencies": { "next": "*", "react": "*", "react-dom": "*" } }, "sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A=="],
|
||||
|
||||
@@ -2797,6 +2811,8 @@
|
||||
|
||||
"stream-to-promise": ["stream-to-promise@2.2.0", "", { "dependencies": { "any-promise": "~1.3.0", "end-of-stream": "~1.1.0", "stream-to-array": "~2.3.0" } }, "sha512-HAGUASw8NT0k8JvIVutB2Y/9iBk7gpgEyAudXwNJmZERdMITGdajOa4VJfD/kNiA3TppQpTP4J+CtcHwdzKBAw=="],
|
||||
|
||||
"streamsearch": ["streamsearch@1.1.0", "", {}, "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg=="],
|
||||
|
||||
"string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
||||
|
||||
"string-width-cjs": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
||||
@@ -3007,7 +3023,7 @@
|
||||
|
||||
"vfile-message": ["vfile-message@4.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw=="],
|
||||
|
||||
"vue": ["vue@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/compiler-sfc": "3.5.12", "@vue/runtime-dom": "3.5.12", "@vue/server-renderer": "3.5.12", "@vue/shared": "3.5.12" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg=="],
|
||||
"vue": ["vue@3.5.21", "", { "dependencies": { "@vue/compiler-dom": "3.5.21", "@vue/compiler-sfc": "3.5.21", "@vue/runtime-dom": "3.5.21", "@vue/server-renderer": "3.5.21", "@vue/shared": "3.5.21" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-xxf9rum9KtOdwdRkiApWL+9hZEMWE90FHh8yS1+KJAiWYh+iGWV1FquPjoO9VUHQ+VIhsCXNNyZ5Sf4++RVZBA=="],
|
||||
|
||||
"vue-demi": ["vue-demi@0.14.10", "", { "peerDependencies": { "@vue/composition-api": "^1.0.0-rc.1", "vue": "^3.0.0-0 || ^2.6.0" }, "optionalPeers": ["@vue/composition-api"], "bin": { "vue-demi-fix": "bin/vue-demi-fix.js", "vue-demi-switch": "bin/vue-demi-switch.js" } }, "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg=="],
|
||||
|
||||
@@ -3059,7 +3075,7 @@
|
||||
|
||||
"yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
|
||||
|
||||
"yaml": ["yaml@2.7.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA=="],
|
||||
"yaml": ["yaml@2.8.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ=="],
|
||||
|
||||
"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=="],
|
||||
|
||||
@@ -3681,8 +3697,6 @@
|
||||
|
||||
"@babel/highlight/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="],
|
||||
|
||||
"@babel/parser/@babel/types": ["@babel/types@7.25.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.7", "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" } }, "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg=="],
|
||||
|
||||
"@changesets/parse/js-yaml": ["js-yaml@3.14.1", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g=="],
|
||||
|
||||
"@codemirror/lang-html/@codemirror/autocomplete": ["@codemirror/autocomplete@6.18.1", "", { "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.17.0", "@lezer/common": "^1.0.0" } }, "sha512-iWHdj/B1ethnHRTwZj+C1obmmuCzquH29EbcKr0qIjA9NfDeBDJ7vs+WOHsFeLeflE4o+dHfYndJloMKHUkWUA=="],
|
||||
@@ -3789,6 +3803,8 @@
|
||||
|
||||
"@opennextjs/aws/path-to-regexp": ["path-to-regexp@6.3.0", "", {}, "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ=="],
|
||||
|
||||
"@opennextjs/aws/yaml": ["yaml@2.7.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA=="],
|
||||
|
||||
"@playwright/test/playwright": ["playwright@1.54.2", "", { "dependencies": { "playwright-core": "1.54.2" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": { "playwright": "cli.js" } }, "sha512-Hu/BMoA1NAdRUuulyvQC0pEqZ4vQbGfn8f7wPXcnqQmM+zct9UliKxsIkLNmz/ku7LElUNqmaiv1TG/aL5ACsw=="],
|
||||
|
||||
"@radix-ui/react-arrow/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
|
||||
@@ -3945,40 +3961,80 @@
|
||||
|
||||
"@rollup/pluginutils/picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="],
|
||||
|
||||
"@scalar/api-client/@scalar/helpers": ["@scalar/helpers@0.0.4", "", {}, "sha512-AkWdiU8zhztb4bJ0U2LHgCtJs+kwWB5UFXebfy9QCLwCP0guhhFR2UJtRCU3QZ8xmZnI0AX0i7BjrxU/MN1roQ=="],
|
||||
|
||||
"@scalar/api-client/@scalar/oas-utils": ["@scalar/oas-utils@0.4.7", "", { "dependencies": { "@hyperjump/browser": "^1.1.0", "@hyperjump/json-schema": "^1.9.6", "@scalar/helpers": "0.0.4", "@scalar/object-utils": "1.2.1", "@scalar/openapi-types": "0.3.3", "@scalar/themes": "0.13.4", "@scalar/types": "0.2.3", "@types/har-format": "^1.2.15", "flatted": "^3.3.1", "microdiff": "^1.4.0", "nanoid": "^5.1.5", "type-fest": "^4.20.0", "yaml": "^2.4.5", "zod": "3.24.1" } }, "sha512-Vp8iZZCjNKXcPpL0Yr6dmy+VOSN1LZ5CdlGAHtp+pxuQTeahV6FxiVjMc9kdFve77fTNyut4seVAD6d7rDUDcA=="],
|
||||
|
||||
"@scalar/api-client/@scalar/object-utils": ["@scalar/object-utils@1.2.1", "", { "dependencies": { "flatted": "^3.3.1", "just-clone": "^6.2.0", "ts-deepmerge": "^7.0.1", "type-fest": "^4.20.0" } }, "sha512-2P/0In6XSrV1Ye8yU3LyOWJKWkzXpxf0thHmTfJriqGBZz41s06td2KKqoqHSEEi+FAsl3O1ngmOOzLM3QUkkw=="],
|
||||
|
||||
"@scalar/api-client/@scalar/openapi-parser": ["@scalar/openapi-parser@0.18.0", "", { "dependencies": { "ajv": "^8.17.1", "ajv-draft-04": "^1.0.0", "ajv-formats": "^3.0.1", "jsonpointer": "^5.0.1", "leven": "^4.0.0", "yaml": "^2.4.5" } }, "sha512-qAWEfJR5f/LwSFULFeSkD56LHgU9ovyj+e1uqy9XaW9Hb9P0ewIGKi+Gd4wTyxfFkdPLXTFYXApjviP6jV+new=="],
|
||||
|
||||
"@scalar/api-client/@scalar/openapi-types": ["@scalar/openapi-types@0.3.3", "", { "dependencies": { "zod": "3.24.1" } }, "sha512-mr3OvbCyvuzSDgv9gR9D3pJAsl82BRNBp1P8ldgRgKF4Wiswfa7nQeKibpX0kHSGXLgiyvxWJULUFwgdWMXNNA=="],
|
||||
|
||||
"@scalar/api-client/@scalar/themes": ["@scalar/themes@0.13.4", "", { "dependencies": { "@scalar/types": "0.2.3", "nanoid": "^5.1.5" } }, "sha512-PMiSqX+MZF29u32ogEjTVA5c/LBd5cE/QPF7lK0EJeemXRy2r/nWbvrXtqD9Y7Sw54g1caVNjK8yJcCYJdB6hw=="],
|
||||
|
||||
"@scalar/api-client/@scalar/types": ["@scalar/types@0.2.3", "", { "dependencies": { "@scalar/openapi-types": "0.3.3", "nanoid": "^5.1.5", "zod": "3.24.1" } }, "sha512-K1/Vp5xaQ8TEGDYwHg88OBuQWJRWrE3ToZ0Z2LJwskcY1Eg+uDiRQXKF4QPngZzu5rrWgRErAq4yte4Y7omqgA=="],
|
||||
|
||||
"@scalar/api-client/pretty-ms": ["pretty-ms@8.0.0", "", { "dependencies": { "parse-ms": "^3.0.0" } }, "sha512-ASJqOugUF1bbzI35STMBUpZqdfYKlJugy6JBziGi2EE+AL5JPJGSzvpeVXojxrr0ViUYoToUjb5kjSEGf7Y83Q=="],
|
||||
|
||||
"@scalar/api-client/vue": ["vue@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/compiler-sfc": "3.5.12", "@vue/runtime-dom": "3.5.12", "@vue/server-renderer": "3.5.12", "@vue/shared": "3.5.12" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg=="],
|
||||
|
||||
"@scalar/api-client/yaml": ["yaml@2.7.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA=="],
|
||||
|
||||
"@scalar/api-client/zod": ["zod@3.24.1", "", {}, "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A=="],
|
||||
|
||||
"@scalar/api-client-react/@scalar/types": ["@scalar/types@0.2.3", "", { "dependencies": { "@scalar/openapi-types": "0.3.3", "nanoid": "^5.1.5", "zod": "3.24.1" } }, "sha512-K1/Vp5xaQ8TEGDYwHg88OBuQWJRWrE3ToZ0Z2LJwskcY1Eg+uDiRQXKF4QPngZzu5rrWgRErAq4yte4Y7omqgA=="],
|
||||
|
||||
"@scalar/api-client-react/vue": ["vue@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/compiler-sfc": "3.5.12", "@vue/runtime-dom": "3.5.12", "@vue/server-renderer": "3.5.12", "@vue/shared": "3.5.12" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg=="],
|
||||
|
||||
"@scalar/components/@scalar/oas-utils": ["@scalar/oas-utils@0.4.7", "", { "dependencies": { "@hyperjump/browser": "^1.1.0", "@hyperjump/json-schema": "^1.9.6", "@scalar/helpers": "0.0.4", "@scalar/object-utils": "1.2.1", "@scalar/openapi-types": "0.3.3", "@scalar/themes": "0.13.4", "@scalar/types": "0.2.3", "@types/har-format": "^1.2.15", "flatted": "^3.3.1", "microdiff": "^1.4.0", "nanoid": "^5.1.5", "type-fest": "^4.20.0", "yaml": "^2.4.5", "zod": "3.24.1" } }, "sha512-Vp8iZZCjNKXcPpL0Yr6dmy+VOSN1LZ5CdlGAHtp+pxuQTeahV6FxiVjMc9kdFve77fTNyut4seVAD6d7rDUDcA=="],
|
||||
|
||||
"@scalar/components/@scalar/themes": ["@scalar/themes@0.13.4", "", { "dependencies": { "@scalar/types": "0.2.3", "nanoid": "^5.1.5" } }, "sha512-PMiSqX+MZF29u32ogEjTVA5c/LBd5cE/QPF7lK0EJeemXRy2r/nWbvrXtqD9Y7Sw54g1caVNjK8yJcCYJdB6hw=="],
|
||||
|
||||
"@scalar/components/vue": ["vue@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/compiler-sfc": "3.5.12", "@vue/runtime-dom": "3.5.12", "@vue/server-renderer": "3.5.12", "@vue/shared": "3.5.12" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg=="],
|
||||
|
||||
"@scalar/draggable/vue": ["vue@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/compiler-sfc": "3.5.12", "@vue/runtime-dom": "3.5.12", "@vue/server-renderer": "3.5.12", "@vue/shared": "3.5.12" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg=="],
|
||||
|
||||
"@scalar/icons/vue": ["vue@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/compiler-sfc": "3.5.12", "@vue/runtime-dom": "3.5.12", "@vue/server-renderer": "3.5.12", "@vue/shared": "3.5.12" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg=="],
|
||||
|
||||
"@scalar/import/@scalar/helpers": ["@scalar/helpers@0.0.4", "", {}, "sha512-AkWdiU8zhztb4bJ0U2LHgCtJs+kwWB5UFXebfy9QCLwCP0guhhFR2UJtRCU3QZ8xmZnI0AX0i7BjrxU/MN1roQ=="],
|
||||
|
||||
"@scalar/import/@scalar/openapi-parser": ["@scalar/openapi-parser@0.18.0", "", { "dependencies": { "ajv": "^8.17.1", "ajv-draft-04": "^1.0.0", "ajv-formats": "^3.0.1", "jsonpointer": "^5.0.1", "leven": "^4.0.0", "yaml": "^2.4.5" } }, "sha512-qAWEfJR5f/LwSFULFeSkD56LHgU9ovyj+e1uqy9XaW9Hb9P0ewIGKi+Gd4wTyxfFkdPLXTFYXApjviP6jV+new=="],
|
||||
|
||||
"@scalar/import/yaml": ["yaml@2.7.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA=="],
|
||||
|
||||
"@scalar/oas-utils/@scalar/openapi-types": ["@scalar/openapi-types@0.2.0", "", { "dependencies": { "zod": "^3.23.8" } }, "sha512-waiKk12cRCqyUCWTOX0K1WEVX46+hVUK+zRPzAahDJ7G0TApvbNkuy5wx7aoUyEk++HHde0XuQnshXnt8jsddA=="],
|
||||
|
||||
"@scalar/oas-utils/@scalar/types": ["@scalar/types@0.1.7", "", { "dependencies": { "@scalar/openapi-types": "0.2.0", "@unhead/schema": "^1.11.11", "nanoid": "^5.1.5", "type-fest": "^4.20.0", "zod": "^3.23.8" } }, "sha512-irIDYzTQG2KLvFbuTI8k2Pz/R4JR+zUUSykVTbEMatkzMmVFnn1VzNSMlODbadycwZunbnL2tA27AXed9URVjw=="],
|
||||
|
||||
"@scalar/oas-utils/yaml": ["yaml@2.7.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA=="],
|
||||
|
||||
"@scalar/object-utils/flatted": ["flatted@3.3.1", "", {}, "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw=="],
|
||||
|
||||
"@scalar/openapi-types/zod": ["zod@3.24.1", "", {}, "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A=="],
|
||||
|
||||
"@scalar/postman-to-openapi/@scalar/helpers": ["@scalar/helpers@0.0.4", "", {}, "sha512-AkWdiU8zhztb4bJ0U2LHgCtJs+kwWB5UFXebfy9QCLwCP0guhhFR2UJtRCU3QZ8xmZnI0AX0i7BjrxU/MN1roQ=="],
|
||||
|
||||
"@scalar/postman-to-openapi/@scalar/oas-utils": ["@scalar/oas-utils@0.4.7", "", { "dependencies": { "@hyperjump/browser": "^1.1.0", "@hyperjump/json-schema": "^1.9.6", "@scalar/helpers": "0.0.4", "@scalar/object-utils": "1.2.1", "@scalar/openapi-types": "0.3.3", "@scalar/themes": "0.13.4", "@scalar/types": "0.2.3", "@types/har-format": "^1.2.15", "flatted": "^3.3.1", "microdiff": "^1.4.0", "nanoid": "^5.1.5", "type-fest": "^4.20.0", "yaml": "^2.4.5", "zod": "3.24.1" } }, "sha512-Vp8iZZCjNKXcPpL0Yr6dmy+VOSN1LZ5CdlGAHtp+pxuQTeahV6FxiVjMc9kdFve77fTNyut4seVAD6d7rDUDcA=="],
|
||||
|
||||
"@scalar/postman-to-openapi/@scalar/openapi-types": ["@scalar/openapi-types@0.3.3", "", { "dependencies": { "zod": "3.24.1" } }, "sha512-mr3OvbCyvuzSDgv9gR9D3pJAsl82BRNBp1P8ldgRgKF4Wiswfa7nQeKibpX0kHSGXLgiyvxWJULUFwgdWMXNNA=="],
|
||||
|
||||
"@scalar/themes/@scalar/types": ["@scalar/types@0.1.7", "", { "dependencies": { "@scalar/openapi-types": "0.2.0", "@unhead/schema": "^1.11.11", "nanoid": "^5.1.5", "type-fest": "^4.20.0", "zod": "^3.23.8" } }, "sha512-irIDYzTQG2KLvFbuTI8k2Pz/R4JR+zUUSykVTbEMatkzMmVFnn1VzNSMlODbadycwZunbnL2tA27AXed9URVjw=="],
|
||||
|
||||
"@scalar/types/@scalar/openapi-types": ["@scalar/openapi-types@0.3.3", "", { "dependencies": { "zod": "3.24.1" } }, "sha512-mr3OvbCyvuzSDgv9gR9D3pJAsl82BRNBp1P8ldgRgKF4Wiswfa7nQeKibpX0kHSGXLgiyvxWJULUFwgdWMXNNA=="],
|
||||
"@scalar/types/@scalar/openapi-types": ["@scalar/openapi-types@0.2.3", "", { "dependencies": { "zod": "3.24.1" } }, "sha512-O1GwqLpcRc3GKXTbeBZ5E12fXR2ltpqGWk4RfhoN4ebKZsPVknV5at5425G97E1SwMy12BporRvn90k1Z+MruQ=="],
|
||||
|
||||
"@scalar/types/zod": ["zod@3.24.1", "", {}, "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A=="],
|
||||
|
||||
"@scalar/use-codemirror/vue": ["vue@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/compiler-sfc": "3.5.12", "@vue/runtime-dom": "3.5.12", "@vue/server-renderer": "3.5.12", "@vue/shared": "3.5.12" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg=="],
|
||||
|
||||
"@scalar/use-hooks/vue": ["vue@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/compiler-sfc": "3.5.12", "@vue/runtime-dom": "3.5.12", "@vue/server-renderer": "3.5.12", "@vue/shared": "3.5.12" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg=="],
|
||||
|
||||
"@scalar/use-hooks/zod": ["zod@3.24.1", "", {}, "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A=="],
|
||||
|
||||
"@scalar/use-toasts/vue": ["vue@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/compiler-sfc": "3.5.12", "@vue/runtime-dom": "3.5.12", "@vue/server-renderer": "3.5.12", "@vue/shared": "3.5.12" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg=="],
|
||||
|
||||
"@scalar/use-tooltip/vue": ["vue@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/compiler-sfc": "3.5.12", "@vue/runtime-dom": "3.5.12", "@vue/server-renderer": "3.5.12", "@vue/shared": "3.5.12" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg=="],
|
||||
|
||||
"@shikijs/core/hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="],
|
||||
|
||||
"@smithy/abort-controller/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
@@ -4209,9 +4265,9 @@
|
||||
|
||||
"@vue/compiler-core/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"@vue/compiler-sfc/magic-string": ["magic-string@0.30.12", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw=="],
|
||||
"@vue/compiler-sfc/magic-string": ["magic-string@0.30.18", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ=="],
|
||||
|
||||
"@vue/compiler-sfc/postcss": ["postcss@8.4.47", "", { "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.1.0", "source-map-js": "^1.2.1" } }, "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ=="],
|
||||
"@vue/compiler-sfc/postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
|
||||
|
||||
"@vueuse/integrations/@vueuse/core": ["@vueuse/core@11.2.0", "", { "dependencies": { "@types/web-bluetooth": "^0.0.20", "@vueuse/metadata": "11.2.0", "@vueuse/shared": "11.2.0", "vue-demi": ">=0.14.10" } }, "sha512-JIUwRcOqOWzcdu1dGlfW04kaJhW3EXnnjJJfLTtddJanymTL7lF1C0+dVVZ/siLfc73mWn+cGP1PE1PKPruRSA=="],
|
||||
|
||||
@@ -4949,10 +5005,6 @@
|
||||
|
||||
"@babel/highlight/chalk/supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "^3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="],
|
||||
|
||||
"@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.7", "", {}, "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g=="],
|
||||
|
||||
"@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.7", "", {}, "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg=="],
|
||||
|
||||
"@changesets/parse/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
|
||||
|
||||
"@codemirror/lang-json/@codemirror/language/@codemirror/view": ["@codemirror/view@6.34.1", "", { "dependencies": { "@codemirror/state": "^6.4.0", "style-mod": "^4.1.0", "w3c-keyname": "^2.2.4" } }, "sha512-t1zK/l9UiRqwUNPm+pdIT0qzJlzuVckbTEMVNFhfWkGiBQClstzg+78vedCvLSX0xJEZ6lwZbPpnljL7L6iwMQ=="],
|
||||
@@ -5071,24 +5123,130 @@
|
||||
|
||||
"@radix-ui/react-visually-hidden/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.1.1", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g=="],
|
||||
|
||||
"@scalar/api-client-react/@scalar/types/@scalar/openapi-types": ["@scalar/openapi-types@0.3.3", "", { "dependencies": { "zod": "3.24.1" } }, "sha512-mr3OvbCyvuzSDgv9gR9D3pJAsl82BRNBp1P8ldgRgKF4Wiswfa7nQeKibpX0kHSGXLgiyvxWJULUFwgdWMXNNA=="],
|
||||
|
||||
"@scalar/api-client-react/@scalar/types/zod": ["zod@3.24.1", "", {}, "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/compiler-dom": ["@vue/compiler-dom@3.5.12", "", { "dependencies": { "@vue/compiler-core": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/compiler-core": "3.5.12", "@vue/compiler-dom": "3.5.12", "@vue/compiler-ssr": "3.5.12", "@vue/shared": "3.5.12", "estree-walker": "^2.0.2", "magic-string": "^0.30.11", "postcss": "^8.4.47", "source-map-js": "^1.2.0" } }, "sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/runtime-dom": ["@vue/runtime-dom@3.5.12", "", { "dependencies": { "@vue/reactivity": "3.5.12", "@vue/runtime-core": "3.5.12", "@vue/shared": "3.5.12", "csstype": "^3.1.3" } }, "sha512-q8VFxR9A2MRfBr6/55Q3umyoN7ya836FzRXajPB6/Vvuv0zOPL+qltd9rIMzG/DbRLAIlREmnLsplEF/kotXKA=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/server-renderer": ["@vue/server-renderer@3.5.12", "", { "dependencies": { "@vue/compiler-ssr": "3.5.12", "@vue/shared": "3.5.12" }, "peerDependencies": { "vue": "3.5.12" } }, "sha512-I3QoeDDeEPZm8yR28JtY+rk880Oqmj43hreIBVTicisFTx/Dl7JpG72g/X7YF8hnQD3IFhkky5i2bPonwrTVPg=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/shared": ["@vue/shared@3.5.12", "", {}, "sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg=="],
|
||||
|
||||
"@scalar/api-client/pretty-ms/parse-ms": ["parse-ms@3.0.0", "", {}, "sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/compiler-dom": ["@vue/compiler-dom@3.5.12", "", { "dependencies": { "@vue/compiler-core": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/compiler-core": "3.5.12", "@vue/compiler-dom": "3.5.12", "@vue/compiler-ssr": "3.5.12", "@vue/shared": "3.5.12", "estree-walker": "^2.0.2", "magic-string": "^0.30.11", "postcss": "^8.4.47", "source-map-js": "^1.2.0" } }, "sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/runtime-dom": ["@vue/runtime-dom@3.5.12", "", { "dependencies": { "@vue/reactivity": "3.5.12", "@vue/runtime-core": "3.5.12", "@vue/shared": "3.5.12", "csstype": "^3.1.3" } }, "sha512-q8VFxR9A2MRfBr6/55Q3umyoN7ya836FzRXajPB6/Vvuv0zOPL+qltd9rIMzG/DbRLAIlREmnLsplEF/kotXKA=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/server-renderer": ["@vue/server-renderer@3.5.12", "", { "dependencies": { "@vue/compiler-ssr": "3.5.12", "@vue/shared": "3.5.12" }, "peerDependencies": { "vue": "3.5.12" } }, "sha512-I3QoeDDeEPZm8yR28JtY+rk880Oqmj43hreIBVTicisFTx/Dl7JpG72g/X7YF8hnQD3IFhkky5i2bPonwrTVPg=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/shared": ["@vue/shared@3.5.12", "", {}, "sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg=="],
|
||||
|
||||
"@scalar/components/@scalar/oas-utils/@scalar/helpers": ["@scalar/helpers@0.0.4", "", {}, "sha512-AkWdiU8zhztb4bJ0U2LHgCtJs+kwWB5UFXebfy9QCLwCP0guhhFR2UJtRCU3QZ8xmZnI0AX0i7BjrxU/MN1roQ=="],
|
||||
|
||||
"@scalar/components/@scalar/oas-utils/@scalar/object-utils": ["@scalar/object-utils@1.2.1", "", { "dependencies": { "flatted": "^3.3.1", "just-clone": "^6.2.0", "ts-deepmerge": "^7.0.1", "type-fest": "^4.20.0" } }, "sha512-2P/0In6XSrV1Ye8yU3LyOWJKWkzXpxf0thHmTfJriqGBZz41s06td2KKqoqHSEEi+FAsl3O1ngmOOzLM3QUkkw=="],
|
||||
|
||||
"@scalar/components/@scalar/oas-utils/@scalar/openapi-types": ["@scalar/openapi-types@0.3.3", "", { "dependencies": { "zod": "3.24.1" } }, "sha512-mr3OvbCyvuzSDgv9gR9D3pJAsl82BRNBp1P8ldgRgKF4Wiswfa7nQeKibpX0kHSGXLgiyvxWJULUFwgdWMXNNA=="],
|
||||
|
||||
"@scalar/components/@scalar/oas-utils/@scalar/types": ["@scalar/types@0.2.3", "", { "dependencies": { "@scalar/openapi-types": "0.3.3", "nanoid": "^5.1.5", "zod": "3.24.1" } }, "sha512-K1/Vp5xaQ8TEGDYwHg88OBuQWJRWrE3ToZ0Z2LJwskcY1Eg+uDiRQXKF4QPngZzu5rrWgRErAq4yte4Y7omqgA=="],
|
||||
|
||||
"@scalar/components/@scalar/oas-utils/yaml": ["yaml@2.7.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA=="],
|
||||
|
||||
"@scalar/components/@scalar/oas-utils/zod": ["zod@3.24.1", "", {}, "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A=="],
|
||||
|
||||
"@scalar/components/@scalar/themes/@scalar/types": ["@scalar/types@0.2.3", "", { "dependencies": { "@scalar/openapi-types": "0.3.3", "nanoid": "^5.1.5", "zod": "3.24.1" } }, "sha512-K1/Vp5xaQ8TEGDYwHg88OBuQWJRWrE3ToZ0Z2LJwskcY1Eg+uDiRQXKF4QPngZzu5rrWgRErAq4yte4Y7omqgA=="],
|
||||
|
||||
"@scalar/components/vue/@vue/compiler-dom": ["@vue/compiler-dom@3.5.12", "", { "dependencies": { "@vue/compiler-core": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg=="],
|
||||
|
||||
"@scalar/components/vue/@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/compiler-core": "3.5.12", "@vue/compiler-dom": "3.5.12", "@vue/compiler-ssr": "3.5.12", "@vue/shared": "3.5.12", "estree-walker": "^2.0.2", "magic-string": "^0.30.11", "postcss": "^8.4.47", "source-map-js": "^1.2.0" } }, "sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw=="],
|
||||
|
||||
"@scalar/components/vue/@vue/runtime-dom": ["@vue/runtime-dom@3.5.12", "", { "dependencies": { "@vue/reactivity": "3.5.12", "@vue/runtime-core": "3.5.12", "@vue/shared": "3.5.12", "csstype": "^3.1.3" } }, "sha512-q8VFxR9A2MRfBr6/55Q3umyoN7ya836FzRXajPB6/Vvuv0zOPL+qltd9rIMzG/DbRLAIlREmnLsplEF/kotXKA=="],
|
||||
|
||||
"@scalar/components/vue/@vue/server-renderer": ["@vue/server-renderer@3.5.12", "", { "dependencies": { "@vue/compiler-ssr": "3.5.12", "@vue/shared": "3.5.12" }, "peerDependencies": { "vue": "3.5.12" } }, "sha512-I3QoeDDeEPZm8yR28JtY+rk880Oqmj43hreIBVTicisFTx/Dl7JpG72g/X7YF8hnQD3IFhkky5i2bPonwrTVPg=="],
|
||||
|
||||
"@scalar/components/vue/@vue/shared": ["@vue/shared@3.5.12", "", {}, "sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/compiler-dom": ["@vue/compiler-dom@3.5.12", "", { "dependencies": { "@vue/compiler-core": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/compiler-core": "3.5.12", "@vue/compiler-dom": "3.5.12", "@vue/compiler-ssr": "3.5.12", "@vue/shared": "3.5.12", "estree-walker": "^2.0.2", "magic-string": "^0.30.11", "postcss": "^8.4.47", "source-map-js": "^1.2.0" } }, "sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/runtime-dom": ["@vue/runtime-dom@3.5.12", "", { "dependencies": { "@vue/reactivity": "3.5.12", "@vue/runtime-core": "3.5.12", "@vue/shared": "3.5.12", "csstype": "^3.1.3" } }, "sha512-q8VFxR9A2MRfBr6/55Q3umyoN7ya836FzRXajPB6/Vvuv0zOPL+qltd9rIMzG/DbRLAIlREmnLsplEF/kotXKA=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/server-renderer": ["@vue/server-renderer@3.5.12", "", { "dependencies": { "@vue/compiler-ssr": "3.5.12", "@vue/shared": "3.5.12" }, "peerDependencies": { "vue": "3.5.12" } }, "sha512-I3QoeDDeEPZm8yR28JtY+rk880Oqmj43hreIBVTicisFTx/Dl7JpG72g/X7YF8hnQD3IFhkky5i2bPonwrTVPg=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/shared": ["@vue/shared@3.5.12", "", {}, "sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/compiler-dom": ["@vue/compiler-dom@3.5.12", "", { "dependencies": { "@vue/compiler-core": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/compiler-core": "3.5.12", "@vue/compiler-dom": "3.5.12", "@vue/compiler-ssr": "3.5.12", "@vue/shared": "3.5.12", "estree-walker": "^2.0.2", "magic-string": "^0.30.11", "postcss": "^8.4.47", "source-map-js": "^1.2.0" } }, "sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/runtime-dom": ["@vue/runtime-dom@3.5.12", "", { "dependencies": { "@vue/reactivity": "3.5.12", "@vue/runtime-core": "3.5.12", "@vue/shared": "3.5.12", "csstype": "^3.1.3" } }, "sha512-q8VFxR9A2MRfBr6/55Q3umyoN7ya836FzRXajPB6/Vvuv0zOPL+qltd9rIMzG/DbRLAIlREmnLsplEF/kotXKA=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/server-renderer": ["@vue/server-renderer@3.5.12", "", { "dependencies": { "@vue/compiler-ssr": "3.5.12", "@vue/shared": "3.5.12" }, "peerDependencies": { "vue": "3.5.12" } }, "sha512-I3QoeDDeEPZm8yR28JtY+rk880Oqmj43hreIBVTicisFTx/Dl7JpG72g/X7YF8hnQD3IFhkky5i2bPonwrTVPg=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/shared": ["@vue/shared@3.5.12", "", {}, "sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg=="],
|
||||
|
||||
"@scalar/postman-to-openapi/@scalar/oas-utils/@scalar/object-utils": ["@scalar/object-utils@1.2.1", "", { "dependencies": { "flatted": "^3.3.1", "just-clone": "^6.2.0", "ts-deepmerge": "^7.0.1", "type-fest": "^4.20.0" } }, "sha512-2P/0In6XSrV1Ye8yU3LyOWJKWkzXpxf0thHmTfJriqGBZz41s06td2KKqoqHSEEi+FAsl3O1ngmOOzLM3QUkkw=="],
|
||||
|
||||
"@scalar/postman-to-openapi/@scalar/oas-utils/@scalar/themes": ["@scalar/themes@0.13.4", "", { "dependencies": { "@scalar/types": "0.2.3", "nanoid": "^5.1.5" } }, "sha512-PMiSqX+MZF29u32ogEjTVA5c/LBd5cE/QPF7lK0EJeemXRy2r/nWbvrXtqD9Y7Sw54g1caVNjK8yJcCYJdB6hw=="],
|
||||
|
||||
"@scalar/postman-to-openapi/@scalar/oas-utils/@scalar/types": ["@scalar/types@0.2.3", "", { "dependencies": { "@scalar/openapi-types": "0.3.3", "nanoid": "^5.1.5", "zod": "3.24.1" } }, "sha512-K1/Vp5xaQ8TEGDYwHg88OBuQWJRWrE3ToZ0Z2LJwskcY1Eg+uDiRQXKF4QPngZzu5rrWgRErAq4yte4Y7omqgA=="],
|
||||
|
||||
"@scalar/postman-to-openapi/@scalar/oas-utils/yaml": ["yaml@2.7.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA=="],
|
||||
|
||||
"@scalar/postman-to-openapi/@scalar/oas-utils/zod": ["zod@3.24.1", "", {}, "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A=="],
|
||||
|
||||
"@scalar/postman-to-openapi/@scalar/openapi-types/zod": ["zod@3.24.1", "", {}, "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A=="],
|
||||
|
||||
"@scalar/themes/@scalar/types/@scalar/openapi-types": ["@scalar/openapi-types@0.2.0", "", { "dependencies": { "zod": "^3.23.8" } }, "sha512-waiKk12cRCqyUCWTOX0K1WEVX46+hVUK+zRPzAahDJ7G0TApvbNkuy5wx7aoUyEk++HHde0XuQnshXnt8jsddA=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/compiler-dom": ["@vue/compiler-dom@3.5.12", "", { "dependencies": { "@vue/compiler-core": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/compiler-core": "3.5.12", "@vue/compiler-dom": "3.5.12", "@vue/compiler-ssr": "3.5.12", "@vue/shared": "3.5.12", "estree-walker": "^2.0.2", "magic-string": "^0.30.11", "postcss": "^8.4.47", "source-map-js": "^1.2.0" } }, "sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/runtime-dom": ["@vue/runtime-dom@3.5.12", "", { "dependencies": { "@vue/reactivity": "3.5.12", "@vue/runtime-core": "3.5.12", "@vue/shared": "3.5.12", "csstype": "^3.1.3" } }, "sha512-q8VFxR9A2MRfBr6/55Q3umyoN7ya836FzRXajPB6/Vvuv0zOPL+qltd9rIMzG/DbRLAIlREmnLsplEF/kotXKA=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/server-renderer": ["@vue/server-renderer@3.5.12", "", { "dependencies": { "@vue/compiler-ssr": "3.5.12", "@vue/shared": "3.5.12" }, "peerDependencies": { "vue": "3.5.12" } }, "sha512-I3QoeDDeEPZm8yR28JtY+rk880Oqmj43hreIBVTicisFTx/Dl7JpG72g/X7YF8hnQD3IFhkky5i2bPonwrTVPg=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/shared": ["@vue/shared@3.5.12", "", {}, "sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/compiler-dom": ["@vue/compiler-dom@3.5.12", "", { "dependencies": { "@vue/compiler-core": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/compiler-core": "3.5.12", "@vue/compiler-dom": "3.5.12", "@vue/compiler-ssr": "3.5.12", "@vue/shared": "3.5.12", "estree-walker": "^2.0.2", "magic-string": "^0.30.11", "postcss": "^8.4.47", "source-map-js": "^1.2.0" } }, "sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/runtime-dom": ["@vue/runtime-dom@3.5.12", "", { "dependencies": { "@vue/reactivity": "3.5.12", "@vue/runtime-core": "3.5.12", "@vue/shared": "3.5.12", "csstype": "^3.1.3" } }, "sha512-q8VFxR9A2MRfBr6/55Q3umyoN7ya836FzRXajPB6/Vvuv0zOPL+qltd9rIMzG/DbRLAIlREmnLsplEF/kotXKA=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/server-renderer": ["@vue/server-renderer@3.5.12", "", { "dependencies": { "@vue/compiler-ssr": "3.5.12", "@vue/shared": "3.5.12" }, "peerDependencies": { "vue": "3.5.12" } }, "sha512-I3QoeDDeEPZm8yR28JtY+rk880Oqmj43hreIBVTicisFTx/Dl7JpG72g/X7YF8hnQD3IFhkky5i2bPonwrTVPg=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/shared": ["@vue/shared@3.5.12", "", {}, "sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/compiler-dom": ["@vue/compiler-dom@3.5.12", "", { "dependencies": { "@vue/compiler-core": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/compiler-core": "3.5.12", "@vue/compiler-dom": "3.5.12", "@vue/compiler-ssr": "3.5.12", "@vue/shared": "3.5.12", "estree-walker": "^2.0.2", "magic-string": "^0.30.11", "postcss": "^8.4.47", "source-map-js": "^1.2.0" } }, "sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/runtime-dom": ["@vue/runtime-dom@3.5.12", "", { "dependencies": { "@vue/reactivity": "3.5.12", "@vue/runtime-core": "3.5.12", "@vue/shared": "3.5.12", "csstype": "^3.1.3" } }, "sha512-q8VFxR9A2MRfBr6/55Q3umyoN7ya836FzRXajPB6/Vvuv0zOPL+qltd9rIMzG/DbRLAIlREmnLsplEF/kotXKA=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/server-renderer": ["@vue/server-renderer@3.5.12", "", { "dependencies": { "@vue/compiler-ssr": "3.5.12", "@vue/shared": "3.5.12" }, "peerDependencies": { "vue": "3.5.12" } }, "sha512-I3QoeDDeEPZm8yR28JtY+rk880Oqmj43hreIBVTicisFTx/Dl7JpG72g/X7YF8hnQD3IFhkky5i2bPonwrTVPg=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/shared": ["@vue/shared@3.5.12", "", {}, "sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/compiler-dom": ["@vue/compiler-dom@3.5.12", "", { "dependencies": { "@vue/compiler-core": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/compiler-core": "3.5.12", "@vue/compiler-dom": "3.5.12", "@vue/compiler-ssr": "3.5.12", "@vue/shared": "3.5.12", "estree-walker": "^2.0.2", "magic-string": "^0.30.11", "postcss": "^8.4.47", "source-map-js": "^1.2.0" } }, "sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/runtime-dom": ["@vue/runtime-dom@3.5.12", "", { "dependencies": { "@vue/reactivity": "3.5.12", "@vue/runtime-core": "3.5.12", "@vue/shared": "3.5.12", "csstype": "^3.1.3" } }, "sha512-q8VFxR9A2MRfBr6/55Q3umyoN7ya836FzRXajPB6/Vvuv0zOPL+qltd9rIMzG/DbRLAIlREmnLsplEF/kotXKA=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/server-renderer": ["@vue/server-renderer@3.5.12", "", { "dependencies": { "@vue/compiler-ssr": "3.5.12", "@vue/shared": "3.5.12" }, "peerDependencies": { "vue": "3.5.12" } }, "sha512-I3QoeDDeEPZm8yR28JtY+rk880Oqmj43hreIBVTicisFTx/Dl7JpG72g/X7YF8hnQD3IFhkky5i2bPonwrTVPg=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/shared": ["@vue/shared@3.5.12", "", {}, "sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg=="],
|
||||
|
||||
"@shikijs/core/hast-util-to-html/property-information": ["property-information@7.0.0", "", {}, "sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg=="],
|
||||
|
||||
"@smithy/chunked-blob-reader-native/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug=="],
|
||||
@@ -5145,7 +5303,11 @@
|
||||
|
||||
"@vercel/routing-utils/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
|
||||
|
||||
"@vue/compiler-sfc/postcss/nanoid": ["nanoid@3.3.7", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="],
|
||||
"@vue/compiler-sfc/magic-string/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
|
||||
|
||||
"@vue/compiler-sfc/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
||||
|
||||
"@vue/compiler-sfc/postcss/picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||
|
||||
"@vueuse/integrations/@vueuse/core/@vueuse/metadata": ["@vueuse/metadata@11.2.0", "", {}, "sha512-L0ZmtRmNx+ZW95DmrgD6vn484gSpVeRbgpWevFKXwqqQxW9hnSi2Ppuh2BzMjnbv4aJRiIw8tQatXT9uOB23dQ=="],
|
||||
|
||||
@@ -5429,6 +5591,172 @@
|
||||
|
||||
"@radix-ui/react-visually-hidden/@radix-ui/react-primitive/@radix-ui/react-slot/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/compiler-dom/@vue/compiler-core": ["@vue/compiler-core@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/shared": "3.5.12", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/compiler-sfc/@babel/parser": ["@babel/parser@7.25.8", "", { "dependencies": { "@babel/types": "^7.25.8" }, "bin": "./bin/babel-parser.js" }, "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/compiler-sfc/@vue/compiler-core": ["@vue/compiler-core@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/shared": "3.5.12", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/compiler-sfc/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/compiler-sfc/magic-string": ["magic-string@0.30.12", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/compiler-sfc/postcss": ["postcss@8.4.47", "", { "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.1.0", "source-map-js": "^1.2.1" } }, "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/runtime-dom/@vue/reactivity": ["@vue/reactivity@3.5.12", "", { "dependencies": { "@vue/shared": "3.5.12" } }, "sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/runtime-dom/@vue/runtime-core": ["@vue/runtime-core@3.5.12", "", { "dependencies": { "@vue/reactivity": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/server-renderer/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/compiler-dom/@vue/compiler-core": ["@vue/compiler-core@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/shared": "3.5.12", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/compiler-sfc/@babel/parser": ["@babel/parser@7.25.8", "", { "dependencies": { "@babel/types": "^7.25.8" }, "bin": "./bin/babel-parser.js" }, "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/compiler-sfc/@vue/compiler-core": ["@vue/compiler-core@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/shared": "3.5.12", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/compiler-sfc/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/compiler-sfc/magic-string": ["magic-string@0.30.12", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/compiler-sfc/postcss": ["postcss@8.4.47", "", { "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.1.0", "source-map-js": "^1.2.1" } }, "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/runtime-dom/@vue/reactivity": ["@vue/reactivity@3.5.12", "", { "dependencies": { "@vue/shared": "3.5.12" } }, "sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/runtime-dom/@vue/runtime-core": ["@vue/runtime-core@3.5.12", "", { "dependencies": { "@vue/reactivity": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/server-renderer/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA=="],
|
||||
|
||||
"@scalar/components/@scalar/themes/@scalar/types/@scalar/openapi-types": ["@scalar/openapi-types@0.3.3", "", { "dependencies": { "zod": "3.24.1" } }, "sha512-mr3OvbCyvuzSDgv9gR9D3pJAsl82BRNBp1P8ldgRgKF4Wiswfa7nQeKibpX0kHSGXLgiyvxWJULUFwgdWMXNNA=="],
|
||||
|
||||
"@scalar/components/@scalar/themes/@scalar/types/zod": ["zod@3.24.1", "", {}, "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A=="],
|
||||
|
||||
"@scalar/components/vue/@vue/compiler-dom/@vue/compiler-core": ["@vue/compiler-core@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/shared": "3.5.12", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw=="],
|
||||
|
||||
"@scalar/components/vue/@vue/compiler-sfc/@babel/parser": ["@babel/parser@7.25.8", "", { "dependencies": { "@babel/types": "^7.25.8" }, "bin": "./bin/babel-parser.js" }, "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ=="],
|
||||
|
||||
"@scalar/components/vue/@vue/compiler-sfc/@vue/compiler-core": ["@vue/compiler-core@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/shared": "3.5.12", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw=="],
|
||||
|
||||
"@scalar/components/vue/@vue/compiler-sfc/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA=="],
|
||||
|
||||
"@scalar/components/vue/@vue/compiler-sfc/magic-string": ["magic-string@0.30.12", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw=="],
|
||||
|
||||
"@scalar/components/vue/@vue/compiler-sfc/postcss": ["postcss@8.4.47", "", { "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.1.0", "source-map-js": "^1.2.1" } }, "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ=="],
|
||||
|
||||
"@scalar/components/vue/@vue/runtime-dom/@vue/reactivity": ["@vue/reactivity@3.5.12", "", { "dependencies": { "@vue/shared": "3.5.12" } }, "sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg=="],
|
||||
|
||||
"@scalar/components/vue/@vue/runtime-dom/@vue/runtime-core": ["@vue/runtime-core@3.5.12", "", { "dependencies": { "@vue/reactivity": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw=="],
|
||||
|
||||
"@scalar/components/vue/@vue/server-renderer/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/compiler-dom/@vue/compiler-core": ["@vue/compiler-core@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/shared": "3.5.12", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/compiler-sfc/@babel/parser": ["@babel/parser@7.25.8", "", { "dependencies": { "@babel/types": "^7.25.8" }, "bin": "./bin/babel-parser.js" }, "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/compiler-sfc/@vue/compiler-core": ["@vue/compiler-core@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/shared": "3.5.12", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/compiler-sfc/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/compiler-sfc/magic-string": ["magic-string@0.30.12", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/compiler-sfc/postcss": ["postcss@8.4.47", "", { "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.1.0", "source-map-js": "^1.2.1" } }, "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/runtime-dom/@vue/reactivity": ["@vue/reactivity@3.5.12", "", { "dependencies": { "@vue/shared": "3.5.12" } }, "sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/runtime-dom/@vue/runtime-core": ["@vue/runtime-core@3.5.12", "", { "dependencies": { "@vue/reactivity": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/server-renderer/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/compiler-dom/@vue/compiler-core": ["@vue/compiler-core@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/shared": "3.5.12", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/compiler-sfc/@babel/parser": ["@babel/parser@7.25.8", "", { "dependencies": { "@babel/types": "^7.25.8" }, "bin": "./bin/babel-parser.js" }, "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/compiler-sfc/@vue/compiler-core": ["@vue/compiler-core@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/shared": "3.5.12", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/compiler-sfc/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/compiler-sfc/magic-string": ["magic-string@0.30.12", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/compiler-sfc/postcss": ["postcss@8.4.47", "", { "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.1.0", "source-map-js": "^1.2.1" } }, "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/runtime-dom/@vue/reactivity": ["@vue/reactivity@3.5.12", "", { "dependencies": { "@vue/shared": "3.5.12" } }, "sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/runtime-dom/@vue/runtime-core": ["@vue/runtime-core@3.5.12", "", { "dependencies": { "@vue/reactivity": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/server-renderer/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/compiler-dom/@vue/compiler-core": ["@vue/compiler-core@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/shared": "3.5.12", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/compiler-sfc/@babel/parser": ["@babel/parser@7.25.8", "", { "dependencies": { "@babel/types": "^7.25.8" }, "bin": "./bin/babel-parser.js" }, "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/compiler-sfc/@vue/compiler-core": ["@vue/compiler-core@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/shared": "3.5.12", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/compiler-sfc/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/compiler-sfc/magic-string": ["magic-string@0.30.12", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/compiler-sfc/postcss": ["postcss@8.4.47", "", { "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.1.0", "source-map-js": "^1.2.1" } }, "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/runtime-dom/@vue/reactivity": ["@vue/reactivity@3.5.12", "", { "dependencies": { "@vue/shared": "3.5.12" } }, "sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/runtime-dom/@vue/runtime-core": ["@vue/runtime-core@3.5.12", "", { "dependencies": { "@vue/reactivity": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/server-renderer/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/compiler-dom/@vue/compiler-core": ["@vue/compiler-core@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/shared": "3.5.12", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/compiler-sfc/@babel/parser": ["@babel/parser@7.25.8", "", { "dependencies": { "@babel/types": "^7.25.8" }, "bin": "./bin/babel-parser.js" }, "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/compiler-sfc/@vue/compiler-core": ["@vue/compiler-core@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/shared": "3.5.12", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/compiler-sfc/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/compiler-sfc/magic-string": ["magic-string@0.30.12", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/compiler-sfc/postcss": ["postcss@8.4.47", "", { "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.1.0", "source-map-js": "^1.2.1" } }, "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/runtime-dom/@vue/reactivity": ["@vue/reactivity@3.5.12", "", { "dependencies": { "@vue/shared": "3.5.12" } }, "sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/runtime-dom/@vue/runtime-core": ["@vue/runtime-core@3.5.12", "", { "dependencies": { "@vue/reactivity": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/server-renderer/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/compiler-dom/@vue/compiler-core": ["@vue/compiler-core@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/shared": "3.5.12", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/compiler-sfc/@babel/parser": ["@babel/parser@7.25.8", "", { "dependencies": { "@babel/types": "^7.25.8" }, "bin": "./bin/babel-parser.js" }, "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/compiler-sfc/@vue/compiler-core": ["@vue/compiler-core@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/shared": "3.5.12", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/compiler-sfc/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/compiler-sfc/magic-string": ["magic-string@0.30.12", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/compiler-sfc/postcss": ["postcss@8.4.47", "", { "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.1.0", "source-map-js": "^1.2.1" } }, "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/runtime-dom/@vue/reactivity": ["@vue/reactivity@3.5.12", "", { "dependencies": { "@vue/shared": "3.5.12" } }, "sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/runtime-dom/@vue/runtime-core": ["@vue/runtime-core@3.5.12", "", { "dependencies": { "@vue/reactivity": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/server-renderer/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/compiler-dom/@vue/compiler-core": ["@vue/compiler-core@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/shared": "3.5.12", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/compiler-sfc/@babel/parser": ["@babel/parser@7.25.8", "", { "dependencies": { "@babel/types": "^7.25.8" }, "bin": "./bin/babel-parser.js" }, "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/compiler-sfc/@vue/compiler-core": ["@vue/compiler-core@3.5.12", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/shared": "3.5.12", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/compiler-sfc/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/compiler-sfc/magic-string": ["magic-string@0.30.12", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/compiler-sfc/postcss": ["postcss@8.4.47", "", { "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.1.0", "source-map-js": "^1.2.1" } }, "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/runtime-dom/@vue/reactivity": ["@vue/reactivity@3.5.12", "", { "dependencies": { "@vue/shared": "3.5.12" } }, "sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/runtime-dom/@vue/runtime-core": ["@vue/runtime-core@3.5.12", "", { "dependencies": { "@vue/reactivity": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/server-renderer/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.12", "", { "dependencies": { "@vue/compiler-dom": "3.5.12", "@vue/shared": "3.5.12" } }, "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA=="],
|
||||
|
||||
"@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
|
||||
|
||||
"@smithy/core/@smithy/util-stream/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g=="],
|
||||
@@ -5483,6 +5811,96 @@
|
||||
|
||||
"@babel/highlight/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser": ["@babel/parser@7.25.8", "", { "dependencies": { "@babel/types": "^7.25.8" }, "bin": "./bin/babel-parser.js" }, "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/compiler-dom/@vue/compiler-core/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/compiler-sfc/@babel/parser/@babel/types": ["@babel/types@7.25.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.7", "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" } }, "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/compiler-sfc/@vue/compiler-core/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/compiler-sfc/postcss/nanoid": ["nanoid@3.3.7", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser": ["@babel/parser@7.25.8", "", { "dependencies": { "@babel/types": "^7.25.8" }, "bin": "./bin/babel-parser.js" }, "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/compiler-dom/@vue/compiler-core/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/compiler-sfc/@babel/parser/@babel/types": ["@babel/types@7.25.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.7", "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" } }, "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/compiler-sfc/@vue/compiler-core/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/compiler-sfc/postcss/nanoid": ["nanoid@3.3.7", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="],
|
||||
|
||||
"@scalar/components/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser": ["@babel/parser@7.25.8", "", { "dependencies": { "@babel/types": "^7.25.8" }, "bin": "./bin/babel-parser.js" }, "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ=="],
|
||||
|
||||
"@scalar/components/vue/@vue/compiler-dom/@vue/compiler-core/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"@scalar/components/vue/@vue/compiler-sfc/@babel/parser/@babel/types": ["@babel/types@7.25.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.7", "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" } }, "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg=="],
|
||||
|
||||
"@scalar/components/vue/@vue/compiler-sfc/@vue/compiler-core/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"@scalar/components/vue/@vue/compiler-sfc/postcss/nanoid": ["nanoid@3.3.7", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser": ["@babel/parser@7.25.8", "", { "dependencies": { "@babel/types": "^7.25.8" }, "bin": "./bin/babel-parser.js" }, "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/compiler-dom/@vue/compiler-core/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/compiler-sfc/@babel/parser/@babel/types": ["@babel/types@7.25.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.7", "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" } }, "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/compiler-sfc/@vue/compiler-core/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/compiler-sfc/postcss/nanoid": ["nanoid@3.3.7", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser": ["@babel/parser@7.25.8", "", { "dependencies": { "@babel/types": "^7.25.8" }, "bin": "./bin/babel-parser.js" }, "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/compiler-dom/@vue/compiler-core/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/compiler-sfc/@babel/parser/@babel/types": ["@babel/types@7.25.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.7", "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" } }, "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/compiler-sfc/@vue/compiler-core/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/compiler-sfc/postcss/nanoid": ["nanoid@3.3.7", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser": ["@babel/parser@7.25.8", "", { "dependencies": { "@babel/types": "^7.25.8" }, "bin": "./bin/babel-parser.js" }, "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/compiler-dom/@vue/compiler-core/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/compiler-sfc/@babel/parser/@babel/types": ["@babel/types@7.25.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.7", "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" } }, "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/compiler-sfc/@vue/compiler-core/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/compiler-sfc/postcss/nanoid": ["nanoid@3.3.7", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser": ["@babel/parser@7.25.8", "", { "dependencies": { "@babel/types": "^7.25.8" }, "bin": "./bin/babel-parser.js" }, "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/compiler-dom/@vue/compiler-core/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/compiler-sfc/@babel/parser/@babel/types": ["@babel/types@7.25.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.7", "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" } }, "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/compiler-sfc/@vue/compiler-core/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/compiler-sfc/postcss/nanoid": ["nanoid@3.3.7", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser": ["@babel/parser@7.25.8", "", { "dependencies": { "@babel/types": "^7.25.8" }, "bin": "./bin/babel-parser.js" }, "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/compiler-dom/@vue/compiler-core/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/compiler-sfc/@babel/parser/@babel/types": ["@babel/types@7.25.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.7", "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" } }, "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/compiler-sfc/@vue/compiler-core/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/compiler-sfc/postcss/nanoid": ["nanoid@3.3.7", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser": ["@babel/parser@7.25.8", "", { "dependencies": { "@babel/types": "^7.25.8" }, "bin": "./bin/babel-parser.js" }, "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/compiler-dom/@vue/compiler-core/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/compiler-sfc/@babel/parser/@babel/types": ["@babel/types@7.25.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.7", "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" } }, "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/compiler-sfc/@vue/compiler-core/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/compiler-sfc/postcss/nanoid": ["nanoid@3.3.7", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="],
|
||||
|
||||
"@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg=="],
|
||||
|
||||
"@smithy/core/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg=="],
|
||||
@@ -5498,5 +5916,95 @@
|
||||
"@aws-sdk/middleware-sdk-sqs/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg=="],
|
||||
|
||||
"@aws-sdk/middleware-sdk-sqs/@smithy/smithy-client/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types": ["@babel/types@7.25.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.7", "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" } }, "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.7", "", {}, "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.7", "", {}, "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types": ["@babel/types@7.25.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.7", "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" } }, "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.7", "", {}, "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.7", "", {}, "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg=="],
|
||||
|
||||
"@scalar/components/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types": ["@babel/types@7.25.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.7", "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" } }, "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg=="],
|
||||
|
||||
"@scalar/components/vue/@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.7", "", {}, "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g=="],
|
||||
|
||||
"@scalar/components/vue/@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.7", "", {}, "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types": ["@babel/types@7.25.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.7", "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" } }, "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.7", "", {}, "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.7", "", {}, "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types": ["@babel/types@7.25.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.7", "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" } }, "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.7", "", {}, "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.7", "", {}, "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types": ["@babel/types@7.25.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.7", "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" } }, "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.7", "", {}, "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.7", "", {}, "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types": ["@babel/types@7.25.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.7", "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" } }, "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.7", "", {}, "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.7", "", {}, "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types": ["@babel/types@7.25.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.7", "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" } }, "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.7", "", {}, "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.7", "", {}, "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types": ["@babel/types@7.25.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.7", "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" } }, "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.7", "", {}, "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.7", "", {}, "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.7", "", {}, "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g=="],
|
||||
|
||||
"@scalar/api-client-react/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.7", "", {}, "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.7", "", {}, "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g=="],
|
||||
|
||||
"@scalar/api-client/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.7", "", {}, "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg=="],
|
||||
|
||||
"@scalar/components/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.7", "", {}, "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g=="],
|
||||
|
||||
"@scalar/components/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.7", "", {}, "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.7", "", {}, "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g=="],
|
||||
|
||||
"@scalar/draggable/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.7", "", {}, "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.7", "", {}, "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g=="],
|
||||
|
||||
"@scalar/icons/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.7", "", {}, "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.7", "", {}, "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g=="],
|
||||
|
||||
"@scalar/use-codemirror/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.7", "", {}, "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.7", "", {}, "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g=="],
|
||||
|
||||
"@scalar/use-hooks/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.7", "", {}, "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.7", "", {}, "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g=="],
|
||||
|
||||
"@scalar/use-toasts/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.7", "", {}, "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.7", "", {}, "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g=="],
|
||||
|
||||
"@scalar/use-tooltip/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.7", "", {}, "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg=="],
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@
|
||||
"workspaces": {
|
||||
"packages": ["packages/*"],
|
||||
"catalog": {
|
||||
"@gitbook/api": "^0.136.0",
|
||||
"@gitbook/api": "^0.139.0",
|
||||
"bidc": "^0.0.2"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"noEmit": false,
|
||||
"declaration": true,
|
||||
"outDir": "dist",
|
||||
|
||||
@@ -121,17 +121,6 @@ export function getCacheTag(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cache tag for a given URL.
|
||||
*/
|
||||
export function getCacheTagForURL(url: string | URL) {
|
||||
const parsedURL = url instanceof URL ? url : new URL(url);
|
||||
return getCacheTag({
|
||||
tag: 'url',
|
||||
hostname: parsedURL.hostname,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tags for a computed content source.
|
||||
*/
|
||||
@@ -182,7 +171,7 @@ export function getComputedContentSourceCacheTags(
|
||||
break;
|
||||
default:
|
||||
// Do not throw for unknown dependency types
|
||||
// as it might mean we are lacking behind the API version
|
||||
// as it might mean we are lagging behind the API version
|
||||
break;
|
||||
}
|
||||
});
|
||||
@@ -198,9 +187,8 @@ export function getComputedContentSourceCacheTags(
|
||||
}
|
||||
|
||||
// We invalidate the computed content when a new version of the integration is deployed.
|
||||
|
||||
if (source.type.startsWith('integration:')) {
|
||||
const integration = source.type.split(':')[1];
|
||||
const integration = source.type.split(':')[1]!;
|
||||
tags.push(
|
||||
getCacheTag({
|
||||
tag: 'integration',
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"noEmit": false,
|
||||
"declaration": true,
|
||||
"outDir": "dist",
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# @gitbook/colors
|
||||
|
||||
## 0.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 17dd382: Add `original` background color step
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 193d591: Fix return type for `colorContrast`
|
||||
|
||||
## 0.3.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"version": "0.3.3",
|
||||
"version": "0.4.0",
|
||||
"devDependencies": {
|
||||
"typescript": "^5.5.3"
|
||||
},
|
||||
|
||||
@@ -8,7 +8,7 @@ type RGBColor = [number, number, number];
|
||||
type OKLABColor = { L: number; A: number; B: number };
|
||||
type OKLCHColor = { L: number; C: number; H: number };
|
||||
|
||||
const D65 = [95.047, 100.0, 108.883]; // Reference white (D65)
|
||||
const D65 = [95.047, 100.0, 108.883] as const; // Reference white (D65)
|
||||
|
||||
export enum ColorCategory {
|
||||
backgrounds = 'backgrounds',
|
||||
@@ -19,7 +19,7 @@ export enum ColorCategory {
|
||||
}
|
||||
|
||||
type ColorSubScale = {
|
||||
[key: string]: number;
|
||||
[key: string]: number | string;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -56,6 +56,8 @@ export const scale: Record<ColorCategory, ColorSubScale> = {
|
||||
solid: 9,
|
||||
/** Hovered solid backgrounds */
|
||||
'solid-hover': 10,
|
||||
/** Original color */
|
||||
original: 'original',
|
||||
},
|
||||
[ColorCategory.text]: {
|
||||
/** Very low-contrast text
|
||||
@@ -211,8 +213,8 @@ export function colorScale(
|
||||
const result = [];
|
||||
|
||||
for (let index = 0; index < mapping.length; index++) {
|
||||
const targetL =
|
||||
foregroundColor.L * mapping[index] + backgroundColor.L * (1 - mapping[index]);
|
||||
const step = mapping[index]!;
|
||||
const targetL = foregroundColor.L * step + backgroundColor.L * (1 - step);
|
||||
|
||||
if (
|
||||
index === 8 &&
|
||||
@@ -295,7 +297,7 @@ export function rgbArrayToHex(rgb: RGBColor): string {
|
||||
|
||||
export function getColor(percentage: number, start: RGBColor, end: RGBColor) {
|
||||
const rgb = end.map((channel, index) => {
|
||||
return Math.round(channel + percentage * (start[index] - channel));
|
||||
return Math.round(channel + percentage * (start[index]! - channel));
|
||||
});
|
||||
|
||||
return rgbArrayToHex(rgb as RGBColor);
|
||||
@@ -392,14 +394,14 @@ export function xyzToLab65(xyz: [number, number, number]): {
|
||||
B: number;
|
||||
} {
|
||||
const [x, y, z] = xyz.map((v, i) => {
|
||||
const scaled = v / D65[i];
|
||||
const scaled = v / D65[i]!;
|
||||
return scaled > 0.008856 ? Math.cbrt(scaled) : 7.787 * scaled + 16 / 116;
|
||||
});
|
||||
|
||||
return {
|
||||
L: 116 * y - 16,
|
||||
A: 500 * (x - y),
|
||||
B: 200 * (y - z),
|
||||
L: 116 * y! - 16,
|
||||
A: 500 * (x! - y!),
|
||||
B: 200 * (y! - z!),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -419,7 +421,10 @@ export function dpsContrast(a: RGBColor, b: RGBColor) {
|
||||
return contrast < 7.5 ? 0 : contrast;
|
||||
}
|
||||
|
||||
export function colorContrast(background: string, foreground: string[] = [LIGHT_BASE, DARK_BASE]) {
|
||||
export function colorContrast(
|
||||
background: string,
|
||||
foreground: string[] = [LIGHT_BASE, DARK_BASE]
|
||||
): string {
|
||||
const bg = hexToRgbArray(background);
|
||||
|
||||
const best: { color?: RGBColor; contrast: number } = {
|
||||
@@ -436,5 +441,5 @@ export function colorContrast(background: string, foreground: string[] = [LIGHT_
|
||||
}
|
||||
}
|
||||
|
||||
return best.color ? rgbArrayToHex(best.color) : foreground[0];
|
||||
return best.color ? rgbArrayToHex(best.color) : foreground[0] || LIGHT_BASE;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"noEmit": false,
|
||||
"declaration": true,
|
||||
"outDir": "dist",
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @gitbook/embed
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 6f368b5: Fix embed assistant window width on small screens
|
||||
|
||||
## 0.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"react": "./dist/react/index.js"
|
||||
}
|
||||
},
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"dependencies": {
|
||||
"@gitbook/api": "catalog:",
|
||||
"@gitbook/icons": "workspace:",
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
--gitbook-widget-top: 1rem;
|
||||
--gitbook-widget-bottom: 1rem;
|
||||
--gitbook-widget-right: 1rem;
|
||||
--gitbook-widget-left: 1rem;
|
||||
|
||||
--gitbook-widget-button-height: 46px;
|
||||
|
||||
@@ -117,7 +118,7 @@
|
||||
bottom: var(--gitbook-widget-window-bottom);
|
||||
right: var(--gitbook-widget-right);
|
||||
z-index: 9998;
|
||||
width: var(--gitbook-widget-window-width);
|
||||
width: calc(min(var(--gitbook-widget-window-width), calc(100vw - var(--gitbook-widget-right) - var(--gitbook-widget-left))));
|
||||
height: calc(min(var(--gitbook-widget-window-height), calc(100vh - var(--gitbook-widget-window-bottom) - var(--gitbook-widget-top))));
|
||||
background-color: var(--gitbook-widget-background-solid);
|
||||
border: 1px solid var(--gitbook-widget-border-color);
|
||||
|
||||
@@ -67,7 +67,7 @@ function getBestUnicodeRange(text: string, ranges: Record<string, string>): stri
|
||||
|
||||
const body = token.slice(2); // drop "U+"
|
||||
const [startHex, endHex] = body.split('-');
|
||||
const start = Number.parseInt(startHex, 16);
|
||||
const start = Number.parseInt(startHex!, 16);
|
||||
const end = endHex ? Number.parseInt(endHex, 16) : start;
|
||||
|
||||
if (Number.isNaN(start) || Number.isNaN(end) || end < start) return null;
|
||||
@@ -92,7 +92,7 @@ function getBestUnicodeRange(text: string, ranges: Record<string, string>): stri
|
||||
|
||||
for (const [label, rangesArr] of Object.entries(parsed)) {
|
||||
if (rangesArr.some(([lo, hi]) => cp >= lo && cp <= hi)) {
|
||||
hits[label]++;
|
||||
hits[label]!++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"module": "ESNext",
|
||||
"target": "es2022",
|
||||
"strict": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "bundler",
|
||||
|
||||
@@ -1,5 +1,44 @@
|
||||
# gitbook
|
||||
|
||||
## 0.17.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 12c9d76: Adapt OpenAPI blocks to eval adaptive exprs & prefill TryIt config
|
||||
- 7911350: Add language selector to site header
|
||||
- 659be55: Track insight event when embedded assistant is displayed.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2e0d706: Fix corner radius of active section on "Line" sidebar style
|
||||
- 78a632b: Fix edit on GitHub button doesn't take you to GitHub
|
||||
- 1edc5d6: Add "hold message" to Assistant
|
||||
- 4520728: Support bold in headings
|
||||
- 61b8507: OpenAPI: Make responses without objects clickable
|
||||
- d1fdc13: Remove ligatures from Lato font
|
||||
- a8fca0e: Fix custom assistant keyboard shortcut
|
||||
- 262a9b1: Fix embed script and assets being cached for too long
|
||||
- c890e01: Fix order in robots.txt preventing indexation of images by Google.
|
||||
- 1839ea2: Fix content min-height with sections
|
||||
- 9201e2c: Adds vertical align to column block
|
||||
- 193d591: Use space language as source of truth for UI locale
|
||||
- f08dd29: Fix Search results are not clickable on sites without header
|
||||
- 17dd382: Add `original` background color step
|
||||
- 4f35882: Fix event ask_question not being tracked
|
||||
- d51b79e: Fix Search bar is broken on site with sections when header is disabled
|
||||
- 6f368b5: Fix embed assistant window width on small screens
|
||||
- Updated dependencies [193d591]
|
||||
- Updated dependencies [12c9d76]
|
||||
- Updated dependencies [4927e96]
|
||||
- Updated dependencies [61b8507]
|
||||
- Updated dependencies [7fefe49]
|
||||
- Updated dependencies [360aa1c]
|
||||
- Updated dependencies [98e42cf]
|
||||
- Updated dependencies [17dd382]
|
||||
- @gitbook/colors@0.4.0
|
||||
- @gitbook/react-openapi@1.4.0
|
||||
- @gitbook/openapi-parser@3.0.2
|
||||
|
||||
## 0.16.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -11,7 +11,7 @@ const args = process.argv.slice(2);
|
||||
const versionId = args[0];
|
||||
|
||||
// The preview URL is in the format https://<versionId>-gitbook-open-v2-server-preview.gitbook.workers.dev
|
||||
const previewHostname = `${versionId.split('-')[0]}-gitbook-open-v2-server-preview.gitbook.workers.dev`;
|
||||
const previewHostname = `${versionId?.split('-')[0]}-gitbook-open-v2-server-preview.gitbook.workers.dev`;
|
||||
|
||||
let updatedFile = file.replace(
|
||||
/"PREVIEW_HOSTNAME": "TO_REPLACE"/,
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
{
|
||||
"name": "gitbook",
|
||||
"version": "0.16.0",
|
||||
"version": "0.17.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@gitbook/api": "catalog:",
|
||||
"@gitbook/browser-types": "workspace:*",
|
||||
"@gitbook/cache-tags": "workspace:*",
|
||||
"@gitbook/colors": "workspace:*",
|
||||
"@gitbook/browser-types": "workspace:*",
|
||||
"@gitbook/expr": "workspace:*",
|
||||
"@gitbook/emoji-codepoints": "workspace:*",
|
||||
"@gitbook/fonts": "workspace:*",
|
||||
"@gitbook/icons": "workspace:*",
|
||||
@@ -14,7 +15,7 @@
|
||||
"@gitbook/react-contentkit": "workspace:*",
|
||||
"@gitbook/react-math": "workspace:*",
|
||||
"@gitbook/react-openapi": "workspace:*",
|
||||
"@opennextjs/cloudflare": "^1.6.4",
|
||||
"@opennextjs/cloudflare": "^1.7.1",
|
||||
"@radix-ui/react-checkbox": "^1.0.4",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.12",
|
||||
"@radix-ui/react-hover-card": "^1.1.15",
|
||||
@@ -27,6 +28,7 @@
|
||||
"@tusbar/cache-control": "^1.0.2",
|
||||
"ai": "^4.2.2",
|
||||
"assert-never": "^1.2.1",
|
||||
"bidc": "catalog:",
|
||||
"bun-types": "^1.1.20",
|
||||
"classnames": "^2.5.1",
|
||||
"direction": "^2.0.1",
|
||||
@@ -45,7 +47,7 @@
|
||||
"memoizee": "^0.4.17",
|
||||
"micromark-extension-frontmatter": "^2.0.0",
|
||||
"micromark-extension-gfm": "^3.0.0",
|
||||
"next": "^15.5.0",
|
||||
"next": "15.3.5",
|
||||
"next-themes": "^0.2.1",
|
||||
"nuqs": "^2.2.3",
|
||||
"object-hash": "^3.0.0",
|
||||
@@ -70,8 +72,7 @@
|
||||
"url-join": "^5.0.0",
|
||||
"usehooks-ts": "^3.1.0",
|
||||
"warn-once": "^0.1.1",
|
||||
"zustand": "^5.0.3",
|
||||
"bidc": "catalog:"
|
||||
"zustand": "^5.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@argos-ci/playwright": "^5.0.9",
|
||||
@@ -104,7 +105,8 @@
|
||||
"clean": "rm -rf ./.next && rm -rf ./public/~gitbook/static/icons && rm -rf ./public/~gitbook/static/math",
|
||||
"dev": "env-cmd --silent -f ../../.env.local next",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"build:local": "GITBOOK_URL=http://localhost:3000 next build",
|
||||
"start": "GITBOOK_URL=http://localhost:3000 next start",
|
||||
"build:cloudflare": "opennextjs-cloudflare build",
|
||||
"dev:cloudflare": "wrangler dev --port 8771 --env preview",
|
||||
"dev:cf:middleware": "wrangler dev --port 8771 --inspector-port 9230 --env dev --config ./openNext/customWorkers/middlewareWrangler.jsonc",
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ export default async function SiteDynamicLayout({
|
||||
const withTracking = shouldTrackEvents(await headers());
|
||||
|
||||
return (
|
||||
<CustomizationRootLayout forcedTheme={forcedTheme} customization={context.customization}>
|
||||
<CustomizationRootLayout forcedTheme={forcedTheme} context={context}>
|
||||
<SiteLayout
|
||||
context={context}
|
||||
forcedTheme={forcedTheme}
|
||||
|
||||
+13
-2
@@ -5,6 +5,8 @@ import {
|
||||
generateEmbeddableViewport,
|
||||
} from '@/components/Embeddable';
|
||||
import { getEmbeddableStaticContext } from '@/lib/embeddable';
|
||||
import { shouldTrackEvents } from '@/lib/tracking';
|
||||
import { headers } from 'next/headers';
|
||||
|
||||
interface SiteStaticLayoutProps {
|
||||
params: Promise<RouteLayoutParams>;
|
||||
@@ -14,9 +16,18 @@ export default async function RootLayout({
|
||||
params,
|
||||
children,
|
||||
}: React.PropsWithChildren<SiteStaticLayoutProps>) {
|
||||
const { context } = await getEmbeddableStaticContext(await params);
|
||||
const { context, visitorAuthClaims } = await getEmbeddableStaticContext(await params);
|
||||
const withTracking = shouldTrackEvents(await headers());
|
||||
|
||||
return <EmbeddableRootLayout context={context}>{children}</EmbeddableRootLayout>;
|
||||
return (
|
||||
<EmbeddableRootLayout
|
||||
context={context}
|
||||
withTracking={withTracking}
|
||||
visitorAuthClaims={visitorAuthClaims}
|
||||
>
|
||||
{children}
|
||||
</EmbeddableRootLayout>
|
||||
);
|
||||
}
|
||||
|
||||
export async function generateViewport({ params }: SiteStaticLayoutProps) {
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ export default async function SiteStaticLayout({
|
||||
const withTracking = shouldTrackEvents();
|
||||
|
||||
return (
|
||||
<CustomizationRootLayout customization={context.customization}>
|
||||
<CustomizationRootLayout context={context}>
|
||||
<SiteLayout
|
||||
context={context}
|
||||
withTracking={withTracking}
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
import type { NextRequest } from 'next/server';
|
||||
|
||||
import { type RouteLayoutParams, getStaticSiteContext } from '@/app/utils';
|
||||
import { serveLLMsFullTxt } from '@/routes/llms-full';
|
||||
|
||||
export const dynamic = 'force-static';
|
||||
|
||||
export async function GET(
|
||||
_request: NextRequest,
|
||||
{ params }: { params: Promise<RouteLayoutParams & { page: string }> }
|
||||
) {
|
||||
const awaitedParams = await params;
|
||||
const page = Number(awaitedParams.page);
|
||||
// If page is not a number, not an integer, or less than 0, return an error
|
||||
if (Number.isNaN(page) || !Number.isInteger(page) || page < 0) {
|
||||
return new Response('Invalid page', { status: 400 });
|
||||
}
|
||||
const { context } = await getStaticSiteContext(awaitedParams);
|
||||
return serveLLMsFullTxt(context, page);
|
||||
}
|
||||
+12
-2
@@ -5,6 +5,7 @@ import {
|
||||
generateEmbeddableViewport,
|
||||
} from '@/components/Embeddable';
|
||||
import { getEmbeddableStaticContext } from '@/lib/embeddable';
|
||||
import { shouldTrackEvents } from '@/lib/tracking';
|
||||
|
||||
interface SiteStaticLayoutProps {
|
||||
params: Promise<RouteLayoutParams>;
|
||||
@@ -14,9 +15,18 @@ export default async function RootLayout({
|
||||
params,
|
||||
children,
|
||||
}: React.PropsWithChildren<SiteStaticLayoutProps>) {
|
||||
const { context } = await getEmbeddableStaticContext(await params);
|
||||
const { context, visitorAuthClaims } = await getEmbeddableStaticContext(await params);
|
||||
const withTracking = shouldTrackEvents();
|
||||
|
||||
return <EmbeddableRootLayout context={context}>{children}</EmbeddableRootLayout>;
|
||||
return (
|
||||
<EmbeddableRootLayout
|
||||
context={context}
|
||||
withTracking={withTracking}
|
||||
visitorAuthClaims={visitorAuthClaims}
|
||||
>
|
||||
{children}
|
||||
</EmbeddableRootLayout>
|
||||
);
|
||||
}
|
||||
|
||||
export async function generateViewport({ params }: SiteStaticLayoutProps) {
|
||||
|
||||
+4
-4
@@ -1,5 +1,6 @@
|
||||
import type { RouteLayoutParams } from '@/app/utils';
|
||||
import { getAssetURL } from '@/lib/assets';
|
||||
import { buildVersion } from '@/lib/build';
|
||||
import { getEmbeddableStaticContext } from '@/lib/embeddable';
|
||||
import type { CreateGitBookOptions } from '@gitbook/embed';
|
||||
import type { NextRequest } from 'next/server';
|
||||
@@ -14,7 +15,6 @@ export async function GET(
|
||||
{ params }: { params: Promise<RouteLayoutParams> }
|
||||
) {
|
||||
const { context } = await getEmbeddableStaticContext(await params);
|
||||
const maxAge = 7 * 24 * 60 * 60;
|
||||
const initOptions: CreateGitBookOptions = {
|
||||
siteURL: context.linker.toAbsoluteURL(context.linker.toPathInSite('')),
|
||||
};
|
||||
@@ -45,13 +45,13 @@ export async function GET(
|
||||
const load = function () {
|
||||
const style = document.createElement('link');
|
||||
style.rel = 'stylesheet';
|
||||
style.href = ${JSON.stringify(getAssetURL('embed/index.css'))};
|
||||
style.href = ${JSON.stringify(getAssetURL(`embed/index.css?v=${buildVersion()}`))};
|
||||
document.head.appendChild(style);
|
||||
|
||||
const script = d.createElement('script');
|
||||
script.type = 'text/javascript';
|
||||
script.async = true;
|
||||
script.src = ${JSON.stringify(getAssetURL('embed/index.js'))};
|
||||
script.src = ${JSON.stringify(getAssetURL(`embed/index.js?v=${buildVersion()}`))};
|
||||
|
||||
var latestScript = d.getElementsByTagName('script')[0];
|
||||
latestScript.parentNode.insertBefore(script, latestScript);
|
||||
@@ -70,7 +70,7 @@ export async function GET(
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/javascript',
|
||||
'Cache-Control': `public, max-age=${maxAge}, immutable`,
|
||||
'Cache-Control': 'public, max-age=86400, stale-while-revalidate=604800',
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from './useAI';
|
||||
export * from './useAIChat';
|
||||
export type { RenderAIMessageOptions } from './server-actions';
|
||||
|
||||
@@ -72,7 +72,7 @@ function DescriptionForPageContentToolCall(props: {
|
||||
}) {
|
||||
const { toolCall, context } = props;
|
||||
|
||||
const language = getSpaceLanguage(context.customization);
|
||||
const language = getSpaceLanguage(context);
|
||||
|
||||
return (
|
||||
<p>
|
||||
@@ -102,7 +102,7 @@ function DescriptionForMCPToolCall(props: {
|
||||
}) {
|
||||
const { toolCall, context } = props;
|
||||
|
||||
const language = getSpaceLanguage(context.customization);
|
||||
const language = getSpaceLanguage(context);
|
||||
|
||||
return (
|
||||
<p>
|
||||
@@ -130,7 +130,7 @@ async function DescriptionForSearchToolCall(props: {
|
||||
}) {
|
||||
const { toolCall, context } = props;
|
||||
|
||||
const language = getSpaceLanguage(context.customization);
|
||||
const language = getSpaceLanguage(context);
|
||||
|
||||
// Resolve all hrefs for search results in parallel
|
||||
const searchResultsWithHrefs = await Promise.all(
|
||||
@@ -187,7 +187,7 @@ async function DescriptionForSearchToolCall(props: {
|
||||
) : null}
|
||||
</summary>
|
||||
{hasResults ? (
|
||||
<div className="mt-1 max-h-0 overflow-y-auto circular-corners:rounded-2xl rounded-corners:rounded-lg border border-tint-subtle p-2 opacity-0 transition-all transition-discrete duration-500 group-open:max-h-96 group-open:opacity-11">
|
||||
<div className="hide-scrollbar mt-1 max-h-0 overflow-y-auto circular-corners:rounded-2xl rounded-corners:rounded-lg border border-tint-subtle p-2 opacity-0 transition-all transition-discrete duration-500 group-open:max-h-96 group-open:opacity-11">
|
||||
<ol className="space-y-1">
|
||||
{searchResultsWithHrefs.map((result, index) => (
|
||||
<li
|
||||
@@ -241,7 +241,7 @@ function DescriptionForGetPagesToolCall(props: {
|
||||
}) {
|
||||
const { toolCall, context } = props;
|
||||
|
||||
const language = getSpaceLanguage(context.customization);
|
||||
const language = getSpaceLanguage(context);
|
||||
|
||||
return (
|
||||
<p>
|
||||
|
||||
@@ -39,7 +39,9 @@ export async function streamRenderAIMessage(
|
||||
|
||||
if (message.steps[stepIndex]) {
|
||||
message.steps = [...message.steps];
|
||||
// @ts-expect-error
|
||||
message.steps[stepIndex] = { ...message.steps[stepIndex] };
|
||||
// @ts-expect-error
|
||||
callback(message.steps[stepIndex]);
|
||||
} else {
|
||||
message.steps = [
|
||||
@@ -52,6 +54,7 @@ export async function streamRenderAIMessage(
|
||||
},
|
||||
},
|
||||
];
|
||||
// @ts-expect-error
|
||||
callback(message.steps[stepIndex]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
EmbeddableFrameSubtitle,
|
||||
EmbeddableFrameTitle,
|
||||
} from '../Embeddable/EmbeddableFrame';
|
||||
import { useTrackEvent } from '../Insights';
|
||||
import { useNow } from '../hooks';
|
||||
import { Button } from '../primitives';
|
||||
import { AIChatControlButton } from './AIChatControlButton';
|
||||
@@ -46,17 +47,6 @@ export function AIChat(props: { trademark: boolean }) {
|
||||
}
|
||||
}, [chat.opened]);
|
||||
|
||||
useHotkeys(
|
||||
'mod+i',
|
||||
(e) => {
|
||||
e.preventDefault();
|
||||
chatController.open();
|
||||
},
|
||||
{
|
||||
enableOnFormTags: true,
|
||||
}
|
||||
);
|
||||
|
||||
useHotkeys(
|
||||
'esc',
|
||||
() => {
|
||||
@@ -65,6 +55,16 @@ export function AIChat(props: { trademark: boolean }) {
|
||||
[]
|
||||
);
|
||||
|
||||
// Track the view of the AI chat
|
||||
const trackEvent = useTrackEvent();
|
||||
React.useEffect(() => {
|
||||
if (chat.opened) {
|
||||
trackEvent({
|
||||
type: 'ask_view',
|
||||
});
|
||||
}
|
||||
}, [chat.opened, trackEvent]);
|
||||
|
||||
if (!chat.opened) {
|
||||
return null;
|
||||
}
|
||||
@@ -224,7 +224,7 @@ export function AIChatBody(props: {
|
||||
<>
|
||||
<div
|
||||
ref={scrollContainerRef}
|
||||
className="flex grow scroll-pt-4 flex-col gap-4 overflow-y-auto p-4"
|
||||
className="gutter-stable flex grow scroll-pt-4 flex-col gap-4 overflow-y-auto p-4"
|
||||
style={{
|
||||
paddingBottom: `${inputHeight}px`,
|
||||
}}
|
||||
|
||||
@@ -12,8 +12,9 @@ import { KeyboardShortcut } from '../primitives/KeyboardShortcut';
|
||||
export function AIChatButton(props: {
|
||||
assistant: Assistant;
|
||||
showLabel?: boolean;
|
||||
withShortcut?: boolean;
|
||||
}) {
|
||||
const { assistant, showLabel = true } = props;
|
||||
const { assistant, showLabel = true, withShortcut = true } = props;
|
||||
const language = useLanguage();
|
||||
|
||||
return (
|
||||
@@ -27,7 +28,12 @@ export function AIChatButton(props: {
|
||||
label={
|
||||
<div className="flex items-center gap-2">
|
||||
{t(language, 'ai_chat_ask', assistant.label)}
|
||||
<KeyboardShortcut keys={['mod', 'i']} className="border-tint-11 text-tint-1" />
|
||||
{withShortcut ? (
|
||||
<KeyboardShortcut
|
||||
keys={['mod', 'i']}
|
||||
className="border-tint-11 text-tint-1"
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
}
|
||||
onClick={() => assistant.open()}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { useLanguage } from '@/intl/client';
|
||||
import { tString } from '@/intl/translate';
|
||||
import { tcls } from '@/lib/tailwind';
|
||||
import { AIMessageRole } from '@gitbook/api';
|
||||
import type React from 'react';
|
||||
@@ -46,17 +48,9 @@ export function AIChatMessages(props: {
|
||||
{message.content ? message.content : null}
|
||||
|
||||
{isLastMessage && chat.loading ? (
|
||||
<div className="flex w-full animate-fade-in-slow flex-wrap gap-2">
|
||||
{Array.from({ length: 7 }).map((_, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="h-4 animate-[fadeIn_500ms_ease_both,pulse_1.5s_infinite] circular-corners:rounded-2xl rounded-corners:rounded-md bg-tint-4"
|
||||
style={{
|
||||
width: `calc(${(index % 4) * 20 + 10}% - 4px)`,
|
||||
animationDelay: `${index * 0.1}s`,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
<div className="flex w-full animate-fade-in-slow flex-col gap-2">
|
||||
{!message.content ? <HoldMessage /> : null}
|
||||
<LoadingSkeleton />
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
@@ -86,3 +80,55 @@ export function AIChatMessages(props: {
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function HoldMessage() {
|
||||
const language = useLanguage();
|
||||
|
||||
return (
|
||||
<div className="animate-[heightIn_500ms_4500ms_ease_both] py-2 text-tint-subtle">
|
||||
{tString(language, 'ai_chat_hold_message_1')
|
||||
.split(' ')
|
||||
.map((word, index) => (
|
||||
<span
|
||||
key={index}
|
||||
className="animate-fade-in-slow"
|
||||
style={{
|
||||
animationDelay: `${5000 + index * 200}ms`,
|
||||
}}
|
||||
>
|
||||
{word}{' '}
|
||||
</span>
|
||||
))}
|
||||
{tString(language, 'ai_chat_hold_message_2')
|
||||
.split(' ')
|
||||
.map((word, index) => (
|
||||
<span
|
||||
key={index}
|
||||
className="animate-fade-in-slow"
|
||||
style={{
|
||||
animationDelay: `${10000 + index * 200}ms`,
|
||||
}}
|
||||
>
|
||||
{word}{' '}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function LoadingSkeleton() {
|
||||
return (
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{Array.from({ length: 7 }).map((_, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="h-4 animate-[fadeIn_500ms_ease_both,pulse_1.5s_infinite] circular-corners:rounded-2xl rounded-corners:rounded-md bg-tint-4"
|
||||
style={{
|
||||
width: `calc(${(index % 4) * 20 + 10}% - 4px)`,
|
||||
animationDelay: `${index * 0.1}s`,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
'use client';
|
||||
|
||||
import type { GitBookSiteContext } from '@/lib/context';
|
||||
import { OpenAPIPrefillContextProvider } from '@gitbook/react-openapi';
|
||||
import * as React from 'react';
|
||||
import { createContext, useContext } from 'react';
|
||||
|
||||
export type AdaptiveVisitorClaimsData = {
|
||||
visitor: {
|
||||
claims: Record<string, unknown> & { unsigned: Record<string, unknown> };
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* In-memory cache of visitor claim readers keyed by contextId.
|
||||
*/
|
||||
const adaptiveVisitorReaderCache = new Map<
|
||||
string,
|
||||
ReturnType<typeof createResourceReader<AdaptiveVisitorClaimsData | null>>
|
||||
>();
|
||||
|
||||
function createResourceReader<T>(promise: Promise<T>) {
|
||||
let result: T | null | undefined;
|
||||
|
||||
const suspender = (async () => {
|
||||
try {
|
||||
result = await promise;
|
||||
} catch {
|
||||
result = null;
|
||||
}
|
||||
})();
|
||||
|
||||
return {
|
||||
read() {
|
||||
if (result === undefined) {
|
||||
throw suspender;
|
||||
}
|
||||
return result;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an adaptive visitor claims cached reader for a given endpoint URL and contextId.
|
||||
*/
|
||||
function getAdaptiveVisitorClaimsReader(url: string, contextId: string) {
|
||||
let reader = adaptiveVisitorReaderCache.get(contextId);
|
||||
if (!reader) {
|
||||
const promise = (async () => {
|
||||
try {
|
||||
const res = await fetch(url);
|
||||
if (!res.ok) {
|
||||
return null;
|
||||
}
|
||||
return await res.json<AdaptiveVisitorClaimsData>();
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
})();
|
||||
|
||||
reader = createResourceReader(promise);
|
||||
adaptiveVisitorReaderCache.set(contextId, reader);
|
||||
}
|
||||
return reader;
|
||||
}
|
||||
|
||||
export type AdaptiveVisitorContextValue = () => AdaptiveVisitorClaimsData | null;
|
||||
|
||||
const AdaptiveVisitorContext = createContext<AdaptiveVisitorContextValue>(() => null);
|
||||
|
||||
/**
|
||||
* Provide context to adapt site based on visitor claims.
|
||||
*/
|
||||
export function AdaptiveVisitorContextProvider(
|
||||
props: React.PropsWithChildren<{
|
||||
visitorClaimsURL: string;
|
||||
contextId: GitBookSiteContext['contextId'] | undefined;
|
||||
}>
|
||||
) {
|
||||
const { visitorClaimsURL, contextId, children } = props;
|
||||
|
||||
const getAdaptiveVisitorClaims = React.useCallback(() => {
|
||||
if (!contextId) {
|
||||
return null;
|
||||
}
|
||||
return getAdaptiveVisitorClaimsReader(visitorClaimsURL, contextId).read();
|
||||
}, [visitorClaimsURL, contextId]);
|
||||
|
||||
return (
|
||||
<AdaptiveVisitorContext.Provider value={getAdaptiveVisitorClaims}>
|
||||
<OpenAPIPrefillContextProvider getPrefillInputContextData={getAdaptiveVisitorClaims}>
|
||||
{children}
|
||||
</OpenAPIPrefillContextProvider>
|
||||
</AdaptiveVisitorContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook that returns a suspensable getter for adaptive visitor claims data.
|
||||
*/
|
||||
export function useAdaptiveVisitor(): AdaptiveVisitorContextValue {
|
||||
return useContext(AdaptiveVisitorContext);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './AdaptiveVisitorContextProvider';
|
||||
@@ -34,69 +34,67 @@ export function AnnouncementBanner(props: {
|
||||
className="theme-bold:bg-header-background pt-4 pb-2"
|
||||
data-nosnippet=""
|
||||
>
|
||||
<div className="scroll-nojump">
|
||||
<div className="transition-all duration-300 lg:chat-open:pr-80 xl:chat-open:pr-96">
|
||||
<div className={tcls('relative', CONTAINER_STYLE)}>
|
||||
<Tag
|
||||
href={contentRef?.href ?? ''}
|
||||
className={tcls(
|
||||
'flex w-full items-start justify-center overflow-hidden circular-corners:rounded-xl rounded-md straight-corners:rounded-none px-4 py-3 text-neutral-strong text-sm theme-bold:ring-1 theme-gradient:ring-1 ring-inset transition-colors',
|
||||
style.container,
|
||||
closeable && 'pr-12',
|
||||
hasLink && style.hover
|
||||
)}
|
||||
insights={
|
||||
announcement.link
|
||||
? {
|
||||
type: 'link_click',
|
||||
link: {
|
||||
target: announcement.link.to,
|
||||
position: SiteInsightsLinkPosition.Announcement,
|
||||
},
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
<Icon
|
||||
icon={style.icon as IconName}
|
||||
className={`mt-0.5 mr-3 size-4 shrink-0 ${style.iconColor}`}
|
||||
/>
|
||||
<div>
|
||||
{announcement.message}
|
||||
{hasLink ? (
|
||||
<div className={tcls(LinkStyles, style.link, 'ml-1 inline')}>
|
||||
{contentRef?.icon ? (
|
||||
<span className="mr-1 ml-2 *:inline">
|
||||
{contentRef?.icon}
|
||||
</span>
|
||||
) : null}
|
||||
{announcement.link?.title && (
|
||||
<span className="mr-1">{announcement.link?.title}</span>
|
||||
)}
|
||||
<Icon
|
||||
icon={
|
||||
announcement.link?.to.kind === 'url'
|
||||
? 'arrow-up-right'
|
||||
: 'chevron-right'
|
||||
}
|
||||
className={tcls('mb-0.5 inline size-3')}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</Tag>
|
||||
{closeable ? (
|
||||
<Button
|
||||
iconOnly
|
||||
icon="close"
|
||||
label={tString(language, 'close')}
|
||||
variant="blank"
|
||||
size="default"
|
||||
onClick={dismissAnnouncement}
|
||||
className={`absolute top-0 right-4 mt-2 mr-2 circular-corners:rounded-lg rounded-sm straight-corners:rounded-none p-1.5 transition-all hover:ring-1 sm:right-6 md:right-8 ${style.close}`}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="transition-all duration-300 lg:chat-open:pr-80 xl:chat-open:pr-96">
|
||||
<div className={tcls('relative', CONTAINER_STYLE)}>
|
||||
<Tag
|
||||
href={contentRef?.href ?? ''}
|
||||
className={tcls(
|
||||
'flex w-full items-start justify-center overflow-hidden circular-corners:rounded-xl rounded-md straight-corners:rounded-none px-4 py-3 text-neutral-strong text-sm theme-bold:ring-1 theme-gradient:ring-1 ring-inset transition-colors',
|
||||
style.container,
|
||||
closeable && 'pr-12',
|
||||
hasLink && style.hover
|
||||
)}
|
||||
insights={
|
||||
announcement.link
|
||||
? {
|
||||
type: 'link_click',
|
||||
link: {
|
||||
target: announcement.link.to,
|
||||
position: SiteInsightsLinkPosition.Announcement,
|
||||
},
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
<Icon
|
||||
icon={style.icon as IconName}
|
||||
className={`mt-0.5 mr-3 size-4 shrink-0 ${style.iconColor}`}
|
||||
/>
|
||||
<div>
|
||||
{announcement.message}
|
||||
{hasLink ? (
|
||||
<div className={tcls(LinkStyles, style.link, 'ml-1 inline')}>
|
||||
{contentRef?.icon ? (
|
||||
<span className="mr-1 ml-2 *:inline">
|
||||
{contentRef?.icon}
|
||||
</span>
|
||||
) : null}
|
||||
{announcement.link?.title && (
|
||||
<span className="mr-1">{announcement.link?.title}</span>
|
||||
)}
|
||||
<Icon
|
||||
icon={
|
||||
announcement.link?.to.kind === 'url'
|
||||
? 'arrow-up-right'
|
||||
: 'chevron-right'
|
||||
}
|
||||
className={tcls('mb-0.5 inline size-3')}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</Tag>
|
||||
{closeable ? (
|
||||
<Button
|
||||
iconOnly
|
||||
icon="close"
|
||||
label={tString(language, 'close')}
|
||||
variant="blank"
|
||||
size="default"
|
||||
onClick={dismissAnnouncement}
|
||||
className={`absolute top-0 right-4 mt-2 mr-2 circular-corners:rounded-lg rounded-sm straight-corners:rounded-none p-1.5 transition-all hover:ring-1 sm:right-6 md:right-8 ${style.close}`}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -119,7 +119,7 @@ export async function highlight(
|
||||
currentIndex += 1; // for the \n
|
||||
|
||||
return {
|
||||
highlighted: Boolean(lineBlock.data.highlighted),
|
||||
highlighted: Boolean(lineBlock?.data.highlighted),
|
||||
tokens: result,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { type ClassValue, tcls } from '@/lib/tailwind';
|
||||
import type { DocumentBlockColumns, Length } from '@gitbook/api';
|
||||
import { tcls } from '@/lib/tailwind';
|
||||
import { type DocumentBlockColumns, type Length, VerticalAlignment } from '@gitbook/api';
|
||||
import type { BlockProps } from '../Block';
|
||||
import { Blocks } from '../Blocks';
|
||||
|
||||
@@ -8,10 +8,12 @@ export function Columns(props: BlockProps<DocumentBlockColumns>) {
|
||||
return (
|
||||
<div className={tcls('flex flex-col gap-x-8 md:flex-row', style)}>
|
||||
{block.nodes.map((columnBlock) => {
|
||||
const width = columnBlock.data.width;
|
||||
const { className, style } = transformLengthToCSS(width);
|
||||
return (
|
||||
<Column key={columnBlock.key} className={className} style={style}>
|
||||
<Column
|
||||
key={columnBlock.key}
|
||||
width={columnBlock.data.width}
|
||||
verticalAlignment={columnBlock.data.verticalAlignment}
|
||||
>
|
||||
<Blocks
|
||||
key={columnBlock.key}
|
||||
nodes={columnBlock.nodes}
|
||||
@@ -29,11 +31,23 @@ export function Columns(props: BlockProps<DocumentBlockColumns>) {
|
||||
|
||||
export function Column(props: {
|
||||
children?: React.ReactNode;
|
||||
className?: ClassValue;
|
||||
style?: React.CSSProperties;
|
||||
width?: Length;
|
||||
verticalAlignment?: VerticalAlignment;
|
||||
}) {
|
||||
const { width, verticalAlignment } = props;
|
||||
const { className, style } = transformLengthToCSS(width);
|
||||
return (
|
||||
<div className={tcls('flex-col', props.className)} style={props.style}>
|
||||
<div
|
||||
className={tcls(
|
||||
'flex flex-col',
|
||||
(verticalAlignment === VerticalAlignment.Top || !verticalAlignment) &&
|
||||
'justify-start',
|
||||
verticalAlignment === VerticalAlignment.Middle && 'justify-center',
|
||||
verticalAlignment === VerticalAlignment.Bottom && 'justify-end',
|
||||
className
|
||||
)}
|
||||
style={style}
|
||||
>
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -7,13 +7,16 @@ import { Block, type BlockProps } from './Block';
|
||||
import { Blocks } from './Blocks';
|
||||
import { getBlockTextStyle } from './spacing';
|
||||
|
||||
export function Hint(props: BlockProps<DocumentBlockHint>) {
|
||||
const { block, style, ancestorBlocks, ...contextProps } = props;
|
||||
export function Hint({
|
||||
block,
|
||||
style,
|
||||
ancestorBlocks,
|
||||
...contextProps
|
||||
}: BlockProps<DocumentBlockHint>) {
|
||||
const hintStyle = HINT_STYLES[block.data.style] ?? HINT_STYLES.info;
|
||||
const firstLine = getBlockTextStyle(block.nodes[0]);
|
||||
|
||||
const firstNode = block.nodes[0];
|
||||
const hasHeading = ['heading-1', 'heading-2', 'heading-3'].includes(block.nodes[0].type);
|
||||
const firstNode = block.nodes[0]!;
|
||||
const firstLine = getBlockTextStyle(firstNode);
|
||||
const hasHeading = ['heading-1', 'heading-2', 'heading-3'].includes(firstNode.type);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
||||
@@ -20,10 +20,7 @@ export async function InlineLink(props: InlineProps<DocumentInlineLink>) {
|
||||
: null;
|
||||
const { contentContext } = context;
|
||||
|
||||
const language =
|
||||
contentContext && 'customization' in contentContext
|
||||
? getSpaceLanguage(contentContext.customization)
|
||||
: languages.en;
|
||||
const language = contentContext ? getSpaceLanguage(contentContext) : languages.en;
|
||||
|
||||
if (!contentContext || !resolved) {
|
||||
return (
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
}
|
||||
|
||||
.contentkit-button-style-primary {
|
||||
@apply bg-primary-solid text-contrast-primary-solid hover:bg-primary-solid-hover hover:text-contrast-primary-solid-hover ring-0 contrast-more:ring-1;
|
||||
@apply bg-primary-original text-contrast-primary-original hover:bg-primary-solid-hover hover:text-contrast-primary-solid-hover ring-0 contrast-more:ring-1;
|
||||
}
|
||||
|
||||
.contentkit-button-style-secondary {
|
||||
|
||||
@@ -19,9 +19,9 @@ export function ListItem(props: BlockProps<DocumentBlockListItem>) {
|
||||
|
||||
const parent = ancestorBlocks[ancestorBlocks.length - 1];
|
||||
assert(
|
||||
(parent && parent.type === 'list-ordered') ||
|
||||
parent.type === 'list-unordered' ||
|
||||
parent.type === 'list-tasks',
|
||||
parent?.type === 'list-ordered' ||
|
||||
parent?.type === 'list-unordered' ||
|
||||
parent?.type === 'list-tasks',
|
||||
'Invalid parent list type'
|
||||
);
|
||||
|
||||
@@ -112,11 +112,11 @@ function getListItemDepth(input: {
|
||||
|
||||
for (let i = ancestorBlocks.length - 1; i >= 0; i--) {
|
||||
const block = ancestorBlocks[i];
|
||||
if (block.type === type) {
|
||||
if (block?.type === type) {
|
||||
depth = depth + 1;
|
||||
continue;
|
||||
}
|
||||
if (block.type === 'list-item') {
|
||||
if (block?.type === 'list-item') {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -11,7 +11,7 @@ import { Heading } from '../Heading';
|
||||
|
||||
import './scalar.css';
|
||||
import './style.css';
|
||||
import { DEFAULT_LOCALE, getCustomizationLocale } from '@/intl/server';
|
||||
import { DEFAULT_LOCALE, getSpaceLocale } from '@/intl/server';
|
||||
import type { GitBookAnyContext } from '@/lib/context';
|
||||
import type {
|
||||
AnyOpenAPIOperationsBlock,
|
||||
@@ -30,10 +30,7 @@ export function getOpenAPIContext(args: {
|
||||
const { props, specUrl, context } = args;
|
||||
const { block } = props;
|
||||
|
||||
const customization = context && 'customization' in context ? context.customization : null;
|
||||
const customizationLocale = customization
|
||||
? getCustomizationLocale(customization)
|
||||
: DEFAULT_LOCALE;
|
||||
const customizationLocale = context ? getSpaceLocale(context) : DEFAULT_LOCALE;
|
||||
const locale = checkIsValidLocale(customizationLocale) ? customizationLocale : DEFAULT_LOCALE;
|
||||
|
||||
return {
|
||||
|
||||
@@ -272,9 +272,8 @@ body {
|
||||
}
|
||||
.scalar-activate-button {
|
||||
@apply flex gap-2 items-center;
|
||||
@apply bg-primary-solid text-contrast-primary-solid hover:bg-primary-solid-hover hover:text-contrast-primary-solid-hover contrast-more:ring-1 rounded-md straight-corners:rounded-none circular-corners:rounded-full circular-corners:px-3 place-self-start;
|
||||
@apply ring-1 ring-tint hover:ring-tint-hover;
|
||||
@apply shadow-sm shadow-tint dark:shadow-tint-1 hover:shadow-md active:shadow-none;
|
||||
@apply bg-primary-original text-contrast-primary-original hover:bg-primary-solid-hover hover:text-contrast-primary-solid-hover contrast-more:ring-1 rounded-md straight-corners:rounded-none circular-corners:rounded-full circular-corners:px-3 place-self-start;
|
||||
@apply shadow-sm shadow-primary dark:shadow-primary-1 hover:shadow-md active:shadow-none;
|
||||
@apply contrast-more:ring-tint-12 contrast-more:hover:ring-2 contrast-more:hover:ring-tint-12;
|
||||
@apply hover:scale-105 active:scale-100 transition-all;
|
||||
@apply grow-0 shrink-0 truncate;
|
||||
|
||||
@@ -565,7 +565,7 @@
|
||||
}
|
||||
|
||||
.openapi-example-empty {
|
||||
@apply relative text-tint bg-tint min-h-20 flex flex-col justify-center items-center;
|
||||
@apply relative text-tint min-h-20 flex flex-col justify-center items-center text-sm;
|
||||
}
|
||||
|
||||
/* Common Elements */
|
||||
@@ -746,6 +746,10 @@ body:has(.openapi-select-popover) {
|
||||
@apply px-3 transition-all;
|
||||
}
|
||||
|
||||
.openapi-disclosure-group-trigger[aria-expanded="true"] > .openapi-disclosure-group-label {
|
||||
@apply font-medium;
|
||||
}
|
||||
|
||||
.openapi-disclosure-group-trigger[aria-expanded="true"] > .openapi-disclosure-group-icon > svg {
|
||||
@apply rotate-90;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ export function StepperStep(props: BlockProps<DocumentBlockStepperStep>) {
|
||||
const { block, style, ancestorBlocks, ...contextProps } = props;
|
||||
|
||||
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');
|
||||
|
||||
const index = ancestor.nodes.indexOf(block);
|
||||
|
||||
@@ -36,8 +36,8 @@ export function StepperStep(props: BlockProps<DocumentBlockStepperStep>) {
|
||||
<div className="relative select-none">
|
||||
<div
|
||||
className={tcls(
|
||||
'can-override-bg can-override-text flex size-[calc(1.75rem+1px)] items-center justify-center rounded-full bg-primary-solid theme-muted:bg-primary-subtle tabular-nums',
|
||||
'font-medium text-contrast-primary-solid theme-muted:text-primary'
|
||||
'can-override-bg can-override-text flex size-[calc(1.75rem+1px)] items-center justify-center rounded-full bg-primary-original theme-muted:bg-primary-subtle tabular-nums contrast-more:bg-primary-solid',
|
||||
'font-medium text-contrast-primary-original theme-muted:text-primary contrast-more:text-contrast-primary-solid'
|
||||
)}
|
||||
>
|
||||
{index + 1}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Image } from '@/components/utils';
|
||||
import { type ResolvedContentRef, resolveContentRef } from '@/lib/references';
|
||||
import { tcls } from '@/lib/tailwind';
|
||||
import {
|
||||
CardsImageObjectFit,
|
||||
type ContentRef,
|
||||
type DocumentTableViewCards,
|
||||
SiteInsightsLinkPosition,
|
||||
@@ -25,8 +26,12 @@ export async function RecordCard(
|
||||
: null;
|
||||
|
||||
const [lightCover, darkCover, target] = await Promise.all([
|
||||
light && context.contentContext ? resolveContentRef(light, context.contentContext) : null,
|
||||
dark && context.contentContext ? resolveContentRef(dark, context.contentContext) : null,
|
||||
light.contentRef && context.contentContext
|
||||
? resolveContentRef(light.contentRef, context.contentContext)
|
||||
: null,
|
||||
dark.contentRef && context.contentContext
|
||||
? resolveContentRef(dark.contentRef, context.contentContext)
|
||||
: null,
|
||||
targetRef && context.contentContext
|
||||
? resolveContentRef(targetRef, context.contentContext)
|
||||
: null,
|
||||
@@ -35,6 +40,10 @@ export async function RecordCard(
|
||||
const darkCoverIsSquareOrPortrait = isSquareOrPortrait(darkCover);
|
||||
const lightCoverIsSquareOrPortrait = isSquareOrPortrait(lightCover);
|
||||
|
||||
const darkObjectFit = `dark:${getObjectFitClass(dark.objectFit)}`;
|
||||
const lightObjectFit = getObjectFitClass(light.objectFit);
|
||||
const objectFits = `${lightObjectFit} ${darkObjectFit}`;
|
||||
|
||||
const body = (
|
||||
<div
|
||||
className={tcls(
|
||||
@@ -94,7 +103,7 @@ export async function RecordCard(
|
||||
'min-w-0',
|
||||
'w-full',
|
||||
'h-full',
|
||||
'object-cover',
|
||||
'bg-tint-subtle',
|
||||
lightCoverIsSquareOrPortrait || darkCoverIsSquareOrPortrait
|
||||
? [
|
||||
lightCoverIsSquareOrPortrait
|
||||
@@ -104,7 +113,8 @@ export async function RecordCard(
|
||||
? 'dark:min-[432px]:aspect-video dark:min-[432px]:h-auto'
|
||||
: '',
|
||||
].filter(Boolean)
|
||||
: ['h-auto', 'aspect-video']
|
||||
: ['h-auto', 'aspect-video'],
|
||||
objectFits
|
||||
)}
|
||||
priority={isOffscreen ? 'lazy' : 'high'}
|
||||
preload
|
||||
@@ -190,3 +200,23 @@ function isSquareOrPortrait(contentRef: ResolvedContentRef | null) {
|
||||
|
||||
return file.dimensions?.width / file.dimensions?.height <= 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CSS class for object-fit based on the objectFit value.
|
||||
*/
|
||||
function getObjectFitClass(objectFit: CardsImageObjectFit | undefined): string {
|
||||
if (!objectFit) {
|
||||
return 'object-cover';
|
||||
}
|
||||
|
||||
switch (objectFit) {
|
||||
case CardsImageObjectFit.Contain:
|
||||
return 'object-contain';
|
||||
case CardsImageObjectFit.Fill:
|
||||
return 'object-fill';
|
||||
case CardsImageObjectFit.Cover:
|
||||
return 'object-cover';
|
||||
default:
|
||||
throw new Error(`Unsupported object fit: ${objectFit}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ export function RecordRow(
|
||||
autoSizedColumns,
|
||||
fixedColumns,
|
||||
});
|
||||
// @ts-expect-error
|
||||
const verticalAlignment = getColumnVerticalAlignment(block.data.definition[column]);
|
||||
|
||||
return (
|
||||
|
||||
@@ -25,7 +25,9 @@ export function ViewGrid(props: TableViewProps<DocumentTableViewGrid>) {
|
||||
/* Only show the header when configured and not empty */
|
||||
const withHeader =
|
||||
!view.hideHeader &&
|
||||
view.columns.some((columnId) => block.data.definition[columnId].title.trim().length > 0);
|
||||
view.columns.some(
|
||||
(columnId) => (block.data.definition[columnId]?.title.trim().length ?? 0) > 0
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={tcls(style, styles.tableWrapper)}>
|
||||
@@ -43,28 +45,31 @@ export function ViewGrid(props: TableViewProps<DocumentTableViewGrid>) {
|
||||
)}
|
||||
>
|
||||
<div role="row" className={tcls('flex', 'w-full')}>
|
||||
{view.columns.map((column) => (
|
||||
<div
|
||||
key={column}
|
||||
role="columnheader"
|
||||
className={tcls(
|
||||
styles.columnHeader,
|
||||
getColumnAlignment(block.data.definition[column])
|
||||
)}
|
||||
style={{
|
||||
width: getColumnWidth({
|
||||
column,
|
||||
columnWidths,
|
||||
autoSizedColumns,
|
||||
fixedColumns,
|
||||
}),
|
||||
minWidth: columnWidths?.[column] || '100px',
|
||||
}}
|
||||
title={block.data.definition[column].title}
|
||||
>
|
||||
{block.data.definition[column].title}
|
||||
</div>
|
||||
))}
|
||||
{view.columns.map((column) => {
|
||||
const definition = block.data.definition[column]!;
|
||||
return (
|
||||
<div
|
||||
key={column}
|
||||
role="columnheader"
|
||||
className={tcls(
|
||||
styles.columnHeader,
|
||||
getColumnAlignment(definition)
|
||||
)}
|
||||
style={{
|
||||
width: getColumnWidth({
|
||||
column,
|
||||
columnWidths,
|
||||
autoSizedColumns,
|
||||
fixedColumns,
|
||||
}),
|
||||
minWidth: columnWidths?.[column] || '100px',
|
||||
}}
|
||||
title={definition.title}
|
||||
>
|
||||
{definition.title}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import type {
|
||||
CardsImageObjectFit,
|
||||
ContentRef,
|
||||
ContentRefFile,
|
||||
ContentRefURL,
|
||||
DocumentTableDefinition,
|
||||
DocumentTableImageRecord,
|
||||
DocumentTableRecord,
|
||||
DocumentTableViewCards,
|
||||
} from '@gitbook/api';
|
||||
@@ -21,53 +23,64 @@ export function getRecordValue<T extends number | string | boolean | string[] |
|
||||
|
||||
/**
|
||||
* Get the covers for a record card.
|
||||
* Returns both the light and dark covers.
|
||||
* Returns both the light and dark covers with their content refs and optional object fit.
|
||||
* The light cover is a string or a content ref (image or files column type).
|
||||
* The dark cover is a content ref (image column type).
|
||||
*/
|
||||
export function getRecordCardCovers(
|
||||
record: DocumentTableRecord,
|
||||
view: DocumentTableViewCards
|
||||
): { [key in 'light' | 'dark']: ContentRefFile | ContentRefURL | null } {
|
||||
return {
|
||||
light: (() => {
|
||||
if (!view.coverDefinition) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const value = getRecordValue(record, view.coverDefinition) as
|
||||
| ContentRefFile
|
||||
| ContentRefURL
|
||||
| string[];
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
if (value.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (typeof value[0] === 'string') {
|
||||
return { kind: 'file', file: value[0] };
|
||||
}
|
||||
}
|
||||
|
||||
return value as ContentRefFile | ContentRefURL;
|
||||
})(),
|
||||
dark: (() => {
|
||||
if (!view.coverDefinitionDark) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const value = getRecordValue(record, view.coverDefinitionDark) as
|
||||
| ContentRefFile
|
||||
| ContentRefURL;
|
||||
|
||||
if (!value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return value;
|
||||
})(),
|
||||
): {
|
||||
[key in 'light' | 'dark']: {
|
||||
contentRef: ContentRefFile | ContentRefURL | null;
|
||||
objectFit?: CardsImageObjectFit;
|
||||
};
|
||||
} {
|
||||
const lightValue = view.coverDefinition
|
||||
? (getRecordValue(record, view.coverDefinition) as DocumentTableImageRecord | string[])
|
||||
: null;
|
||||
|
||||
const darkValue = view.coverDefinitionDark
|
||||
? (getRecordValue(record, view.coverDefinitionDark) as DocumentTableImageRecord)
|
||||
: null;
|
||||
|
||||
return {
|
||||
light: processCoverValue(lightValue),
|
||||
dark: processCoverValue(darkValue),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a cover value and return the content ref and object fit.
|
||||
*/
|
||||
function processCoverValue(value: DocumentTableImageRecord | string[] | null | undefined): {
|
||||
contentRef: ContentRefFile | ContentRefURL | null;
|
||||
objectFit?: CardsImageObjectFit;
|
||||
} {
|
||||
if (!value) {
|
||||
return { contentRef: null };
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
if (value.length === 0) {
|
||||
return { contentRef: null };
|
||||
}
|
||||
|
||||
if (typeof value[0] === 'string') {
|
||||
return { contentRef: { kind: 'file', file: value[0] } };
|
||||
}
|
||||
}
|
||||
|
||||
// Check if it's the new schema with objectFit
|
||||
if (value && typeof value === 'object' && 'ref' in value && 'objectFit' in value) {
|
||||
return {
|
||||
contentRef: value.ref,
|
||||
objectFit: value.objectFit,
|
||||
};
|
||||
}
|
||||
|
||||
// It's a direct ContentRef
|
||||
return { contentRef: value as ContentRefFile | ContentRefURL };
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -206,7 +206,7 @@ export function DynamicTabs(
|
||||
'max-w-full',
|
||||
'truncate',
|
||||
|
||||
active.id === tab.id
|
||||
active?.id === tab.id
|
||||
? [
|
||||
'shrink-0',
|
||||
'active-tab',
|
||||
@@ -222,7 +222,7 @@ export function DynamicTabs(
|
||||
<button
|
||||
type="button"
|
||||
role="tab"
|
||||
aria-selected={active.id === tab.id}
|
||||
aria-selected={active?.id === tab.id}
|
||||
aria-controls={getTabPanelId(tab.id)}
|
||||
id={getTabButtonId(tab.id)}
|
||||
onClick={() => {
|
||||
@@ -255,7 +255,7 @@ export function DynamicTabs(
|
||||
role="tabpanel"
|
||||
id={getTabPanelId(tab.id)}
|
||||
aria-labelledby={getTabButtonId(tab.id)}
|
||||
className={tcls('p-4', tab.id !== active.id ? 'hidden' : null)}
|
||||
className={tcls('p-4', tab.id !== active?.id ? 'hidden' : null)}
|
||||
>
|
||||
{tabsBody[index]}
|
||||
</div>
|
||||
|
||||
@@ -59,15 +59,15 @@ interface MarkedLeafProps<Mark extends DocumentTextMark> {
|
||||
}
|
||||
|
||||
function Bold(props: MarkedLeafProps<DocumentMarkBold>) {
|
||||
return <strong className={tcls('font-bold')}>{props.children}</strong>;
|
||||
return <strong className="font-bold">{props.children}</strong>;
|
||||
}
|
||||
|
||||
function Italic(props: MarkedLeafProps<DocumentMarkItalic>) {
|
||||
return <i className={tcls('font-italic')}>{props.children}</i>;
|
||||
return <i className="font-italic">{props.children}</i>;
|
||||
}
|
||||
|
||||
function Strikethrough(props: MarkedLeafProps<DocumentMarkStrikethrough>) {
|
||||
return <s className={tcls('line-through')}>{props.children}</s>;
|
||||
return <s className="line-through">{props.children}</s>;
|
||||
}
|
||||
|
||||
function Keyboard(props: MarkedLeafProps<DocumentMarkKeyboard>) {
|
||||
|
||||
@@ -43,9 +43,9 @@ export function getBlockTextStyle(block: DocumentBlock): {
|
||||
case 'list-ordered':
|
||||
case 'list-tasks':
|
||||
case 'list-unordered':
|
||||
return getBlockTextStyle(block.nodes[0]);
|
||||
return getBlockTextStyle(block.nodes[0]!);
|
||||
case 'list-item':
|
||||
return getBlockTextStyle(block.nodes[0]);
|
||||
return getBlockTextStyle(block.nodes[0]!);
|
||||
default:
|
||||
return {
|
||||
textSize: 'text-base',
|
||||
|
||||
@@ -21,7 +21,7 @@ export function isBlockOffscreen(
|
||||
|
||||
const allAncestors = [document, ...ancestorBlocks];
|
||||
for (let index = allAncestors.length - 1; index >= 0; index--) {
|
||||
const parent = allAncestors[index];
|
||||
const parent = allAncestors[index]!;
|
||||
const offset = getBlockOffset({ block: current, parent });
|
||||
|
||||
if (offset > screenHeight) {
|
||||
|
||||
@@ -7,6 +7,9 @@ import {
|
||||
AIChatDynamicIcon,
|
||||
AIChatSubtitle,
|
||||
} from '@/components/AIChat';
|
||||
import * as api from '@gitbook/api';
|
||||
import React from 'react';
|
||||
import { useTrackEvent } from '../Insights';
|
||||
import {
|
||||
EmbeddableFrame,
|
||||
EmbeddableFrameBody,
|
||||
@@ -28,6 +31,20 @@ export function EmbeddableAIChat(props: {
|
||||
const chatController = useAIChatController();
|
||||
const configuration = useEmbeddableConfiguration();
|
||||
|
||||
// Track the view of the AI chat
|
||||
const trackEvent = useTrackEvent();
|
||||
React.useEffect(() => {
|
||||
trackEvent(
|
||||
{
|
||||
type: 'ask_view',
|
||||
},
|
||||
{
|
||||
pageId: null,
|
||||
displayContext: api.SiteInsightsDisplayContext.Embed,
|
||||
}
|
||||
);
|
||||
}, [trackEvent]);
|
||||
|
||||
return (
|
||||
<EmbeddableFrame>
|
||||
<EmbeddableFrameHeader>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { type PagePathParams, getSitePageData } from '@/components/SitePage';
|
||||
|
||||
import { PageBody } from '@/components/PageBody';
|
||||
import type { GitBookSiteContext } from '@/lib/context';
|
||||
import { SiteInsightsDisplayContext } from '@gitbook/api';
|
||||
import type { Metadata } from 'next';
|
||||
import { Button } from '../primitives';
|
||||
import {
|
||||
@@ -54,6 +55,7 @@ export async function EmbeddableDocsPage(props: EmbeddableDocsPageProps) {
|
||||
ancestors={ancestors}
|
||||
document={document}
|
||||
withPageFeedback={withPageFeedback}
|
||||
insightsDisplayContext={SiteInsightsDisplayContext.Embed}
|
||||
/>
|
||||
</div>
|
||||
</EmbeddableFrameBody>
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
import { AIChatProvider, AIContextProvider } from '@/components/AI';
|
||||
import { AIContextProvider } from '@/components/AI';
|
||||
import { CustomizationRootLayout } from '@/components/RootLayout';
|
||||
import {
|
||||
SiteLayoutClientContexts,
|
||||
generateSiteLayoutMetadata,
|
||||
generateSiteLayoutViewport,
|
||||
} from '@/components/SiteLayout';
|
||||
import type { VisitorAuthClaims } from '@/lib/adaptive';
|
||||
import type { GitBookSiteContext } from '@/lib/context';
|
||||
import { CustomizationAIMode } from '@gitbook/api';
|
||||
import { SpaceLayoutServerContext } from '../SpaceLayout';
|
||||
import { EmbeddableIframeAPI } from './EmbeddableIframeAPI';
|
||||
|
||||
type EmbeddableRootLayoutProps = {
|
||||
context: GitBookSiteContext;
|
||||
withTracking: boolean;
|
||||
visitorAuthClaims: VisitorAuthClaims;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -18,10 +22,12 @@ type EmbeddableRootLayoutProps = {
|
||||
*/
|
||||
export async function EmbeddableRootLayout({
|
||||
context,
|
||||
withTracking,
|
||||
visitorAuthClaims,
|
||||
children,
|
||||
}: React.PropsWithChildren<EmbeddableRootLayoutProps>) {
|
||||
return (
|
||||
<CustomizationRootLayout customization={context.customization}>
|
||||
<CustomizationRootLayout context={context}>
|
||||
<SiteLayoutClientContexts
|
||||
forcedTheme={context.customization.themes.default}
|
||||
externalLinksTarget={context.customization.externalLinks.target}
|
||||
@@ -31,8 +37,11 @@ export async function EmbeddableRootLayout({
|
||||
aiMode={CustomizationAIMode.Assistant}
|
||||
trademark={context.customization.trademark.enabled}
|
||||
>
|
||||
<AIChatProvider
|
||||
renderMessageOptions={{
|
||||
<SpaceLayoutServerContext
|
||||
context={context}
|
||||
withTracking={withTracking}
|
||||
visitorAuthClaims={visitorAuthClaims}
|
||||
aiChatRenderMessageOptions={{
|
||||
withLinkPreviews: false,
|
||||
asEmbeddable: true,
|
||||
}}
|
||||
@@ -41,17 +50,17 @@ export async function EmbeddableRootLayout({
|
||||
<EmbeddableIframeAPI
|
||||
baseURL={context.linker.toPathInSpace('~gitbook/embed/')}
|
||||
/>
|
||||
</AIChatProvider>
|
||||
</SpaceLayoutServerContext>
|
||||
</AIContextProvider>
|
||||
</SiteLayoutClientContexts>
|
||||
</CustomizationRootLayout>
|
||||
);
|
||||
}
|
||||
|
||||
export async function generateEmbeddableViewport({ context }: EmbeddableRootLayoutProps) {
|
||||
export async function generateEmbeddableViewport({ context }: { context: GitBookSiteContext }) {
|
||||
return generateSiteLayoutViewport(context);
|
||||
}
|
||||
|
||||
export async function generateEmbeddableMetadata({ context }: EmbeddableRootLayoutProps) {
|
||||
export async function generateEmbeddableMetadata({ context }: { context: GitBookSiteContext }) {
|
||||
return generateSiteLayoutMetadata(context);
|
||||
}
|
||||
|
||||
@@ -32,111 +32,109 @@ export function Footer(props: { context: GitBookSiteContext }) {
|
||||
mobileOnly ? 'xl:hidden' : null
|
||||
)}
|
||||
>
|
||||
<div className="scroll-nojump">
|
||||
<div className={tcls(CONTAINER_STYLE, 'px-4', 'py-8', 'lg:py-12', 'mx-auto')}>
|
||||
<div
|
||||
className={tcls(
|
||||
'mx-auto grid max-w-3xl site-width-wide:max-w-screen-2xl justify-between gap-12 lg:max-w-none!',
|
||||
'grid-cols-[auto_auto]',
|
||||
'lg:grid-cols-[18rem_minmax(auto,48rem)_auto]',
|
||||
'xl:grid-cols-[18rem_minmax(auto,48rem)_14rem]',
|
||||
'lg:site-width-wide:grid-cols-[18rem_minmax(auto,80rem)_auto]',
|
||||
'xl:site-width-wide:grid-cols-[18rem_minmax(auto,80rem)_14rem]',
|
||||
'lg:page-no-toc:grid-cols-[minmax(auto,48rem)_auto]',
|
||||
'xl:page-no-toc:grid-cols-[14rem_minmax(auto,48rem)_14rem]',
|
||||
'lg:[body:has(.site-width-wide,.page-no-toc)_&]:grid-cols-[minmax(auto,90rem)_auto]',
|
||||
'xl:[body:has(.site-width-wide,.page-no-toc)_&]:grid-cols-[14rem_minmax(auto,90rem)_14rem]'
|
||||
)}
|
||||
>
|
||||
{
|
||||
// Footer Logo
|
||||
customization.footer.logo ? (
|
||||
<div className="col-start-1 row-start-1">
|
||||
<Image
|
||||
alt="Logo"
|
||||
resize={context.imageResizer}
|
||||
sources={{
|
||||
light: {
|
||||
src: customization.footer.logo.light,
|
||||
},
|
||||
dark: customization.footer.logo.dark
|
||||
? {
|
||||
src: customization.footer.logo.dark,
|
||||
}
|
||||
: null,
|
||||
}}
|
||||
priority="lazy"
|
||||
style={[
|
||||
'w-auto',
|
||||
'max-w-40',
|
||||
'lg:max-w-64',
|
||||
'max-h-10',
|
||||
'lg:max-h-12',
|
||||
'object-contain',
|
||||
'object-left',
|
||||
'rounded-sm',
|
||||
'straight-corners:rounded-xs',
|
||||
]}
|
||||
sizes={[
|
||||
{
|
||||
width: 320,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
<div className={tcls(CONTAINER_STYLE, 'px-4', 'py-8', 'lg:py-12', 'mx-auto')}>
|
||||
<div
|
||||
className={tcls(
|
||||
'mx-auto grid max-w-3xl site-width-wide:max-w-screen-2xl justify-between gap-12 lg:max-w-none!',
|
||||
'grid-cols-[auto_auto]',
|
||||
'lg:grid-cols-[18rem_minmax(auto,48rem)_auto]',
|
||||
'xl:grid-cols-[18rem_minmax(auto,48rem)_14rem]',
|
||||
'lg:site-width-wide:grid-cols-[18rem_minmax(auto,80rem)_auto]',
|
||||
'xl:site-width-wide:grid-cols-[18rem_minmax(auto,80rem)_14rem]',
|
||||
'lg:page-no-toc:grid-cols-[minmax(auto,48rem)_auto]',
|
||||
'xl:page-no-toc:grid-cols-[14rem_minmax(auto,48rem)_14rem]',
|
||||
'lg:[body:has(.site-width-wide,.page-no-toc)_&]:grid-cols-[minmax(auto,90rem)_auto]',
|
||||
'xl:[body:has(.site-width-wide,.page-no-toc)_&]:grid-cols-[14rem_minmax(auto,90rem)_14rem]'
|
||||
)}
|
||||
>
|
||||
{
|
||||
// Footer Logo
|
||||
customization.footer.logo ? (
|
||||
<div className="col-start-1 row-start-1">
|
||||
<Image
|
||||
alt="Logo"
|
||||
resize={context.imageResizer}
|
||||
sources={{
|
||||
light: {
|
||||
src: customization.footer.logo.light,
|
||||
},
|
||||
dark: customization.footer.logo.dark
|
||||
? {
|
||||
src: customization.footer.logo.dark,
|
||||
}
|
||||
: null,
|
||||
}}
|
||||
priority="lazy"
|
||||
style={[
|
||||
'w-auto',
|
||||
'max-w-40',
|
||||
'lg:max-w-64',
|
||||
'max-h-10',
|
||||
'lg:max-h-12',
|
||||
'object-contain',
|
||||
'object-left',
|
||||
'rounded-sm',
|
||||
'straight-corners:rounded-xs',
|
||||
]}
|
||||
sizes={[
|
||||
{
|
||||
width: 320,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
|
||||
{
|
||||
// Theme Toggle
|
||||
customization.themes.toggeable ? (
|
||||
<div className="-col-start-2 row-start-1 flex items-start justify-end xl:hidden">
|
||||
<React.Suspense fallback={null}>
|
||||
<ThemeToggler />
|
||||
</React.Suspense>
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
{
|
||||
// Theme Toggle
|
||||
customization.themes.toggeable ? (
|
||||
<div className="-col-start-2 row-start-1 flex items-start justify-end xl:hidden">
|
||||
<React.Suspense fallback={null}>
|
||||
<ThemeToggler />
|
||||
</React.Suspense>
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
|
||||
{
|
||||
// Navigation groups (split into equal columns)
|
||||
customization.footer.groups?.length > 0 ? (
|
||||
<div
|
||||
className={tcls(
|
||||
'col-span-2 lg:page-has-toc:col-span-1 lg:page-has-toc:col-start-2 xl:page-no-toc:col-span-1 xl:page-no-toc:col-start-2'
|
||||
{
|
||||
// Navigation groups (split into equal columns)
|
||||
customization.footer.groups?.length > 0 ? (
|
||||
<div
|
||||
className={tcls(
|
||||
'col-span-2 lg:page-has-toc:col-span-1 lg:page-has-toc:col-start-2 xl:page-no-toc:col-span-1 xl:page-no-toc:col-start-2'
|
||||
)}
|
||||
>
|
||||
<div className="mx-auto flex max-w-3xl site-width-wide:max-w-screen-2xl flex-col gap-10 sm:flex-row sm:gap-6">
|
||||
{partition(customization.footer.groups, FOOTER_COLUMNS).map(
|
||||
(column, columnIndex) => (
|
||||
<div
|
||||
key={columnIndex}
|
||||
className="flex flex-1 grow flex-col gap-10"
|
||||
>
|
||||
{column.map((group, groupIndex) => (
|
||||
<FooterLinksGroup
|
||||
key={groupIndex}
|
||||
group={group}
|
||||
context={context}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
>
|
||||
<div className="mx-auto flex max-w-3xl site-width-wide:max-w-screen-2xl flex-col gap-10 sm:flex-row sm:gap-6">
|
||||
{partition(customization.footer.groups, FOOTER_COLUMNS).map(
|
||||
(column, columnIndex) => (
|
||||
<div
|
||||
key={columnIndex}
|
||||
className="flex flex-1 grow flex-col gap-10"
|
||||
>
|
||||
{column.map((group, groupIndex) => (
|
||||
<FooterLinksGroup
|
||||
key={groupIndex}
|
||||
group={group}
|
||||
context={context}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
|
||||
{
|
||||
// Legal
|
||||
customization.footer.copyright ? (
|
||||
<div className="order-last col-span-full flex w-full grow flex-col items-center gap-2 text-center text-tint text-xs">
|
||||
<p>{customization.footer.copyright}</p>
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
</div>
|
||||
{
|
||||
// Legal
|
||||
customization.footer.copyright ? (
|
||||
<div className="order-last col-span-full flex w-full grow flex-col items-center gap-2 text-center text-tint text-xs">
|
||||
<p>{customization.footer.copyright}</p>
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@@ -3,13 +3,14 @@ import type { GitBookSiteContext } from '@/lib/context';
|
||||
import { CONTAINER_STYLE, HEADER_HEIGHT_DESKTOP } from '@/components/layout';
|
||||
import { getSpaceLanguage, t } from '@/intl/server';
|
||||
import { tcls } from '@/lib/tailwind';
|
||||
import { SearchContainer } from '../Search';
|
||||
import { SiteSectionTabs, encodeClientSiteSections } from '../SiteSections';
|
||||
import { HeaderLink } from './HeaderLink';
|
||||
import { HeaderLinkMore } from './HeaderLinkMore';
|
||||
import { HeaderLinks } from './HeaderLinks';
|
||||
import { HeaderLogo } from './HeaderLogo';
|
||||
import { HeaderMobileMenu } from './HeaderMobileMenu';
|
||||
import { SpacesDropdown } from './SpacesDropdown';
|
||||
import { TranslationsDropdown } from './SpacesDropdown';
|
||||
|
||||
/**
|
||||
* Render the header for the space.
|
||||
@@ -17,9 +18,9 @@ import { SpacesDropdown } from './SpacesDropdown';
|
||||
export function Header(props: {
|
||||
context: GitBookSiteContext;
|
||||
withTopHeader?: boolean;
|
||||
search?: React.ReactNode;
|
||||
withVariants?: 'generic' | 'translations';
|
||||
}) {
|
||||
const { context, withTopHeader, search } = props;
|
||||
const { context, withTopHeader, withVariants } = props;
|
||||
const { siteSpace, siteSpaces, sections, customization } = context;
|
||||
|
||||
return (
|
||||
@@ -56,135 +57,145 @@ export function Header(props: {
|
||||
'theme-bold:shadow-tint-12/2'
|
||||
)}
|
||||
>
|
||||
<div className="scroll-nojump">
|
||||
<div className="transition-all duration-300 lg:chat-open:pr-80 xl:chat-open:pr-96">
|
||||
<div className="transition-all duration-300 lg:chat-open:pr-80 xl:chat-open:pr-96">
|
||||
<div
|
||||
className={tcls(
|
||||
'gap-4',
|
||||
'lg:gap-6',
|
||||
'flex',
|
||||
'items-center',
|
||||
'justify-between',
|
||||
'w-full',
|
||||
'py-3',
|
||||
'min-h-16',
|
||||
'sm:h-16',
|
||||
CONTAINER_STYLE
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={tcls(
|
||||
'gap-4',
|
||||
'lg:gap-6',
|
||||
'flex',
|
||||
'items-center',
|
||||
'justify-between',
|
||||
'w-full',
|
||||
'py-3',
|
||||
'min-h-16',
|
||||
'sm:h-16',
|
||||
CONTAINER_STYLE
|
||||
'flex max-w-full lg:basis-72',
|
||||
'min-w-0 shrink items-center justify-start gap-2 lg:gap-4'
|
||||
)}
|
||||
>
|
||||
<div
|
||||
<HeaderMobileMenu
|
||||
className={tcls(
|
||||
'flex max-w-full lg:basis-72',
|
||||
'min-w-0 shrink items-center justify-start gap-2 lg:gap-4'
|
||||
'lg:hidden',
|
||||
'-ml-2',
|
||||
'text-tint-strong',
|
||||
'theme-bold:text-header-link',
|
||||
'hover:bg-tint-hover',
|
||||
'hover:theme-bold:bg-header-link/3',
|
||||
withVariants === 'generic' ? '' : 'page-no-toc:hidden'
|
||||
)}
|
||||
>
|
||||
<HeaderMobileMenu
|
||||
className={tcls(
|
||||
'lg:hidden',
|
||||
'-ml-2',
|
||||
'text-tint-strong',
|
||||
'theme-bold:text-header-link',
|
||||
'hover:bg-tint-hover',
|
||||
'hover:theme-bold:bg-header-link/3',
|
||||
'page-no-toc:hidden'
|
||||
)}
|
||||
/>
|
||||
<HeaderLogo context={context} />
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={tcls(
|
||||
'flex',
|
||||
'grow-0',
|
||||
'shrink-0',
|
||||
'md:basis-56',
|
||||
'justify-self-end',
|
||||
'items-center',
|
||||
'gap-2',
|
||||
'search' in customization.styling &&
|
||||
customization.styling.search === 'prominent'
|
||||
? [
|
||||
'md:grow-[0.8]',
|
||||
'lg:basis-40',
|
||||
'md:max-w-[40%]',
|
||||
'lg:max-w-lg',
|
||||
'lg:ml-[max(calc((100%-18rem-48rem)/2),1.5rem)]', // container (100%) - sidebar (18rem) - content (48rem)
|
||||
'xl:ml-[max(calc((100%-18rem-48rem-14rem-3rem)/2),1.5rem)]', // container (100%) - sidebar (18rem) - content (48rem) - outline (14rem) - margin (3rem)
|
||||
'md:mr-auto',
|
||||
'order-last',
|
||||
'md:order-[unset]',
|
||||
]
|
||||
: ['order-last']
|
||||
)}
|
||||
>
|
||||
{search}
|
||||
</div>
|
||||
|
||||
{customization.header.links.length > 0 && (
|
||||
<HeaderLinks>
|
||||
{customization.header.links.map((link) => {
|
||||
return (
|
||||
<HeaderLink
|
||||
key={link.title}
|
||||
link={link}
|
||||
context={context}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<HeaderLinkMore
|
||||
label={t(getSpaceLanguage(customization), 'more')}
|
||||
links={customization.header.links}
|
||||
context={context}
|
||||
/>
|
||||
</HeaderLinks>
|
||||
)}
|
||||
/>
|
||||
<HeaderLogo context={context} />
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={tcls(
|
||||
'flex',
|
||||
'grow-0',
|
||||
'shrink-0',
|
||||
'md:basis-56',
|
||||
'justify-self-end',
|
||||
'items-center',
|
||||
'gap-2',
|
||||
'search' in customization.styling &&
|
||||
customization.styling.search === 'prominent'
|
||||
? [
|
||||
'md:grow-[0.8]',
|
||||
'lg:basis-40',
|
||||
'md:max-w-[40%]',
|
||||
'lg:max-w-lg',
|
||||
'lg:ml-[max(calc((100%-18rem-48rem)/2),1.5rem)]', // container (100%) - sidebar (18rem) - content (48rem)
|
||||
'xl:ml-[max(calc((100%-18rem-48rem-14rem-3rem)/2),1.5rem)]', // container (100%) - sidebar (18rem) - content (48rem) - outline (14rem) - margin (3rem)
|
||||
'md:mr-auto',
|
||||
'order-last',
|
||||
'md:order-[unset]',
|
||||
]
|
||||
: ['order-last']
|
||||
)}
|
||||
>
|
||||
<SearchContainer
|
||||
style={customization.styling.search}
|
||||
isMultiVariants={siteSpaces.length > 1}
|
||||
spaceTitle={siteSpace.title}
|
||||
siteSpaceId={siteSpace.id}
|
||||
viewport={!withTopHeader ? 'mobile' : undefined}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{customization.header.links.length > 0 ||
|
||||
(!sections && withVariants === 'translations') ? (
|
||||
<HeaderLinks>
|
||||
{customization.header.links.length > 0 ? (
|
||||
<>
|
||||
{customization.header.links.map((link) => {
|
||||
return (
|
||||
<HeaderLink
|
||||
key={link.title}
|
||||
link={link}
|
||||
context={context}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<HeaderLinkMore
|
||||
label={t(getSpaceLanguage(context), 'more')}
|
||||
links={customization.header.links}
|
||||
context={context}
|
||||
/>
|
||||
</>
|
||||
) : null}
|
||||
{!sections && withVariants === 'translations' ? (
|
||||
<TranslationsDropdown
|
||||
context={context}
|
||||
siteSpace={siteSpace}
|
||||
siteSpaces={siteSpaces}
|
||||
className="flex! theme-bold:text-header-link hover:theme-bold:bg-header-link/3"
|
||||
/>
|
||||
) : null}
|
||||
</HeaderLinks>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{sections || siteSpaces.length > 1 ? (
|
||||
<div className="scroll-nojump">
|
||||
<div className="transition-all duration-300 lg:chat-open:pr-80 xl:chat-open:pr-96">
|
||||
{sections ? (
|
||||
<div className="transition-all duration-300 lg:chat-open:pr-80 xl:chat-open:pr-96">
|
||||
<div
|
||||
className={tcls(
|
||||
'w-full',
|
||||
'overflow-x-auto',
|
||||
'no-scrollbar',
|
||||
'-mb-4 pb-4', // Positive padding / negative margin allows the navigation menu indicator to show in a scroll viewƒ
|
||||
!sections ? ['hidden', 'page-no-toc:flex'] : 'flex'
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={tcls(
|
||||
'w-full',
|
||||
'overflow-x-auto',
|
||||
'no-scrollbar',
|
||||
'-mb-4 pb-4', // Positive padding / negative margin allows the navigation menu indicator to show in a scroll viewƒ
|
||||
!sections ? ['hidden', 'page-no-toc:flex'] : 'flex'
|
||||
CONTAINER_STYLE,
|
||||
'grow',
|
||||
'flex',
|
||||
'items-end',
|
||||
'page-default-width:2xl:px-[calc((100%-1536px+4rem)/2)]'
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={tcls(
|
||||
CONTAINER_STYLE,
|
||||
'grow',
|
||||
'flex',
|
||||
'items-end',
|
||||
'page-default-width:2xl:px-[calc((100%-1536px+4rem)/2)]'
|
||||
)}
|
||||
>
|
||||
{siteSpaces.length > 1 && (
|
||||
<div
|
||||
id="variants"
|
||||
className="my-2 mr-5 grow border-tint border-r pr-5 *:grow only:mr-0 only:border-none only:pr-0 sm:max-w-64"
|
||||
>
|
||||
<SpacesDropdown
|
||||
context={context}
|
||||
siteSpace={siteSpace}
|
||||
siteSpaces={siteSpaces}
|
||||
className="w-full grow py-1"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{sections &&
|
||||
(sections.list.some((s) => s.object === 'site-section-group') || // If there's even a single group, show the tabs
|
||||
sections.list.length > 1) && ( // Otherwise, show the tabs if there's more than one section
|
||||
<SiteSectionTabs
|
||||
sections={encodeClientSiteSections(context, sections)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{sections.list.some((s) => s.object === 'site-section-group') || // If there's even a single group, show the tabs
|
||||
sections.list.length > 1 ? ( // Otherwise, show the tabs if there's more than one section
|
||||
<SiteSectionTabs
|
||||
sections={encodeClientSiteSections(context, sections)}
|
||||
/>
|
||||
) : null}
|
||||
{withVariants === 'translations' ? (
|
||||
<div className="site-background before:contents[] -mr-4 sm:-mr-6 md:-mr-8 sticky inset-y-0 right-0 z-10 ml-6 flex h-full items-center py-2 pr-4 before:mr-4 before:h-full before:border-tint before:border-l sm:pr-6 md:pr-8">
|
||||
<TranslationsDropdown
|
||||
context={context}
|
||||
siteSpace={siteSpace}
|
||||
siteSpaces={siteSpaces}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -138,7 +138,7 @@ function HeaderItemButton(
|
||||
|
||||
function getHeaderLinkClassName(_props: { headerPreset: CustomizationHeaderPreset }) {
|
||||
return tcls(
|
||||
'flex items-center',
|
||||
'flex items-center gap-1',
|
||||
'shrink',
|
||||
'contrast-more:underline',
|
||||
'truncate',
|
||||
|
||||
@@ -1,18 +1,29 @@
|
||||
import type { SiteSpace } from '@gitbook/api';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import type { GitBookSiteContext } from '@/lib/context';
|
||||
import { getSiteSpaceURL } from '@/lib/sites';
|
||||
import { tcls } from '@/lib/tailwind';
|
||||
import { Button, type ButtonProps } from '../primitives';
|
||||
import { DropdownChevron, DropdownMenu } from '../primitives/DropdownMenu';
|
||||
import { SpacesDropdownMenuItems } from './SpacesDropdownMenuItem';
|
||||
|
||||
// Memoized regex for checking if a string starts with an emoji
|
||||
const EMOJI_REGEX = /^\p{Emoji}/u;
|
||||
|
||||
function startsWithEmoji(text: string): boolean {
|
||||
return EMOJI_REGEX.test(text);
|
||||
}
|
||||
|
||||
export function SpacesDropdown(props: {
|
||||
context: GitBookSiteContext;
|
||||
siteSpace: SiteSpace;
|
||||
siteSpaces: SiteSpace[];
|
||||
className?: string;
|
||||
variant?: ButtonProps['variant'];
|
||||
icon?: ButtonProps['icon'];
|
||||
}) {
|
||||
const { context, siteSpace, siteSpaces, className } = props;
|
||||
const { context, siteSpace, siteSpaces, className, variant = 'secondary', icon } = props;
|
||||
|
||||
return (
|
||||
<DropdownMenu
|
||||
@@ -21,48 +32,16 @@ export function SpacesDropdown(props: {
|
||||
'group-focus-within/dropdown:group-hover/dropdown:visible' // When the dropdown is already open, it should remain visible when hovered
|
||||
)}
|
||||
button={
|
||||
<div
|
||||
<Button
|
||||
icon={icon}
|
||||
data-testid="space-dropdown-button"
|
||||
className={tcls(
|
||||
'flex',
|
||||
'flex-row',
|
||||
'items-center',
|
||||
'transition-all',
|
||||
'hover:cursor-pointer',
|
||||
|
||||
'px-3',
|
||||
'py-2',
|
||||
'gap-2',
|
||||
|
||||
'rounded-md',
|
||||
'straight-corners:rounded-none',
|
||||
|
||||
'bg-tint-base',
|
||||
|
||||
'text-sm',
|
||||
'text-tint',
|
||||
'hover:text-tint-strong',
|
||||
'data-[state=open]:text-tint-strong',
|
||||
|
||||
'ring-1',
|
||||
'ring-tint-subtle',
|
||||
'hover:ring-tint-hover',
|
||||
'data-[state=open]:ring-tint-hover',
|
||||
|
||||
'contrast-more:bg-tint-base',
|
||||
'contrast-more:ring-1',
|
||||
'contrast-more:hover:ring-2',
|
||||
'contrast-more:data-[state=open]:ring-2',
|
||||
'contrast-more:ring-tint',
|
||||
'contrast-more:hover:ring-tint-hover',
|
||||
'contrast-more:data-[state=open]:ring-tint-hover',
|
||||
|
||||
className
|
||||
)}
|
||||
size="medium"
|
||||
variant={variant}
|
||||
trailing={<DropdownChevron />}
|
||||
className={tcls('bg-tint-base', className)}
|
||||
>
|
||||
<span className={tcls('truncate', 'grow')}>{siteSpace.title}</span>
|
||||
<DropdownChevron />
|
||||
</div>
|
||||
<span className="button-content">{siteSpace.title}</span>
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<SpacesDropdownMenuItems
|
||||
@@ -77,3 +56,32 @@ export function SpacesDropdown(props: {
|
||||
</DropdownMenu>
|
||||
);
|
||||
}
|
||||
|
||||
export function TranslationsDropdown(props: {
|
||||
context: GitBookSiteContext;
|
||||
siteSpace: SiteSpace;
|
||||
siteSpaces: SiteSpace[];
|
||||
className?: string;
|
||||
}) {
|
||||
const { context, siteSpace, siteSpaces, className } = props;
|
||||
|
||||
// Memoize the emoji check to avoid repeated regex execution
|
||||
const hasEmojiPrefix = useMemo(() => startsWithEmoji(siteSpace.title), [siteSpace.title]);
|
||||
|
||||
return (
|
||||
<SpacesDropdown
|
||||
icon="globe"
|
||||
context={context}
|
||||
siteSpace={siteSpace}
|
||||
siteSpaces={siteSpaces}
|
||||
variant="blank"
|
||||
className={tcls(
|
||||
'-mx-2 bg-transparent px-2 py-1 lg:max-w-64 max-md:[&_.button-content]:hidden',
|
||||
hasEmojiPrefix
|
||||
? 'md:[&_.button-leading-icon]:hidden' // If the title starts with an emoji, don't show the icon (on desktop)
|
||||
: '',
|
||||
className
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ export type InsightsEventName = api.SiteInsightsEvent['type'];
|
||||
* Context for an event on a page.
|
||||
*/
|
||||
export interface InsightsEventPageContext {
|
||||
displayContext: api.SiteInsightsDisplayContext;
|
||||
pageId: string | null;
|
||||
}
|
||||
|
||||
@@ -46,7 +47,9 @@ type TrackEventCallback = <EventName extends InsightsEventName>(
|
||||
options?: InsightsEventOptions
|
||||
) => void;
|
||||
|
||||
const InsightsContext = React.createContext<TrackEventCallback>(() => {});
|
||||
const InsightsContext = React.createContext<TrackEventCallback>(() => {
|
||||
console.error('useTrackEvent must be used within an InsightsProvider');
|
||||
});
|
||||
|
||||
interface InsightsProviderProps {
|
||||
/** If true, the events will be sent to the server. */
|
||||
@@ -263,6 +266,7 @@ function transformEvents(input: {
|
||||
siteShareKey: input.context.siteShareKey ?? null,
|
||||
revision: input.context.revisionId,
|
||||
page: input.pageContext.pageId,
|
||||
displayContext: input.pageContext.displayContext,
|
||||
};
|
||||
|
||||
return input.events.map((partialEvent) => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import type { SiteInsightsDisplayContext } from '@gitbook/api';
|
||||
import * as React from 'react';
|
||||
|
||||
import { useCurrentPage } from '../hooks';
|
||||
@@ -8,7 +9,10 @@ import { useTrackEvent } from './InsightsProvider';
|
||||
/**
|
||||
* Track a page view event.
|
||||
*/
|
||||
export function TrackPageViewEvent() {
|
||||
export function TrackPageViewEvent(props: {
|
||||
displayContext: SiteInsightsDisplayContext;
|
||||
}) {
|
||||
const { displayContext } = props;
|
||||
const page = useCurrentPage();
|
||||
const trackEvent = useTrackEvent();
|
||||
|
||||
@@ -19,9 +23,10 @@ export function TrackPageViewEvent() {
|
||||
},
|
||||
{
|
||||
pageId: page?.pageId ?? null,
|
||||
displayContext,
|
||||
}
|
||||
);
|
||||
}, [page, trackEvent]);
|
||||
}, [page, trackEvent, displayContext]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ export async function PDFPage(props: {
|
||||
|
||||
const customization =
|
||||
'customization' in baseContext ? baseContext.customization : defaultCustomization();
|
||||
const language = getSpaceLanguage(customization);
|
||||
const language = getSpaceLanguage(baseContext);
|
||||
|
||||
// Compute the pages to render
|
||||
const { pages, total } = selectPages(baseContext.revision.pages, pdfParams);
|
||||
@@ -149,8 +149,7 @@ export async function PDFPage(props: {
|
||||
trademark={
|
||||
customization.trademark.enabled ? (
|
||||
<TrademarkLink
|
||||
space={context.space}
|
||||
customization={customization}
|
||||
context={context}
|
||||
placement={SiteInsightsTrademarkPlacement.Pdf}
|
||||
/>
|
||||
) : null
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { CustomizationRootLayout } from '@/components/RootLayout';
|
||||
import type { GitBookSiteContext, GitBookSpaceContext } from '@/lib/context';
|
||||
import { defaultCustomization } from '@/lib/utils';
|
||||
import { CustomizationThemeMode } from '@gitbook/api';
|
||||
|
||||
/**
|
||||
@@ -13,12 +12,7 @@ export async function PDFRootLayout(props: {
|
||||
const { context, children } = props;
|
||||
|
||||
return (
|
||||
<CustomizationRootLayout
|
||||
customization={
|
||||
'customization' in context ? context.customization : defaultCustomization()
|
||||
}
|
||||
forcedTheme={CustomizationThemeMode.Light}
|
||||
>
|
||||
<CustomizationRootLayout context={context} forcedTheme={CustomizationThemeMode.Light}>
|
||||
{children}
|
||||
</CustomizationRootLayout>
|
||||
);
|
||||
|
||||
+71
-19
@@ -2,31 +2,32 @@
|
||||
|
||||
import { useAIChatState } from '@/components/AI';
|
||||
import type { Assistant } from '@/components/AI';
|
||||
import { ChatGPTIcon } from '@/components/AIActions/assets/ChatGPTIcon';
|
||||
import { ClaudeIcon } from '@/components/AIActions/assets/ClaudeIcon';
|
||||
import { MarkdownIcon } from '@/components/AIActions/assets/MarkdownIcon';
|
||||
import { ChatGPTIcon } from '@/components/PageActions/assets/ChatGPTIcon';
|
||||
import { ClaudeIcon } from '@/components/PageActions/assets/ClaudeIcon';
|
||||
import { MarkdownIcon } from '@/components/PageActions/assets/MarkdownIcon';
|
||||
import { Button } from '@/components/primitives/Button';
|
||||
import { DropdownMenuItem, useDropdownMenuClose } from '@/components/primitives/DropdownMenu';
|
||||
import { tString, useLanguage } from '@/intl/client';
|
||||
import type { TranslationLanguage } from '@/intl/translations';
|
||||
import type { GitSyncState } from '@gitbook/api';
|
||||
import { Icon, type IconName, IconStyle } from '@gitbook/icons';
|
||||
import assertNever from 'assert-never';
|
||||
import QuickLRU from 'quick-lru';
|
||||
import type React from 'react';
|
||||
import { create } from 'zustand';
|
||||
|
||||
type AIActionType = 'button' | 'dropdown-menu-item';
|
||||
type PageActionType = 'button' | 'dropdown-menu-item';
|
||||
|
||||
/**
|
||||
* Opens our AI Docs Assistant.
|
||||
*/
|
||||
export function OpenAIAssistant(props: { assistant: Assistant; type: AIActionType }) {
|
||||
export function OpenAIAssistant(props: { assistant: Assistant; type: PageActionType }) {
|
||||
const { assistant, type } = props;
|
||||
const chat = useAIChatState();
|
||||
const language = useLanguage();
|
||||
|
||||
return (
|
||||
<AIActionWrapper
|
||||
<PageActionWrapper
|
||||
type={type}
|
||||
icon={assistant.icon}
|
||||
label={assistant.label}
|
||||
@@ -90,7 +91,7 @@ const markdownCache = new QuickLRU<string, string>({ maxSize: 10 });
|
||||
*/
|
||||
export function CopyMarkdown(props: {
|
||||
markdownPageUrl: string;
|
||||
type: AIActionType;
|
||||
type: PageActionType;
|
||||
isDefaultAction?: boolean;
|
||||
}) {
|
||||
const { markdownPageUrl, type, isDefaultAction } = props;
|
||||
@@ -130,7 +131,7 @@ export function CopyMarkdown(props: {
|
||||
};
|
||||
|
||||
return (
|
||||
<AIActionWrapper
|
||||
<PageActionWrapper
|
||||
type={type}
|
||||
icon={copied ? 'check' : 'copy'}
|
||||
label={copied ? tString(language, 'code_copied') : tString(language, 'copy_page')}
|
||||
@@ -145,12 +146,12 @@ export function CopyMarkdown(props: {
|
||||
/**
|
||||
* Redirects to the markdown version of the page.
|
||||
*/
|
||||
export function ViewAsMarkdown(props: { markdownPageUrl: string; type: AIActionType }) {
|
||||
export function ViewAsMarkdown(props: { markdownPageUrl: string; type: PageActionType }) {
|
||||
const { markdownPageUrl, type } = props;
|
||||
const language = useLanguage();
|
||||
|
||||
return (
|
||||
<AIActionWrapper
|
||||
<PageActionWrapper
|
||||
type={type}
|
||||
icon={<MarkdownIcon className="size-4 fill-current" />}
|
||||
label={tString(language, 'view_page_markdown')}
|
||||
@@ -166,7 +167,7 @@ export function ViewAsMarkdown(props: { markdownPageUrl: string; type: AIActionT
|
||||
export function OpenInLLM(props: {
|
||||
provider: 'chatgpt' | 'claude';
|
||||
url: string;
|
||||
type: AIActionType;
|
||||
type: PageActionType;
|
||||
}) {
|
||||
const { provider, url, type } = props;
|
||||
const language = useLanguage();
|
||||
@@ -174,7 +175,7 @@ export function OpenInLLM(props: {
|
||||
const providerLabel = provider === 'chatgpt' ? 'ChatGPT' : 'Claude';
|
||||
|
||||
return (
|
||||
<AIActionWrapper
|
||||
<PageActionWrapper
|
||||
type={type}
|
||||
icon={
|
||||
provider === 'chatgpt' ? (
|
||||
@@ -191,11 +192,48 @@ export function OpenInLLM(props: {
|
||||
);
|
||||
}
|
||||
|
||||
export function GitEditLink(props: {
|
||||
type: PageActionType;
|
||||
provider: GitSyncState['installationProvider'];
|
||||
url: string;
|
||||
}) {
|
||||
const { type, provider, url } = props;
|
||||
const language = useLanguage();
|
||||
|
||||
const providerName =
|
||||
provider === 'github' ? 'GitHub' : provider === 'gitlab' ? 'GitLab' : 'Git';
|
||||
|
||||
return (
|
||||
<PageActionWrapper
|
||||
type={type}
|
||||
icon={provider === 'gitlab' ? 'gitlab' : 'github'}
|
||||
label={tString(language, 'edit_on_git', providerName)}
|
||||
shortLabel={tString(language, 'edit')}
|
||||
href={url}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function ViewAsPDF(props: { url: string; type: PageActionType }) {
|
||||
const { url, type } = props;
|
||||
const language = useLanguage();
|
||||
|
||||
return (
|
||||
<PageActionWrapper
|
||||
type={type}
|
||||
icon="file-pdf"
|
||||
label={tString(language, 'pdf_download')}
|
||||
href={url}
|
||||
target="_self"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps an action in a button (for the default action) or dropdown menu item.
|
||||
*/
|
||||
function AIActionWrapper(props: {
|
||||
type: AIActionType;
|
||||
function PageActionWrapper(props: {
|
||||
type: PageActionType;
|
||||
icon: IconName | React.ReactNode;
|
||||
label: string;
|
||||
/**
|
||||
@@ -205,10 +243,22 @@ function AIActionWrapper(props: {
|
||||
onClick?: (e: React.MouseEvent) => void;
|
||||
description?: string;
|
||||
href?: string;
|
||||
target?: React.HTMLAttributeAnchorTarget;
|
||||
disabled?: boolean;
|
||||
loading?: boolean;
|
||||
}) {
|
||||
const { type, icon, label, shortLabel, onClick, href, description, disabled, loading } = props;
|
||||
const {
|
||||
type,
|
||||
icon,
|
||||
label,
|
||||
shortLabel,
|
||||
onClick,
|
||||
href,
|
||||
target = '_blank',
|
||||
description,
|
||||
disabled,
|
||||
loading,
|
||||
} = props;
|
||||
|
||||
if (type === 'button') {
|
||||
return (
|
||||
@@ -222,7 +272,7 @@ function AIActionWrapper(props: {
|
||||
className="bg-tint-base text-sm"
|
||||
onClick={onClick}
|
||||
href={href}
|
||||
target={href ? '_blank' : undefined}
|
||||
target={href ? target : undefined}
|
||||
disabled={disabled || loading}
|
||||
>
|
||||
{shortLabel}
|
||||
@@ -234,7 +284,7 @@ function AIActionWrapper(props: {
|
||||
<DropdownMenuItem
|
||||
className="flex items-stretch gap-2.5 p-2"
|
||||
href={href}
|
||||
target="_blank"
|
||||
target={target}
|
||||
onClick={onClick}
|
||||
disabled={disabled || loading}
|
||||
>
|
||||
@@ -255,9 +305,11 @@ function AIActionWrapper(props: {
|
||||
</div>
|
||||
|
||||
<div className="flex flex-1 flex-col gap-0.5">
|
||||
<span className="flex items-center gap-2 text-tint-strong">
|
||||
<span className="flex items-center gap-1 text-tint-strong">
|
||||
<span className="truncate font-medium text-sm">{label}</span>
|
||||
{href ? <Icon icon="arrow-up-right" className="size-3 shrink-0" /> : null}
|
||||
{href && target === '_blank' ? (
|
||||
<Icon icon="arrow-up-right" className="size-3 shrink-0 text-tint-subtle" />
|
||||
) : null}
|
||||
</span>
|
||||
{description && <span className="text-tint text-xs">{description}</span>}
|
||||
</div>
|
||||
+57
-23
@@ -2,38 +2,50 @@
|
||||
|
||||
import {
|
||||
CopyMarkdown,
|
||||
GitEditLink,
|
||||
OpenAIAssistant,
|
||||
OpenInLLM,
|
||||
ViewAsMarkdown,
|
||||
} from '@/components/AIActions/AIActions';
|
||||
ViewAsPDF,
|
||||
} from '@/components/PageActions/PageActions';
|
||||
import { Button, ButtonGroup } from '@/components/primitives/Button';
|
||||
import { DropdownMenu, DropdownMenuSeparator } from '@/components/primitives/DropdownMenu';
|
||||
import { tString, useLanguage } from '@/intl/client';
|
||||
import type { SiteCustomizationSettings } from '@gitbook/api';
|
||||
import type { GitSyncState, SiteCustomizationSettings } from '@gitbook/api';
|
||||
import { Icon } from '@gitbook/icons';
|
||||
import { useRef } from 'react';
|
||||
import { useAI } from '../AI';
|
||||
|
||||
interface AIActionsDropdownProps {
|
||||
interface PageActionsDropdownProps {
|
||||
markdownPageUrl: string;
|
||||
className?: string;
|
||||
actions: SiteCustomizationSettings['pageActions'];
|
||||
editOnGit?: {
|
||||
provider: GitSyncState['installationProvider'];
|
||||
url: string;
|
||||
};
|
||||
pdfUrl?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dropdown menu for the AI Actions (Ask Docs Assistant, Copy page, View as Markdown, Open in LLM).
|
||||
*/
|
||||
export function AIActionsDropdown(props: AIActionsDropdownProps) {
|
||||
export function PageActionsDropdown(props: PageActionsDropdownProps) {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const assistants = useAI().assistants.filter(
|
||||
(assistant) => assistant.ui === true && assistant.pageAction
|
||||
);
|
||||
const language = useLanguage();
|
||||
|
||||
return assistants.length > 0 || props.actions.markdown || props.actions.externalAI ? (
|
||||
const defaultActions = [assistants.length > 0, props.actions.markdown, props.editOnGit].filter(
|
||||
Boolean
|
||||
);
|
||||
const dropdownActions = [props.actions.externalAI, props.pdfUrl].filter(Boolean);
|
||||
|
||||
return [...defaultActions, ...dropdownActions].length > 0 ? (
|
||||
<ButtonGroup ref={ref} className={props.className}>
|
||||
<DefaultAction {...props} />
|
||||
{props.actions.markdown || props.actions.externalAI ? (
|
||||
{defaultActions.length > 0 ? <DefaultAction {...props} /> : null}
|
||||
{dropdownActions.length > 0 ? (
|
||||
<DropdownMenu
|
||||
align="end"
|
||||
className="!min-w-60 max-w-max"
|
||||
@@ -45,15 +57,18 @@ export function AIActionsDropdown(props: AIActionsDropdownProps) {
|
||||
className="size-3 transition-transform group-data-[state=open]/button:rotate-180"
|
||||
/>
|
||||
}
|
||||
label={tString(language, 'more')}
|
||||
iconOnly
|
||||
label={tString(
|
||||
language,
|
||||
defaultActions.some(Boolean) ? 'more' : 'actions'
|
||||
)}
|
||||
iconOnly={defaultActions.some(Boolean)}
|
||||
size="xsmall"
|
||||
variant="secondary"
|
||||
className="bg-tint-base text-sm"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<AIActionsDropdownMenuContent {...props} />
|
||||
<PageActionsDropdownMenuContent {...props} />
|
||||
</DropdownMenu>
|
||||
) : null}
|
||||
</ButtonGroup>
|
||||
@@ -63,7 +78,7 @@ export function AIActionsDropdown(props: AIActionsDropdownProps) {
|
||||
/**
|
||||
* The content of the dropdown menu.
|
||||
*/
|
||||
function AIActionsDropdownMenuContent(props: AIActionsDropdownProps) {
|
||||
function PageActionsDropdownMenuContent(props: PageActionsDropdownProps) {
|
||||
const { markdownPageUrl, actions } = props;
|
||||
const assistants = useAI().assistants.filter(
|
||||
(assistant) => assistant.ui === true && assistant.pageAction
|
||||
@@ -98,6 +113,22 @@ function AIActionsDropdownMenuContent(props: AIActionsDropdownProps) {
|
||||
<OpenInLLM provider="claude" url={markdownPageUrl} type="dropdown-menu-item" />
|
||||
</>
|
||||
) : null}
|
||||
|
||||
{props.editOnGit || props.pdfUrl ? (
|
||||
<>
|
||||
<DropdownMenuSeparator className="first:hidden" />
|
||||
{props.editOnGit ? (
|
||||
<GitEditLink
|
||||
type="dropdown-menu-item"
|
||||
provider={props.editOnGit.provider}
|
||||
url={props.editOnGit.url}
|
||||
/>
|
||||
) : null}
|
||||
{props.pdfUrl ? (
|
||||
<ViewAsPDF url={props.pdfUrl} type="dropdown-menu-item" />
|
||||
) : null}
|
||||
</>
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -105,31 +136,34 @@ function AIActionsDropdownMenuContent(props: AIActionsDropdownProps) {
|
||||
/**
|
||||
* A default action shown as a quick-access button beside the dropdown menu
|
||||
*/
|
||||
function DefaultAction(props: AIActionsDropdownProps) {
|
||||
function DefaultAction(props: PageActionsDropdownProps) {
|
||||
const { markdownPageUrl, actions } = props;
|
||||
const assistants = useAI().assistants.filter(
|
||||
(assistant) => assistant.ui === true && assistant.pageAction
|
||||
);
|
||||
|
||||
if (assistants.length) {
|
||||
return <OpenAIAssistant assistant={assistants[0]} type="button" />;
|
||||
const assistant = assistants[0];
|
||||
if (assistant) {
|
||||
return <OpenAIAssistant assistant={assistant} type="button" />;
|
||||
}
|
||||
|
||||
if (props.editOnGit) {
|
||||
return (
|
||||
<GitEditLink
|
||||
type="button"
|
||||
provider={props.editOnGit.provider}
|
||||
url={props.editOnGit.url}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (actions.markdown) {
|
||||
return (
|
||||
<CopyMarkdown
|
||||
isDefaultAction={!assistants.length}
|
||||
isDefaultAction={!assistant}
|
||||
markdownPageUrl={markdownPageUrl}
|
||||
type="button"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (actions.externalAI) {
|
||||
return (
|
||||
<>
|
||||
<OpenInLLM provider="chatgpt" url={markdownPageUrl} type="button" />
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ export const AsideSectionHighlight = React.memo(
|
||||
'rounded-md',
|
||||
'straight-corners:rounded-none',
|
||||
'circular-corners:rounded-2xl',
|
||||
'sidebar-list-line:rounded-l-none',
|
||||
'sidebar-list-line:rounded-l-none!',
|
||||
|
||||
'sidebar-list-pill:bg-primary',
|
||||
'[html.theme-muted.sidebar-list-pill_&]:bg-primary-hover',
|
||||
|
||||
@@ -4,18 +4,15 @@ import {
|
||||
type RevisionPageDocument,
|
||||
SiteAdsStatus,
|
||||
SiteInsightsAdPlacement,
|
||||
type Space,
|
||||
} from '@gitbook/api';
|
||||
import { Icon } from '@gitbook/icons';
|
||||
import React from 'react';
|
||||
import urlJoin from 'url-join';
|
||||
|
||||
import { getSpaceLanguage, t } from '@/intl/server';
|
||||
import { getDocumentSections } from '@/lib/document-sections';
|
||||
import { tcls } from '@/lib/tailwind';
|
||||
|
||||
import { Ad } from '../Ads';
|
||||
import { getPDFURLSearchParams } from '../PDF';
|
||||
import { PageFeedbackForm } from '../PageFeedback';
|
||||
import { ThemeToggler } from '../ThemeToggler';
|
||||
import { ScrollSectionsList } from './ScrollSectionsList';
|
||||
@@ -118,11 +115,7 @@ export function PageAside(props: {
|
||||
<PageAsideSections document={document} context={context} />
|
||||
</React.Suspense>
|
||||
) : null}
|
||||
<PageAsideActions
|
||||
page={page}
|
||||
withPageFeedback={withPageFeedback}
|
||||
context={context}
|
||||
/>
|
||||
<PageAsideActions page={page} withPageFeedback={withPageFeedback} />
|
||||
</div>
|
||||
) : null}
|
||||
{customization.themes.toggeable || site.ads ? (
|
||||
@@ -135,7 +128,7 @@ export function PageAside(props: {
|
||||
|
||||
function PageAsideHeader(props: { context: GitBookSiteContext }) {
|
||||
const { context } = props;
|
||||
const language = getSpaceLanguage(context.customization);
|
||||
const language = getSpaceLanguage(context);
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -171,34 +164,16 @@ async function PageAsideSections(props: { document: JSONDocument; context: GitBo
|
||||
|
||||
function PageAsideActions(props: {
|
||||
withPageFeedback: boolean;
|
||||
context: GitBookSiteContext;
|
||||
page: RevisionPageDocument;
|
||||
}) {
|
||||
const { page, withPageFeedback, context } = props;
|
||||
const { customization, space } = context;
|
||||
const language = getSpaceLanguage(customization);
|
||||
|
||||
const pdfHref = context.linker.toPathInSpace(
|
||||
`~gitbook/pdf?${getPDFURLSearchParams({
|
||||
page: page.id,
|
||||
only: true,
|
||||
limit: 100,
|
||||
}).toString()}`
|
||||
);
|
||||
const { page, withPageFeedback } = props;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={tcls(
|
||||
'flex',
|
||||
'flex-col',
|
||||
'gap-3',
|
||||
'sidebar-list-default:px-3',
|
||||
'border-t',
|
||||
'first:border-none',
|
||||
'border-tint-subtle',
|
||||
'pt-5',
|
||||
'first:pt-0',
|
||||
'xl:max-2xl:page-api-block:p-5',
|
||||
'flex flex-col gap-3',
|
||||
'border-tint-subtle border-t first:border-none',
|
||||
'sidebar-list-default:px-3 pt-5 first:pt-0 xl:max-2xl:page-api-block:p-5',
|
||||
'empty:hidden'
|
||||
)}
|
||||
>
|
||||
@@ -207,57 +182,6 @@ function PageAsideActions(props: {
|
||||
<PageFeedbackForm pageId={page.id} />
|
||||
</React.Suspense>
|
||||
) : null}
|
||||
{customization.git.showEditLink && space.gitSync?.url && page.git ? (
|
||||
<div>
|
||||
<a
|
||||
href={urlJoin(space.gitSync.url, page.git.path)}
|
||||
className={tcls(
|
||||
'flex',
|
||||
'flex-row',
|
||||
'items-center',
|
||||
'text-sm',
|
||||
'hover:text-tint-strong',
|
||||
'links-accent:hover:underline',
|
||||
'links-accent:hover:underline-offset-4',
|
||||
'links-accent:hover:decoration-[3px]',
|
||||
'links-accent:hover:decoration-primary-subtle',
|
||||
'py-2'
|
||||
)}
|
||||
>
|
||||
<Icon
|
||||
icon={
|
||||
space.gitSync.installationProvider === 'gitlab'
|
||||
? 'gitlab'
|
||||
: 'github'
|
||||
}
|
||||
className={tcls('size-4', 'mr-1.5')}
|
||||
/>
|
||||
{t(language, 'edit_on_git', getGitSyncName(space))}
|
||||
</a>
|
||||
</div>
|
||||
) : null}
|
||||
{customization.pdf.enabled ? (
|
||||
<div>
|
||||
<a
|
||||
href={pdfHref}
|
||||
className={tcls(
|
||||
'flex',
|
||||
'flex-row',
|
||||
'items-center',
|
||||
'text-sm',
|
||||
'hover:text-tint-strong',
|
||||
'links-accent:hover:underline',
|
||||
'links-accent:hover:underline-offset-4',
|
||||
'links-accent:hover:decoration-[3px]',
|
||||
'links-accent:hover:decoration-primary-subtle',
|
||||
'py-2'
|
||||
)}
|
||||
>
|
||||
<Icon icon="file-pdf" className={tcls('size-4', 'mr-1.5')} />
|
||||
{t(language, 'pdf_download')}
|
||||
</a>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -296,14 +220,3 @@ async function PageAsideFooter(props: { context: GitBookSiteContext }) {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function getGitSyncName(space: Space): string {
|
||||
if (space.gitSync?.installationProvider === 'github') {
|
||||
return 'GitHub';
|
||||
}
|
||||
if (space.gitSync?.installationProvider === 'gitlab') {
|
||||
return 'GitLab';
|
||||
}
|
||||
|
||||
return 'Git';
|
||||
}
|
||||
|
||||
@@ -19,14 +19,8 @@ const SECTION_INTERSECTING_THRESHOLD = 0.9;
|
||||
*/
|
||||
const ACTIVE_ITEM_OFFSET = 100;
|
||||
|
||||
export function ScrollSectionsList(props: { sections: DocumentSection[] }) {
|
||||
const { sections } = props;
|
||||
|
||||
const ids = React.useMemo(() => {
|
||||
return sections.map((section) => {
|
||||
return section.id;
|
||||
});
|
||||
}, [sections]);
|
||||
export function ScrollSectionsList({ sections }: { sections: DocumentSection[] }) {
|
||||
const ids = React.useMemo(() => sections.map(({ id }) => id), [sections]);
|
||||
|
||||
const enabled = useBodyLoaded();
|
||||
|
||||
@@ -101,7 +95,7 @@ export function ScrollSectionsList(props: { sections: DocumentSection[] }) {
|
||||
'rounded-md',
|
||||
'straight-corners:rounded-none',
|
||||
'circular-corners:rounded-2xl',
|
||||
'sidebar-list-line:rounded-l-none',
|
||||
'sidebar-list-line:rounded-l-none!',
|
||||
|
||||
'hover:bg-tint-hover',
|
||||
'theme-gradient:hover:bg-tint-12/1',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { GitBookSiteContext } from '@/lib/context';
|
||||
import type { JSONDocument, RevisionPageDocument } from '@gitbook/api';
|
||||
import type { JSONDocument, RevisionPageDocument, SiteInsightsDisplayContext } from '@gitbook/api';
|
||||
import React from 'react';
|
||||
|
||||
import { getSpaceLanguage } from '@/intl/server';
|
||||
@@ -26,8 +26,9 @@ export function PageBody(props: {
|
||||
ancestors: AncestorRevisionPage[];
|
||||
document: JSONDocument | null;
|
||||
withPageFeedback: boolean;
|
||||
insightsDisplayContext: SiteInsightsDisplayContext;
|
||||
}) {
|
||||
const { page, context, ancestors, document, withPageFeedback } = props;
|
||||
const { page, context, ancestors, document, withPageFeedback, insightsDisplayContext } = props;
|
||||
const { customization } = context;
|
||||
|
||||
const contentFullWidth = document ? hasFullWidthBlock(document) : false;
|
||||
@@ -42,7 +43,7 @@ export function PageBody(props: {
|
||||
: false;
|
||||
const pageWidthWide = page.layout.width === 'wide';
|
||||
const siteWidthWide = pageWidthWide || contentFullWidth;
|
||||
const language = getSpaceLanguage(customization);
|
||||
const language = getSpaceLanguage(context);
|
||||
const updatedAt = page.updatedAt ?? page.createdAt;
|
||||
|
||||
return (
|
||||
@@ -117,7 +118,7 @@ export function PageBody(props: {
|
||||
}
|
||||
</main>
|
||||
|
||||
<TrackPageViewEvent />
|
||||
<TrackPageViewEvent displayContext={insightsDisplayContext} />
|
||||
</CurrentPageProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -17,9 +17,9 @@ export async function PageFooterNavigation(props: {
|
||||
page: RevisionPageDocument;
|
||||
}) {
|
||||
const { context, page } = props;
|
||||
const { customization, revision, linker } = context;
|
||||
const { revision, linker } = context;
|
||||
const { previous, next } = resolvePrevNextPages(revision.pages, page);
|
||||
const language = getSpaceLanguage(customization);
|
||||
const language = getSpaceLanguage(context);
|
||||
const previousHref = previous
|
||||
? linker.toPathForPage({ pages: revision.pages, page: previous })
|
||||
: '';
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { AIActionsDropdown } from '@/components/AIActions/AIActionsDropdown';
|
||||
import type { GitBookSiteContext } from '@/lib/context';
|
||||
import type { AncestorRevisionPage } from '@/lib/pages';
|
||||
import { tcls } from '@/lib/tailwind';
|
||||
import type { RevisionPageDocument } from '@gitbook/api';
|
||||
import { Icon } from '@gitbook/icons';
|
||||
import urlJoin from 'url-join';
|
||||
import { getPDFURLSearchParams } from '../PDF';
|
||||
import { PageActionsDropdown } from '../PageActions/PageActionsDropdown';
|
||||
import { PageIcon } from '../PageIcon';
|
||||
import { StyledLink } from '../primitives';
|
||||
|
||||
@@ -19,8 +21,6 @@ export async function PageHeader(props: {
|
||||
return null;
|
||||
}
|
||||
|
||||
const pageActions = context.customization.pageActions;
|
||||
|
||||
const hasAncestors = ancestors.length > 0;
|
||||
|
||||
return (
|
||||
@@ -38,9 +38,30 @@ export async function PageHeader(props: {
|
||||
>
|
||||
{page.layout.tableOfContents ? (
|
||||
// Show page actions if *any* of the actions are enabled
|
||||
<AIActionsDropdown
|
||||
<PageActionsDropdown
|
||||
markdownPageUrl={`${context.linker.toAbsoluteURL(context.linker.toPathInSpace(page.path))}.md`}
|
||||
actions={pageActions}
|
||||
editOnGit={
|
||||
context.customization.git.showEditLink &&
|
||||
context.space.gitSync?.url &&
|
||||
page.git
|
||||
? {
|
||||
provider: context.space?.gitSync?.installationProvider,
|
||||
url: urlJoin(context.space.gitSync.url, page.git.path),
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
pdfUrl={
|
||||
context.customization.pdf.enabled
|
||||
? context.linker.toPathInSpace(
|
||||
`~gitbook/pdf?${getPDFURLSearchParams({
|
||||
page: page.id,
|
||||
only: true,
|
||||
limit: 100,
|
||||
}).toString()}`
|
||||
)
|
||||
: undefined
|
||||
}
|
||||
actions={context.customization.pageActions}
|
||||
className={tcls(
|
||||
'float-right ml-4 xl:max-2xl:page-api-block:mr-62',
|
||||
hasAncestors ? '-my-1.5' : '-mt-3 xs:mt-2'
|
||||
|
||||
@@ -31,7 +31,9 @@ import { RootLayoutClientContexts } from './RootLayoutClientContexts';
|
||||
|
||||
import '@gitbook/icons/style.css';
|
||||
import './globals.css';
|
||||
import type { GitBookAnyContext } from '@/lib/context';
|
||||
import { GITBOOK_FONTS_URL, GITBOOK_ICONS_TOKEN, GITBOOK_ICONS_URL } from '@/lib/env';
|
||||
import { defaultCustomization } from '@/lib/utils';
|
||||
import { AnnouncementDismissedScript } from '../Announcement';
|
||||
|
||||
function preloadFont(fontData: FontData) {
|
||||
@@ -56,12 +58,14 @@ function preloadFont(fontData: FontData) {
|
||||
*/
|
||||
export async function CustomizationRootLayout(props: {
|
||||
forcedTheme?: CustomizationThemeMode | null;
|
||||
customization: SiteCustomizationSettings;
|
||||
context: GitBookAnyContext;
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const { customization, forcedTheme, children } = props;
|
||||
const { context, forcedTheme, children } = props;
|
||||
const customization =
|
||||
'customization' in context ? context.customization : defaultCustomization();
|
||||
|
||||
const language = getSpaceLanguage(customization);
|
||||
const language = getSpaceLanguage(context);
|
||||
const tintColor = getTintColor(customization);
|
||||
const mixColor = getTintMixColor(customization.styling.primaryColor, tintColor);
|
||||
const sidebarStyles = getSidebarStyles(customization);
|
||||
@@ -94,7 +98,9 @@ export async function CustomizationRootLayout(props: {
|
||||
'depth' in customization.styling && `depth-${customization.styling.depth}`,
|
||||
fontNotoColorEmoji.variable,
|
||||
monospaceFontData.type === 'default' ? monospaceFontData.variable : null,
|
||||
fontData.type === 'default' ? fontData.variable : null,
|
||||
fontData.type === 'default'
|
||||
? [fontData.variable, `font-${customization.styling.font}`]
|
||||
: null,
|
||||
|
||||
// Set the dark/light class statically to avoid flashing and make it work when JS is disabled
|
||||
(forcedTheme ?? customization.themes.default) === CustomizationThemeMode.Dark
|
||||
@@ -138,7 +144,12 @@ export async function CustomizationRootLayout(props: {
|
||||
customization.styling.primaryColor.light
|
||||
)
|
||||
};
|
||||
--header-link: ${hexToRgb(customization.header.linkColor?.light ?? colorContrast(tintColor?.light ?? customization.styling.primaryColor.light))};
|
||||
--header-link: ${hexToRgb(
|
||||
customization.header.linkColor?.light ??
|
||||
colorContrast(
|
||||
tintColor?.light ?? customization.styling.primaryColor.light
|
||||
)
|
||||
)};
|
||||
|
||||
${generateColorVariable('info', infoColor.light)}
|
||||
${generateColorVariable('warning', warningColor.light)}
|
||||
@@ -152,7 +163,12 @@ export async function CustomizationRootLayout(props: {
|
||||
${generateColorVariable('neutral', DEFAULT_TINT_COLOR, { darkMode: true })}
|
||||
|
||||
--header-background: ${hexToRgb(customization.header.backgroundColor?.dark ?? tintColor?.dark ?? customization.styling.primaryColor.dark)};
|
||||
--header-link: ${hexToRgb(customization.header.linkColor?.dark ?? colorContrast(tintColor?.dark ?? customization.styling.primaryColor.dark))};
|
||||
--header-link: ${hexToRgb(
|
||||
customization.header.linkColor?.dark ??
|
||||
colorContrast(
|
||||
tintColor?.dark ?? customization.styling.primaryColor.dark
|
||||
)
|
||||
)};
|
||||
|
||||
${generateColorVariable('info', infoColor.dark, { darkMode: true })}
|
||||
${generateColorVariable('warning', warningColor.dark, { darkMode: true })}
|
||||
@@ -161,16 +177,7 @@ export async function CustomizationRootLayout(props: {
|
||||
}
|
||||
`}</style>
|
||||
</head>
|
||||
<body
|
||||
className={tcls(
|
||||
'[html.sidebar-filled.theme-bold.tint_&]:bg-tint-subtle',
|
||||
'bg-tint-base',
|
||||
'theme-muted:bg-tint-subtle',
|
||||
|
||||
'theme-gradient:bg-gradient-primary',
|
||||
'theme-gradient-tint:bg-gradient-tint'
|
||||
)}
|
||||
>
|
||||
<body className="site-background">
|
||||
<IconsProvider
|
||||
assetsURL={GITBOOK_ICONS_URL}
|
||||
assetsURLToken={GITBOOK_ICONS_TOKEN}
|
||||
|
||||
@@ -20,8 +20,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@utility hide-scroll {
|
||||
/* hide scroll bar but still scroll */
|
||||
@utility no-scrollbar {
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
@@ -29,6 +28,22 @@
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
@utility hide-scrollbar {
|
||||
/* Hide scrollbar by default */
|
||||
scrollbar-color: transparent transparent;
|
||||
transition: scrollbar-color 0.2s ease-in-out;
|
||||
|
||||
&:hover {
|
||||
/* Show scrollbar on hover */
|
||||
scrollbar-color: unset;
|
||||
}
|
||||
|
||||
@media (prefers-contrast: more) {
|
||||
/* Always show scrollbar in high contrast mode */
|
||||
scrollbar-color: unset;
|
||||
}
|
||||
}
|
||||
|
||||
@utility linear-mask-gradient {
|
||||
mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1) 96px, rgba(0, 0, 0, 0));
|
||||
mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1) 96px, rgba(0, 0, 0, 0));
|
||||
@@ -46,7 +61,6 @@
|
||||
|
||||
@utility gutter-stable {
|
||||
scrollbar-gutter: stable;
|
||||
scrollbar-gutter: stable;
|
||||
}
|
||||
|
||||
@utility triangle {
|
||||
@@ -143,45 +157,13 @@
|
||||
@apply bg-linear-to-bl from-tint-4 to-tint-base to-60% bg-fixed;
|
||||
}
|
||||
|
||||
@utility scroll-nojump {
|
||||
/**
|
||||
* Utility to prevent horizontal jumps when the vertical scrollbar appears
|
||||
* It should be used on main containers of the layout, while preserving horizontal delimiters.
|
||||
* It basically adds a margin-left with the width of the scrollbar, and a width that compensates for it; when a scrollbar is displayed.
|
||||
* Inspired by https://aykevl.nl/2014/09/fix-jumping-scrollbar, but adapted to work on child elements of "html"
|
||||
*/
|
||||
width: 100%;
|
||||
@media screen and (min-width: 1536px) {
|
||||
margin-left: var(--scrollbar-width);
|
||||
margin-right: 0;
|
||||
width: calc(100% - var(--scrollbar-width));
|
||||
body:has(.page-full-width) & {
|
||||
margin-left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
@utility site-background {
|
||||
@apply [html.sidebar-filled.theme-bold.tint_&]:bg-tint-subtle;
|
||||
@apply bg-tint-base;
|
||||
@apply theme-muted:bg-tint-subtle;
|
||||
|
||||
/**
|
||||
* Utility to prevent horizontal jumps when the vertical scrollbar appears
|
||||
* It should be used on main containers of the layout, while preserving horizontal delimiters.
|
||||
* It basically adds a margin-left with the width of the scrollbar, and a width that compensates for it; when a scrollbar is displayed.
|
||||
* Inspired by https://aykevl.nl/2014/09/fix-jumping-scrollbar, but adapted to work on child elements of "html"
|
||||
*/
|
||||
width: 100%;
|
||||
@media screen and (min-width: 1536px) {
|
||||
margin-left: var(--scrollbar-width);
|
||||
margin-right: 0;
|
||||
width: calc(100% - var(--scrollbar-width));
|
||||
}
|
||||
}
|
||||
|
||||
@utility page-full-width {
|
||||
@media screen and (min-width: 1536px) {
|
||||
body:has(&) .scroll-nojump {
|
||||
margin-left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
@apply theme-gradient:bg-gradient-primary;
|
||||
@apply theme-gradient-tint:bg-gradient-tint;
|
||||
}
|
||||
|
||||
@utility elevate-link {
|
||||
@@ -211,14 +193,59 @@
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--scrollbar-width: calc(100vw - 100%);
|
||||
@apply leading-relaxed;
|
||||
interpolate-size: allow-keywords; /* Opt-in for modern browsers to interpolate "auto" values in transitions/animations. */
|
||||
}
|
||||
|
||||
/* Modern browsers with `scrollbar-*` support */
|
||||
@supports (scrollbar-color: auto) {
|
||||
* {
|
||||
scrollbar-color: theme("colors.tint.7") transparent;
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
@media (prefers-contrast: more) {
|
||||
* {
|
||||
scrollbar-color: theme("colors.tint.11") transparent;
|
||||
scrollbar-width: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise, use `::-webkit-scrollbar-*` pseudo-elements */
|
||||
@supports selector(::-webkit-scrollbar) {
|
||||
::-webkit-scrollbar {
|
||||
background: transparent;
|
||||
max-width: 8px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: theme("colors.tint.7");
|
||||
border-radius: 8px;
|
||||
transition: background 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: theme("colors.tint.8");
|
||||
}
|
||||
|
||||
@media (prefers-contrast: more) {
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: theme("colors.tint.11");
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: theme("colors.tint.12");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
@apply text-tint-strong antialiased;
|
||||
}
|
||||
html {
|
||||
@apply gutter-stable;
|
||||
scrollbar-width: auto;
|
||||
}
|
||||
h1 {
|
||||
@apply tracking-[-0.025em] text-tint-strong text-balance;
|
||||
@@ -249,22 +276,6 @@
|
||||
@apply subpixel-antialiased;
|
||||
}
|
||||
|
||||
/* Light mode */
|
||||
::-webkit-scrollbar {
|
||||
@apply bg-tint-subtle;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
@apply bg-tint-7;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
@apply bg-tint-8;
|
||||
}
|
||||
|
||||
.flip-heading-hash {
|
||||
@apply [h1,h2,h3,h4]:content-start;
|
||||
@apply [h1,h2,h3,h4]:auto-cols-[auto_1fr];
|
||||
@@ -357,6 +368,11 @@ html.dark.code-monochrome {
|
||||
--shiki-token-function: rgb(var(--primary-10));
|
||||
}
|
||||
|
||||
html.font-Lato {
|
||||
/* Lato's default ligatures impact readability, so we turn them off */
|
||||
font-variant-ligatures: no-common-ligatures;
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
.highlight-line {
|
||||
@apply grid grid-cols-subgrid col-span-2 relative ring-1 ring-transparent hover:ring-tint-hover hover:z-1 rounded-sm;
|
||||
|
||||
@@ -23,13 +23,14 @@ interface SearchContainerProps {
|
||||
isMultiVariants: boolean;
|
||||
style: CustomizationSearchStyle;
|
||||
className?: string;
|
||||
viewport?: 'desktop' | 'mobile';
|
||||
}
|
||||
|
||||
/**
|
||||
* Client component to render the search input and results.
|
||||
*/
|
||||
export function SearchContainer(props: SearchContainerProps) {
|
||||
const { siteSpaceId, spaceTitle, isMultiVariants, style, className } = props;
|
||||
const { siteSpaceId, spaceTitle, isMultiVariants, style, className, viewport } = props;
|
||||
|
||||
const { assistants } = useAI();
|
||||
|
||||
@@ -55,7 +56,7 @@ export function SearchContainer(props: SearchContainerProps) {
|
||||
initialRef.current = true;
|
||||
|
||||
// For simplicity we're only triggering the first assistant
|
||||
assistants[0].open(state?.ask ?? undefined);
|
||||
assistants[0]?.open(state?.ask ?? undefined);
|
||||
}, [state?.ask, assistants.length, assistants[0]?.open]);
|
||||
|
||||
const onClose = React.useCallback(
|
||||
@@ -88,6 +89,19 @@ export function SearchContainer(props: SearchContainerProps) {
|
||||
}
|
||||
);
|
||||
|
||||
useHotkeys(
|
||||
'mod+i',
|
||||
(e) => {
|
||||
e.preventDefault();
|
||||
if (assistants) {
|
||||
assistants[0]?.open();
|
||||
}
|
||||
},
|
||||
{
|
||||
enableOnFormTags: true,
|
||||
}
|
||||
);
|
||||
|
||||
const onOpen = React.useCallback(() => {
|
||||
if (state?.open) {
|
||||
return;
|
||||
@@ -145,6 +159,8 @@ export function SearchContainer(props: SearchContainerProps) {
|
||||
|
||||
const showAsk = withSearchAI && normalizedAsk; // withSearchAI && normalizedAsk;
|
||||
|
||||
const visible = viewport === 'desktop' ? !isMobile : viewport === 'mobile' ? isMobile : true;
|
||||
|
||||
return (
|
||||
<SearchAskProvider value={searchAsk}>
|
||||
<Popover
|
||||
@@ -168,7 +184,7 @@ export function SearchContainer(props: SearchContainerProps) {
|
||||
) : null
|
||||
}
|
||||
rootProps={{
|
||||
open: state?.open ?? false,
|
||||
open: visible && (state?.open ?? false),
|
||||
onOpenChange: (open) => {
|
||||
open ? onOpen() : onClose();
|
||||
},
|
||||
@@ -178,7 +194,7 @@ export function SearchContainer(props: SearchContainerProps) {
|
||||
onOpenAutoFocus: (event) => event.preventDefault(),
|
||||
align: 'start',
|
||||
className:
|
||||
'bg-tint-base has-[.empty]:hidden scroll-py-2 w-128 p-2 max-h-[min(32rem,var(--radix-popover-content-available-height))] max-w-[min(var(--radix-popover-content-available-width),32rem)]',
|
||||
'bg-tint-base has-[.empty]:hidden gutter-stable scroll-py-2 w-128 p-2 pr-1 max-h-[min(32rem,var(--radix-popover-content-available-height))] max-w-[min(var(--radix-popover-content-available-width),32rem)]',
|
||||
onInteractOutside: (event) => {
|
||||
// Don't close if clicking on the search input itself
|
||||
if (searchInputRef.current?.contains(event.target as Node)) {
|
||||
@@ -211,10 +227,11 @@ export function SearchContainer(props: SearchContainerProps) {
|
||||
</Popover>
|
||||
{assistants
|
||||
.filter((assistant) => assistant.ui === true)
|
||||
.map((assistant) => (
|
||||
.map((assistant, index) => (
|
||||
<AIChatButton
|
||||
key={assistant.id}
|
||||
assistant={assistant}
|
||||
withShortcut={index === 0}
|
||||
showLabel={
|
||||
assistants.filter((assistant) => assistant.ui === true).length === 1 &&
|
||||
style === CustomizationSearchStyle.Prominent
|
||||
|
||||
@@ -46,7 +46,7 @@ export const SearchInput = React.forwardRef<HTMLDivElement, SearchInputProps>(
|
||||
}, [isOpen, value]);
|
||||
|
||||
return (
|
||||
<div className="relative flex size-9 grow">
|
||||
<div className={tcls('relative flex size-9 grow', className)}>
|
||||
{/* biome-ignore lint/a11y/useKeyWithClickEvents: this div needs an onClick to show the input on mobile, where it's normally hidden.
|
||||
Normally you'd also need to add a keyboard trigger to do the same without a pointer, but in this case the input already be focused on its own. */}
|
||||
<div
|
||||
@@ -62,8 +62,7 @@ export const SearchInput = React.forwardRef<HTMLDivElement, SearchInputProps>(
|
||||
'theme-bold:border-header-link/3 has-[input:focus-visible]:theme-bold:border-header-link/5 has-[input:focus-visible]:theme-bold:bg-header-link/3 has-[input:focus-visible]:theme-bold:ring-header-link/5',
|
||||
'theme-bold:before:absolute theme-bold:before:inset-0 theme-bold:before:bg-header-background/7 theme-bold:before:backdrop-blur-xl ', // Special overlay to make the transparent colors of theme-bold visible.
|
||||
'relative z-30 shrink grow justify-start max-md:absolute max-md:right-0',
|
||||
isOpen ? 'max-md:w-56' : 'max-md:w-[38px]',
|
||||
className
|
||||
isOpen ? 'max-md:w-56' : 'max-md:w-[38px]'
|
||||
)}
|
||||
>
|
||||
{value && isOpen ? (
|
||||
|
||||
@@ -296,7 +296,7 @@ export const SearchResults = React.forwardRef(function SearchResults(
|
||||
key={item.id}
|
||||
question={item.question}
|
||||
active={index === cursor}
|
||||
assistant={assistants[0]}
|
||||
assistant={assistants[0]!}
|
||||
recommended
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -71,8 +71,7 @@ export interface AskAnswerResult {
|
||||
export async function searchAllSiteContent(query: string): Promise<OrderedComputedResult[]> {
|
||||
return traceErrorOnly('Search.searchAllSiteContent', async () => {
|
||||
const context = await getServerActionBaseContext();
|
||||
|
||||
return await searchSiteContent(context, {
|
||||
return searchSiteContent(context, {
|
||||
query,
|
||||
scope: { mode: 'all' },
|
||||
});
|
||||
@@ -270,7 +269,7 @@ async function searchSiteContent(
|
||||
|
||||
return (
|
||||
await Promise.all(
|
||||
searchResults.map(async (spaceItem) => {
|
||||
searchResults.map((spaceItem) => {
|
||||
const found = findSiteSpaceBy(
|
||||
structure,
|
||||
(siteSpace) => siteSpace.space.id === spaceItem.id
|
||||
|
||||
@@ -13,7 +13,7 @@ import { buildVersion } from '@/lib/build';
|
||||
import { GITBOOK_API_PUBLIC_URL, GITBOOK_ASSETS_URL, GITBOOK_ICONS_URL } from '@/lib/env';
|
||||
import { getResizedImageURL } from '@/lib/images';
|
||||
import { isSiteIndexable } from '@/lib/seo';
|
||||
import { AIChatProvider, AIContextProvider } from '../AI';
|
||||
import { AIContextProvider } from '../AI';
|
||||
import { RocketLoaderDetector } from './RocketLoaderDetector';
|
||||
import { SiteLayoutClientContexts } from './SiteLayoutClientContexts';
|
||||
|
||||
@@ -58,15 +58,13 @@ export async function SiteLayout(props: {
|
||||
aiMode={customization.ai?.mode}
|
||||
trademark={customization.trademark.enabled}
|
||||
>
|
||||
<AIChatProvider>
|
||||
<SpaceLayout
|
||||
context={context}
|
||||
withTracking={withTracking}
|
||||
visitorAuthClaims={visitorAuthClaims}
|
||||
>
|
||||
{children}
|
||||
</SpaceLayout>
|
||||
</AIChatProvider>
|
||||
<SpaceLayout
|
||||
context={context}
|
||||
withTracking={withTracking}
|
||||
visitorAuthClaims={visitorAuthClaims}
|
||||
>
|
||||
{children}
|
||||
</SpaceLayout>
|
||||
</AIContextProvider>
|
||||
|
||||
{scripts.length > 0 ? (
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import type { GitBookSiteContext } from '@/lib/context';
|
||||
import { getPageDocument } from '@/lib/data';
|
||||
import { CustomizationHeaderPreset, CustomizationThemeMode } from '@gitbook/api';
|
||||
import {
|
||||
CustomizationHeaderPreset,
|
||||
CustomizationThemeMode,
|
||||
SiteInsightsDisplayContext,
|
||||
} from '@gitbook/api';
|
||||
import type { Metadata, Viewport } from 'next';
|
||||
import { notFound, redirect } from 'next/navigation';
|
||||
import React from 'react';
|
||||
@@ -65,6 +69,7 @@ export async function SitePage(props: SitePageProps) {
|
||||
ancestors={ancestors}
|
||||
document={document}
|
||||
withPageFeedback={withPageFeedback}
|
||||
insightsDisplayContext={SiteInsightsDisplayContext.Site}
|
||||
/>
|
||||
</div>
|
||||
<React.Suspense fallback={null}>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { TrackPageViewEvent } from '@/components/Insights';
|
||||
import { t, useLanguage } from '@/intl/client';
|
||||
import { tcls } from '@/lib/tailwind';
|
||||
import { SiteInsightsDisplayContext } from '@gitbook/api';
|
||||
import { useRouter, useSearchParams } from 'next/navigation';
|
||||
import { useEffect } from 'react';
|
||||
import { useSpaceBasePath } from '../SpaceLayout/SpaceLayoutContext';
|
||||
@@ -46,7 +47,7 @@ export function SitePageNotFound() {
|
||||
</div>
|
||||
|
||||
{/* Track the page not found as a page view */}
|
||||
<TrackPageViewEvent />
|
||||
<TrackPageViewEvent displayContext={SiteInsightsDisplayContext.Site} />
|
||||
</div>
|
||||
</CurrentPageProvider>
|
||||
);
|
||||
|
||||
@@ -38,7 +38,7 @@ export function SiteSectionList(props: { sections: ClientSiteSections; className
|
||||
>
|
||||
<TOCScrollContainer
|
||||
style={{ maxHeight: `${MAX_ITEMS * 3 + 2}rem` }}
|
||||
className="gutter-stable overflow-y-auto px-2 pb-6"
|
||||
className="overflow-y-auto px-2 pb-4"
|
||||
>
|
||||
{sectionsAndGroups.map((item) => {
|
||||
if (item.object === 'site-section-group') {
|
||||
@@ -110,7 +110,7 @@ export function SiteSectionListItem(props: {
|
||||
className={tcls(
|
||||
'flex size-8 shrink-0 items-center justify-center rounded-md straight-corners:rounded-none bg-tint-subtle text-lg text-tint leading-none shadow-tint shadow-xs ring-1 ring-tint-subtle transition-transform group-hover/section-link:scale-110 group-hover/section-link:ring-tint-hover group-active/section-link:scale-90 group-active/section-link:shadow-none contrast-more:text-tint-strong dark:shadow-none',
|
||||
isActive
|
||||
? 'bg-primary tint:bg-primary-solid text-primary-subtle tint:text-contrast-primary-solid shadow-md shadow-primary ring-primary group-hover/section-link:ring-primary-hover, contrast-more:text-primary contrast-more:ring-2 contrast-more:ring-primary'
|
||||
? 'bg-primary tint:bg-primary-original text-primary-subtle tint:text-contrast-primary-original shadow-md shadow-primary ring-primary group-hover/section-link:ring-primary-hover, contrast-more:text-primary contrast-more:ring-2 contrast-more:ring-primary'
|
||||
: null
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
CustomizationHeaderPreset,
|
||||
CustomizationSearchStyle,
|
||||
} from '@gitbook/api';
|
||||
import React from 'react';
|
||||
import type React from 'react';
|
||||
|
||||
import { Footer } from '@/components/Footer';
|
||||
import { Header, HeaderLogo } from '@/components/Header';
|
||||
@@ -12,9 +12,13 @@ import { TableOfContents } from '@/components/TableOfContents';
|
||||
import { CONTAINER_STYLE } from '@/components/layout';
|
||||
import { tcls } from '@/lib/tailwind';
|
||||
|
||||
import { getSpaceLanguage } from '@/intl/server';
|
||||
import type { VisitorAuthClaims } from '@/lib/adaptive';
|
||||
import { GITBOOK_APP_URL } from '@/lib/env';
|
||||
import { AIChatProvider } from '../AI';
|
||||
import type { RenderAIMessageOptions } from '../AI';
|
||||
import { AIChat } from '../AIChat';
|
||||
import { AdaptiveVisitorContextProvider } from '../Adaptive';
|
||||
import { Announcement } from '../Announcement';
|
||||
import { SpacesDropdown } from '../Header/SpacesDropdown';
|
||||
import { InsightsProvider } from '../Insights';
|
||||
@@ -23,10 +27,7 @@ import { SiteSectionList, encodeClientSiteSections } from '../SiteSections';
|
||||
import { CurrentContentProvider } from '../hooks';
|
||||
import { SpaceLayoutContextProvider } from './SpaceLayoutContext';
|
||||
|
||||
/**
|
||||
* Render the entire layout of the space (header, table of contents, footer).
|
||||
*/
|
||||
export function SpaceLayout(props: {
|
||||
type SpaceLayoutProps = {
|
||||
context: GitBookSiteContext;
|
||||
|
||||
/** Whether to enable tracking of events into site insights. */
|
||||
@@ -35,39 +36,21 @@ export function SpaceLayout(props: {
|
||||
/** The visitor auth claims. */
|
||||
visitorAuthClaims: VisitorAuthClaims;
|
||||
|
||||
/** The options for rendering AI messages. */
|
||||
aiChatRenderMessageOptions?: RenderAIMessageOptions;
|
||||
|
||||
/** The children of the layout. */
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const { context, withTracking, visitorAuthClaims, children } = props;
|
||||
const { siteSpace, customization, sections, siteSpaces } = context;
|
||||
};
|
||||
|
||||
const withTopHeader = customization.header.preset !== CustomizationHeaderPreset.None;
|
||||
/**
|
||||
* Provide all contexts for a space.
|
||||
*/
|
||||
export function SpaceLayoutServerContext(props: SpaceLayoutProps) {
|
||||
const { context, withTracking, visitorAuthClaims, aiChatRenderMessageOptions, children } =
|
||||
props;
|
||||
|
||||
const withSections = Boolean(sections && sections.list.length > 1);
|
||||
const isMultiVariants = Boolean(siteSpaces.length > 1);
|
||||
|
||||
const withFooter =
|
||||
customization.themes.toggeable ||
|
||||
customization.footer.copyright ||
|
||||
customization.footer.logo ||
|
||||
customization.footer.groups?.length;
|
||||
|
||||
const search = (
|
||||
<div className="flex grow items-center gap-2">
|
||||
<React.Suspense fallback={null}>
|
||||
<SearchContainer
|
||||
style={
|
||||
customization.header.preset === CustomizationHeaderPreset.None
|
||||
? CustomizationSearchStyle.Subtle
|
||||
: customization.styling.search
|
||||
}
|
||||
isMultiVariants={siteSpaces.length > 1}
|
||||
spaceTitle={siteSpace.title}
|
||||
siteSpaceId={siteSpace.id}
|
||||
/>
|
||||
</React.Suspense>
|
||||
</div>
|
||||
);
|
||||
const { customization } = context;
|
||||
|
||||
const eventUrl = new URL(
|
||||
context.linker.toAbsoluteURL(context.linker.toPathInSite('/~gitbook/__evt'))
|
||||
@@ -75,99 +58,150 @@ export function SpaceLayout(props: {
|
||||
eventUrl.searchParams.set('o', context.organizationId);
|
||||
eventUrl.searchParams.set('s', context.site.id);
|
||||
|
||||
const getVisitorClaimsUrl = context.linker.toAbsoluteURL(
|
||||
context.linker.toPathInSite('/~gitbook/visitor')
|
||||
);
|
||||
|
||||
return (
|
||||
<SpaceLayoutContextProvider basePath={context.linker.toPathInSpace('')}>
|
||||
<CurrentContentProvider
|
||||
organizationId={context.organizationId}
|
||||
siteId={context.site.id}
|
||||
siteSectionId={context.sections?.current?.id ?? null}
|
||||
siteSpaceId={context.siteSpace.id}
|
||||
siteShareKey={context.shareKey ?? null}
|
||||
spaceId={context.space.id}
|
||||
revisionId={context.revisionId}
|
||||
visitorAuthClaims={visitorAuthClaims}
|
||||
<AdaptiveVisitorContextProvider
|
||||
contextId={context.contextId}
|
||||
visitorClaimsURL={getVisitorClaimsUrl}
|
||||
>
|
||||
<InsightsProvider
|
||||
enabled={withTracking}
|
||||
appURL={GITBOOK_APP_URL}
|
||||
eventUrl={eventUrl.toString()}
|
||||
visitorCookieTrackingEnabled={customization.insights?.trackingCookie}
|
||||
<CurrentContentProvider
|
||||
organizationId={context.organizationId}
|
||||
siteId={context.site.id}
|
||||
siteSectionId={context.sections?.current?.id ?? null}
|
||||
siteSpaceId={context.siteSpace.id}
|
||||
siteShareKey={context.shareKey ?? null}
|
||||
spaceId={context.space.id}
|
||||
revisionId={context.revisionId}
|
||||
visitorAuthClaims={visitorAuthClaims}
|
||||
>
|
||||
<Announcement context={context} />
|
||||
<Header withTopHeader={withTopHeader} context={context} search={search} />
|
||||
{customization.ai?.mode === CustomizationAIMode.Assistant ? (
|
||||
<AIChat trademark={customization.trademark.enabled} />
|
||||
) : null}
|
||||
<div className="scroll-nojump">
|
||||
<div className="motion-safe:transition-all motion-safe:duration-300 lg:chat-open:mr-80 xl:chat-open:mr-96">
|
||||
<div
|
||||
className={tcls(
|
||||
'flex',
|
||||
'flex-col',
|
||||
'lg:flex-row',
|
||||
CONTAINER_STYLE,
|
||||
'site-width-wide:max-w-full',
|
||||
|
||||
// Ensure the footer is display below the viewport even if the content is not enough
|
||||
withFooter && 'min-h-[calc(100vh-64px)]',
|
||||
withTopHeader ? null : 'lg:min-h-screen'
|
||||
)}
|
||||
>
|
||||
<TableOfContents
|
||||
context={context}
|
||||
header={
|
||||
withTopHeader ? null : (
|
||||
<div
|
||||
className={tcls(
|
||||
'hidden',
|
||||
'pr-4',
|
||||
'md:flex',
|
||||
'grow-0',
|
||||
'flex-wrap',
|
||||
'dark:shadow-light/1',
|
||||
'text-base/tight'
|
||||
)}
|
||||
>
|
||||
<HeaderLogo context={context} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
innerHeader={
|
||||
// displays the search button and/or the space dropdown in the ToC according to the header/variant settings. E.g if there is no header, the search button will be displayed in the ToC.
|
||||
<>
|
||||
{!withTopHeader && search}
|
||||
{!withTopHeader && withSections && sections && (
|
||||
<SiteSectionList
|
||||
className={tcls('hidden', 'lg:block')}
|
||||
sections={encodeClientSiteSections(
|
||||
context,
|
||||
sections
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
{isMultiVariants && !sections && (
|
||||
<SpacesDropdown
|
||||
context={context}
|
||||
siteSpace={siteSpace}
|
||||
siteSpaces={siteSpaces}
|
||||
className={tcls(
|
||||
'w-full',
|
||||
'page-no-toc:hidden',
|
||||
'page-no-toc:site-header-none:flex'
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<div className="flex min-w-0 flex-1 flex-col">{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{withFooter ? <Footer context={context} /> : null}
|
||||
</InsightsProvider>
|
||||
</CurrentContentProvider>
|
||||
<InsightsProvider
|
||||
enabled={withTracking}
|
||||
appURL={GITBOOK_APP_URL}
|
||||
eventUrl={eventUrl.toString()}
|
||||
visitorCookieTrackingEnabled={customization.insights?.trackingCookie}
|
||||
>
|
||||
<AIChatProvider renderMessageOptions={aiChatRenderMessageOptions}>
|
||||
{children}
|
||||
</AIChatProvider>
|
||||
</InsightsProvider>
|
||||
</CurrentContentProvider>
|
||||
</AdaptiveVisitorContextProvider>
|
||||
</SpaceLayoutContextProvider>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the entire layout of the space (header, table of contents, footer).
|
||||
*/
|
||||
export function SpaceLayout(props: SpaceLayoutProps) {
|
||||
const { context, children } = props;
|
||||
const { siteSpace, customization, sections, siteSpaces } = context;
|
||||
|
||||
const withTopHeader = customization.header.preset !== CustomizationHeaderPreset.None;
|
||||
|
||||
const withSections = Boolean(sections && sections.list.length > 1);
|
||||
|
||||
const currentLanguage = getSpaceLanguage(context);
|
||||
const withVariants: 'generic' | 'translations' | undefined =
|
||||
siteSpaces.length > 1
|
||||
? siteSpaces.some(
|
||||
(space) => space.space.language && space.space.language !== currentLanguage.locale
|
||||
)
|
||||
? 'translations'
|
||||
: 'generic'
|
||||
: undefined;
|
||||
|
||||
const withFooter =
|
||||
customization.themes.toggeable ||
|
||||
customization.footer.copyright ||
|
||||
customization.footer.logo ||
|
||||
customization.footer.groups?.length;
|
||||
|
||||
return (
|
||||
<SpaceLayoutServerContext {...props}>
|
||||
<Announcement context={context} />
|
||||
<Header withTopHeader={withTopHeader} withVariants={withVariants} context={context} />
|
||||
{customization.ai?.mode === CustomizationAIMode.Assistant ? (
|
||||
<AIChat trademark={customization.trademark.enabled} />
|
||||
) : null}
|
||||
|
||||
<div className="motion-safe:transition-all motion-safe:duration-300 lg:chat-open:mr-80 xl:chat-open:mr-96">
|
||||
<div
|
||||
className={tcls(
|
||||
'flex',
|
||||
'flex-col',
|
||||
'lg:flex-row',
|
||||
CONTAINER_STYLE,
|
||||
'site-width-wide:max-w-full',
|
||||
|
||||
// Ensure the footer is display below the viewport even if the content is not enough
|
||||
withFooter && [
|
||||
'site-header:min-h-[calc(100vh-64px)]',
|
||||
'site-header-sections:min-h-[calc(100vh-108px)]',
|
||||
],
|
||||
withTopHeader ? null : 'lg:min-h-screen'
|
||||
)}
|
||||
>
|
||||
<TableOfContents
|
||||
context={context}
|
||||
header={
|
||||
withTopHeader ? null : (
|
||||
<div
|
||||
className={tcls(
|
||||
'hidden',
|
||||
'pr-4',
|
||||
'lg:flex',
|
||||
'grow-0',
|
||||
'flex-wrap',
|
||||
'dark:shadow-light/1',
|
||||
'text-base/tight'
|
||||
)}
|
||||
>
|
||||
<HeaderLogo context={context} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
innerHeader={
|
||||
// displays the search button and/or the space dropdown in the ToC according to the header/variant settings. E.g if there is no header, the search button will be displayed in the ToC.
|
||||
<>
|
||||
{!withTopHeader && (
|
||||
<div className="flex gap-2">
|
||||
<SearchContainer
|
||||
style={CustomizationSearchStyle.Subtle}
|
||||
isMultiVariants={siteSpaces.length > 1}
|
||||
spaceTitle={siteSpace.title}
|
||||
siteSpaceId={siteSpace.id}
|
||||
className="max-lg:hidden"
|
||||
viewport="desktop"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{!withTopHeader && withSections && sections && (
|
||||
<SiteSectionList
|
||||
className={tcls('hidden', 'lg:block')}
|
||||
sections={encodeClientSiteSections(context, sections)}
|
||||
/>
|
||||
)}
|
||||
{withVariants === 'generic' && (
|
||||
<SpacesDropdown
|
||||
context={context}
|
||||
siteSpace={siteSpace}
|
||||
siteSpaces={siteSpaces}
|
||||
className="w-full px-3 py-2"
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<div className="flex min-w-0 flex-1 flex-col">{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{withFooter ? <Footer context={context} /> : null}
|
||||
</SpaceLayoutServerContext>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ import { SiteInsightsTrademarkPlacement } from '@gitbook/api';
|
||||
import type React from 'react';
|
||||
|
||||
import { tcls } from '@/lib/tailwind';
|
||||
|
||||
import { PagesList } from './PagesList';
|
||||
import { TOCScrollContainer } from './TOCScroller';
|
||||
import { TableOfContentsScript } from './TableOfContentsScript';
|
||||
@@ -16,7 +15,7 @@ export async function TableOfContents(props: {
|
||||
innerHeader?: React.ReactNode; // Displayed outside the scrollable TOC, directly above the page list
|
||||
}) {
|
||||
const { innerHeader, context, header } = props;
|
||||
const { space, customization, revision } = context;
|
||||
const { customization, revision } = context;
|
||||
|
||||
const pages = await encodeClientTableOfContents(context, revision.pages, revision.pages);
|
||||
|
||||
@@ -57,6 +56,8 @@ export async function TableOfContents(props: {
|
||||
// Client-side dynamic positioning (CSS vars applied by script)
|
||||
'lg:[html[style*="--toc-top-offset"]_&]:top-(--toc-top-offset)!',
|
||||
'lg:[html[style*="--toc-height"]_&]:h-(--toc-height)!',
|
||||
'lg:page-no-toc:[html[style*="--outline-top-offset"]_&]:top-(--outline-top-offset)!',
|
||||
'lg:page-no-toc:[html[style*="--outline-height"]_&]:top-(--outline-height)!',
|
||||
|
||||
'pt-6',
|
||||
'pb-4',
|
||||
@@ -96,17 +97,16 @@ export async function TableOfContents(props: {
|
||||
'page-has-toc:[html.sidebar-filled.circular-corners_&]:rounded-3xl'
|
||||
)}
|
||||
>
|
||||
{innerHeader && <div className="px-5 *:my-4">{innerHeader}</div>}
|
||||
{innerHeader ? (
|
||||
<div className="my-4 flex flex-col space-y-4 px-5 empty:hidden">
|
||||
{innerHeader}
|
||||
</div>
|
||||
) : null}
|
||||
<TOCScrollContainer // The scrollview inside the sidebar
|
||||
className={tcls(
|
||||
'flex grow flex-col p-2',
|
||||
customization.trademark.enabled && 'lg:pb-20',
|
||||
'lg:gutter-stable overflow-y-auto',
|
||||
'[&::-webkit-scrollbar]:bg-transparent',
|
||||
'[&::-webkit-scrollbar-thumb]:bg-transparent',
|
||||
'[&::-webkit-scrollbar]:group-hover:bg-tint-subtle',
|
||||
'[&::-webkit-scrollbar-thumb]:group-hover:bg-tint-7',
|
||||
'[&::-webkit-scrollbar-thumb:hover]:group-hover:bg-tint-8'
|
||||
'hide-scrollbar overflow-y-auto'
|
||||
)}
|
||||
>
|
||||
<PagesList
|
||||
@@ -115,8 +115,7 @@ export async function TableOfContents(props: {
|
||||
/>
|
||||
{customization.trademark.enabled ? (
|
||||
<Trademark
|
||||
space={space}
|
||||
customization={customization}
|
||||
context={context}
|
||||
placement={SiteInsightsTrademarkPlacement.Sidebar}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
@@ -1,21 +1,17 @@
|
||||
import type {
|
||||
SiteCustomizationSettings,
|
||||
SiteInsightsTrademarkPlacement,
|
||||
Space,
|
||||
} from '@gitbook/api';
|
||||
import type { SiteInsightsTrademarkPlacement } from '@gitbook/api';
|
||||
import { Icon } from '@gitbook/icons';
|
||||
|
||||
import { getSpaceLanguage, t } from '@/intl/server';
|
||||
import { tcls } from '@/lib/tailwind';
|
||||
|
||||
import type { GitBookSpaceContext } from '@/lib/context';
|
||||
import { Link } from '../primitives';
|
||||
|
||||
/**
|
||||
* Trademark link to the GitBook.
|
||||
*/
|
||||
export function Trademark(props: {
|
||||
space: Space;
|
||||
customization: SiteCustomizationSettings;
|
||||
context: GitBookSpaceContext;
|
||||
placement: SiteInsightsTrademarkPlacement;
|
||||
}) {
|
||||
return (
|
||||
@@ -71,12 +67,12 @@ export function Trademark(props: {
|
||||
* Trademark link to the GitBook.
|
||||
*/
|
||||
export function TrademarkLink(props: {
|
||||
space: Space;
|
||||
customization: SiteCustomizationSettings;
|
||||
context: GitBookSpaceContext;
|
||||
placement: SiteInsightsTrademarkPlacement;
|
||||
}) {
|
||||
const { space, customization, placement } = props;
|
||||
const language = getSpaceLanguage(customization);
|
||||
const { context, placement } = props;
|
||||
const { space } = context;
|
||||
const language = getSpaceLanguage(context);
|
||||
|
||||
const url = new URL('https://www.gitbook.com');
|
||||
url.searchParams.set('utm_source', 'content');
|
||||
|
||||
@@ -25,7 +25,7 @@ export function useHasBeenInViewport(
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
([entry]) => {
|
||||
if (entry.isIntersecting) {
|
||||
if (entry?.isIntersecting) {
|
||||
setVisible(true);
|
||||
observer.disconnect();
|
||||
}
|
||||
|
||||
@@ -30,8 +30,9 @@ export function useInViewportListener(
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
([entry]) => {
|
||||
isIntersectingRef.current = entry.isIntersecting;
|
||||
listenerRef.current(entry.isIntersecting, () => {
|
||||
const isIntersecting = entry?.isIntersecting ?? false;
|
||||
isIntersectingRef.current = isIntersecting;
|
||||
listenerRef.current(isIntersecting, () => {
|
||||
observer.disconnect();
|
||||
});
|
||||
},
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import * as React from 'react';
|
||||
|
||||
export function useIsMobile(breakpoint = 640): boolean {
|
||||
export function useIsMobile(breakpoint = 1024): boolean {
|
||||
const [isMobile, setIsMobile] = React.useState(false);
|
||||
|
||||
React.useEffect(() => {
|
||||
|
||||
@@ -5,19 +5,22 @@ import React from 'react';
|
||||
*/
|
||||
export function useScrollActiveId(
|
||||
ids: string[],
|
||||
options: {
|
||||
{
|
||||
rootMargin,
|
||||
threshold = 0.5,
|
||||
enabled,
|
||||
}: {
|
||||
rootMargin?: string;
|
||||
threshold?: number;
|
||||
enabled: boolean;
|
||||
} = { enabled: true }
|
||||
) {
|
||||
const { rootMargin, threshold = 0.5, enabled } = options;
|
||||
|
||||
const [activeId, setActiveId] = React.useState<string>(ids[0]);
|
||||
const [activeId, setActiveId] = React.useState<string>(ids[0]!);
|
||||
const sectionsIntersectingMap = React.useRef<Map<string, boolean>>(new Map());
|
||||
|
||||
React.useEffect(() => {
|
||||
const defaultActiveId = ids[0];
|
||||
// @ts-expect-error
|
||||
setActiveId((activeId) => (ids.indexOf(activeId) !== -1 ? activeId : defaultActiveId));
|
||||
if (!enabled) {
|
||||
return;
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Link, type LinkInsightsProps } from './Link';
|
||||
import { useClassnames } from './StyleProvider';
|
||||
import { Tooltip } from './Tooltip';
|
||||
|
||||
type ButtonProps = {
|
||||
export type ButtonProps = {
|
||||
href?: string;
|
||||
variant?: 'primary' | 'secondary' | 'blank' | 'header';
|
||||
icon?: IconName | React.ReactNode;
|
||||
@@ -25,11 +25,13 @@ type ButtonProps = {
|
||||
|
||||
export const variantClasses = {
|
||||
primary: [
|
||||
'bg-primary-solid',
|
||||
'text-contrast-primary-solid',
|
||||
'bg-primary-original',
|
||||
'text-contrast-primary-original',
|
||||
'hover:bg-primary-solid-hover',
|
||||
'hover:text-contrast-primary-solid-hover',
|
||||
'border-0',
|
||||
'contrast-more:bg-primary-solid',
|
||||
'contrast-more:text-contrast-primary-solid',
|
||||
'contrast-more:border',
|
||||
'disabled:bg-primary-subtle',
|
||||
'disabled:text-primary/8',
|
||||
@@ -130,7 +132,10 @@ export const Button = React.forwardRef<
|
||||
<>
|
||||
{icon ? (
|
||||
typeof icon === 'string' ? (
|
||||
<Icon icon={icon as IconName} className={tcls('size-[1em]')} />
|
||||
<Icon
|
||||
icon={icon as IconName}
|
||||
className={tcls('button-leading-icon size-[1em]')}
|
||||
/>
|
||||
) : (
|
||||
icon
|
||||
)
|
||||
@@ -139,36 +144,32 @@ export const Button = React.forwardRef<
|
||||
</>
|
||||
);
|
||||
|
||||
if (href) {
|
||||
return (
|
||||
<Link
|
||||
ref={ref as React.Ref<HTMLAnchorElement>}
|
||||
href={href}
|
||||
className={domClassName}
|
||||
classNames={['ButtonStyles']}
|
||||
insights={insights}
|
||||
aria-label={label?.toString()}
|
||||
aria-pressed={active === undefined ? undefined : active}
|
||||
target={target}
|
||||
{...rest}
|
||||
>
|
||||
{content}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
const button = (
|
||||
const button = href ? (
|
||||
<Link
|
||||
ref={ref as React.Ref<HTMLAnchorElement>}
|
||||
href={href}
|
||||
className={domClassName}
|
||||
classNames={['ButtonStyles']}
|
||||
insights={insights}
|
||||
aria-label={label?.toString()}
|
||||
aria-pressed={active}
|
||||
target={target}
|
||||
{...rest}
|
||||
>
|
||||
{content}
|
||||
</Link>
|
||||
) : (
|
||||
<button
|
||||
ref={ref as React.Ref<HTMLButtonElement>}
|
||||
type="button"
|
||||
className={tcls(buttonOnlyClassNames, domClassName)}
|
||||
aria-label={label?.toString()}
|
||||
aria-pressed={active === undefined ? undefined : active}
|
||||
aria-pressed={active}
|
||||
disabled={disabled}
|
||||
{...rest}
|
||||
>
|
||||
{content}
|
||||
{trailing}
|
||||
{trailing ? <span className="button-trailing-icon ms-auto">{trailing}</span> : null}
|
||||
</button>
|
||||
);
|
||||
|
||||
|
||||
@@ -31,8 +31,8 @@ export const Checkbox = React.forwardRef<
|
||||
'flex',
|
||||
'items-center',
|
||||
'justify-center',
|
||||
'data-[state=checked]:bg-primary-solid',
|
||||
'data-[state=checked]:text-contrast-primary-solid',
|
||||
'data-[state=checked]:bg-primary-original',
|
||||
'data-[state=checked]:text-contrast-primary-original',
|
||||
'contrast-more:ring-tint-12',
|
||||
{ small: 'size-4', medium: 'size-5' }[size],
|
||||
className
|
||||
|
||||
@@ -86,7 +86,7 @@ export function DropdownMenu(props: {
|
||||
>
|
||||
<div
|
||||
className={tcls(
|
||||
'flex max-h-96 min-w-40 max-w-[40vw] flex-col gap-1 overflow-auto circular-corners:rounded-xl rounded-md straight-corners:rounded-none border border-tint bg-tint-base p-2 shadow-lg sm:min-w-52 sm:max-w-80',
|
||||
'flex max-h-[30rem] min-w-40 max-w-[40vw] flex-col gap-1 overflow-auto circular-corners:rounded-xl rounded-md straight-corners:rounded-none border border-tint bg-tint-base p-2 shadow-lg sm:min-w-52 sm:max-w-80',
|
||||
className
|
||||
)}
|
||||
>
|
||||
@@ -110,7 +110,6 @@ export function DropdownChevron() {
|
||||
'shrink-0',
|
||||
'opacity-6',
|
||||
'size-3',
|
||||
'ms-1',
|
||||
'transition-all',
|
||||
'group-hover/dropdown:opacity-11',
|
||||
'group-data-[state=open]/dropdown:opacity-11',
|
||||
|
||||
@@ -28,6 +28,7 @@ export const ButtonStyles = [
|
||||
|
||||
'hover:depth-subtle:-translate-y-px',
|
||||
'focus-visible:depth-subtle:-translate-y-px',
|
||||
'data-[state=open]:depth-subtle:-translate-y-px',
|
||||
'active:depth-subtle:translate-y-0',
|
||||
'transition-all',
|
||||
|
||||
|
||||
@@ -41,8 +41,8 @@ export function ZoomImage(
|
||||
// Since the image is removed from the DOM when the modal is opened,
|
||||
// We only care when the size is defined.
|
||||
if (imgEntry && imgEntry.contentRect.width !== 0) {
|
||||
viewWidth = entries[0]?.contentRect.width;
|
||||
setPlaceholderRect(entries[0].contentRect);
|
||||
viewWidth = imgEntry.contentRect.width;
|
||||
setPlaceholderRect(imgEntry.contentRect);
|
||||
onChange();
|
||||
}
|
||||
})
|
||||
|
||||
@@ -3,201 +3,180 @@ import type { CustomizationFontDefinition } from '@gitbook/api';
|
||||
import stylelint from 'stylelint';
|
||||
import { generateFontFacesCSS, getFontSourcesToPreload } from './custom';
|
||||
|
||||
const TEST_FONTS: { [key in string]: CustomizationFontDefinition } = {
|
||||
basic: {
|
||||
id: 'open-sans',
|
||||
custom: true,
|
||||
fontFamily: 'Open Sans',
|
||||
fontFaces: [
|
||||
{
|
||||
weight: 400,
|
||||
sources: [
|
||||
{
|
||||
url: 'https://example.com/fonts/opensans-regular.woff2',
|
||||
format: 'woff2',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
weight: 700,
|
||||
sources: [
|
||||
{
|
||||
url: 'https://example.com/fonts/opensans-bold.woff2',
|
||||
format: 'woff2',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
permissions: {
|
||||
edit: false,
|
||||
const TEST_FONTS_BASIC: CustomizationFontDefinition = {
|
||||
id: 'open-sans',
|
||||
custom: true,
|
||||
fontFamily: 'Open Sans',
|
||||
fontFaces: [
|
||||
{
|
||||
weight: 400,
|
||||
sources: [
|
||||
{
|
||||
url: 'https://example.com/fonts/opensans-regular.woff2',
|
||||
format: 'woff2',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
weight: 700,
|
||||
sources: [
|
||||
{
|
||||
url: 'https://example.com/fonts/opensans-bold.woff2',
|
||||
format: 'woff2',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
permissions: {
|
||||
edit: false,
|
||||
},
|
||||
};
|
||||
|
||||
multiWeight: {
|
||||
id: 'roboto',
|
||||
custom: true,
|
||||
fontFamily: 'Roboto',
|
||||
fontFaces: [
|
||||
{
|
||||
weight: 300,
|
||||
sources: [
|
||||
{
|
||||
url: 'https://example.com/fonts/roboto-light.woff2',
|
||||
format: 'woff2',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
weight: 400,
|
||||
sources: [
|
||||
{
|
||||
url: 'https://example.com/fonts/roboto-regular.woff2',
|
||||
format: 'woff2',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
weight: 500,
|
||||
sources: [
|
||||
{
|
||||
url: 'https://example.com/fonts/roboto-medium.woff2',
|
||||
format: 'woff2',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
weight: 700,
|
||||
sources: [
|
||||
{
|
||||
url: 'https://example.com/fonts/roboto-bold.woff2',
|
||||
format: 'woff2',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
weight: 900,
|
||||
sources: [
|
||||
{
|
||||
url: 'https://example.com/fonts/roboto-black.woff2',
|
||||
format: 'woff2',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
permissions: {
|
||||
edit: false,
|
||||
const TEST_FONTS_MULTI_WEIGHT: CustomizationFontDefinition = {
|
||||
id: 'roboto',
|
||||
custom: true,
|
||||
fontFamily: 'Roboto',
|
||||
fontFaces: [
|
||||
{
|
||||
weight: 300,
|
||||
sources: [
|
||||
{
|
||||
url: 'https://example.com/fonts/roboto-light.woff2',
|
||||
format: 'woff2',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
weight: 400,
|
||||
sources: [
|
||||
{
|
||||
url: 'https://example.com/fonts/roboto-regular.woff2',
|
||||
format: 'woff2',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
weight: 500,
|
||||
sources: [
|
||||
{
|
||||
url: 'https://example.com/fonts/roboto-medium.woff2',
|
||||
format: 'woff2',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
weight: 700,
|
||||
sources: [
|
||||
{
|
||||
url: 'https://example.com/fonts/roboto-bold.woff2',
|
||||
format: 'woff2',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
weight: 900,
|
||||
sources: [
|
||||
{
|
||||
url: 'https://example.com/fonts/roboto-black.woff2',
|
||||
format: 'woff2',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
permissions: {
|
||||
edit: false,
|
||||
},
|
||||
};
|
||||
|
||||
multiSource: {
|
||||
id: 'lato',
|
||||
custom: true,
|
||||
fontFamily: 'Lato',
|
||||
fontFaces: [
|
||||
{
|
||||
weight: 400,
|
||||
sources: [
|
||||
{
|
||||
url: 'https://example.com/fonts/lato-regular.woff2',
|
||||
format: 'woff2',
|
||||
},
|
||||
{ url: 'https://example.com/fonts/lato-regular.woff', format: 'woff' },
|
||||
],
|
||||
},
|
||||
],
|
||||
permissions: {
|
||||
edit: false,
|
||||
const TEST_FONTS_MULTI_SOURCE: CustomizationFontDefinition = {
|
||||
id: 'lato',
|
||||
custom: true,
|
||||
fontFamily: 'Lato',
|
||||
fontFaces: [
|
||||
{
|
||||
weight: 400,
|
||||
sources: [
|
||||
{
|
||||
url: 'https://example.com/fonts/lato-regular.woff2',
|
||||
format: 'woff2',
|
||||
},
|
||||
{ url: 'https://example.com/fonts/lato-regular.woff', format: 'woff' },
|
||||
],
|
||||
},
|
||||
],
|
||||
permissions: {
|
||||
edit: false,
|
||||
},
|
||||
};
|
||||
|
||||
missingFormat: {
|
||||
id: 'source-sans',
|
||||
custom: true,
|
||||
fontFamily: 'Source Sans Pro',
|
||||
fontFaces: [
|
||||
{
|
||||
weight: 400,
|
||||
sources: [
|
||||
{ url: 'https://example.com/fonts/sourcesans-regular.woff2' },
|
||||
{
|
||||
url: 'https://example.com/fonts/sourcesans-regular.woff',
|
||||
format: 'woff',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
permissions: {
|
||||
edit: false,
|
||||
const TEST_FONTS_MISSING_FORMAT: CustomizationFontDefinition = {
|
||||
id: 'source-sans',
|
||||
custom: true,
|
||||
fontFamily: 'Source Sans Pro',
|
||||
fontFaces: [
|
||||
{
|
||||
weight: 400,
|
||||
sources: [
|
||||
{ url: 'https://example.com/fonts/sourcesans-regular.woff2' },
|
||||
{
|
||||
url: 'https://example.com/fonts/sourcesans-regular.woff',
|
||||
format: 'woff',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
permissions: {
|
||||
edit: false,
|
||||
},
|
||||
};
|
||||
|
||||
empty: {
|
||||
id: 'empty-font',
|
||||
custom: true,
|
||||
fontFamily: 'Empty Font',
|
||||
fontFaces: [],
|
||||
permissions: {
|
||||
edit: false,
|
||||
},
|
||||
const TEST_FONTS_EMPTY: CustomizationFontDefinition = {
|
||||
id: 'empty-font',
|
||||
custom: true,
|
||||
fontFamily: 'Empty Font',
|
||||
fontFaces: [],
|
||||
permissions: {
|
||||
edit: false,
|
||||
},
|
||||
};
|
||||
|
||||
specialChars: {
|
||||
id: 'special-font',
|
||||
custom: true,
|
||||
fontFamily: 'Special Font & Co.',
|
||||
fontFaces: [
|
||||
{
|
||||
weight: 400,
|
||||
sources: [{ url: 'https://example.com/fonts/special.woff2', format: 'woff2' }],
|
||||
},
|
||||
],
|
||||
permissions: {
|
||||
edit: false,
|
||||
const TEST_FONTS_SPECIAL_CHARS: CustomizationFontDefinition = {
|
||||
id: 'special-font',
|
||||
custom: true,
|
||||
fontFamily: 'Special Font & Co.',
|
||||
fontFaces: [
|
||||
{
|
||||
weight: 400,
|
||||
sources: [{ url: 'https://example.com/fonts/special.woff2', format: 'woff2' }],
|
||||
},
|
||||
],
|
||||
permissions: {
|
||||
edit: false,
|
||||
},
|
||||
};
|
||||
|
||||
complex: {
|
||||
id: 'complex-font',
|
||||
custom: true,
|
||||
fontFamily: 'Complex Font',
|
||||
fontFaces: [
|
||||
{
|
||||
weight: 400,
|
||||
sources: [
|
||||
{ url: 'https://example.com/fonts/regular.woff2' },
|
||||
{ url: 'https://example.com/fonts/regular.woff' },
|
||||
],
|
||||
},
|
||||
{
|
||||
weight: 700,
|
||||
sources: [
|
||||
{ url: 'https://example.com/fonts/bold.woff2' },
|
||||
{ url: 'https://example.com/fonts/bold.woff' },
|
||||
],
|
||||
},
|
||||
],
|
||||
permissions: {
|
||||
edit: false,
|
||||
const TEST_FONTS_COMPLEX: CustomizationFontDefinition = {
|
||||
id: 'complex-font',
|
||||
custom: true,
|
||||
fontFamily: 'Complex Font',
|
||||
fontFaces: [
|
||||
{
|
||||
weight: 400,
|
||||
sources: [
|
||||
{ url: 'https://example.com/fonts/regular.woff2' },
|
||||
{ url: 'https://example.com/fonts/regular.woff' },
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
variousURLs: {
|
||||
id: 'various-urls',
|
||||
custom: true,
|
||||
fontFamily: 'Various URLs Font',
|
||||
fontFaces: [
|
||||
{
|
||||
weight: 400,
|
||||
sources: [
|
||||
{ url: 'https://example.com/fonts.woff2' },
|
||||
{ url: 'https://example.com/fonts.woff' },
|
||||
{ url: 'https://example.com/fonts.woff2' },
|
||||
],
|
||||
},
|
||||
],
|
||||
permissions: {
|
||||
edit: false,
|
||||
{
|
||||
weight: 700,
|
||||
sources: [
|
||||
{ url: 'https://example.com/fonts/bold.woff2' },
|
||||
{ url: 'https://example.com/fonts/bold.woff' },
|
||||
],
|
||||
},
|
||||
],
|
||||
permissions: {
|
||||
edit: false,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -229,7 +208,7 @@ async function isCSSValid(css: string): Promise<boolean> {
|
||||
|
||||
describe('generateFontFacesCSS', () => {
|
||||
test('basic case with regular and bold weights', async () => {
|
||||
const css = generateFontFacesCSS(TEST_FONTS.basic, 'content');
|
||||
const css = generateFontFacesCSS(TEST_FONTS_BASIC, 'content');
|
||||
|
||||
const isValid = await isCSSValid(css);
|
||||
expect(isValid).toBe(true);
|
||||
@@ -244,7 +223,7 @@ describe('generateFontFacesCSS', () => {
|
||||
});
|
||||
|
||||
test('mono type', async () => {
|
||||
const css = generateFontFacesCSS(TEST_FONTS.basic, 'mono');
|
||||
const css = generateFontFacesCSS(TEST_FONTS_BASIC, 'mono');
|
||||
|
||||
const isValid = await isCSSValid(css);
|
||||
expect(isValid).toBe(true);
|
||||
@@ -259,7 +238,7 @@ describe('generateFontFacesCSS', () => {
|
||||
});
|
||||
|
||||
test('multiple font weights', async () => {
|
||||
const css = generateFontFacesCSS(TEST_FONTS.multiWeight, 'content');
|
||||
const css = generateFontFacesCSS(TEST_FONTS_MULTI_WEIGHT, 'content');
|
||||
|
||||
const isValid = await isCSSValid(css);
|
||||
expect(isValid).toBe(true);
|
||||
@@ -270,7 +249,7 @@ describe('generateFontFacesCSS', () => {
|
||||
});
|
||||
|
||||
test('multiple sources for a single weight', async () => {
|
||||
const css = generateFontFacesCSS(TEST_FONTS.multiSource, 'content');
|
||||
const css = generateFontFacesCSS(TEST_FONTS_MULTI_SOURCE, 'content');
|
||||
|
||||
const isValid = await isCSSValid(css);
|
||||
expect(isValid).toBe(true);
|
||||
@@ -281,7 +260,7 @@ describe('generateFontFacesCSS', () => {
|
||||
});
|
||||
|
||||
test('missing format property', async () => {
|
||||
const css = generateFontFacesCSS(TEST_FONTS.missingFormat, 'content');
|
||||
const css = generateFontFacesCSS(TEST_FONTS_MISSING_FORMAT, 'content');
|
||||
|
||||
const isValid = await isCSSValid(css);
|
||||
expect(isValid).toBe(true);
|
||||
@@ -292,13 +271,13 @@ describe('generateFontFacesCSS', () => {
|
||||
});
|
||||
|
||||
test('empty font faces array', async () => {
|
||||
const css = generateFontFacesCSS(TEST_FONTS.empty, 'content');
|
||||
const css = generateFontFacesCSS(TEST_FONTS_EMPTY, 'content');
|
||||
|
||||
expect(css).toBe('');
|
||||
});
|
||||
|
||||
test('font with special characters in name', async () => {
|
||||
const css = generateFontFacesCSS(TEST_FONTS.specialChars, 'content');
|
||||
const css = generateFontFacesCSS(TEST_FONTS_SPECIAL_CHARS, 'content');
|
||||
|
||||
// Validate CSS syntax
|
||||
const isValid = await isCSSValid(css);
|
||||
@@ -308,13 +287,13 @@ describe('generateFontFacesCSS', () => {
|
||||
|
||||
describe('getFontSourcesToPreload', () => {
|
||||
const preloadTestCases = [
|
||||
{ name: 'basic case', font: TEST_FONTS.basic, expectedCount: 2 },
|
||||
{ name: 'multiple weights', font: TEST_FONTS.multiWeight, expectedCount: 2 },
|
||||
{ name: 'multiple sources', font: TEST_FONTS.multiSource, expectedCount: 2 },
|
||||
{ name: 'missing format', font: TEST_FONTS.missingFormat, expectedCount: 2 },
|
||||
{ name: 'empty font faces', font: TEST_FONTS.empty, expectedCount: 0 },
|
||||
{ name: 'special characters', font: TEST_FONTS.specialChars, expectedCount: 1 },
|
||||
{ name: 'complex case', font: TEST_FONTS.complex, expectedCount: 4 },
|
||||
{ name: 'basic case', font: TEST_FONTS_BASIC, expectedCount: 2 },
|
||||
{ name: 'multiple weights', font: TEST_FONTS_MULTI_WEIGHT, expectedCount: 2 },
|
||||
{ name: 'multiple sources', font: TEST_FONTS_MULTI_SOURCE, expectedCount: 2 },
|
||||
{ name: 'missing format', font: TEST_FONTS_MISSING_FORMAT, expectedCount: 2 },
|
||||
{ name: 'empty font faces', font: TEST_FONTS_EMPTY, expectedCount: 0 },
|
||||
{ name: 'special characters', font: TEST_FONTS_SPECIAL_CHARS, expectedCount: 1 },
|
||||
{ name: 'complex case', font: TEST_FONTS_COMPLEX, expectedCount: 4 },
|
||||
];
|
||||
|
||||
preloadTestCases.forEach(({ name, font, expectedCount }) => {
|
||||
|
||||
@@ -121,7 +121,7 @@ const raleway = Raleway({
|
||||
});
|
||||
|
||||
const roboto = Roboto({
|
||||
weight: ['400', '500', '700'],
|
||||
weight: ['400', '500', '600', '700'],
|
||||
variable: '--font-content',
|
||||
preload: false,
|
||||
display: 'swap',
|
||||
|
||||
@@ -1,25 +1,44 @@
|
||||
import type { SiteCustomizationSettings } from '@gitbook/api';
|
||||
|
||||
import type { GitBookAnyContext } from '@/lib/context';
|
||||
import { type TranslationLanguage, languages } from './translations';
|
||||
|
||||
export * from './translate';
|
||||
|
||||
export const DEFAULT_LOCALE = 'en';
|
||||
type TranslationLocale = keyof typeof languages;
|
||||
|
||||
export const DEFAULT_LOCALE = 'en' satisfies TranslationLocale;
|
||||
|
||||
/**
|
||||
* Get the locale of the customization.
|
||||
* Get the locale to use for a space.
|
||||
*/
|
||||
export function getCustomizationLocale(customization: SiteCustomizationSettings): string {
|
||||
return customization.internationalization.locale;
|
||||
export function getSpaceLocale(context: GitBookAnyContext): TranslationLocale {
|
||||
const { space } = context;
|
||||
const customization = 'site' in context ? context.customization : null;
|
||||
|
||||
// If the language is configured in the space, use it in priority
|
||||
if (space.language) {
|
||||
if (checkIsValidLocale(space.language)) {
|
||||
return space.language;
|
||||
}
|
||||
return DEFAULT_LOCALE;
|
||||
}
|
||||
|
||||
// Otherwise fallback to the deprecated customization settings
|
||||
if (customization) {
|
||||
return checkIsValidLocale(customization.internationalization.locale)
|
||||
? customization.internationalization.locale
|
||||
: DEFAULT_LOCALE;
|
||||
}
|
||||
|
||||
return DEFAULT_LOCALE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the translation context for a space to use in the server components.
|
||||
*/
|
||||
export function getSpaceLanguage(customization: SiteCustomizationSettings): TranslationLanguage {
|
||||
export function getSpaceLanguage(context: GitBookAnyContext): TranslationLanguage {
|
||||
const fallback = languages[DEFAULT_LOCALE];
|
||||
|
||||
const locale = getCustomizationLocale(customization);
|
||||
const locale = getSpaceLocale(context);
|
||||
|
||||
let language = fallback;
|
||||
// @ts-ignore
|
||||
@@ -33,3 +52,7 @@ export function getSpaceLanguage(customization: SiteCustomizationSettings): Tran
|
||||
...language,
|
||||
};
|
||||
}
|
||||
|
||||
function checkIsValidLocale(locale: string): locale is TranslationLocale {
|
||||
return locale in languages;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ export function t(
|
||||
const [partToPush, partToReplace] = currentStringToReplace.split(`\${${i + 1}}`);
|
||||
parts.push(<React.Fragment key={`string-${i}`}>{partToPush}</React.Fragment>);
|
||||
parts.push(<React.Fragment key={`arg-${i}`}>{arg}</React.Fragment>);
|
||||
// @ts-expect-error
|
||||
currentStringToReplace = partToReplace;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -48,6 +48,7 @@ export const de = {
|
||||
close: 'Schließen',
|
||||
view: 'Anzeigen',
|
||||
edit_on_git: 'Bearbeiten auf ${1}',
|
||||
edit: 'Bearbeiten',
|
||||
notfound_title: 'Seite nicht gefunden',
|
||||
notfound_link:
|
||||
'Dieser Link verweist auf eine Seite, die entfernt wurde oder nicht mehr existiert.',
|
||||
@@ -81,6 +82,8 @@ export const de = {
|
||||
ai_chat_working: 'Arbeite...',
|
||||
ai_chat_context_badge: 'KI',
|
||||
ai_chat_error: 'Etwas ist schief gelaufen.',
|
||||
ai_chat_hold_message_1: 'Überlege es mir durch…',
|
||||
ai_chat_hold_message_2: 'Einen Moment…',
|
||||
ai_chat_context_title: 'Basierend auf Ihrem Kontext',
|
||||
ai_chat_context_description:
|
||||
'Der Assistent verwendet KI und Ihren Kontext, um Antworten zu generieren und Aktionen durchzuführen.',
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user