[READ-ONLY] Mirror of https://github.com/flo-bit/contrail. atproto backend in a bottle flo-bit.dev/contrail/
0

Configure Feed

Select the types of activity you want to include in your feed.

pubsub

Florian (Apr 22, 2026, 10:47 AM +0200) aec16dea 33a6faaa

+2319 -3409
+5 -2
package.json
··· 7 7 "files": [ 8 8 "dist", 9 9 "spaces-lexicon-templates/**/*.json", 10 - "community-lexicon-templates/**/*.json" 10 + "community-lexicon-templates/**/*.json", 11 + "realtime-lexicon-templates/**/*.json" 11 12 ], 12 13 "exports": { 13 14 ".": { ··· 35 36 "import": "./dist/publish.js" 36 37 }, 37 38 "./spaces-lexicon-templates/*.json": "./spaces-lexicon-templates/*.json", 38 - "./community-lexicon-templates/*.json": "./community-lexicon-templates/*.json" 39 + "./community-lexicon-templates/*.json": "./community-lexicon-templates/*.json", 40 + "./realtime-lexicon-templates/*.json": "./realtime-lexicon-templates/*.json" 39 41 }, 40 42 "repository": { 41 43 "type": "git", ··· 67 69 }, 68 70 "dependencies": { 69 71 "@atcute/atproto": "^3.1.10", 72 + "@atcute/cid": "^2.4.1", 70 73 "@atcute/client": "^4.2.1", 71 74 "@atcute/identity": "^1.1.4", 72 75 "@atcute/identity-resolver": "^1.2.2",
+20 -3406
pnpm-lock.yaml
··· 11 11 '@atcute/atproto': 12 12 specifier: ^3.1.10 13 13 version: 3.1.10 14 + '@atcute/cid': 15 + specifier: ^2.4.1 16 + version: 2.4.1 14 17 '@atcute/client': 15 18 specifier: ^4.2.1 16 19 version: 4.2.1 ··· 56 59 version: 8.20.0 57 60 tsup: 58 61 specifier: ^8.5.0 59 - version: 8.5.1(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3) 62 + version: 8.5.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3) 60 63 tsx: 61 64 specifier: ^4.21.0 62 65 version: 4.21.0 ··· 65 68 version: 5.9.3 66 69 vitest: 67 70 specifier: ^4.1.0 68 - version: 4.1.0(@types/node@25.5.0)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.0)(tsx@4.21.0)) 71 + version: 4.1.0(@types/node@25.5.0)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.0)(jiti@2.6.1)(tsx@4.21.0)) 69 72 wrangler: 70 73 specifier: ^4.63.0 71 74 version: 4.63.0(@cloudflare/workers-types@4.20260205.0) 72 75 73 - examples/sveltekit-cloudflare-workers: 74 - dependencies: 75 - '@atcute/jetstream': 76 - specifier: ^1.1.2 77 - version: 1.1.2 78 - '@atmo-dev/contrail': 79 - specifier: ^0.1.1 80 - version: 0.1.1(pg@8.20.0) 81 - '@foxui/core': 82 - specifier: ^0.9.1 83 - version: 0.9.1(@internationalized/date@3.12.0)(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(tailwindcss@4.2.2) 84 - '@foxui/social': 85 - specifier: ^0.8.10 86 - version: 0.8.10(@internationalized/date@3.12.0)(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(@tiptap/extension-code-block@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3))(@tiptap/extensions@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3))(highlight.js@11.11.1)(svelte@5.55.4(@typescript-eslint/types@8.58.2))(tailwindcss@4.2.2) 87 - '@foxui/time': 88 - specifier: ^0.8.5 89 - version: 0.8.5(@internationalized/date@3.12.0)(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(tailwindcss@4.2.2) 90 - valibot: 91 - specifier: ^1.3.1 92 - version: 1.3.1(typescript@6.0.2) 93 - devDependencies: 94 - '@atcute/atproto': 95 - specifier: ^3.1.10 96 - version: 3.1.10 97 - '@atcute/bluesky': 98 - specifier: ^3.3.0 99 - version: 3.3.2 100 - '@atcute/client': 101 - specifier: ^4.2.1 102 - version: 4.2.1 103 - '@atcute/identity-resolver': 104 - specifier: ^1.2.2 105 - version: 1.2.2(@atcute/identity@1.1.4) 106 - '@atcute/lex-cli': 107 - specifier: ^2.5.3 108 - version: 2.5.3 109 - '@atcute/lexicon-doc': 110 - specifier: ^2.1.2 111 - version: 2.1.2 112 - '@atcute/lexicons': 113 - specifier: ^1.2.9 114 - version: 1.2.9 115 - '@atcute/oauth-node-client': 116 - specifier: ^1.1.0 117 - version: 1.1.0 118 - '@atcute/tid': 119 - specifier: ^1.1.2 120 - version: 1.1.2 121 - '@cloudflare/workers-types': 122 - specifier: ^4.20260317.1 123 - version: 4.20260414.1 124 - '@eslint/compat': 125 - specifier: ^2.0.3 126 - version: 2.0.5(eslint@10.2.0(jiti@2.6.1)) 127 - '@eslint/js': 128 - specifier: ^10.0.1 129 - version: 10.0.1(eslint@10.2.0(jiti@2.6.1)) 130 - '@sveltejs/adapter-cloudflare': 131 - specifier: ^7.2.8 132 - version: 7.2.8(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(wrangler@4.82.2(@cloudflare/workers-types@4.20260414.1)) 133 - '@sveltejs/kit': 134 - specifier: ^2.55.0 135 - version: 2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)) 136 - '@sveltejs/vite-plugin-svelte': 137 - specifier: ^7.0.0 138 - version: 7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)) 139 - '@tailwindcss/forms': 140 - specifier: ^0.5.11 141 - version: 0.5.11(tailwindcss@4.2.2) 142 - '@tailwindcss/vite': 143 - specifier: ^4.2.2 144 - version: 4.2.2(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)) 145 - bits-ui: 146 - specifier: ^2.16.4 147 - version: 2.17.3(@internationalized/date@3.12.0)(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 148 - eslint: 149 - specifier: ^10.1.0 150 - version: 10.2.0(jiti@2.6.1) 151 - eslint-config-prettier: 152 - specifier: ^10.1.8 153 - version: 10.1.8(eslint@10.2.0(jiti@2.6.1)) 154 - eslint-plugin-svelte: 155 - specifier: ^3.16.0 156 - version: 3.17.0(eslint@10.2.0(jiti@2.6.1))(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 157 - globals: 158 - specifier: ^17.4.0 159 - version: 17.5.0 160 - prettier: 161 - specifier: ^3.8.1 162 - version: 3.8.1 163 - prettier-plugin-svelte: 164 - specifier: ^3.5.1 165 - version: 3.5.1(prettier@3.8.1)(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 166 - prettier-plugin-tailwindcss: 167 - specifier: ^0.7.2 168 - version: 0.7.2(prettier-plugin-svelte@3.5.1(prettier@3.8.1)(svelte@5.55.4(@typescript-eslint/types@8.58.2)))(prettier@3.8.1) 169 - svelte: 170 - specifier: ^5.55.0 171 - version: 5.55.4(@typescript-eslint/types@8.58.2) 172 - svelte-check: 173 - specifier: ^4.4.5 174 - version: 4.4.6(picomatch@4.0.4)(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2) 175 - tailwindcss: 176 - specifier: ^4.2.2 177 - version: 4.2.2 178 - tsx: 179 - specifier: ^4.21.0 180 - version: 4.21.0 181 - typescript: 182 - specifier: ^6.0.2 183 - version: 6.0.2 184 - typescript-eslint: 185 - specifier: ^8.57.2 186 - version: 8.58.2(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2) 187 - vite: 188 - specifier: ^8.0.3 189 - version: 8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0) 190 - wrangler: 191 - specifier: ^4.78.0 192 - version: 4.82.2(@cloudflare/workers-types@4.20260414.1) 193 - 194 76 packages: 195 77 196 78 '@atcute/atproto@3.1.10': 197 79 resolution: {integrity: sha512-+GKZpOc0PJcdWMQEkTfg/rSNDAAHxmAUGBl60g2az15etqJn5WaUPNGFE2sB7hKpwi5Ue2h/L0OacINcE/JDDQ==} 198 80 199 - '@atcute/atproto@3.1.11': 200 - resolution: {integrity: sha512-yh+ASvA+iHHQij6UeHEKp2+rwvFvQR8A6/5Dk/xvqDslIikWEFx9VlprNwm/clQIPl2bLuQg+LHS8uY9o5nFTA==} 201 - 202 - '@atcute/bluesky-richtext-segmenter@3.0.0': 203 - resolution: {integrity: sha512-NhZTUKtFpeBBbILwAcxj5u4RobIoHOmGw3CAaaEFNebKYSvmTecrXJ7XufHw5DFOUdr8SiKXQVRQxGAxulMNWg==} 204 - 205 - '@atcute/bluesky@3.3.2': 206 - resolution: {integrity: sha512-BqVXghoNFbBm38hveWqPQQ25VZxHXmqYk5h0NG8YFiwNLrI8Ww1nXHAJzS65zyHwV5QeSA6EDFaTrQwm+7cCFQ==} 207 - 208 81 '@atcute/car@5.1.1': 209 82 resolution: {integrity: sha512-MeRUJNXYgAHrJZw7mMoZJb9xIqv3LZLQw90rRRAVAo8SGNdICwyqe6Bf2LGesX73QM04MBuYO6Kqhvold3TFfg==} 210 83 ··· 256 129 '@atcute/multibase@1.2.0': 257 130 resolution: {integrity: sha512-ZK2GRra+qIYq9nNuQB52m2ul0hOmCQEtPobGfTSUxm7pF0OGEkWGkWHugFhNEDVzHzTwPxHp6VGotdZFue4lYQ==} 258 131 259 - '@atcute/oauth-crypto@0.1.0': 260 - resolution: {integrity: sha512-qZYDCNLF/4B6AndYT1rsQelN8621AC5u/sL5PHvlr/qqAbmmUwCBGjEgRSyZtHE1AqD60VNiSMlOgAuEQTSl3w==} 261 - 262 - '@atcute/oauth-keyset@0.1.0': 263 - resolution: {integrity: sha512-+wqT/+I5Lg9VzKnKY3g88+N45xbq+wsdT6bHDGqCVa2u57gRvolFF4dY+weMfc/OX641BIZO6/o+zFtKBsMQnQ==} 264 - 265 - '@atcute/oauth-node-client@1.1.0': 266 - resolution: {integrity: sha512-xCp/VfjtvTeKscKR/oI2hdMTp1/DaF/7ll8b6yZOCgbKlVDDfhCn5mmKNVARGTNaoywxrXG3XffbWCIx3/E87w==} 267 - 268 - '@atcute/oauth-types@0.1.1': 269 - resolution: {integrity: sha512-u+3KMjse3Uc/9hDyilu1QVN7IpcnjVXgRzhddzBB8Uh6wePHNVBDdi9wQvFTVVA3zmxtMJVptXRyLLg6Ou9bqg==} 270 - 271 132 '@atcute/repo@0.1.3': 272 133 resolution: {integrity: sha512-kN4gkrkQgJwI5xkVQ9zSdI8ULR47uH48EdJdjMvKAWsSDu8zKYd8ZQ6n778qa6o3WYEq02v9QVf7pzeU+3fYVA==} 273 134 274 - '@atcute/tid@1.1.2': 275 - resolution: {integrity: sha512-bmPuOX/TOfcm/vsK9vM98spjkcx2wgd9S2PeK5oLgEr8IbNRPq7iMCAPzOL1nu5XAW3LlkOYQEbYRcw5vcQ37w==} 276 - 277 - '@atcute/time-ms@1.3.2': 278 - resolution: {integrity: sha512-F+qOyR9pO55g1d/QmN+Gr+fimoUQQLusdGSB6pjV0wW5KPILR4oQ4e2ZhWzqUbeHLAgWvgoTTMsMDdz62Xa2tg==} 279 - 280 135 '@atcute/uint8array@1.1.1': 281 136 resolution: {integrity: sha512-3LsC8XB8TKe9q/5hOA5sFuzGaIFdJZJNewC5OKa3o/eU6+K7JR6see9Zy2JbQERNVnRl11EzbNov1efgLMAs4g==} 282 137 ··· 295 150 '@atcute/xrpc-server@0.1.12': 296 151 resolution: {integrity: sha512-70KIerQlljp5+s6t0u6YNN9klEboQUZa2hhoi/hmXIO1cIKEORettTMctnyjfcCJaSfAuj42dxPu51GTZBlm8w==} 297 152 298 - '@atmo-dev/contrail@0.1.1': 299 - resolution: {integrity: sha512-7BdLYjHHGC2EKlT/p3KszJAE6Pv1FPPuLVG+eYRpXSTF6iwrk/FVA0Dep7lTowbLlo5mQBpbEpo2CrQtUZAPfQ==} 300 - peerDependencies: 301 - pg: ^8.0.0 302 - peerDependenciesMeta: 303 - pg: 304 - optional: true 305 - 306 153 '@babel/runtime@7.29.2': 307 154 resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} 308 155 engines: {node: '>=6.9.0'} ··· 379 226 workerd: 380 227 optional: true 381 228 382 - '@cloudflare/unenv-preset@2.16.0': 383 - resolution: {integrity: sha512-8ovsRpwzPoEqPUzoErAYVv8l3FMZNeBVQfJTvtzP4AgLSRGZISRfuChFxHWUQd3n6cnrwkuTGxT+2cGo8EsyYg==} 384 - peerDependencies: 385 - unenv: 2.0.0-rc.24 386 - workerd: 1.20260301.1 || ~1.20260302.1 || ~1.20260303.1 || ~1.20260304.1 || >1.20260305.0 <2.0.0-0 387 - peerDependenciesMeta: 388 - workerd: 389 - optional: true 390 - 391 229 '@cloudflare/workerd-darwin-64@1.20260205.0': 392 230 resolution: {integrity: sha512-ToOItqcirmWPwR+PtT+Q4bdjTn/63ZxhJKEfW4FNn7FxMTS1Tw5dml0T0mieOZbCpcvY8BdvPKFCSlJuI8IVHQ==} 393 231 engines: {node: '>=16'} 394 232 cpu: [x64] 395 233 os: [darwin] 396 234 397 - '@cloudflare/workerd-darwin-64@1.20260410.1': 398 - resolution: {integrity: sha512-0sh6xPmCKUfv/lUklP1dfyeKxCuEZGS0HeduxnucL8ECxSgAdWTOD42h/lQTwZCIiWtyHB+ZNB9hsS2Mlf0tMQ==} 399 - engines: {node: '>=16'} 400 - cpu: [x64] 401 - os: [darwin] 402 - 403 235 '@cloudflare/workerd-darwin-arm64@1.20260205.0': 404 236 resolution: {integrity: sha512-402ZqLz+LrG0NDXp7Hn7IZbI0DyhjNfjAlVenb0K3yod9KCuux0u3NksNBvqJx0mIGHvVR4K05h+jfT5BTHqGA==} 405 237 engines: {node: '>=16'} 406 238 cpu: [arm64] 407 239 os: [darwin] 408 240 409 - '@cloudflare/workerd-darwin-arm64@1.20260410.1': 410 - resolution: {integrity: sha512-r2On29gPvlk/eiH/OpeUT23xoB8W8D1PHr8lul5nyxElLqvh3yNxZUnJWrbcOl+ubfrvw7+jFwgopMe17xyf0g==} 411 - engines: {node: '>=16'} 412 - cpu: [arm64] 413 - os: [darwin] 414 - 415 241 '@cloudflare/workerd-linux-64@1.20260205.0': 416 242 resolution: {integrity: sha512-rz9jBzazIA18RHY+osa19hvsPfr0LZI1AJzIjC6UqkKKphcTpHBEQ25Xt8cIA34ivMIqeENpYnnmpDFesLkfcQ==} 417 243 engines: {node: '>=16'} 418 244 cpu: [x64] 419 245 os: [linux] 420 246 421 - '@cloudflare/workerd-linux-64@1.20260410.1': 422 - resolution: {integrity: sha512-qWORRcAzPZeHJjrcYBNZTN6Y9l+iZQUz4KBdWbNrM6My4CpNrXS5kErPR373vG//5QPaDGwMXgBqyn9xfzarJQ==} 423 - engines: {node: '>=16'} 424 - cpu: [x64] 425 - os: [linux] 426 - 427 247 '@cloudflare/workerd-linux-arm64@1.20260205.0': 428 248 resolution: {integrity: sha512-jr6cKpMM/DBEbL+ATJ9rYue758CKp0SfA/nXt5vR32iINVJrb396ye9iat2y9Moa/PgPKnTrFgmT6urUmG3IUg==} 429 - engines: {node: '>=16'} 430 - cpu: [arm64] 431 - os: [linux] 432 - 433 - '@cloudflare/workerd-linux-arm64@1.20260410.1': 434 - resolution: {integrity: sha512-jQfuHL4mnGDFyomSS3JNs9TpTvCu6Vzz2QSNCfJRstMzTICUFLMc4Vp/xKK+M5xkb0PoAu/G0hHx7jrxB2j+OQ==} 435 249 engines: {node: '>=16'} 436 250 cpu: [arm64] 437 251 os: [linux] 438 252 439 253 '@cloudflare/workerd-windows-64@1.20260205.0': 440 254 resolution: {integrity: sha512-SMPW5jCZYOG7XFIglSlsgN8ivcl0pCrSAYxCwxtWvZ88whhcDB/aISNtiQiDZujPH8tIo2hE5dEkxW7tGEwc3A==} 441 - engines: {node: '>=16'} 442 - cpu: [x64] 443 - os: [win32] 444 - 445 - '@cloudflare/workerd-windows-64@1.20260410.1': 446 - resolution: {integrity: sha512-h8q/nbheDqpknY7AAOz19MuQkZAR1/bnoZnKipyeUPXt5No+y6HlTtva9Bohx5Fhc1MW2CX2MQVdb55qtkkqZQ==} 447 255 engines: {node: '>=16'} 448 256 cpu: [x64] 449 257 os: [win32] ··· 451 259 '@cloudflare/workers-types@4.20260205.0': 452 260 resolution: {integrity: sha512-LTnpvcodmiuMwxmbrO2Fd0+Avbm2UVLLJxT8J2pRWPfoM44gmbIecXwOPZmDAMeadKWrBsQ+B0sloQAhUu5fpA==} 453 261 454 - '@cloudflare/workers-types@4.20260414.1': 455 - resolution: {integrity: sha512-E2wgYT1ywoM1M68nmVpxKdKzXsZm5vOu2plsqUixlK7YIydqsw31dZ+EjwXnAsdEjLaYC6XfsJayil8AEhyaBQ==} 456 - 457 262 '@cspotcode/source-map-support@0.8.1': 458 263 resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} 459 264 engines: {node: '>=12'} 460 - 461 - '@emnapi/core@1.9.0': 462 - resolution: {integrity: sha512-0DQ98G9ZQZOxfUcQn1waV2yS8aWdZ6kJMbYCJB3oUBecjWYO1fqJ+a1DRfPF3O5JEkwqwP1A9QEN/9mYm2Yd0w==} 463 265 464 266 '@emnapi/core@1.9.2': 465 267 resolution: {integrity: sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==} ··· 470 272 '@emnapi/runtime@1.9.2': 471 273 resolution: {integrity: sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==} 472 274 473 - '@emnapi/wasi-threads@1.2.0': 474 - resolution: {integrity: sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==} 475 - 476 275 '@emnapi/wasi-threads@1.2.1': 477 276 resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} 478 277 ··· 482 281 cpu: [ppc64] 483 282 os: [aix] 484 283 485 - '@esbuild/aix-ppc64@0.27.3': 486 - resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} 487 - engines: {node: '>=18'} 488 - cpu: [ppc64] 489 - os: [aix] 490 - 491 284 '@esbuild/android-arm64@0.27.0': 492 285 resolution: {integrity: sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==} 493 286 engines: {node: '>=18'} 494 287 cpu: [arm64] 495 288 os: [android] 496 289 497 - '@esbuild/android-arm64@0.27.3': 498 - resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==} 499 - engines: {node: '>=18'} 500 - cpu: [arm64] 501 - os: [android] 502 - 503 290 '@esbuild/android-arm@0.27.0': 504 291 resolution: {integrity: sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==} 505 - engines: {node: '>=18'} 506 - cpu: [arm] 507 - os: [android] 508 - 509 - '@esbuild/android-arm@0.27.3': 510 - resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==} 511 292 engines: {node: '>=18'} 512 293 cpu: [arm] 513 294 os: [android] ··· 518 299 cpu: [x64] 519 300 os: [android] 520 301 521 - '@esbuild/android-x64@0.27.3': 522 - resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==} 523 - engines: {node: '>=18'} 524 - cpu: [x64] 525 - os: [android] 526 - 527 302 '@esbuild/darwin-arm64@0.27.0': 528 303 resolution: {integrity: sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==} 529 304 engines: {node: '>=18'} 530 305 cpu: [arm64] 531 306 os: [darwin] 532 307 533 - '@esbuild/darwin-arm64@0.27.3': 534 - resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==} 535 - engines: {node: '>=18'} 536 - cpu: [arm64] 537 - os: [darwin] 538 - 539 308 '@esbuild/darwin-x64@0.27.0': 540 309 resolution: {integrity: sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==} 541 310 engines: {node: '>=18'} 542 311 cpu: [x64] 543 312 os: [darwin] 544 313 545 - '@esbuild/darwin-x64@0.27.3': 546 - resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==} 547 - engines: {node: '>=18'} 548 - cpu: [x64] 549 - os: [darwin] 550 - 551 314 '@esbuild/freebsd-arm64@0.27.0': 552 315 resolution: {integrity: sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==} 553 316 engines: {node: '>=18'} 554 317 cpu: [arm64] 555 318 os: [freebsd] 556 319 557 - '@esbuild/freebsd-arm64@0.27.3': 558 - resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==} 559 - engines: {node: '>=18'} 560 - cpu: [arm64] 561 - os: [freebsd] 562 - 563 320 '@esbuild/freebsd-x64@0.27.0': 564 321 resolution: {integrity: sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==} 565 322 engines: {node: '>=18'} 566 323 cpu: [x64] 567 324 os: [freebsd] 568 325 569 - '@esbuild/freebsd-x64@0.27.3': 570 - resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==} 571 - engines: {node: '>=18'} 572 - cpu: [x64] 573 - os: [freebsd] 574 - 575 326 '@esbuild/linux-arm64@0.27.0': 576 327 resolution: {integrity: sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==} 577 328 engines: {node: '>=18'} 578 329 cpu: [arm64] 579 330 os: [linux] 580 331 581 - '@esbuild/linux-arm64@0.27.3': 582 - resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==} 583 - engines: {node: '>=18'} 584 - cpu: [arm64] 585 - os: [linux] 586 - 587 332 '@esbuild/linux-arm@0.27.0': 588 333 resolution: {integrity: sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==} 589 334 engines: {node: '>=18'} 590 335 cpu: [arm] 591 336 os: [linux] 592 337 593 - '@esbuild/linux-arm@0.27.3': 594 - resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==} 595 - engines: {node: '>=18'} 596 - cpu: [arm] 597 - os: [linux] 598 - 599 338 '@esbuild/linux-ia32@0.27.0': 600 339 resolution: {integrity: sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==} 601 340 engines: {node: '>=18'} 602 341 cpu: [ia32] 603 342 os: [linux] 604 343 605 - '@esbuild/linux-ia32@0.27.3': 606 - resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==} 607 - engines: {node: '>=18'} 608 - cpu: [ia32] 609 - os: [linux] 610 - 611 344 '@esbuild/linux-loong64@0.27.0': 612 345 resolution: {integrity: sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==} 613 - engines: {node: '>=18'} 614 - cpu: [loong64] 615 - os: [linux] 616 - 617 - '@esbuild/linux-loong64@0.27.3': 618 - resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==} 619 346 engines: {node: '>=18'} 620 347 cpu: [loong64] 621 348 os: [linux] ··· 626 353 cpu: [mips64el] 627 354 os: [linux] 628 355 629 - '@esbuild/linux-mips64el@0.27.3': 630 - resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==} 631 - engines: {node: '>=18'} 632 - cpu: [mips64el] 633 - os: [linux] 634 - 635 356 '@esbuild/linux-ppc64@0.27.0': 636 357 resolution: {integrity: sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==} 637 358 engines: {node: '>=18'} 638 359 cpu: [ppc64] 639 360 os: [linux] 640 361 641 - '@esbuild/linux-ppc64@0.27.3': 642 - resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==} 643 - engines: {node: '>=18'} 644 - cpu: [ppc64] 645 - os: [linux] 646 - 647 362 '@esbuild/linux-riscv64@0.27.0': 648 363 resolution: {integrity: sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==} 649 364 engines: {node: '>=18'} 650 365 cpu: [riscv64] 651 366 os: [linux] 652 367 653 - '@esbuild/linux-riscv64@0.27.3': 654 - resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==} 655 - engines: {node: '>=18'} 656 - cpu: [riscv64] 657 - os: [linux] 658 - 659 368 '@esbuild/linux-s390x@0.27.0': 660 369 resolution: {integrity: sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==} 661 370 engines: {node: '>=18'} 662 371 cpu: [s390x] 663 372 os: [linux] 664 373 665 - '@esbuild/linux-s390x@0.27.3': 666 - resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==} 667 - engines: {node: '>=18'} 668 - cpu: [s390x] 669 - os: [linux] 670 - 671 374 '@esbuild/linux-x64@0.27.0': 672 375 resolution: {integrity: sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==} 673 376 engines: {node: '>=18'} 674 377 cpu: [x64] 675 378 os: [linux] 676 379 677 - '@esbuild/linux-x64@0.27.3': 678 - resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==} 679 - engines: {node: '>=18'} 680 - cpu: [x64] 681 - os: [linux] 682 - 683 380 '@esbuild/netbsd-arm64@0.27.0': 684 381 resolution: {integrity: sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==} 685 382 engines: {node: '>=18'} 686 383 cpu: [arm64] 687 384 os: [netbsd] 688 385 689 - '@esbuild/netbsd-arm64@0.27.3': 690 - resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==} 691 - engines: {node: '>=18'} 692 - cpu: [arm64] 693 - os: [netbsd] 694 - 695 386 '@esbuild/netbsd-x64@0.27.0': 696 387 resolution: {integrity: sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==} 697 388 engines: {node: '>=18'} 698 389 cpu: [x64] 699 390 os: [netbsd] 700 391 701 - '@esbuild/netbsd-x64@0.27.3': 702 - resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==} 703 - engines: {node: '>=18'} 704 - cpu: [x64] 705 - os: [netbsd] 706 - 707 392 '@esbuild/openbsd-arm64@0.27.0': 708 393 resolution: {integrity: sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==} 709 394 engines: {node: '>=18'} 710 395 cpu: [arm64] 711 396 os: [openbsd] 712 397 713 - '@esbuild/openbsd-arm64@0.27.3': 714 - resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==} 715 - engines: {node: '>=18'} 716 - cpu: [arm64] 717 - os: [openbsd] 718 - 719 398 '@esbuild/openbsd-x64@0.27.0': 720 399 resolution: {integrity: sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==} 721 400 engines: {node: '>=18'} 722 401 cpu: [x64] 723 402 os: [openbsd] 724 403 725 - '@esbuild/openbsd-x64@0.27.3': 726 - resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==} 727 - engines: {node: '>=18'} 728 - cpu: [x64] 729 - os: [openbsd] 730 - 731 404 '@esbuild/openharmony-arm64@0.27.0': 732 405 resolution: {integrity: sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==} 733 - engines: {node: '>=18'} 734 - cpu: [arm64] 735 - os: [openharmony] 736 - 737 - '@esbuild/openharmony-arm64@0.27.3': 738 - resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==} 739 406 engines: {node: '>=18'} 740 407 cpu: [arm64] 741 408 os: [openharmony] 742 409 743 410 '@esbuild/sunos-x64@0.27.0': 744 411 resolution: {integrity: sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==} 745 - engines: {node: '>=18'} 746 - cpu: [x64] 747 - os: [sunos] 748 - 749 - '@esbuild/sunos-x64@0.27.3': 750 - resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==} 751 412 engines: {node: '>=18'} 752 413 cpu: [x64] 753 414 os: [sunos] ··· 758 419 cpu: [arm64] 759 420 os: [win32] 760 421 761 - '@esbuild/win32-arm64@0.27.3': 762 - resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==} 763 - engines: {node: '>=18'} 764 - cpu: [arm64] 765 - os: [win32] 766 - 767 422 '@esbuild/win32-ia32@0.27.0': 768 423 resolution: {integrity: sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==} 769 424 engines: {node: '>=18'} 770 425 cpu: [ia32] 771 426 os: [win32] 772 427 773 - '@esbuild/win32-ia32@0.27.3': 774 - resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==} 775 - engines: {node: '>=18'} 776 - cpu: [ia32] 777 - os: [win32] 778 - 779 428 '@esbuild/win32-x64@0.27.0': 780 429 resolution: {integrity: sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==} 781 430 engines: {node: '>=18'} 782 431 cpu: [x64] 783 432 os: [win32] 784 433 785 - '@esbuild/win32-x64@0.27.3': 786 - resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==} 787 - engines: {node: '>=18'} 788 - cpu: [x64] 789 - os: [win32] 790 - 791 - '@eslint-community/eslint-utils@4.9.1': 792 - resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} 793 - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 794 - peerDependencies: 795 - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 796 - 797 - '@eslint-community/regexpp@4.12.2': 798 - resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} 799 - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} 800 - 801 - '@eslint/compat@2.0.5': 802 - resolution: {integrity: sha512-IbHDbHJfkVNv6xjlET8AIVo/K1NQt7YT4Rp6ok/clyBGcpRx1l6gv0Rq3vBvYfPJIZt6ODf66Zq08FJNDpnzgg==} 803 - engines: {node: ^20.19.0 || ^22.13.0 || >=24} 804 - peerDependencies: 805 - eslint: ^8.40 || 9 || 10 806 - peerDependenciesMeta: 807 - eslint: 808 - optional: true 809 - 810 - '@eslint/config-array@0.23.5': 811 - resolution: {integrity: sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==} 812 - engines: {node: ^20.19.0 || ^22.13.0 || >=24} 813 - 814 - '@eslint/config-helpers@0.5.5': 815 - resolution: {integrity: sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==} 816 - engines: {node: ^20.19.0 || ^22.13.0 || >=24} 817 - 818 - '@eslint/core@1.2.1': 819 - resolution: {integrity: sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==} 820 - engines: {node: ^20.19.0 || ^22.13.0 || >=24} 821 - 822 - '@eslint/js@10.0.1': 823 - resolution: {integrity: sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==} 824 - engines: {node: ^20.19.0 || ^22.13.0 || >=24} 825 - peerDependencies: 826 - eslint: ^10.0.0 827 - peerDependenciesMeta: 828 - eslint: 829 - optional: true 830 - 831 - '@eslint/object-schema@3.0.5': 832 - resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==} 833 - engines: {node: ^20.19.0 || ^22.13.0 || >=24} 834 - 835 - '@eslint/plugin-kit@0.7.1': 836 - resolution: {integrity: sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ==} 837 - engines: {node: ^20.19.0 || ^22.13.0 || >=24} 838 - 839 - '@floating-ui/core@1.7.5': 840 - resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} 841 - 842 - '@floating-ui/dom@1.7.6': 843 - resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==} 844 - 845 - '@floating-ui/utils@0.2.11': 846 - resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} 847 - 848 - '@fontsource-variable/geist-mono@5.2.7': 849 - resolution: {integrity: sha512-ZKlZ5sjtalb2TwXKs400mAGDlt/+2ENLNySPx0wTz3bP3mWARCsUW+rpxzZc7e05d2qGch70pItt3K4qttbIYA==} 850 - 851 - '@fontsource-variable/geist@5.2.8': 852 - resolution: {integrity: sha512-cJ6m9e+8MQ5dCYJsLylfZrgBh6KkG4bOLckB35Tr9J/EqdkEM6QllH5PxqP1dhTvFup+HtMRPuz9xOjxXJggxw==} 853 - 854 - '@foxui/core@0.9.1': 855 - resolution: {integrity: sha512-GnMegqx5gz71U85FK85ayEEHuD3bvpNET8HeNsJU1Gj+OVkKKvUY9q/XqmCY3tsfEqY0Mv+RM1iQSnsZn5LZ6w==} 856 - peerDependencies: 857 - svelte: '>=5' 858 - tailwindcss: '>=3' 859 - 860 - '@foxui/social@0.8.10': 861 - resolution: {integrity: sha512-d9FB1BjWFbvldNlrXogdJU/a90dDdNqvBWGAkLRK2i7iiBAaWkKceWL3xc8N5+79+hfD8Ydg4ptCk3wx3bkguw==} 862 - peerDependencies: 863 - svelte: '>=5' 864 - tailwindcss: '>=3' 865 - 866 - '@foxui/text@0.8.5': 867 - resolution: {integrity: sha512-K7XsJGWdyRdXlRxjD8Z4TQ9xy7T/rVrB/z+U0YGGIjIER1DQGLawPwBQ5WXYQeNCBS1ab8mG67uFZw2sA5aFPQ==} 868 - peerDependencies: 869 - svelte: '>=5' 870 - tailwindcss: '>=3' 871 - 872 - '@foxui/time@0.8.5': 873 - resolution: {integrity: sha512-InXhgKZW4URArJWW87hblhHMAoNii0iueKCxei72SCvlABZ/y5QoX/ewhrgk7/47qbfrlgyqBzshDtF60kTqcg==} 874 - peerDependencies: 875 - svelte: '>=5' 876 - tailwindcss: '>=3' 877 - 878 - '@humanfs/core@0.19.1': 879 - resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} 880 - engines: {node: '>=18.18.0'} 881 - 882 - '@humanfs/node@0.16.7': 883 - resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} 884 - engines: {node: '>=18.18.0'} 885 - 886 - '@humanwhocodes/module-importer@1.0.1': 887 - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} 888 - engines: {node: '>=12.22'} 889 - 890 - '@humanwhocodes/retry@0.4.3': 891 - resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} 892 - engines: {node: '>=18.18'} 893 - 894 434 '@img/colour@1.0.0': 895 435 resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==} 896 436 engines: {node: '>=18'} ··· 1037 577 '@types/node': 1038 578 optional: true 1039 579 1040 - '@internationalized/date@3.12.0': 1041 - resolution: {integrity: sha512-/PyIMzK29jtXaGU23qTvNZxvBXRtKbNnGDFD+PY6CZw/Y8Ex8pFUzkuCJCG9aOqmShjqhS9mPqP6Dk5onQY8rQ==} 1042 - 1043 - '@jis3r/icons@2.7.0': 1044 - resolution: {integrity: sha512-RXee+W1AoWFHtFliLZ7SQxVopAezmCH0xU45HKTvvpDQ+6Y3g6tUHvKOK16J52TM8YsN4WDnsiOmcwau+bHmwg==} 1045 - peerDependencies: 1046 - svelte: ^5.0.0 1047 - 1048 580 '@jridgewell/gen-mapping@0.3.13': 1049 581 resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} 1050 - 1051 - '@jridgewell/remapping@2.3.5': 1052 - resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} 1053 582 1054 583 '@jridgewell/resolve-uri@3.1.2': 1055 584 resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} ··· 1064 593 '@jridgewell/trace-mapping@0.3.9': 1065 594 resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} 1066 595 1067 - '@lucide/svelte@1.8.0': 1068 - resolution: {integrity: sha512-+zYQUKqEOVP5lxbGmxL1OVgGMQtRK91eIJ0bR+3Cr1ts4oQEsQfxyzzd5X47psJlblAuGFrl2xm4YuATjR9oaA==} 1069 - peerDependencies: 1070 - svelte: ^5 1071 - 1072 596 '@manypkg/find-root@1.1.0': 1073 597 resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} 1074 598 ··· 1080 604 1081 605 '@mary-ext/simple-event-emitter@1.0.0': 1082 606 resolution: {integrity: sha512-meA/zJZKIN1RVBNEYIbjufkUrW7/tRjHH60FjolpG1ixJKo76TB208qefQLNdOVDA7uIG0CGEDuhmMirtHKLAg==} 1083 - 1084 - '@napi-rs/wasm-runtime@1.1.1': 1085 - resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} 1086 607 1087 608 '@napi-rs/wasm-runtime@1.1.3': 1088 609 resolution: {integrity: sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ==} ··· 1105 626 resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} 1106 627 engines: {node: '>= 8'} 1107 628 1108 - '@number-flow/svelte@0.4.0': 1109 - resolution: {integrity: sha512-9tnowrlZlBV3IVe3Gm1V7yXSf4Ugag2k7iW45xqb04HXSa1ApEImopvGWAjJpHDvS849o+UCb0YH461Mtde9lA==} 1110 - peerDependencies: 1111 - svelte: ^4 || ^5 1112 - 1113 629 '@optique/core@0.6.11': 1114 630 resolution: {integrity: sha512-GVLFihzBA1j78NFlkU5N1Lu0jRqET0k6Z66WK8VQKG/a3cxmCInVGSKMIdQG8i6pgC8wD5OizF6Y3QMztmhAxg==} 1115 631 engines: {bun: '>=1.2.0', deno: '>=2.3.0', node: '>=20.0.0'} ··· 1118 634 resolution: {integrity: sha512-tsXBEygGSzNpFK2gjsRlXBn7FiScUeLFWIZNpoAZ8iG85Km0/3K9xgqlQAXoQ+uEZBe4XplnzyCDvmEgbyNT8w==} 1119 635 engines: {bun: '>=1.2.0', deno: '>=2.3.0', node: '>=20.0.0'} 1120 636 1121 - '@oxc-project/runtime@0.115.0': 1122 - resolution: {integrity: sha512-Rg8Wlt5dCbXhQnsXPrkOjL1DTSvXLgb2R/KYfnf1/K+R0k6UMLEmbQXPM+kwrWqSmWA2t0B1EtHy2/3zikQpvQ==} 1123 - engines: {node: ^20.19.0 || >=22.12.0} 1124 - 1125 - '@oxc-project/types@0.115.0': 1126 - resolution: {integrity: sha512-4n91DKnebUS4yjUHl2g3/b2T+IUdCfmoZGhmwsovZCDaJSs+QkVAM+0AqqTxHSsHfeiMuueT75cZaZcT/m0pSw==} 1127 - 1128 637 '@oxc-project/types@0.124.0': 1129 638 resolution: {integrity: sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==} 1130 - 1131 - '@polka/url@1.0.0-next.29': 1132 - resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} 1133 639 1134 640 '@poppinss/colors@4.1.6': 1135 641 resolution: {integrity: sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==} ··· 1140 646 '@poppinss/exception@1.2.3': 1141 647 resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==} 1142 648 1143 - '@remirror/core-constants@3.0.0': 1144 - resolution: {integrity: sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==} 1145 - 1146 649 '@rolldown/binding-android-arm64@1.0.0-rc.15': 1147 650 resolution: {integrity: sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA==} 1148 651 engines: {node: ^20.19.0 || >=22.12.0} 1149 652 cpu: [arm64] 1150 653 os: [android] 1151 654 1152 - '@rolldown/binding-android-arm64@1.0.0-rc.9': 1153 - resolution: {integrity: sha512-lcJL0bN5hpgJfSIz/8PIf02irmyL43P+j1pTCfbD1DbLkmGRuFIA4DD3B3ZOvGqG0XiVvRznbKtN0COQVaKUTg==} 1154 - engines: {node: ^20.19.0 || >=22.12.0} 1155 - cpu: [arm64] 1156 - os: [android] 1157 - 1158 655 '@rolldown/binding-darwin-arm64@1.0.0-rc.15': 1159 656 resolution: {integrity: sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg==} 1160 657 engines: {node: ^20.19.0 || >=22.12.0} 1161 658 cpu: [arm64] 1162 659 os: [darwin] 1163 660 1164 - '@rolldown/binding-darwin-arm64@1.0.0-rc.9': 1165 - resolution: {integrity: sha512-J7Zk3kLYFsLtuH6U+F4pS2sYVzac0qkjcO5QxHS7OS7yZu2LRs+IXo+uvJ/mvpyUljDJ3LROZPoQfgBIpCMhdQ==} 1166 - engines: {node: ^20.19.0 || >=22.12.0} 1167 - cpu: [arm64] 1168 - os: [darwin] 1169 - 1170 661 '@rolldown/binding-darwin-x64@1.0.0-rc.15': 1171 662 resolution: {integrity: sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw==} 1172 663 engines: {node: ^20.19.0 || >=22.12.0} 1173 664 cpu: [x64] 1174 665 os: [darwin] 1175 666 1176 - '@rolldown/binding-darwin-x64@1.0.0-rc.9': 1177 - resolution: {integrity: sha512-iwtmmghy8nhfRGeNAIltcNXzD0QMNaaA5U/NyZc1Ia4bxrzFByNMDoppoC+hl7cDiUq5/1CnFthpT9n+UtfFyg==} 1178 - engines: {node: ^20.19.0 || >=22.12.0} 1179 - cpu: [x64] 1180 - os: [darwin] 1181 - 1182 667 '@rolldown/binding-freebsd-x64@1.0.0-rc.15': 1183 668 resolution: {integrity: sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw==} 1184 669 engines: {node: ^20.19.0 || >=22.12.0} 1185 670 cpu: [x64] 1186 671 os: [freebsd] 1187 672 1188 - '@rolldown/binding-freebsd-x64@1.0.0-rc.9': 1189 - resolution: {integrity: sha512-DLFYI78SCiZr5VvdEplsVC2Vx53lnA4/Ga5C65iyldMVaErr86aiqCoNBLl92PXPfDtUYjUh+xFFor40ueNs4Q==} 1190 - engines: {node: ^20.19.0 || >=22.12.0} 1191 - cpu: [x64] 1192 - os: [freebsd] 1193 - 1194 673 '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15': 1195 674 resolution: {integrity: sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA==} 1196 675 engines: {node: ^20.19.0 || >=22.12.0} 1197 676 cpu: [arm] 1198 677 os: [linux] 1199 678 1200 - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.9': 1201 - resolution: {integrity: sha512-CsjTmTwd0Hri6iTw/DRMK7kOZ7FwAkrO4h8YWKoX/kcj833e4coqo2wzIFywtch/8Eb5enQ/lwLM7w6JX1W5RQ==} 1202 - engines: {node: ^20.19.0 || >=22.12.0} 1203 - cpu: [arm] 1204 - os: [linux] 1205 - 1206 679 '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15': 1207 680 resolution: {integrity: sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w==} 1208 - engines: {node: ^20.19.0 || >=22.12.0} 1209 - cpu: [arm64] 1210 - os: [linux] 1211 - 1212 - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.9': 1213 - resolution: {integrity: sha512-2x9O2JbSPxpxMDhP9Z74mahAStibTlrBMW0520+epJH5sac7/LwZW5Bmg/E6CXuEF53JJFW509uP+lSedaUNxg==} 1214 681 engines: {node: ^20.19.0 || >=22.12.0} 1215 682 cpu: [arm64] 1216 683 os: [linux] ··· 1221 688 cpu: [arm64] 1222 689 os: [linux] 1223 690 1224 - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.9': 1225 - resolution: {integrity: sha512-JA1QRW31ogheAIRhIg9tjMfsYbglXXYGNPLdPEYrwFxdbkQCAzvpSCSHCDWNl4hTtrol8WeboCSEpjdZK8qrCg==} 1226 - engines: {node: ^20.19.0 || >=22.12.0} 1227 - cpu: [arm64] 1228 - os: [linux] 1229 - 1230 691 '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15': 1231 692 resolution: {integrity: sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ==} 1232 693 engines: {node: ^20.19.0 || >=22.12.0} 1233 694 cpu: [ppc64] 1234 695 os: [linux] 1235 696 1236 - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.9': 1237 - resolution: {integrity: sha512-aOKU9dJheda8Kj8Y3w9gnt9QFOO+qKPAl8SWd7JPHP+Cu0EuDAE5wokQubLzIDQWg2myXq2XhTpOVS07qqvT+w==} 1238 - engines: {node: ^20.19.0 || >=22.12.0} 1239 - cpu: [ppc64] 1240 - os: [linux] 1241 - 1242 697 '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15': 1243 698 resolution: {integrity: sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ==} 1244 699 engines: {node: ^20.19.0 || >=22.12.0} 1245 700 cpu: [s390x] 1246 701 os: [linux] 1247 702 1248 - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.9': 1249 - resolution: {integrity: sha512-OalO94fqj7IWRn3VdXWty75jC5dk4C197AWEuMhIpvVv2lw9fiPhud0+bW2ctCxb3YoBZor71QHbY+9/WToadA==} 1250 - engines: {node: ^20.19.0 || >=22.12.0} 1251 - cpu: [s390x] 1252 - os: [linux] 1253 - 1254 703 '@rolldown/binding-linux-x64-gnu@1.0.0-rc.15': 1255 704 resolution: {integrity: sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA==} 1256 705 engines: {node: ^20.19.0 || >=22.12.0} 1257 706 cpu: [x64] 1258 707 os: [linux] 1259 708 1260 - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.9': 1261 - resolution: {integrity: sha512-cVEl1vZtBsBZna3YMjGXNvnYYrOJ7RzuWvZU0ffvJUexWkukMaDuGhUXn0rjnV0ptzGVkvc+vW9Yqy6h8YX4pg==} 1262 - engines: {node: ^20.19.0 || >=22.12.0} 1263 - cpu: [x64] 1264 - os: [linux] 1265 - 1266 709 '@rolldown/binding-linux-x64-musl@1.0.0-rc.15': 1267 710 resolution: {integrity: sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw==} 1268 711 engines: {node: ^20.19.0 || >=22.12.0} 1269 712 cpu: [x64] 1270 713 os: [linux] 1271 714 1272 - '@rolldown/binding-linux-x64-musl@1.0.0-rc.9': 1273 - resolution: {integrity: sha512-UzYnKCIIc4heAKgI4PZ3dfBGUZefGCJ1TPDuLHoCzgrMYPb5Rv6TLFuYtyM4rWyHM7hymNdsg5ik2C+UD9VDbA==} 1274 - engines: {node: ^20.19.0 || >=22.12.0} 1275 - cpu: [x64] 1276 - os: [linux] 1277 - 1278 715 '@rolldown/binding-openharmony-arm64@1.0.0-rc.15': 1279 716 resolution: {integrity: sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg==} 1280 717 engines: {node: ^20.19.0 || >=22.12.0} 1281 718 cpu: [arm64] 1282 719 os: [openharmony] 1283 720 1284 - '@rolldown/binding-openharmony-arm64@1.0.0-rc.9': 1285 - resolution: {integrity: sha512-+6zoiF+RRyf5cdlFQP7nm58mq7+/2PFaY2DNQeD4B87N36JzfF/l9mdBkkmTvSYcYPE8tMh/o3cRlsx1ldLfog==} 1286 - engines: {node: ^20.19.0 || >=22.12.0} 1287 - cpu: [arm64] 1288 - os: [openharmony] 1289 - 1290 721 '@rolldown/binding-wasm32-wasi@1.0.0-rc.15': 1291 722 resolution: {integrity: sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q==} 1292 - engines: {node: '>=14.0.0'} 1293 - cpu: [wasm32] 1294 - 1295 - '@rolldown/binding-wasm32-wasi@1.0.0-rc.9': 1296 - resolution: {integrity: sha512-rgFN6sA/dyebil3YTlL2evvi/M+ivhfnyxec7AccTpRPccno/rPoNlqybEZQBkcbZu8Hy+eqNJCqfBR8P7Pg8g==} 1297 723 engines: {node: '>=14.0.0'} 1298 724 cpu: [wasm32] 1299 725 1300 726 '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15': 1301 727 resolution: {integrity: sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA==} 1302 - engines: {node: ^20.19.0 || >=22.12.0} 1303 - cpu: [arm64] 1304 - os: [win32] 1305 - 1306 - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.9': 1307 - resolution: {integrity: sha512-lHVNUG/8nlF1IQk1C0Ci574qKYyty2goMiPlRqkC5R+3LkXDkL5Dhx8ytbxq35m+pkHVIvIxviD+TWLdfeuadA==} 1308 728 engines: {node: ^20.19.0 || >=22.12.0} 1309 729 cpu: [arm64] 1310 730 os: [win32] ··· 1315 735 cpu: [x64] 1316 736 os: [win32] 1317 737 1318 - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.9': 1319 - resolution: {integrity: sha512-G0oA4+w1iY5AGi5HcDTxWsoxF509hrFIPB2rduV5aDqS9FtDg1CAfa7V34qImbjfhIcA8C+RekocJZA96EarwQ==} 1320 - engines: {node: ^20.19.0 || >=22.12.0} 1321 - cpu: [x64] 1322 - os: [win32] 1323 - 1324 738 '@rolldown/pluginutils@1.0.0-rc.15': 1325 739 resolution: {integrity: sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g==} 1326 - 1327 - '@rolldown/pluginutils@1.0.0-rc.9': 1328 - resolution: {integrity: sha512-w6oiRWgEBl04QkFZgmW+jnU1EC9b57Oihi2ot3HNWIQRqgHp5PnYDia5iZ5FF7rpa4EQdiqMDXjlqKGXBhsoXw==} 1329 740 1330 741 '@rollup/rollup-android-arm-eabi@4.60.1': 1331 742 resolution: {integrity: sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA==} ··· 1462 873 '@standard-schema/spec@1.1.0': 1463 874 resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} 1464 875 1465 - '@sveltejs/acorn-typescript@1.0.9': 1466 - resolution: {integrity: sha512-lVJX6qEgs/4DOcRTpo56tmKzVPtoWAaVbL4hfO7t7NVwl9AAXzQR6cihesW1BmNMPl+bK6dreu2sOKBP2Q9CIA==} 1467 - peerDependencies: 1468 - acorn: ^8.9.0 1469 - 1470 - '@sveltejs/adapter-cloudflare@7.2.8': 1471 - resolution: {integrity: sha512-bIdhY/Fi4AQmqiBdQVKnafH1h9Gw+xbCvHyUu4EouC8rJOU02zwhi14k/FDhQ0mJF1iblIu3m8UNQ8GpGIvIOQ==} 1472 - peerDependencies: 1473 - '@sveltejs/kit': ^2.0.0 1474 - wrangler: ^4.0.0 1475 - 1476 - '@sveltejs/kit@2.57.1': 1477 - resolution: {integrity: sha512-VRdSbB96cI1EnRh09CqmnQqP/YJvET5buj8S6k7CxaJqBJD4bw4fRKDjcarAj/eX9k2eHifQfDH8NtOh+ZxxPw==} 1478 - engines: {node: '>=18.13'} 1479 - hasBin: true 1480 - peerDependencies: 1481 - '@opentelemetry/api': ^1.0.0 1482 - '@sveltejs/vite-plugin-svelte': ^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0 1483 - svelte: ^4.0.0 || ^5.0.0-next.0 1484 - typescript: ^5.3.3 || ^6.0.0 1485 - vite: ^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0 1486 - peerDependenciesMeta: 1487 - '@opentelemetry/api': 1488 - optional: true 1489 - typescript: 1490 - optional: true 1491 - 1492 - '@sveltejs/vite-plugin-svelte@7.0.0': 1493 - resolution: {integrity: sha512-ILXmxC7HAsnkK2eslgPetrqqW1BKSL7LktsFgqzNj83MaivMGZzluWq32m25j2mDOjmSKX7GGWahePhuEs7P/g==} 1494 - engines: {node: ^20.19 || ^22.12 || >=24} 1495 - peerDependencies: 1496 - svelte: ^5.46.4 1497 - vite: ^8.0.0-beta.7 || ^8.0.0 1498 - 1499 - '@swc/helpers@0.5.21': 1500 - resolution: {integrity: sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==} 1501 - 1502 - '@tailwindcss/forms@0.5.11': 1503 - resolution: {integrity: sha512-h9wegbZDPurxG22xZSoWtdzc41/OlNEUQERNqI/0fOwa2aVlWGu7C35E/x6LDyD3lgtztFSSjKZyuVM0hxhbgA==} 1504 - peerDependencies: 1505 - tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1' 1506 - 1507 - '@tailwindcss/node@4.2.2': 1508 - resolution: {integrity: sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==} 1509 - 1510 - '@tailwindcss/oxide-android-arm64@4.2.2': 1511 - resolution: {integrity: sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==} 1512 - engines: {node: '>= 20'} 1513 - cpu: [arm64] 1514 - os: [android] 1515 - 1516 - '@tailwindcss/oxide-darwin-arm64@4.2.2': 1517 - resolution: {integrity: sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==} 1518 - engines: {node: '>= 20'} 1519 - cpu: [arm64] 1520 - os: [darwin] 1521 - 1522 - '@tailwindcss/oxide-darwin-x64@4.2.2': 1523 - resolution: {integrity: sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==} 1524 - engines: {node: '>= 20'} 1525 - cpu: [x64] 1526 - os: [darwin] 1527 - 1528 - '@tailwindcss/oxide-freebsd-x64@4.2.2': 1529 - resolution: {integrity: sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==} 1530 - engines: {node: '>= 20'} 1531 - cpu: [x64] 1532 - os: [freebsd] 1533 - 1534 - '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2': 1535 - resolution: {integrity: sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==} 1536 - engines: {node: '>= 20'} 1537 - cpu: [arm] 1538 - os: [linux] 1539 - 1540 - '@tailwindcss/oxide-linux-arm64-gnu@4.2.2': 1541 - resolution: {integrity: sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==} 1542 - engines: {node: '>= 20'} 1543 - cpu: [arm64] 1544 - os: [linux] 1545 - 1546 - '@tailwindcss/oxide-linux-arm64-musl@4.2.2': 1547 - resolution: {integrity: sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==} 1548 - engines: {node: '>= 20'} 1549 - cpu: [arm64] 1550 - os: [linux] 1551 - 1552 - '@tailwindcss/oxide-linux-x64-gnu@4.2.2': 1553 - resolution: {integrity: sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==} 1554 - engines: {node: '>= 20'} 1555 - cpu: [x64] 1556 - os: [linux] 1557 - 1558 - '@tailwindcss/oxide-linux-x64-musl@4.2.2': 1559 - resolution: {integrity: sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==} 1560 - engines: {node: '>= 20'} 1561 - cpu: [x64] 1562 - os: [linux] 1563 - 1564 - '@tailwindcss/oxide-wasm32-wasi@4.2.2': 1565 - resolution: {integrity: sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==} 1566 - engines: {node: '>=14.0.0'} 1567 - cpu: [wasm32] 1568 - bundledDependencies: 1569 - - '@napi-rs/wasm-runtime' 1570 - - '@emnapi/core' 1571 - - '@emnapi/runtime' 1572 - - '@tybys/wasm-util' 1573 - - '@emnapi/wasi-threads' 1574 - - tslib 1575 - 1576 - '@tailwindcss/oxide-win32-arm64-msvc@4.2.2': 1577 - resolution: {integrity: sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==} 1578 - engines: {node: '>= 20'} 1579 - cpu: [arm64] 1580 - os: [win32] 1581 - 1582 - '@tailwindcss/oxide-win32-x64-msvc@4.2.2': 1583 - resolution: {integrity: sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==} 1584 - engines: {node: '>= 20'} 1585 - cpu: [x64] 1586 - os: [win32] 1587 - 1588 - '@tailwindcss/oxide@4.2.2': 1589 - resolution: {integrity: sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==} 1590 - engines: {node: '>= 20'} 1591 - 1592 - '@tailwindcss/vite@4.2.2': 1593 - resolution: {integrity: sha512-mEiF5HO1QqCLXoNEfXVA1Tzo+cYsrqV7w9Juj2wdUFyW07JRenqMG225MvPwr3ZD9N1bFQj46X7r33iHxLUW0w==} 1594 - peerDependencies: 1595 - vite: ^5.2.0 || ^6 || ^7 || ^8 1596 - 1597 - '@tiptap/core@3.22.3': 1598 - resolution: {integrity: sha512-Dv9MKK5BDWCF0N2l6/Pxv3JNCce2kwuWf2cKMBc2bEetx0Pn6o7zlFmSxMvYK4UtG1Tw9Yg/ZHi6QOFWK0Zm9Q==} 1599 - peerDependencies: 1600 - '@tiptap/pm': ^3.22.3 1601 - 1602 - '@tiptap/extension-blockquote@3.22.3': 1603 - resolution: {integrity: sha512-IaUx3zh7yLHXzIXKL+fw/jzFhsIImdhJyw0lMhe8FfYrefFqXJFYW/sey6+L/e8B3AWvTksPA6VBwefzbH77JA==} 1604 - peerDependencies: 1605 - '@tiptap/core': ^3.22.3 1606 - 1607 - '@tiptap/extension-bold@3.22.3': 1608 - resolution: {integrity: sha512-tysipHla2zCWr8XNIWRaW9O+7i7/SoEqnRqSRUUi2ailcJjlia+RBy3RykhkgyThrQDStu5KGBS/UvrXwA+O1A==} 1609 - peerDependencies: 1610 - '@tiptap/core': ^3.22.3 1611 - 1612 - '@tiptap/extension-bubble-menu@3.22.3': 1613 - resolution: {integrity: sha512-Y6zQjh0ypDg32HWgICEvmPSKjGLr39k3aDxxt/H0uQEZSfw4smT0hxUyyyjVjx68C6t6MTnwdfz0hPI5lL68vQ==} 1614 - peerDependencies: 1615 - '@tiptap/core': ^3.22.3 1616 - '@tiptap/pm': ^3.22.3 1617 - 1618 - '@tiptap/extension-bullet-list@3.22.3': 1619 - resolution: {integrity: sha512-xOmW/b1hgECIE6r3IeZvKn4VVlG3+dfTjCWE6lnnyLaqdNkNhKS1CwUmDZdYNLUS2ryIUtgz5ID1W/8A3PhbiA==} 1620 - peerDependencies: 1621 - '@tiptap/extension-list': ^3.22.3 1622 - 1623 - '@tiptap/extension-code-block-lowlight@3.22.3': 1624 - resolution: {integrity: sha512-NGFuD9zb1QfnCgD2zW4XaUEdQvd/ydm9FmXXh8eawx/+C8xt3p21DIKRERvxWrCvvVNzIUEpZRRYehPOJiD1eg==} 1625 - peerDependencies: 1626 - '@tiptap/core': ^3.22.3 1627 - '@tiptap/extension-code-block': ^3.22.3 1628 - '@tiptap/pm': ^3.22.3 1629 - highlight.js: ^11 1630 - lowlight: ^2 || ^3 1631 - 1632 - '@tiptap/extension-code-block@3.22.3': 1633 - resolution: {integrity: sha512-RiQtEjDAPrHpdo6sw6b7fOw/PijqgFIsozKKkGcSeBgWHQuFg7q9OxJTj+l0e60rVwSu/5gmKEEobzM9bX+t2Q==} 1634 - peerDependencies: 1635 - '@tiptap/core': ^3.22.3 1636 - '@tiptap/pm': ^3.22.3 1637 - 1638 - '@tiptap/extension-code@3.22.3': 1639 - resolution: {integrity: sha512-wafWTDQOuMKtXpZEuk1PFQmzopabBciNLryL90MB9S03MNLaQQZYLnmYkDBlzAaLAbgF5QiC+2XZQEBQuTVjFQ==} 1640 - peerDependencies: 1641 - '@tiptap/core': ^3.22.3 1642 - 1643 - '@tiptap/extension-document@3.22.3': 1644 - resolution: {integrity: sha512-MCSr1PFPtTd++lA3H1RNgqAczAE59XXJ5wUFIQf2F+/0DPY5q2SU4g5QsNJVxPPft5mrNT4C6ty8xBPrALFEdA==} 1645 - peerDependencies: 1646 - '@tiptap/core': ^3.22.3 1647 - 1648 - '@tiptap/extension-dropcursor@3.22.3': 1649 - resolution: {integrity: sha512-taXq9Tl5aybdFbptJtFRHX9LFJzbXphAbPp4/vutFyTrBu5meXDxuS+B9pEmE+Or0XcolTlW2nDZB0Tqnr18JQ==} 1650 - peerDependencies: 1651 - '@tiptap/extensions': ^3.22.3 1652 - 1653 - '@tiptap/extension-floating-menu@3.22.3': 1654 - resolution: {integrity: sha512-0f8b4KZ3XKai8GXWseIYJGdOfQr3evtFbBo3U08zy2aYzMMXWG0zEF7qe5/oiYp2aZ95edjjITnEceviTsZkIg==} 1655 - peerDependencies: 1656 - '@floating-ui/dom': ^1.0.0 1657 - '@tiptap/core': ^3.22.3 1658 - '@tiptap/pm': ^3.22.3 1659 - 1660 - '@tiptap/extension-gapcursor@3.22.3': 1661 - resolution: {integrity: sha512-L/Px4UeQEVG/D9WIlcAOIej+4wyIBCMUSYicSR+hW68UsObe4rxVbUas1QgidQKm6DOhoT7U7D4KQHA/Gdg/7A==} 1662 - peerDependencies: 1663 - '@tiptap/extensions': ^3.22.3 1664 - 1665 - '@tiptap/extension-hard-break@3.22.3': 1666 - resolution: {integrity: sha512-J0v8I99y9tbvVmgKYKzKP/JYNsWaZYS7avn4rzLft2OhnyTfwt3OoY8DtpHmmi6apSUaCtoWHWta/TmoEfK1nQ==} 1667 - peerDependencies: 1668 - '@tiptap/core': ^3.22.3 1669 - 1670 - '@tiptap/extension-heading@3.22.3': 1671 - resolution: {integrity: sha512-XBHuhiEV2EEhZHpOLcplLqAmBIhJciU3I6AtwmqeEqDC0P114uMEfAO7JGlbBZdCYotNer26PKnu44TBTeNtkw==} 1672 - peerDependencies: 1673 - '@tiptap/core': ^3.22.3 1674 - 1675 - '@tiptap/extension-history@3.22.3': 1676 - resolution: {integrity: sha512-3kev2iP84YPjwUk8BaM28EQiVHbBmE0lkcIjh/6yvgRxRwblzRwyJuFcsVOY5ouBVxl9Rg1rcFFCAs8CFNFkUg==} 1677 - peerDependencies: 1678 - '@tiptap/extensions': ^3.22.3 1679 - 1680 - '@tiptap/extension-horizontal-rule@3.22.3': 1681 - resolution: {integrity: sha512-wI2bFzScs+KgWeBH/BtypcVKeYelCyqV0RG8nxsZMWtPrBhqixzNd0Oi3gEKtjSjKUqMQ/kjJAIRuESr5UzlHA==} 1682 - peerDependencies: 1683 - '@tiptap/core': ^3.22.3 1684 - '@tiptap/pm': ^3.22.3 1685 - 1686 - '@tiptap/extension-image@3.22.3': 1687 - resolution: {integrity: sha512-Qpp8c5LOQaNpHrzjqZtoxtIR+8sSqJ7k8v+8anmYw3nxjvt2kpfT28Vd7aWMX55ZS43LaxMx+MkZqbmgUmMP0w==} 1688 - peerDependencies: 1689 - '@tiptap/core': ^3.22.3 1690 - 1691 - '@tiptap/extension-italic@3.22.3': 1692 - resolution: {integrity: sha512-LteA4cb4EGCiUtrK2JHvDF/Zg0/YqV4DUyHhAAho+oGEQDupZlsS6m0ia5wQcclkiTLzsoPrwcSNu6RDGQ16wQ==} 1693 - peerDependencies: 1694 - '@tiptap/core': ^3.22.3 1695 - 1696 - '@tiptap/extension-link@3.22.3': 1697 - resolution: {integrity: sha512-S8/P2o9pv6B3kqLjH2TRWwSAximGbciNc6R8/QcN6HWLYxp0N0JoqN3rZHl9VWIBAGRWc4zkt80dhqrl2xmgfQ==} 1698 - peerDependencies: 1699 - '@tiptap/core': ^3.22.3 1700 - '@tiptap/pm': ^3.22.3 1701 - 1702 - '@tiptap/extension-list-item@3.22.3': 1703 - resolution: {integrity: sha512-80CNf4oO5y8+LdckT4CyMe1t01EyhpRrQC9H45JW20P7559Nrchp5my3vvMtIAJbpTPPZtcB7LwdzWGKsG5drg==} 1704 - peerDependencies: 1705 - '@tiptap/extension-list': ^3.22.3 1706 - 1707 - '@tiptap/extension-list-keymap@3.22.3': 1708 - resolution: {integrity: sha512-pKuyj5llu35zd/s2u/H9aydKZjmPRAIK5P1q/YXULhhCNln2RnmuRfQ5NklAqTD3yGciQ2lxDwwf7J6iw3ergA==} 1709 - peerDependencies: 1710 - '@tiptap/extension-list': ^3.22.3 1711 - 1712 - '@tiptap/extension-list@3.22.3': 1713 - resolution: {integrity: sha512-rqvv/dtqwbX+8KnPv0eMYp6PnBcuhPMol5cv1GlS8Nq/Cxt68EWGUHBuTFesw+hdnRQLmKwzoO1DlRn7PhxYRQ==} 1714 - peerDependencies: 1715 - '@tiptap/core': ^3.22.3 1716 - '@tiptap/pm': ^3.22.3 1717 - 1718 - '@tiptap/extension-ordered-list@3.22.3': 1719 - resolution: {integrity: sha512-orAghtmd+K4Euu4BgI1hG+iZDXBYOyl5YTwiLBc2mQn+pqtZ9LqaH2us4ETwEwNP3/IWXGSAimUZ19nuL+eM2w==} 1720 - peerDependencies: 1721 - '@tiptap/extension-list': ^3.22.3 1722 - 1723 - '@tiptap/extension-paragraph@3.22.3': 1724 - resolution: {integrity: sha512-oO7rhfyhEuwm+50s9K3GZPjYyEEEvFAvm1wXopvZnhbkBLydIWImBfrZoC5IQh4/sRDlTIjosV2C+ji5y0tUSg==} 1725 - peerDependencies: 1726 - '@tiptap/core': ^3.22.3 1727 - 1728 - '@tiptap/extension-placeholder@3.22.3': 1729 - resolution: {integrity: sha512-7vbtlDVO00odqCnsMSmA4b6wjL5PFdfExFsdsDO0K0VemqHZ/doIRx/tosNUD1VYSOyKQd8U7efUjkFyVoIPlg==} 1730 - peerDependencies: 1731 - '@tiptap/extensions': ^3.22.3 1732 - 1733 - '@tiptap/extension-strike@3.22.3': 1734 - resolution: {integrity: sha512-jY2InoUlKkuk5KHoIDGdML1OCA2n6PRHAtxwHNkAmiYh0Khf0zaVPGFpx4dgQrN7W5Q1WE6oBZnjrvy6qb7w0g==} 1735 - peerDependencies: 1736 - '@tiptap/core': ^3.22.3 1737 - 1738 - '@tiptap/extension-text@3.22.3': 1739 - resolution: {integrity: sha512-Q9R7JsTdomP5uUjtPjNKxHT1xoh/i9OJZnmgJLe7FcgZEaPOQ3bWxmKZoLZQfDfZjyB8BtH+Hc7nUvhCMOePxw==} 1740 - peerDependencies: 1741 - '@tiptap/core': ^3.22.3 1742 - 1743 - '@tiptap/extension-typography@3.22.3': 1744 - resolution: {integrity: sha512-QQv1KUHsr3LTGhtPIG/ZP15Cj5VmI5ChgK4Q7UZ7JZBppBKAeMnyAnOcO2ith+qZ8qp5s+UiQ7Unp0zP1VSYkg==} 1745 - peerDependencies: 1746 - '@tiptap/core': ^3.22.3 1747 - 1748 - '@tiptap/extension-underline@3.22.3': 1749 - resolution: {integrity: sha512-Ch6CBWRa5w90yYSPUW6x9Py9JdrXMqk3pZ9OIlMYD8A7BqyZGfiHerX7XDMYDS09KjyK3U9XH60/zxYOzXdDLA==} 1750 - peerDependencies: 1751 - '@tiptap/core': ^3.22.3 1752 - 1753 - '@tiptap/extensions@3.22.3': 1754 - resolution: {integrity: sha512-s5eiMq0m5N6N+W7dU6rd60KgZyyCD7FvtPNNswISfPr12EQwJBfbjWwTqd0UKNzA4fNrhQEERXnzORkykttPeA==} 1755 - peerDependencies: 1756 - '@tiptap/core': ^3.22.3 1757 - '@tiptap/pm': ^3.22.3 1758 - 1759 - '@tiptap/markdown@3.22.3': 1760 - resolution: {integrity: sha512-Ajw8AkAae7IET1sxZqNv+dhZQSuLY0AHWocowTny1azyiBtmRRKygkGK0ysVA+k6UxmBD6K+tvnbpjQ0/ACl4A==} 1761 - peerDependencies: 1762 - '@tiptap/core': ^3.22.3 1763 - '@tiptap/pm': ^3.22.3 1764 - 1765 - '@tiptap/pm@3.22.3': 1766 - resolution: {integrity: sha512-NjfWjZuvrqmpICT+GZWNIjtOdhPyqFKDMtQy7tsQ5rErM9L2ZQdy/+T/BKSO1JdTeBhdg9OP+0yfsqoYp2aT6A==} 1767 - 1768 - '@tiptap/starter-kit@3.22.3': 1769 - resolution: {integrity: sha512-vdW/Oo1fdwTL1VOQ5YYbTov00ANeHLquBVEZyL/EkV7Xv5io9rXQsCysJfTSHhiQlyr2MtWFB4+CPGuwXjQWOQ==} 1770 - 1771 - '@tiptap/suggestion@3.22.3': 1772 - resolution: {integrity: sha512-m2c+5gDj2vW7UI1J4JHCKehQUVE12qBhgF+DC+WEWUU8ZrFNf5OEYWQHDNsopa5RRpilfKfhPNbMtXgvGOsk6g==} 1773 - peerDependencies: 1774 - '@tiptap/core': ^3.22.3 1775 - '@tiptap/pm': ^3.22.3 1776 - 1777 876 '@tybys/wasm-util@0.10.1': 1778 877 resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} 1779 878 1780 879 '@types/chai@5.2.3': 1781 880 resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} 1782 881 1783 - '@types/cookie@0.6.0': 1784 - resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} 1785 - 1786 882 '@types/deep-eql@4.0.2': 1787 883 resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} 1788 884 1789 - '@types/esrecurse@4.3.1': 1790 - resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} 1791 - 1792 885 '@types/estree@1.0.8': 1793 886 resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} 1794 887 1795 - '@types/hast@3.0.4': 1796 - resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} 1797 - 1798 - '@types/json-schema@7.0.15': 1799 - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} 1800 - 1801 - '@types/linkify-it@5.0.0': 1802 - resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} 1803 - 1804 - '@types/markdown-it@14.1.2': 1805 - resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} 1806 - 1807 - '@types/mdurl@2.0.0': 1808 - resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} 1809 - 1810 888 '@types/node@12.20.55': 1811 889 resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} 1812 890 ··· 1816 894 '@types/pg@8.20.0': 1817 895 resolution: {integrity: sha512-bEPFOaMAHTEP1EzpvHTbmwR8UsFyHSKsRisLIHVMXnpNefSbGA1bD6CVy+qKjGSqmZqNqBDV2azOBo8TgkcVow==} 1818 896 1819 - '@types/trusted-types@2.0.7': 1820 - resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} 1821 - 1822 - '@types/unist@3.0.3': 1823 - resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} 1824 - 1825 - '@typescript-eslint/eslint-plugin@8.58.2': 1826 - resolution: {integrity: sha512-aC2qc5thQahutKjP+cl8cgN9DWe3ZUqVko30CMSZHnFEHyhOYoZSzkGtAI2mcwZ38xeImDucI4dnqsHiOYuuCw==} 1827 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 1828 - peerDependencies: 1829 - '@typescript-eslint/parser': ^8.58.2 1830 - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 1831 - typescript: '>=4.8.4 <6.1.0' 1832 - 1833 - '@typescript-eslint/parser@8.58.2': 1834 - resolution: {integrity: sha512-/Zb/xaIDfxeJnvishjGdcR4jmr7S+bda8PKNhRGdljDM+elXhlvN0FyPSsMnLmJUrVG9aPO6dof80wjMawsASg==} 1835 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 1836 - peerDependencies: 1837 - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 1838 - typescript: '>=4.8.4 <6.1.0' 1839 - 1840 - '@typescript-eslint/project-service@8.58.2': 1841 - resolution: {integrity: sha512-Cq6UfpZZk15+r87BkIh5rDpi38W4b+Sjnb8wQCPPDDweS/LRCFjCyViEbzHk5Ck3f2QDfgmlxqSa7S7clDtlfg==} 1842 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 1843 - peerDependencies: 1844 - typescript: '>=4.8.4 <6.1.0' 1845 - 1846 - '@typescript-eslint/scope-manager@8.58.2': 1847 - resolution: {integrity: sha512-SgmyvDPexWETQek+qzZnrG6844IaO02UVyOLhI4wpo82dpZJY9+6YZCKAMFzXb7qhx37mFK1QcPQ18tud+vo6Q==} 1848 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 1849 - 1850 - '@typescript-eslint/tsconfig-utils@8.58.2': 1851 - resolution: {integrity: sha512-3SR+RukipDvkkKp/d0jP0dyzuls3DbGmwDpVEc5wqk5f38KFThakqAAO0XMirWAE+kT00oTauTbzMFGPoAzB0A==} 1852 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 1853 - peerDependencies: 1854 - typescript: '>=4.8.4 <6.1.0' 1855 - 1856 - '@typescript-eslint/type-utils@8.58.2': 1857 - resolution: {integrity: sha512-Z7EloNR/B389FvabdGeTo2XMs4W9TjtPiO9DAsmT0yom0bwlPyRjkJ1uCdW1DvrrrYP50AJZ9Xc3sByZA9+dcg==} 1858 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 1859 - peerDependencies: 1860 - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 1861 - typescript: '>=4.8.4 <6.1.0' 1862 - 1863 - '@typescript-eslint/types@8.58.2': 1864 - resolution: {integrity: sha512-9TukXyATBQf/Jq9AMQXfvurk+G5R2MwfqQGDR2GzGz28HvY/lXNKGhkY+6IOubwcquikWk5cjlgPvD2uAA7htQ==} 1865 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 1866 - 1867 - '@typescript-eslint/typescript-estree@8.58.2': 1868 - resolution: {integrity: sha512-ELGuoofuhhoCvNbQjFFiobFcGgcDCEm0ThWdmO4Z0UzLqPXS3KFvnEZ+SHewwOYHjM09tkzOWXNTv9u6Gqtyuw==} 1869 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 1870 - peerDependencies: 1871 - typescript: '>=4.8.4 <6.1.0' 1872 - 1873 - '@typescript-eslint/utils@8.58.2': 1874 - resolution: {integrity: sha512-QZfjHNEzPY8+l0+fIXMvuQ2sJlplB4zgDZvA+NmvZsZv3EQwOcc1DuIU1VJUTWZ/RKouBMhDyNaBMx4sWvrzRA==} 1875 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 1876 - peerDependencies: 1877 - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 1878 - typescript: '>=4.8.4 <6.1.0' 1879 - 1880 - '@typescript-eslint/visitor-keys@8.58.2': 1881 - resolution: {integrity: sha512-f1WO2Lx8a9t8DARmcWAUPJbu0G20bJlj8L4z72K00TMeJAoyLr/tHhI/pzYBLrR4dXWkcxO1cWYZEOX8DKHTqA==} 1882 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 1883 - 1884 - '@use-gesture/core@10.3.1': 1885 - resolution: {integrity: sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw==} 1886 - 1887 - '@use-gesture/vanilla@10.3.1': 1888 - resolution: {integrity: sha512-lT4scGLu59ovA3zmtUonukAGcA0AdOOh+iwNDS05Bsu7Lq9aZToDHhI6D8Q2qvsVraovtsLLYwPrWdG/noMAKw==} 1889 - 1890 897 '@vitest/expect@4.1.0': 1891 898 resolution: {integrity: sha512-EIxG7k4wlWweuCLG9Y5InKFwpMEOyrMb6ZJ1ihYu02LVj/bzUwn2VMU+13PinsjRW75XnITeFrQBMH5+dLvCDA==} 1892 899 ··· 1916 923 '@vitest/utils@4.1.0': 1917 924 resolution: {integrity: sha512-XfPXT6a8TZY3dcGY8EdwsBulFCIw+BeeX0RZn2x/BtiY/75YGh8FeWGG8QISN/WhaqSrE2OrlDgtF8q5uhOTmw==} 1918 925 1919 - acorn-jsx@5.3.2: 1920 - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} 1921 - peerDependencies: 1922 - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 1923 - 1924 926 acorn@8.16.0: 1925 927 resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} 1926 928 engines: {node: '>=0.4.0'} 1927 929 hasBin: true 1928 - 1929 - ajv@6.14.0: 1930 - resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} 1931 930 1932 931 ansi-colors@4.1.3: 1933 932 resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} ··· 1946 945 argparse@2.0.1: 1947 946 resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} 1948 947 1949 - aria-query@5.3.1: 1950 - resolution: {integrity: sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==} 1951 - engines: {node: '>= 0.4'} 1952 - 1953 948 array-union@2.1.0: 1954 949 resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} 1955 950 engines: {node: '>=8'} ··· 1958 953 resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} 1959 954 engines: {node: '>=12'} 1960 955 1961 - axobject-query@4.1.0: 1962 - resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} 1963 - engines: {node: '>= 0.4'} 1964 - 1965 - balanced-match@4.0.4: 1966 - resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} 1967 - engines: {node: 18 || 20 || >=22} 1968 - 1969 956 better-path-resolve@1.0.0: 1970 957 resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} 1971 958 engines: {node: '>=4'} 1972 959 1973 - bits-ui@2.17.3: 1974 - resolution: {integrity: sha512-Bef41uY9U2jaBJHPhcPvmBNkGec5Wx2z6eioDsTmsaR2vH4QoaOcPi75gzCG3+/2TNr6v/qBwzgWNPYCxNtrEA==} 1975 - engines: {node: '>=20'} 1976 - peerDependencies: 1977 - '@internationalized/date': ^3.8.1 1978 - svelte: ^5.33.0 1979 - 1980 960 blake3-wasm@2.1.5: 1981 961 resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} 1982 962 1983 - brace-expansion@5.0.5: 1984 - resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} 1985 - engines: {node: 18 || 20 || >=22} 1986 - 1987 963 braces@3.0.3: 1988 964 resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} 1989 965 engines: {node: '>=8'} ··· 2009 985 resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} 2010 986 engines: {node: '>= 14.16.0'} 2011 987 2012 - clsx@2.1.1: 2013 - resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} 2014 - engines: {node: '>=6'} 2015 - 2016 988 commander@4.1.1: 2017 989 resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} 2018 990 engines: {node: '>= 6'} ··· 2027 999 convert-source-map@2.0.0: 2028 1000 resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} 2029 1001 2030 - cookie@0.6.0: 2031 - resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} 2032 - engines: {node: '>= 0.6'} 2033 - 2034 1002 cookie@1.1.1: 2035 1003 resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} 2036 1004 engines: {node: '>=18'} 2037 1005 2038 - core-js@3.49.0: 2039 - resolution: {integrity: sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==} 2040 - 2041 - crelt@1.0.6: 2042 - resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} 2043 - 2044 1006 cross-spawn@7.0.6: 2045 1007 resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} 2046 1008 engines: {node: '>= 8'} 2047 1009 2048 - cssesc@3.0.0: 2049 - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} 2050 - engines: {node: '>=4'} 2051 - hasBin: true 2052 - 2053 - custom-event-polyfill@1.0.7: 2054 - resolution: {integrity: sha512-TDDkd5DkaZxZFM8p+1I3yAlvM3rSr1wbrOliG4yJiwinMZN8z/iGL7BTlDkrJcYTmgUSb4ywVCc3ZaUtOtC76w==} 2055 - 2056 1010 debug@4.4.3: 2057 1011 resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} 2058 1012 engines: {node: '>=6.0'} ··· 2062 1016 supports-color: 2063 1017 optional: true 2064 1018 2065 - deep-is@0.1.4: 2066 - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} 2067 - 2068 - deepmerge@4.3.1: 2069 - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} 2070 - engines: {node: '>=0.10.0'} 2071 - 2072 - dequal@2.0.3: 2073 - resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} 2074 - engines: {node: '>=6'} 2075 - 2076 1019 detect-indent@6.1.0: 2077 1020 resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} 2078 1021 engines: {node: '>=8'} ··· 2081 1024 resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} 2082 1025 engines: {node: '>=8'} 2083 1026 2084 - devalue@5.7.1: 2085 - resolution: {integrity: sha512-MUbZ586EgQqdRnC4yDrlod3BEdyvE4TapGYHMW2CiaW+KkkFmWEFqBUaLltEZCGi0iFXCEjRF0OjF0DV2QHjOA==} 2086 - 2087 - devlop@1.1.0: 2088 - resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} 2089 - 2090 1027 dir-glob@3.0.1: 2091 1028 resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} 2092 1029 engines: {node: '>=8'} 2093 1030 2094 - dompurify@3.4.0: 2095 - resolution: {integrity: sha512-nolgK9JcaUXMSmW+j1yaSvaEaoXYHwWyGJlkoCTghc97KgGDDSnpoU/PlEnw63Ah+TGKFOyY+X5LnxaWbCSfXg==} 2096 - 2097 - emoji-picker-element@1.29.1: 2098 - resolution: {integrity: sha512-TOiHzu9Dqib3x4MwcAi3wi3RdyT4SoeB4b15AvH1ks4SBwTl7DeebhZ0d3x6dNi4XfNU7IGRZ7NBQllj0RqwrQ==} 2099 - 2100 - enhanced-resolve@5.20.1: 2101 - resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==} 2102 - engines: {node: '>=10.13.0'} 2103 - 2104 1031 enquirer@2.4.1: 2105 1032 resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} 2106 1033 engines: {node: '>=8.6'} 2107 1034 2108 - entities@4.5.0: 2109 - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} 2110 - engines: {node: '>=0.12'} 2111 - 2112 1035 error-stack-parser-es@1.0.5: 2113 1036 resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} 2114 1037 ··· 2120 1043 engines: {node: '>=18'} 2121 1044 hasBin: true 2122 1045 2123 - esbuild@0.27.3: 2124 - resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==} 2125 - engines: {node: '>=18'} 2126 - hasBin: true 2127 - 2128 - escape-string-regexp@4.0.0: 2129 - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} 2130 - engines: {node: '>=10'} 2131 - 2132 - eslint-config-prettier@10.1.8: 2133 - resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} 2134 - hasBin: true 2135 - peerDependencies: 2136 - eslint: '>=7.0.0' 2137 - 2138 - eslint-plugin-svelte@3.17.0: 2139 - resolution: {integrity: sha512-sF6wgd5FLS2P8CCaOy2HdYYYEcZ6TwL251dLHUkNmtLnWECk1Dwc+j6VeulmmnFxr7Xs0WNtjweOA+bJ0PnaFw==} 2140 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 2141 - peerDependencies: 2142 - eslint: ^8.57.1 || ^9.0.0 || ^10.0.0 2143 - svelte: ^3.37.0 || ^4.0.0 || ^5.0.0 2144 - peerDependenciesMeta: 2145 - svelte: 2146 - optional: true 2147 - 2148 - eslint-scope@8.4.0: 2149 - resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} 2150 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 2151 - 2152 - eslint-scope@9.1.2: 2153 - resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==} 2154 - engines: {node: ^20.19.0 || ^22.13.0 || >=24} 2155 - 2156 - eslint-visitor-keys@3.4.3: 2157 - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} 2158 - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 2159 - 2160 - eslint-visitor-keys@4.2.1: 2161 - resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} 2162 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 2163 - 2164 - eslint-visitor-keys@5.0.1: 2165 - resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} 2166 - engines: {node: ^20.19.0 || ^22.13.0 || >=24} 2167 - 2168 - eslint@10.2.0: 2169 - resolution: {integrity: sha512-+L0vBFYGIpSNIt/KWTpFonPrqYvgKw1eUI5Vn7mEogrQcWtWYtNQ7dNqC+px/J0idT3BAkiWrhfS7k+Tum8TUA==} 2170 - engines: {node: ^20.19.0 || ^22.13.0 || >=24} 2171 - hasBin: true 2172 - peerDependencies: 2173 - jiti: '*' 2174 - peerDependenciesMeta: 2175 - jiti: 2176 - optional: true 2177 - 2178 1046 esm-env@1.2.2: 2179 1047 resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} 2180 1048 2181 - espree@10.4.0: 2182 - resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} 2183 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 2184 - 2185 - espree@11.2.0: 2186 - resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==} 2187 - engines: {node: ^20.19.0 || ^22.13.0 || >=24} 2188 - 2189 1049 esprima@4.0.1: 2190 1050 resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} 2191 1051 engines: {node: '>=4'} 2192 1052 hasBin: true 2193 1053 2194 - esquery@1.7.0: 2195 - resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} 2196 - engines: {node: '>=0.10'} 2197 - 2198 - esrap@2.2.5: 2199 - resolution: {integrity: sha512-/yLB1538mag+dn0wsePTe8C0rDIjUOaJpMs2McodSzmM2msWcZsBSdRtg6HOBt0A/r82BN+Md3pgwSc/uWt2Ig==} 2200 - peerDependencies: 2201 - '@typescript-eslint/types': ^8.2.0 2202 - peerDependenciesMeta: 2203 - '@typescript-eslint/types': 2204 - optional: true 2205 - 2206 - esrecurse@4.3.0: 2207 - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} 2208 - engines: {node: '>=4.0'} 2209 - 2210 - estraverse@5.3.0: 2211 - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} 2212 - engines: {node: '>=4.0'} 2213 - 2214 1054 estree-walker@3.0.3: 2215 1055 resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} 2216 1056 2217 - esutils@2.0.3: 2218 - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} 2219 - engines: {node: '>=0.10.0'} 2220 - 2221 1057 event-target-polyfill@0.0.4: 2222 1058 resolution: {integrity: sha512-Gs6RLjzlLRdT8X9ZipJdIZI/Y6/HhRLyq9RdDlCsnpxr/+Nn6bU2EFGuC94GjxqhM+Nmij2Vcq98yoHrU8uNFQ==} 2223 1059 ··· 2228 1064 extendable-error@0.1.7: 2229 1065 resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} 2230 1066 2231 - fast-deep-equal@3.1.3: 2232 - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} 2233 - 2234 1067 fast-glob@3.3.3: 2235 1068 resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} 2236 1069 engines: {node: '>=8.6.0'} 2237 1070 2238 - fast-json-stable-stringify@2.1.0: 2239 - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} 2240 - 2241 - fast-levenshtein@2.0.6: 2242 - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} 2243 - 2244 1071 fastq@1.20.1: 2245 1072 resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} 2246 1073 ··· 2253 1080 picomatch: 2254 1081 optional: true 2255 1082 2256 - file-entry-cache@8.0.0: 2257 - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} 2258 - engines: {node: '>=16.0.0'} 2259 - 2260 1083 fill-range@7.1.1: 2261 1084 resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} 2262 1085 engines: {node: '>=8'} ··· 2265 1088 resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} 2266 1089 engines: {node: '>=8'} 2267 1090 2268 - find-up@5.0.0: 2269 - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} 2270 - engines: {node: '>=10'} 2271 - 2272 1091 fix-dts-default-cjs-exports@1.0.1: 2273 1092 resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} 2274 1093 2275 - flat-cache@4.0.1: 2276 - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} 2277 - engines: {node: '>=16'} 2278 - 2279 - flatted@3.4.2: 2280 - resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} 2281 - 2282 1094 fs-extra@7.0.1: 2283 1095 resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} 2284 1096 engines: {node: '>=6 <7 || >=8'} ··· 2299 1111 resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 2300 1112 engines: {node: '>= 6'} 2301 1113 2302 - glob-parent@6.0.2: 2303 - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} 2304 - engines: {node: '>=10.13.0'} 2305 - 2306 - globals@16.5.0: 2307 - resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} 2308 - engines: {node: '>=18'} 2309 - 2310 - globals@17.5.0: 2311 - resolution: {integrity: sha512-qoV+HK2yFl/366t2/Cb3+xxPUo5BuMynomoDmiaZBIdbs+0pYbjfZU+twLhGKp4uCZ/+NbtpVepH5bGCxRyy2g==} 2312 - engines: {node: '>=18'} 2313 - 2314 1114 globby@11.1.0: 2315 1115 resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} 2316 1116 engines: {node: '>=10'} ··· 2318 1118 graceful-fs@4.2.11: 2319 1119 resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} 2320 1120 2321 - highlight.js@11.11.1: 2322 - resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} 2323 - engines: {node: '>=12.0.0'} 2324 - 2325 - hls.js@1.6.16: 2326 - resolution: {integrity: sha512-VSIRpLfRwlAAdGL4wiTucx2ScRipo0ed1FBatWkyt832jC4CReKstga6yIhYVwGu9LOBjuX9wzmRMeQdBJtzEA==} 2327 - 2328 1121 hono@4.12.8: 2329 1122 resolution: {integrity: sha512-VJCEvtrezO1IAR+kqEYnxUOoStaQPGrCmX3j4wDTNOcD1uRPFpGlwQUIW8niPuvHXaTUxeOUl5MMDGrl+tmO9A==} 2330 1123 engines: {node: '>=16.9.0'} ··· 2341 1134 resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} 2342 1135 engines: {node: '>= 4'} 2343 1136 2344 - ignore@7.0.5: 2345 - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} 2346 - engines: {node: '>= 4'} 2347 - 2348 - imurmurhash@0.1.4: 2349 - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} 2350 - engines: {node: '>=0.8.19'} 2351 - 2352 - inline-style-parser@0.2.7: 2353 - resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} 2354 - 2355 - is-emoji-supported@0.0.5: 2356 - resolution: {integrity: sha512-WOlXUhDDHxYqcSmFZis+xWhhqXiK2SU0iYiqmth5Ip0FHLZQAt9rKL5ahnilE8/86WH8tZ3bmNNNC+bTzamqlw==} 2357 - 2358 1137 is-extglob@2.1.1: 2359 1138 resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 2360 1139 engines: {node: '>=0.10.0'} ··· 2367 1146 resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 2368 1147 engines: {node: '>=0.12.0'} 2369 1148 2370 - is-reference@3.0.3: 2371 - resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} 2372 - 2373 1149 is-subdir@1.2.0: 2374 1150 resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} 2375 1151 engines: {node: '>=4'} ··· 2397 1173 resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} 2398 1174 hasBin: true 2399 1175 2400 - json-buffer@3.0.1: 2401 - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} 2402 - 2403 - json-schema-traverse@0.4.1: 2404 - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} 2405 - 2406 - json-stable-stringify-without-jsonify@1.0.1: 2407 - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} 2408 - 2409 1176 jsonfile@4.0.0: 2410 1177 resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} 2411 1178 2412 - keyv@4.5.4: 2413 - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} 2414 - 2415 1179 kleur@4.1.5: 2416 1180 resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} 2417 1181 engines: {node: '>=6'} 2418 - 2419 - known-css-properties@0.37.0: 2420 - resolution: {integrity: sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==} 2421 - 2422 - levn@0.4.1: 2423 - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} 2424 - engines: {node: '>= 0.8.0'} 2425 1182 2426 1183 lightningcss-android-arm64@1.32.0: 2427 1184 resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} ··· 2493 1250 resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} 2494 1251 engines: {node: '>= 12.0.0'} 2495 1252 2496 - lilconfig@2.1.0: 2497 - resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} 2498 - engines: {node: '>=10'} 2499 - 2500 1253 lilconfig@3.1.3: 2501 1254 resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} 2502 1255 engines: {node: '>=14'} ··· 2504 1257 lines-and-columns@1.2.4: 2505 1258 resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} 2506 1259 2507 - linkify-it@5.0.0: 2508 - resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} 2509 - 2510 - linkifyjs@4.3.2: 2511 - resolution: {integrity: sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==} 2512 - 2513 1260 load-tsconfig@0.2.5: 2514 1261 resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} 2515 1262 engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 2516 1263 2517 - loadjs@4.3.0: 2518 - resolution: {integrity: sha512-vNX4ZZLJBeDEOBvdr2v/F+0aN5oMuPu7JTqrMwp+DtgK+AryOlpy6Xtm2/HpNr+azEa828oQjOtWsB6iDtSfSQ==} 2519 - 2520 - locate-character@3.0.0: 2521 - resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} 2522 - 2523 1264 locate-path@5.0.0: 2524 1265 resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} 2525 1266 engines: {node: '>=8'} 2526 1267 2527 - locate-path@6.0.0: 2528 - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} 2529 - engines: {node: '>=10'} 2530 - 2531 1268 lodash.startcase@4.4.0: 2532 1269 resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} 2533 1270 2534 - lowlight@3.3.0: 2535 - resolution: {integrity: sha512-0JNhgFoPvP6U6lE/UdVsSq99tn6DhjjpAj5MxG49ewd2mOBVtwWYIT8ClyABhq198aXXODMU6Ox8DrGy/CpTZQ==} 2536 - 2537 - lz-string@1.5.0: 2538 - resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} 2539 - hasBin: true 2540 - 2541 1271 magic-string@0.30.21: 2542 1272 resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} 2543 1273 2544 - markdown-it@14.1.1: 2545 - resolution: {integrity: sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==} 2546 - hasBin: true 2547 - 2548 - marked@17.0.6: 2549 - resolution: {integrity: sha512-gB0gkNafnonOw0obSTEGZTT86IuhILt2Wfx0mWH/1Au83kybTayroZ/V6nS25mN7u8ASy+5fMhgB3XPNrOZdmA==} 2550 - engines: {node: '>= 20'} 2551 - hasBin: true 2552 - 2553 - mdurl@2.0.0: 2554 - resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} 2555 - 2556 1274 merge2@1.4.1: 2557 1275 resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} 2558 1276 engines: {node: '>= 8'} ··· 2561 1279 resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} 2562 1280 engines: {node: '>=8.6'} 2563 1281 2564 - mini-svg-data-uri@1.4.4: 2565 - resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==} 2566 - hasBin: true 2567 - 2568 1282 miniflare@4.20260205.0: 2569 1283 resolution: {integrity: sha512-jG1TknEDeFqcq/z5gsOm1rKeg4cNG7ruWxEuiPxl3pnQumavxo8kFpeQC6XKVpAhh2PI9ODGyIYlgd77sTHl5g==} 2570 1284 engines: {node: '>=18.0.0'} 2571 1285 hasBin: true 2572 1286 2573 - miniflare@4.20260410.0: 2574 - resolution: {integrity: sha512-94LEU8d+XPVGp18eW4+bu1v7Tnq7srhqWMIsrx2jhSkdbTnGqg1I613R0GKY4eygBYl9MbqXEhzK/bczJb6uMg==} 2575 - engines: {node: '>=18.0.0'} 2576 - hasBin: true 2577 - 2578 - minimatch@10.2.5: 2579 - resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} 2580 - engines: {node: 18 || 20 || >=22} 2581 - 2582 1287 mlly@1.8.2: 2583 1288 resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} 2584 1289 2585 - mode-watcher@1.1.0: 2586 - resolution: {integrity: sha512-mUT9RRGPDYenk59qJauN1rhsIMKBmWA3xMF+uRwE8MW/tjhaDSCCARqkSuDTq8vr4/2KcAxIGVjACxTjdk5C3g==} 2587 - peerDependencies: 2588 - svelte: ^5.27.0 2589 - 2590 1290 mri@1.2.0: 2591 1291 resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} 2592 1292 engines: {node: '>=4'} 2593 1293 2594 - mrmime@2.0.1: 2595 - resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} 2596 - engines: {node: '>=10'} 2597 - 2598 1294 ms@2.1.3: 2599 1295 resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 2600 1296 ··· 2611 1307 engines: {node: ^18 || >=20} 2612 1308 hasBin: true 2613 1309 2614 - natural-compare@1.4.0: 2615 - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} 2616 - 2617 - number-flow@0.6.0: 2618 - resolution: {integrity: sha512-K8flNq2Wqus53vjp/btVo3qXFkagF8dIdYavreBfE7hlvFFG/b1HMGEH6nZL+mlrJ+4lbLP9OmPv3t2rmRkpSQ==} 2619 - 2620 1310 object-assign@4.1.1: 2621 1311 resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} 2622 1312 engines: {node: '>=0.10.0'} ··· 2624 1314 obug@2.1.1: 2625 1315 resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} 2626 1316 2627 - optionator@0.9.4: 2628 - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} 2629 - engines: {node: '>= 0.8.0'} 2630 - 2631 - orderedmap@2.1.1: 2632 - resolution: {integrity: sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==} 2633 - 2634 1317 outdent@0.5.0: 2635 1318 resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} 2636 1319 ··· 2642 1325 resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} 2643 1326 engines: {node: '>=6'} 2644 1327 2645 - p-limit@3.1.0: 2646 - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} 2647 - engines: {node: '>=10'} 2648 - 2649 1328 p-locate@4.1.0: 2650 1329 resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} 2651 1330 engines: {node: '>=8'} 2652 - 2653 - p-locate@5.0.0: 2654 - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} 2655 - engines: {node: '>=10'} 2656 1331 2657 1332 p-map@2.1.0: 2658 1333 resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} ··· 2746 1421 pkg-types@1.3.1: 2747 1422 resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} 2748 1423 2749 - plyr@3.8.4: 2750 - resolution: {integrity: sha512-DrzLbK9Wol3zeiuZCleD9aUOl0KAaBHR9H6WVVVYPZ4Ya+LYxUFTgSF1jooHcMQCv96Ws96wCaZzIoP3bES8pQ==} 2751 - 2752 - postcss-load-config@3.1.4: 2753 - resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} 2754 - engines: {node: '>= 10'} 2755 - peerDependencies: 2756 - postcss: '>=8.0.9' 2757 - ts-node: '>=9.0.0' 2758 - peerDependenciesMeta: 2759 - postcss: 2760 - optional: true 2761 - ts-node: 2762 - optional: true 2763 - 2764 1424 postcss-load-config@6.0.1: 2765 1425 resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} 2766 1426 engines: {node: '>= 18'} ··· 2778 1438 optional: true 2779 1439 yaml: 2780 1440 optional: true 2781 - 2782 - postcss-safe-parser@7.0.1: 2783 - resolution: {integrity: sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==} 2784 - engines: {node: '>=18.0'} 2785 - peerDependencies: 2786 - postcss: ^8.4.31 2787 - 2788 - postcss-scss@4.0.9: 2789 - resolution: {integrity: sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==} 2790 - engines: {node: '>=12.0'} 2791 - peerDependencies: 2792 - postcss: ^8.4.29 2793 - 2794 - postcss-selector-parser@7.1.1: 2795 - resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} 2796 - engines: {node: '>=4'} 2797 1441 2798 1442 postcss@8.5.8: 2799 1443 resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} ··· 2815 1459 resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} 2816 1460 engines: {node: '>=0.10.0'} 2817 1461 2818 - prelude-ls@1.2.1: 2819 - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} 2820 - engines: {node: '>= 0.8.0'} 2821 - 2822 - prettier-plugin-svelte@3.5.1: 2823 - resolution: {integrity: sha512-65+fr5+cgIKWKiqM1Doum4uX6bY8iFCdztvvp2RcF+AJoieaw9kJOFMNcJo/bkmKYsxFaM9OsVZK/gWauG/5mg==} 2824 - peerDependencies: 2825 - prettier: ^3.0.0 2826 - svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0 2827 - 2828 - prettier-plugin-tailwindcss@0.7.2: 2829 - resolution: {integrity: sha512-LkphyK3Fw+q2HdMOoiEHWf93fNtYJwfamoKPl7UwtjFQdei/iIBoX11G6j706FzN3ymX9mPVi97qIY8328vdnA==} 2830 - engines: {node: '>=20.19'} 2831 - peerDependencies: 2832 - '@ianvs/prettier-plugin-sort-imports': '*' 2833 - '@prettier/plugin-hermes': '*' 2834 - '@prettier/plugin-oxc': '*' 2835 - '@prettier/plugin-pug': '*' 2836 - '@shopify/prettier-plugin-liquid': '*' 2837 - '@trivago/prettier-plugin-sort-imports': '*' 2838 - '@zackad/prettier-plugin-twig': '*' 2839 - prettier: ^3.0 2840 - prettier-plugin-astro: '*' 2841 - prettier-plugin-css-order: '*' 2842 - prettier-plugin-jsdoc: '*' 2843 - prettier-plugin-marko: '*' 2844 - prettier-plugin-multiline-arrays: '*' 2845 - prettier-plugin-organize-attributes: '*' 2846 - prettier-plugin-organize-imports: '*' 2847 - prettier-plugin-sort-imports: '*' 2848 - prettier-plugin-svelte: '*' 2849 - peerDependenciesMeta: 2850 - '@ianvs/prettier-plugin-sort-imports': 2851 - optional: true 2852 - '@prettier/plugin-hermes': 2853 - optional: true 2854 - '@prettier/plugin-oxc': 2855 - optional: true 2856 - '@prettier/plugin-pug': 2857 - optional: true 2858 - '@shopify/prettier-plugin-liquid': 2859 - optional: true 2860 - '@trivago/prettier-plugin-sort-imports': 2861 - optional: true 2862 - '@zackad/prettier-plugin-twig': 2863 - optional: true 2864 - prettier-plugin-astro: 2865 - optional: true 2866 - prettier-plugin-css-order: 2867 - optional: true 2868 - prettier-plugin-jsdoc: 2869 - optional: true 2870 - prettier-plugin-marko: 2871 - optional: true 2872 - prettier-plugin-multiline-arrays: 2873 - optional: true 2874 - prettier-plugin-organize-attributes: 2875 - optional: true 2876 - prettier-plugin-organize-imports: 2877 - optional: true 2878 - prettier-plugin-sort-imports: 2879 - optional: true 2880 - prettier-plugin-svelte: 2881 - optional: true 2882 - 2883 1462 prettier@2.8.8: 2884 1463 resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} 2885 1464 engines: {node: '>=10.13.0'} ··· 2890 1469 engines: {node: '>=14'} 2891 1470 hasBin: true 2892 1471 2893 - prosemirror-changeset@2.4.1: 2894 - resolution: {integrity: sha512-96WBLhOaYhJ+kPhLg3uW359Tz6I/MfcrQfL4EGv4SrcqKEMC1gmoGrXHecPE8eOwTVCJ4IwgfzM8fFad25wNfw==} 2895 - 2896 - prosemirror-collab@1.3.1: 2897 - resolution: {integrity: sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==} 2898 - 2899 - prosemirror-commands@1.7.1: 2900 - resolution: {integrity: sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==} 2901 - 2902 - prosemirror-dropcursor@1.8.2: 2903 - resolution: {integrity: sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==} 2904 - 2905 - prosemirror-gapcursor@1.4.1: 2906 - resolution: {integrity: sha512-pMdYaEnjNMSwl11yjEGtgTmLkR08m/Vl+Jj443167p9eB3HVQKhYCc4gmHVDsLPODfZfjr/MmirsdyZziXbQKw==} 2907 - 2908 - prosemirror-history@1.5.0: 2909 - resolution: {integrity: sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==} 2910 - 2911 - prosemirror-inputrules@1.5.1: 2912 - resolution: {integrity: sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==} 2913 - 2914 - prosemirror-keymap@1.2.3: 2915 - resolution: {integrity: sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==} 2916 - 2917 - prosemirror-markdown@1.13.4: 2918 - resolution: {integrity: sha512-D98dm4cQ3Hs6EmjK500TdAOew4Z03EV71ajEFiWra3Upr7diytJsjF4mPV2dW+eK5uNectiRj0xFxYI9NLXDbw==} 2919 - 2920 - prosemirror-menu@1.3.0: 2921 - resolution: {integrity: sha512-TImyPXCHPcDsSka2/lwJ6WjTASr4re/qWq1yoTTuLOqfXucwF6VcRa2LWCkM/EyTD1UO3CUwiH8qURJoWJRxwg==} 2922 - 2923 - prosemirror-model@1.25.4: 2924 - resolution: {integrity: sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==} 2925 - 2926 - prosemirror-schema-basic@1.2.4: 2927 - resolution: {integrity: sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==} 2928 - 2929 - prosemirror-schema-list@1.5.1: 2930 - resolution: {integrity: sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==} 2931 - 2932 - prosemirror-state@1.4.4: 2933 - resolution: {integrity: sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==} 2934 - 2935 - prosemirror-tables@1.8.5: 2936 - resolution: {integrity: sha512-V/0cDCsHKHe/tfWkeCmthNUcEp1IVO3p6vwN8XtwE9PZQLAZJigbw3QoraAdfJPir4NKJtNvOB8oYGKRl+t0Dw==} 2937 - 2938 - prosemirror-trailing-node@3.0.0: 2939 - resolution: {integrity: sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==} 2940 - peerDependencies: 2941 - prosemirror-model: ^1.22.1 2942 - prosemirror-state: ^1.4.2 2943 - prosemirror-view: ^1.33.8 2944 - 2945 - prosemirror-transform@1.12.0: 2946 - resolution: {integrity: sha512-GxboyN4AMIsoHNtz5uf2r2Ru551i5hWeCMD6E2Ib4Eogqoub0NflniaBPVQ4MrGE5yZ8JV9tUHg9qcZTTrcN4w==} 2947 - 2948 - prosemirror-view@1.41.8: 2949 - resolution: {integrity: sha512-TnKDdohEatgyZNGCDWIdccOHXhYloJwbwU+phw/a23KBvJIR9lWQWW7WHHK3vBdOLDNuF7TaX98GObUZOWkOnA==} 2950 - 2951 - punycode.js@2.3.1: 2952 - resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} 2953 - engines: {node: '>=6'} 2954 - 2955 - punycode@2.3.1: 2956 - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} 2957 - engines: {node: '>=6'} 2958 - 2959 1472 quansync@0.2.11: 2960 1473 resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} 2961 1474 2962 1475 queue-microtask@1.2.3: 2963 1476 resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} 2964 1477 2965 - rangetouch@2.0.1: 2966 - resolution: {integrity: sha512-sln+pNSc8NGaHoLzwNBssFSf/rSYkqeBXzX1AtJlkJiUaVSJSbRAWJk+4omsXkN+EJalzkZhWQ3th1m0FpR5xA==} 2967 - 2968 1478 read-yaml-file@1.1.0: 2969 1479 resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} 2970 1480 engines: {node: '>=6'} ··· 2972 1482 readdirp@4.1.2: 2973 1483 resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} 2974 1484 engines: {node: '>= 14.18.0'} 2975 - 2976 - regexparam@3.0.0: 2977 - resolution: {integrity: sha512-RSYAtP31mvYLkAHrOlh25pCNQ5hWnT106VukGaaFfuJrZFkGRX5GhUAdPqpSDXxOhA2c4akmRuplv1mRqnBn6Q==} 2978 - engines: {node: '>=8'} 2979 1485 2980 1486 resolve-from@5.0.0: 2981 1487 resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} ··· 2993 1499 engines: {node: ^20.19.0 || >=22.12.0} 2994 1500 hasBin: true 2995 1501 2996 - rolldown@1.0.0-rc.9: 2997 - resolution: {integrity: sha512-9EbgWge7ZH+yqb4d2EnELAntgPTWbfL8ajiTW+SyhJEC4qhBbkCKbqFV4Ge4zmu5ziQuVbWxb/XwLZ+RIO7E8Q==} 2998 - engines: {node: ^20.19.0 || >=22.12.0} 2999 - hasBin: true 3000 - 3001 1502 rollup@4.60.1: 3002 1503 resolution: {integrity: sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==} 3003 1504 engines: {node: '>=18.0.0', npm: '>=8.0.0'} 3004 1505 hasBin: true 3005 1506 3006 - rope-sequence@1.3.4: 3007 - resolution: {integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==} 3008 - 3009 1507 run-parallel@1.2.0: 3010 1508 resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} 3011 1509 3012 - runed@0.23.4: 3013 - resolution: {integrity: sha512-9q8oUiBYeXIDLWNK5DfCWlkL0EW3oGbk845VdKlPeia28l751VpfesaB/+7pI6rnbx1I6rqoZ2fZxptOJLxILA==} 3014 - peerDependencies: 3015 - svelte: ^5.7.0 3016 - 3017 - runed@0.25.0: 3018 - resolution: {integrity: sha512-7+ma4AG9FT2sWQEA0Egf6mb7PBT2vHyuHail1ie8ropfSjvZGtEAx8YTmUjv/APCsdRRxEVvArNjALk9zFSOrg==} 3019 - peerDependencies: 3020 - svelte: ^5.7.0 3021 - 3022 - runed@0.28.0: 3023 - resolution: {integrity: sha512-k2xx7RuO9hWcdd9f+8JoBeqWtYrm5CALfgpkg2YDB80ds/QE4w0qqu34A7fqiAwiBBSBQOid7TLxwxVC27ymWQ==} 3024 - peerDependencies: 3025 - svelte: ^5.7.0 3026 - 3027 - runed@0.35.1: 3028 - resolution: {integrity: sha512-2F4Q/FZzbeJTFdIS/PuOoPRSm92sA2LhzTnv6FXhCoENb3huf5+fDuNOg1LNvGOouy3u/225qxmuJvcV3IZK5Q==} 3029 - peerDependencies: 3030 - '@sveltejs/kit': ^2.21.0 3031 - svelte: ^5.7.0 3032 - peerDependenciesMeta: 3033 - '@sveltejs/kit': 3034 - optional: true 3035 - 3036 - sade@1.8.1: 3037 - resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} 3038 - engines: {node: '>=6'} 3039 - 3040 1510 safer-buffer@2.1.2: 3041 1511 resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} 3042 1512 ··· 3045 1515 engines: {node: '>=10'} 3046 1516 hasBin: true 3047 1517 3048 - set-cookie-parser@3.1.0: 3049 - resolution: {integrity: sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw==} 3050 - 3051 1518 sharp@0.34.5: 3052 1519 resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} 3053 1520 engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} ··· 3066 1533 signal-exit@4.1.0: 3067 1534 resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} 3068 1535 engines: {node: '>=14'} 3069 - 3070 - sirv@3.0.2: 3071 - resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} 3072 - engines: {node: '>=18'} 3073 1536 3074 1537 slash@3.0.0: 3075 1538 resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} ··· 3107 1570 resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} 3108 1571 engines: {node: '>=4'} 3109 1572 3110 - style-to-object@1.0.14: 3111 - resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} 3112 - 3113 1573 sucrase@3.35.1: 3114 1574 resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} 3115 1575 engines: {node: '>=16 || 14 >=14.17'} ··· 3119 1579 resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} 3120 1580 engines: {node: '>=18'} 3121 1581 3122 - svelte-check@4.4.6: 3123 - resolution: {integrity: sha512-kP1zG81EWaFe9ZyTv4ZXv44Csi6Pkdpb7S3oj6m+K2ec/IcDg/a8LsFsnVLqm2nxtkSwsd5xPj/qFkTBgXHXjg==} 3124 - engines: {node: '>= 18.0.0'} 3125 - hasBin: true 3126 - peerDependencies: 3127 - svelte: ^4.0.0 || ^5.0.0-next.0 3128 - typescript: '>=5.0.0' 3129 - 3130 - svelte-eslint-parser@1.6.0: 3131 - resolution: {integrity: sha512-qoB1ehychT6OxEtQAqc/guSqLS20SlA53Uijl7x375s8nlUT0lb9ol/gzraEEatQwsyPTJo87s2CmKL9Xab+Uw==} 3132 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0, pnpm: 10.30.3} 3133 - peerDependencies: 3134 - svelte: ^3.37.0 || ^4.0.0 || ^5.0.0 3135 - peerDependenciesMeta: 3136 - svelte: 3137 - optional: true 3138 - 3139 - svelte-sonner@1.1.0: 3140 - resolution: {integrity: sha512-3lYM6ZIqWe+p9vwwWHGWP/ZdvHiUtzURsud2quIxivrX4rvpXh6i+geBGn0m3JS6KwW6W8VgbOl3xQMcDuh6gg==} 3141 - peerDependencies: 3142 - svelte: ^5.0.0 3143 - 3144 - svelte-tiptap@3.0.1: 3145 - resolution: {integrity: sha512-Vi3kVGOd01f7mslOxGbJB7z2QavdvH+6WffhB+Y5fleTiZaW0YWqIboyO2u/uh4BQeosiINmmuRJ+Qwb7mYP+A==} 3146 - peerDependencies: 3147 - '@floating-ui/dom': ^1.0.0 3148 - '@tiptap/core': ^3.0.0 3149 - '@tiptap/extension-bubble-menu': ^3.0.0 3150 - '@tiptap/extension-floating-menu': ^3.0.0 3151 - '@tiptap/pm': ^3.0.0 3152 - svelte: ^5.0.0 3153 - 3154 - svelte-toolbelt@0.10.6: 3155 - resolution: {integrity: sha512-YWuX+RE+CnWYx09yseAe4ZVMM7e7GRFZM6OYWpBKOb++s+SQ8RBIMMe+Bs/CznBMc0QPLjr+vDBxTAkozXsFXQ==} 3156 - engines: {node: '>=18', pnpm: '>=8.7.0'} 3157 - peerDependencies: 3158 - svelte: ^5.30.2 3159 - 3160 - svelte-toolbelt@0.7.1: 3161 - resolution: {integrity: sha512-HcBOcR17Vx9bjaOceUvxkY3nGmbBmCBBbuWLLEWO6jtmWH8f/QoWmbyUfQZrpDINH39en1b8mptfPQT9VKQ1xQ==} 3162 - engines: {node: '>=18', pnpm: '>=8.7.0'} 3163 - peerDependencies: 3164 - svelte: ^5.0.0 3165 - 3166 - svelte@5.55.4: 3167 - resolution: {integrity: sha512-q8DFohk6vUswSng95IZb9nzWJnbINZsK7OiM1snAa3qCjJBL0ZQpvMyAaVXjUukdM75J/m8UE8xwqat8Ors/zQ==} 3168 - engines: {node: '>=18'} 3169 - 3170 - tabbable@6.4.0: 3171 - resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==} 3172 - 3173 - tailwind-merge@3.5.0: 3174 - resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==} 3175 - 3176 - tailwind-variants@3.2.2: 3177 - resolution: {integrity: sha512-Mi4kHeMTLvKlM98XPnK+7HoBPmf4gygdFmqQPaDivc3DpYS6aIY6KiG/PgThrGvii5YZJqRsPz0aPyhoFzmZgg==} 3178 - engines: {node: '>=16.x', pnpm: '>=7.x'} 3179 - peerDependencies: 3180 - tailwind-merge: '>=3.0.0' 3181 - tailwindcss: '*' 3182 - peerDependenciesMeta: 3183 - tailwind-merge: 3184 - optional: true 3185 - 3186 - tailwindcss@4.2.2: 3187 - resolution: {integrity: sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==} 3188 - 3189 - tapable@2.3.2: 3190 - resolution: {integrity: sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==} 3191 - engines: {node: '>=6'} 3192 - 3193 1582 term-size@2.2.1: 3194 1583 resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} 3195 1584 engines: {node: '>=8'} ··· 3223 1612 resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 3224 1613 engines: {node: '>=8.0'} 3225 1614 3226 - totalist@3.0.1: 3227 - resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} 3228 - engines: {node: '>=6'} 3229 - 3230 1615 tree-kill@1.2.2: 3231 1616 resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} 3232 1617 hasBin: true 3233 1618 3234 - ts-api-utils@2.5.0: 3235 - resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} 3236 - engines: {node: '>=18.12'} 3237 - peerDependencies: 3238 - typescript: '>=4.8.4' 3239 - 3240 1619 ts-interface-checker@0.1.13: 3241 1620 resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} 3242 1621 ··· 3267 1646 engines: {node: '>=18.0.0'} 3268 1647 hasBin: true 3269 1648 3270 - type-check@0.4.0: 3271 - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} 3272 - engines: {node: '>= 0.8.0'} 3273 - 3274 1649 type-fest@4.41.0: 3275 1650 resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} 3276 1651 engines: {node: '>=16'} 3277 1652 3278 - typescript-eslint@8.58.2: 3279 - resolution: {integrity: sha512-V8iSng9mRbdZjl54VJ9NKr6ZB+dW0J3TzRXRGcSbLIej9jV86ZRtlYeTKDR/QLxXykocJ5icNzbsl2+5TzIvcQ==} 3280 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 3281 - peerDependencies: 3282 - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 3283 - typescript: '>=4.8.4 <6.1.0' 3284 - 3285 1653 typescript@5.9.3: 3286 1654 resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} 3287 1655 engines: {node: '>=14.17'} 3288 1656 hasBin: true 3289 1657 3290 - typescript@6.0.2: 3291 - resolution: {integrity: sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==} 3292 - engines: {node: '>=14.17'} 3293 - hasBin: true 3294 - 3295 - uc.micro@2.1.0: 3296 - resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} 3297 - 3298 1658 ufo@1.6.3: 3299 1659 resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} 3300 1660 ··· 3303 1663 3304 1664 undici@7.18.2: 3305 1665 resolution: {integrity: sha512-y+8YjDFzWdQlSE9N5nzKMT3g4a5UBX1HKowfdXh0uvAnTaqqwqB92Jt4UXBAeKekDs5IaDKyJFR4X1gYVCgXcw==} 3306 - engines: {node: '>=20.18.1'} 3307 - 3308 - undici@7.24.4: 3309 - resolution: {integrity: sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w==} 3310 1666 engines: {node: '>=20.18.1'} 3311 1667 3312 1668 unenv@2.0.0-rc.24: ··· 3319 1675 resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} 3320 1676 engines: {node: '>= 4.0.0'} 3321 1677 3322 - uri-js@4.4.1: 3323 - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} 3324 - 3325 - url-polyfill@1.1.14: 3326 - resolution: {integrity: sha512-p4f3TTAG6ADVF3mwbXw7hGw+QJyw5CnNGvYh5fCuQQZIiuKUswqcznyV3pGDP9j0TSmC4UvRKm8kl1QsX1diiQ==} 3327 - 3328 - util-deprecate@1.0.2: 3329 - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} 3330 - 3331 - valibot@1.3.1: 3332 - resolution: {integrity: sha512-sfdRir/QFM0JaF22hqTroPc5xy4DimuGQVKFrzF1YfGwaS1nJot3Y8VqMdLO2Lg27fMzat2yD3pY5PbAYO39Gg==} 3333 - peerDependencies: 3334 - typescript: '>=5' 3335 - peerDependenciesMeta: 3336 - typescript: 3337 - optional: true 3338 - 3339 - vite@8.0.0: 3340 - resolution: {integrity: sha512-fPGaRNj9Zytaf8LEiBhY7Z6ijnFKdzU/+mL8EFBaKr7Vw1/FWcTBAMW0wLPJAGMPX38ZPVCVgLceWiEqeoqL2Q==} 3341 - engines: {node: ^20.19.0 || >=22.12.0} 3342 - hasBin: true 3343 - peerDependencies: 3344 - '@types/node': ^20.19.0 || >=22.12.0 3345 - '@vitejs/devtools': ^0.0.0-alpha.31 3346 - esbuild: ^0.27.0 3347 - jiti: '>=1.21.0' 3348 - less: ^4.0.0 3349 - sass: ^1.70.0 3350 - sass-embedded: ^1.70.0 3351 - stylus: '>=0.54.8' 3352 - sugarss: ^5.0.0 3353 - terser: ^5.16.0 3354 - tsx: ^4.8.1 3355 - yaml: ^2.4.2 3356 - peerDependenciesMeta: 3357 - '@types/node': 3358 - optional: true 3359 - '@vitejs/devtools': 3360 - optional: true 3361 - esbuild: 3362 - optional: true 3363 - jiti: 3364 - optional: true 3365 - less: 3366 - optional: true 3367 - sass: 3368 - optional: true 3369 - sass-embedded: 3370 - optional: true 3371 - stylus: 3372 - optional: true 3373 - sugarss: 3374 - optional: true 3375 - terser: 3376 - optional: true 3377 - tsx: 3378 - optional: true 3379 - yaml: 3380 - optional: true 3381 - 3382 1678 vite@8.0.8: 3383 1679 resolution: {integrity: sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw==} 3384 1680 engines: {node: ^20.19.0 || >=22.12.0} ··· 3422 1718 yaml: 3423 1719 optional: true 3424 1720 3425 - vitefu@1.1.3: 3426 - resolution: {integrity: sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==} 3427 - peerDependencies: 3428 - vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 3429 - peerDependenciesMeta: 3430 - vite: 3431 - optional: true 3432 - 3433 1721 vitest@4.1.0: 3434 1722 resolution: {integrity: sha512-YbDrMF9jM2Lqc++2530UourxZHmkKLxrs4+mYhEwqWS97WJ7wOYEkcr+QfRgJ3PW9wz3odRijLZjHEaRLTNbqw==} 3435 1723 engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} ··· 3465 1753 jsdom: 3466 1754 optional: true 3467 1755 3468 - w3c-keyname@2.2.8: 3469 - resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} 3470 - 3471 - web-haptics@0.0.6: 3472 - resolution: {integrity: sha512-eCzcf1LDi20+Fr0x9V3OkX92k0gxEQXaHajmhXHitsnk6SxPeshv8TBtBRqxyst8HI1uf2FyFVE7QS3jo1gkrw==} 3473 - peerDependencies: 3474 - react: '>=18' 3475 - react-dom: '>=18' 3476 - svelte: '>=4' 3477 - vue: '>=3' 3478 - peerDependenciesMeta: 3479 - react: 3480 - optional: true 3481 - react-dom: 3482 - optional: true 3483 - svelte: 3484 - optional: true 3485 - vue: 3486 - optional: true 3487 - 3488 1756 which@2.0.2: 3489 1757 resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 3490 1758 engines: {node: '>= 8'} ··· 3495 1763 engines: {node: '>=8'} 3496 1764 hasBin: true 3497 1765 3498 - word-wrap@1.2.5: 3499 - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} 3500 - engines: {node: '>=0.10.0'} 3501 - 3502 1766 workerd@1.20260205.0: 3503 1767 resolution: {integrity: sha512-CcMH5clHwrH8VlY7yWS9C/G/C8g9czIz1yU3akMSP9Z3CkEMFSoC3GGdj5G7Alw/PHEeez1+1IrlYger4pwu+w==} 3504 1768 engines: {node: '>=16'} 3505 1769 hasBin: true 3506 1770 3507 - workerd@1.20260410.1: 3508 - resolution: {integrity: sha512-T/GRD6Y5vN9g4CnGmOlfST1w7bj+1IjRFvX0K7CodZPJuPVPNPGhz8Wppah0WdT6A7I8Kad3zgZ2OkDdWtENrg==} 3509 - engines: {node: '>=16'} 3510 - hasBin: true 3511 - 3512 - worktop@0.8.0-next.18: 3513 - resolution: {integrity: sha512-+TvsA6VAVoMC3XDKR5MoC/qlLqDixEfOBysDEKnPIPou/NvoPWCAuXHXMsswwlvmEuvX56lQjvELLyLuzTKvRw==} 3514 - engines: {node: '>=12'} 3515 - 3516 1771 wrangler@4.63.0: 3517 1772 resolution: {integrity: sha512-+R04jF7Eb8K3KRMSgoXpcIdLb8GC62eoSGusYh1pyrSMm/10E0hbKkd7phMJO4HxXc6R7mOHC5SSoX9eof30Uw==} 3518 1773 engines: {node: '>=20.0.0'} 3519 1774 hasBin: true 3520 1775 peerDependencies: 3521 1776 '@cloudflare/workers-types': ^4.20260205.0 3522 - peerDependenciesMeta: 3523 - '@cloudflare/workers-types': 3524 - optional: true 3525 - 3526 - wrangler@4.82.2: 3527 - resolution: {integrity: sha512-SKfW21sTJUkM/Qd8zc9oc8TBkAWHRsXuTxE6XdToC55Ct84pR+IfRdaTjCTuC0dL+KYvauSvSn2rtqS2Ae+Dcw==} 3528 - engines: {node: '>=20.3.0'} 3529 - hasBin: true 3530 - peerDependencies: 3531 - '@cloudflare/workers-types': ^4.20260410.1 3532 1777 peerDependenciesMeta: 3533 1778 '@cloudflare/workers-types': 3534 1779 optional: true ··· 3549 1794 resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} 3550 1795 engines: {node: '>=0.4'} 3551 1796 3552 - yaml@1.10.3: 3553 - resolution: {integrity: sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==} 3554 - engines: {node: '>= 6'} 3555 - 3556 - yocto-queue@0.1.0: 3557 - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} 3558 - engines: {node: '>=10'} 3559 - 3560 1797 yocto-queue@1.2.2: 3561 1798 resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} 3562 1799 engines: {node: '>=12.20'} ··· 3567 1804 youch@4.1.0-beta.10: 3568 1805 resolution: {integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==} 3569 1806 3570 - zimmerframe@1.1.4: 3571 - resolution: {integrity: sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==} 3572 - 3573 1807 snapshots: 3574 1808 3575 1809 '@atcute/atproto@3.1.10': 3576 1810 dependencies: 3577 1811 '@atcute/lexicons': 1.2.9 3578 - 3579 - '@atcute/atproto@3.1.11': 3580 - dependencies: 3581 - '@atcute/lexicons': 1.3.0 3582 - 3583 - '@atcute/bluesky-richtext-segmenter@3.0.0': {} 3584 - 3585 - '@atcute/bluesky@3.3.2': 3586 - dependencies: 3587 - '@atcute/atproto': 3.1.11 3588 - '@atcute/lexicons': 1.3.0 3589 1812 3590 1813 '@atcute/car@5.1.1': 3591 1814 dependencies: ··· 3694 1917 dependencies: 3695 1918 '@atcute/uint8array': 1.1.1 3696 1919 3697 - '@atcute/oauth-crypto@0.1.0': 3698 - dependencies: 3699 - '@atcute/multibase': 1.2.0 3700 - '@atcute/uint8array': 1.1.1 3701 - '@badrap/valita': 0.4.6 3702 - nanoid: 5.1.7 3703 - 3704 - '@atcute/oauth-keyset@0.1.0': 3705 - dependencies: 3706 - '@atcute/oauth-crypto': 0.1.0 3707 - 3708 - '@atcute/oauth-node-client@1.1.0': 3709 - dependencies: 3710 - '@atcute/client': 4.2.1 3711 - '@atcute/identity': 1.1.4 3712 - '@atcute/identity-resolver': 1.2.2(@atcute/identity@1.1.4) 3713 - '@atcute/lexicons': 1.2.9 3714 - '@atcute/oauth-crypto': 0.1.0 3715 - '@atcute/oauth-keyset': 0.1.0 3716 - '@atcute/oauth-types': 0.1.1 3717 - '@atcute/util-fetch': 1.0.5 3718 - '@badrap/valita': 0.4.6 3719 - nanoid: 5.1.7 3720 - 3721 - '@atcute/oauth-types@0.1.1': 3722 - dependencies: 3723 - '@atcute/identity': 1.1.4 3724 - '@atcute/lexicons': 1.2.9 3725 - '@atcute/oauth-keyset': 0.1.0 3726 - '@badrap/valita': 0.4.6 3727 - 3728 1920 '@atcute/repo@0.1.3': 3729 1921 dependencies: 3730 1922 '@atcute/car': 5.1.1 ··· 3735 1927 '@atcute/mst': 1.0.0 3736 1928 '@atcute/uint8array': 1.1.1 3737 1929 3738 - '@atcute/tid@1.1.2': 3739 - dependencies: 3740 - '@atcute/time-ms': 1.3.2 3741 - 3742 - '@atcute/time-ms@1.3.2': {} 3743 - 3744 1930 '@atcute/uint8array@1.1.1': {} 3745 1931 3746 1932 '@atcute/util-fetch@1.0.5': ··· 3768 1954 '@atcute/uint8array': 1.1.1 3769 1955 '@badrap/valita': 0.4.6 3770 1956 nanoid: 5.1.7 3771 - 3772 - '@atmo-dev/contrail@0.1.1(pg@8.20.0)': 3773 - dependencies: 3774 - '@atcute/atproto': 3.1.11 3775 - '@atcute/client': 4.2.1 3776 - '@atcute/identity': 1.1.4 3777 - '@atcute/identity-resolver': 1.2.2(@atcute/identity@1.1.4) 3778 - '@atcute/jetstream': 1.1.2 3779 - '@atcute/lexicons': 1.3.0 3780 - '@atcute/xrpc-server': 0.1.12 3781 - hono: 4.12.8 3782 - optionalDependencies: 3783 - pg: 8.20.0 3784 1957 3785 1958 '@babel/runtime@7.29.2': {} 3786 1959 ··· 3937 2110 optionalDependencies: 3938 2111 workerd: 1.20260205.0 3939 2112 3940 - '@cloudflare/unenv-preset@2.16.0(unenv@2.0.0-rc.24)(workerd@1.20260410.1)': 3941 - dependencies: 3942 - unenv: 2.0.0-rc.24 3943 - optionalDependencies: 3944 - workerd: 1.20260410.1 3945 - 3946 2113 '@cloudflare/workerd-darwin-64@1.20260205.0': 3947 2114 optional: true 3948 2115 3949 - '@cloudflare/workerd-darwin-64@1.20260410.1': 3950 - optional: true 3951 - 3952 2116 '@cloudflare/workerd-darwin-arm64@1.20260205.0': 3953 2117 optional: true 3954 2118 3955 - '@cloudflare/workerd-darwin-arm64@1.20260410.1': 3956 - optional: true 3957 - 3958 2119 '@cloudflare/workerd-linux-64@1.20260205.0': 3959 - optional: true 3960 - 3961 - '@cloudflare/workerd-linux-64@1.20260410.1': 3962 2120 optional: true 3963 2121 3964 2122 '@cloudflare/workerd-linux-arm64@1.20260205.0': 3965 2123 optional: true 3966 2124 3967 - '@cloudflare/workerd-linux-arm64@1.20260410.1': 3968 - optional: true 3969 - 3970 2125 '@cloudflare/workerd-windows-64@1.20260205.0': 3971 2126 optional: true 3972 2127 3973 - '@cloudflare/workerd-windows-64@1.20260410.1': 3974 - optional: true 3975 - 3976 2128 '@cloudflare/workers-types@4.20260205.0': {} 3977 2129 3978 - '@cloudflare/workers-types@4.20260414.1': {} 3979 - 3980 2130 '@cspotcode/source-map-support@0.8.1': 3981 2131 dependencies: 3982 2132 '@jridgewell/trace-mapping': 0.3.9 3983 - 3984 - '@emnapi/core@1.9.0': 3985 - dependencies: 3986 - '@emnapi/wasi-threads': 1.2.0 3987 - tslib: 2.8.1 3988 - optional: true 3989 2133 3990 2134 '@emnapi/core@1.9.2': 3991 2135 dependencies: ··· 4003 2147 tslib: 2.8.1 4004 2148 optional: true 4005 2149 4006 - '@emnapi/wasi-threads@1.2.0': 4007 - dependencies: 4008 - tslib: 2.8.1 4009 - optional: true 4010 - 4011 2150 '@emnapi/wasi-threads@1.2.1': 4012 2151 dependencies: 4013 2152 tslib: 2.8.1 ··· 4016 2155 '@esbuild/aix-ppc64@0.27.0': 4017 2156 optional: true 4018 2157 4019 - '@esbuild/aix-ppc64@0.27.3': 4020 - optional: true 4021 - 4022 2158 '@esbuild/android-arm64@0.27.0': 4023 2159 optional: true 4024 2160 4025 - '@esbuild/android-arm64@0.27.3': 4026 - optional: true 4027 - 4028 2161 '@esbuild/android-arm@0.27.0': 4029 2162 optional: true 4030 2163 4031 - '@esbuild/android-arm@0.27.3': 4032 - optional: true 4033 - 4034 2164 '@esbuild/android-x64@0.27.0': 4035 2165 optional: true 4036 2166 4037 - '@esbuild/android-x64@0.27.3': 4038 - optional: true 4039 - 4040 2167 '@esbuild/darwin-arm64@0.27.0': 4041 - optional: true 4042 - 4043 - '@esbuild/darwin-arm64@0.27.3': 4044 2168 optional: true 4045 2169 4046 2170 '@esbuild/darwin-x64@0.27.0': 4047 - optional: true 4048 - 4049 - '@esbuild/darwin-x64@0.27.3': 4050 2171 optional: true 4051 2172 4052 2173 '@esbuild/freebsd-arm64@0.27.0': 4053 2174 optional: true 4054 2175 4055 - '@esbuild/freebsd-arm64@0.27.3': 4056 - optional: true 4057 - 4058 2176 '@esbuild/freebsd-x64@0.27.0': 4059 2177 optional: true 4060 2178 4061 - '@esbuild/freebsd-x64@0.27.3': 4062 - optional: true 4063 - 4064 2179 '@esbuild/linux-arm64@0.27.0': 4065 2180 optional: true 4066 2181 4067 - '@esbuild/linux-arm64@0.27.3': 4068 - optional: true 4069 - 4070 2182 '@esbuild/linux-arm@0.27.0': 4071 2183 optional: true 4072 2184 4073 - '@esbuild/linux-arm@0.27.3': 4074 - optional: true 4075 - 4076 2185 '@esbuild/linux-ia32@0.27.0': 4077 2186 optional: true 4078 2187 4079 - '@esbuild/linux-ia32@0.27.3': 4080 - optional: true 4081 - 4082 2188 '@esbuild/linux-loong64@0.27.0': 4083 2189 optional: true 4084 2190 4085 - '@esbuild/linux-loong64@0.27.3': 4086 - optional: true 4087 - 4088 2191 '@esbuild/linux-mips64el@0.27.0': 4089 2192 optional: true 4090 2193 4091 - '@esbuild/linux-mips64el@0.27.3': 4092 - optional: true 4093 - 4094 2194 '@esbuild/linux-ppc64@0.27.0': 4095 2195 optional: true 4096 2196 4097 - '@esbuild/linux-ppc64@0.27.3': 4098 - optional: true 4099 - 4100 2197 '@esbuild/linux-riscv64@0.27.0': 4101 2198 optional: true 4102 2199 4103 - '@esbuild/linux-riscv64@0.27.3': 4104 - optional: true 4105 - 4106 2200 '@esbuild/linux-s390x@0.27.0': 4107 - optional: true 4108 - 4109 - '@esbuild/linux-s390x@0.27.3': 4110 2201 optional: true 4111 2202 4112 2203 '@esbuild/linux-x64@0.27.0': 4113 - optional: true 4114 - 4115 - '@esbuild/linux-x64@0.27.3': 4116 2204 optional: true 4117 2205 4118 2206 '@esbuild/netbsd-arm64@0.27.0': 4119 2207 optional: true 4120 2208 4121 - '@esbuild/netbsd-arm64@0.27.3': 4122 - optional: true 4123 - 4124 2209 '@esbuild/netbsd-x64@0.27.0': 4125 - optional: true 4126 - 4127 - '@esbuild/netbsd-x64@0.27.3': 4128 2210 optional: true 4129 2211 4130 2212 '@esbuild/openbsd-arm64@0.27.0': 4131 2213 optional: true 4132 2214 4133 - '@esbuild/openbsd-arm64@0.27.3': 4134 - optional: true 4135 - 4136 2215 '@esbuild/openbsd-x64@0.27.0': 4137 2216 optional: true 4138 2217 4139 - '@esbuild/openbsd-x64@0.27.3': 4140 - optional: true 4141 - 4142 2218 '@esbuild/openharmony-arm64@0.27.0': 4143 2219 optional: true 4144 2220 4145 - '@esbuild/openharmony-arm64@0.27.3': 4146 - optional: true 4147 - 4148 2221 '@esbuild/sunos-x64@0.27.0': 4149 2222 optional: true 4150 2223 4151 - '@esbuild/sunos-x64@0.27.3': 4152 - optional: true 4153 - 4154 2224 '@esbuild/win32-arm64@0.27.0': 4155 2225 optional: true 4156 2226 4157 - '@esbuild/win32-arm64@0.27.3': 4158 - optional: true 4159 - 4160 2227 '@esbuild/win32-ia32@0.27.0': 4161 - optional: true 4162 - 4163 - '@esbuild/win32-ia32@0.27.3': 4164 2228 optional: true 4165 2229 4166 2230 '@esbuild/win32-x64@0.27.0': 4167 2231 optional: true 4168 2232 4169 - '@esbuild/win32-x64@0.27.3': 4170 - optional: true 4171 - 4172 - '@eslint-community/eslint-utils@4.9.1(eslint@10.2.0(jiti@2.6.1))': 4173 - dependencies: 4174 - eslint: 10.2.0(jiti@2.6.1) 4175 - eslint-visitor-keys: 3.4.3 4176 - 4177 - '@eslint-community/regexpp@4.12.2': {} 4178 - 4179 - '@eslint/compat@2.0.5(eslint@10.2.0(jiti@2.6.1))': 4180 - dependencies: 4181 - '@eslint/core': 1.2.1 4182 - optionalDependencies: 4183 - eslint: 10.2.0(jiti@2.6.1) 4184 - 4185 - '@eslint/config-array@0.23.5': 4186 - dependencies: 4187 - '@eslint/object-schema': 3.0.5 4188 - debug: 4.4.3 4189 - minimatch: 10.2.5 4190 - transitivePeerDependencies: 4191 - - supports-color 4192 - 4193 - '@eslint/config-helpers@0.5.5': 4194 - dependencies: 4195 - '@eslint/core': 1.2.1 4196 - 4197 - '@eslint/core@1.2.1': 4198 - dependencies: 4199 - '@types/json-schema': 7.0.15 4200 - 4201 - '@eslint/js@10.0.1(eslint@10.2.0(jiti@2.6.1))': 4202 - optionalDependencies: 4203 - eslint: 10.2.0(jiti@2.6.1) 4204 - 4205 - '@eslint/object-schema@3.0.5': {} 4206 - 4207 - '@eslint/plugin-kit@0.7.1': 4208 - dependencies: 4209 - '@eslint/core': 1.2.1 4210 - levn: 0.4.1 4211 - 4212 - '@floating-ui/core@1.7.5': 4213 - dependencies: 4214 - '@floating-ui/utils': 0.2.11 4215 - 4216 - '@floating-ui/dom@1.7.6': 4217 - dependencies: 4218 - '@floating-ui/core': 1.7.5 4219 - '@floating-ui/utils': 0.2.11 4220 - 4221 - '@floating-ui/utils@0.2.11': {} 4222 - 4223 - '@fontsource-variable/geist-mono@5.2.7': {} 4224 - 4225 - '@fontsource-variable/geist@5.2.8': {} 4226 - 4227 - '@foxui/core@0.9.1(@internationalized/date@3.12.0)(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(tailwindcss@4.2.2)': 4228 - dependencies: 4229 - '@fontsource-variable/geist': 5.2.8 4230 - '@fontsource-variable/geist-mono': 5.2.7 4231 - '@jis3r/icons': 2.7.0(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 4232 - '@lucide/svelte': 1.8.0(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 4233 - '@number-flow/svelte': 0.4.0(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 4234 - bits-ui: 2.17.3(@internationalized/date@3.12.0)(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 4235 - clsx: 2.1.1 4236 - dompurify: 3.4.0 4237 - mode-watcher: 1.1.0(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 4238 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 4239 - svelte-sonner: 1.1.0(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 4240 - tailwind-merge: 3.5.0 4241 - tailwind-variants: 3.2.2(tailwind-merge@3.5.0)(tailwindcss@4.2.2) 4242 - tailwindcss: 4.2.2 4243 - web-haptics: 0.0.6(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 4244 - transitivePeerDependencies: 4245 - - '@internationalized/date' 4246 - - '@sveltejs/kit' 4247 - - react 4248 - - react-dom 4249 - - vue 4250 - 4251 - '@foxui/social@0.8.10(@internationalized/date@3.12.0)(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(@tiptap/extension-code-block@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3))(@tiptap/extensions@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3))(highlight.js@11.11.1)(svelte@5.55.4(@typescript-eslint/types@8.58.2))(tailwindcss@4.2.2)': 4252 - dependencies: 4253 - '@atcute/bluesky': 3.3.2 4254 - '@atcute/bluesky-richtext-segmenter': 3.0.0 4255 - '@foxui/core': 0.9.1(@internationalized/date@3.12.0)(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(tailwindcss@4.2.2) 4256 - '@foxui/text': 0.8.5(@internationalized/date@3.12.0)(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(@tiptap/extension-code-block@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3))(@tiptap/extensions@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3))(highlight.js@11.11.1)(svelte@5.55.4(@typescript-eslint/types@8.58.2))(tailwindcss@4.2.2) 4257 - '@foxui/time': 0.8.5(@internationalized/date@3.12.0)(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(tailwindcss@4.2.2) 4258 - '@use-gesture/vanilla': 10.3.1 4259 - bits-ui: 2.17.3(@internationalized/date@3.12.0)(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 4260 - emoji-picker-element: 1.29.1 4261 - hls.js: 1.6.16 4262 - is-emoji-supported: 0.0.5 4263 - plyr: 3.8.4 4264 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 4265 - tailwindcss: 4.2.2 4266 - transitivePeerDependencies: 4267 - - '@internationalized/date' 4268 - - '@sveltejs/kit' 4269 - - '@tiptap/extension-code-block' 4270 - - '@tiptap/extensions' 4271 - - highlight.js 4272 - - react 4273 - - react-dom 4274 - - vue 4275 - 4276 - '@foxui/text@0.8.5(@internationalized/date@3.12.0)(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(@tiptap/extension-code-block@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3))(@tiptap/extensions@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3))(highlight.js@11.11.1)(svelte@5.55.4(@typescript-eslint/types@8.58.2))(tailwindcss@4.2.2)': 4277 - dependencies: 4278 - '@floating-ui/dom': 1.7.6 4279 - '@foxui/core': 0.9.1(@internationalized/date@3.12.0)(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(tailwindcss@4.2.2) 4280 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 4281 - '@tiptap/extension-bubble-menu': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3) 4282 - '@tiptap/extension-code-block-lowlight': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/extension-code-block@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3)(highlight.js@11.11.1)(lowlight@3.3.0) 4283 - '@tiptap/extension-document': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3)) 4284 - '@tiptap/extension-dropcursor': 3.22.3(@tiptap/extensions@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3)) 4285 - '@tiptap/extension-floating-menu': 3.22.3(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3) 4286 - '@tiptap/extension-history': 3.22.3(@tiptap/extensions@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3)) 4287 - '@tiptap/extension-image': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3)) 4288 - '@tiptap/extension-link': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3) 4289 - '@tiptap/extension-paragraph': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3)) 4290 - '@tiptap/extension-placeholder': 3.22.3(@tiptap/extensions@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3)) 4291 - '@tiptap/extension-strike': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3)) 4292 - '@tiptap/extension-text': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3)) 4293 - '@tiptap/extension-typography': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3)) 4294 - '@tiptap/extension-underline': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3)) 4295 - '@tiptap/markdown': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3) 4296 - '@tiptap/pm': 3.22.3 4297 - '@tiptap/starter-kit': 3.22.3 4298 - '@tiptap/suggestion': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3) 4299 - bits-ui: 2.17.3(@internationalized/date@3.12.0)(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 4300 - lowlight: 3.3.0 4301 - state: link:@tiptap/pm/state 4302 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 4303 - svelte-tiptap: 3.0.1(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/extension-bubble-menu@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3))(@tiptap/extension-floating-menu@3.22.3(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3)(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 4304 - tailwindcss: 4.2.2 4305 - transitivePeerDependencies: 4306 - - '@internationalized/date' 4307 - - '@sveltejs/kit' 4308 - - '@tiptap/extension-code-block' 4309 - - '@tiptap/extensions' 4310 - - highlight.js 4311 - - react 4312 - - react-dom 4313 - - vue 4314 - 4315 - '@foxui/time@0.8.5(@internationalized/date@3.12.0)(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(tailwindcss@4.2.2)': 4316 - dependencies: 4317 - '@foxui/core': 0.9.1(@internationalized/date@3.12.0)(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(tailwindcss@4.2.2) 4318 - '@number-flow/svelte': 0.4.0(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 4319 - bits-ui: 2.17.3(@internationalized/date@3.12.0)(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 4320 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 4321 - tailwindcss: 4.2.2 4322 - transitivePeerDependencies: 4323 - - '@internationalized/date' 4324 - - '@sveltejs/kit' 4325 - - react 4326 - - react-dom 4327 - - vue 4328 - 4329 - '@humanfs/core@0.19.1': {} 4330 - 4331 - '@humanfs/node@0.16.7': 4332 - dependencies: 4333 - '@humanfs/core': 0.19.1 4334 - '@humanwhocodes/retry': 0.4.3 4335 - 4336 - '@humanwhocodes/module-importer@1.0.1': {} 4337 - 4338 - '@humanwhocodes/retry@0.4.3': {} 4339 - 4340 2233 '@img/colour@1.0.0': {} 4341 2234 4342 2235 '@img/sharp-darwin-arm64@0.34.5': ··· 4440 2333 optionalDependencies: 4441 2334 '@types/node': 25.5.0 4442 2335 4443 - '@internationalized/date@3.12.0': 4444 - dependencies: 4445 - '@swc/helpers': 0.5.21 4446 - 4447 - '@jis3r/icons@2.7.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))': 4448 - dependencies: 4449 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 4450 - 4451 2336 '@jridgewell/gen-mapping@0.3.13': 4452 2337 dependencies: 4453 2338 '@jridgewell/sourcemap-codec': 1.5.5 4454 - '@jridgewell/trace-mapping': 0.3.31 4455 - 4456 - '@jridgewell/remapping@2.3.5': 4457 - dependencies: 4458 - '@jridgewell/gen-mapping': 0.3.13 4459 2339 '@jridgewell/trace-mapping': 0.3.31 4460 2340 4461 2341 '@jridgewell/resolve-uri@3.1.2': {} ··· 4472 2352 '@jridgewell/resolve-uri': 3.1.2 4473 2353 '@jridgewell/sourcemap-codec': 1.5.5 4474 2354 4475 - '@lucide/svelte@1.8.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))': 4476 - dependencies: 4477 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 4478 - 4479 2355 '@manypkg/find-root@1.1.0': 4480 2356 dependencies: 4481 2357 '@babel/runtime': 7.29.2 ··· 4498 2374 4499 2375 '@mary-ext/simple-event-emitter@1.0.0': {} 4500 2376 4501 - '@napi-rs/wasm-runtime@1.1.1': 4502 - dependencies: 4503 - '@emnapi/core': 1.9.0 4504 - '@emnapi/runtime': 1.8.1 4505 - '@tybys/wasm-util': 0.10.1 4506 - optional: true 4507 - 4508 2377 '@napi-rs/wasm-runtime@1.1.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)': 4509 2378 dependencies: 4510 2379 '@emnapi/core': 1.9.2 ··· 4526 2395 '@nodelib/fs.scandir': 2.1.5 4527 2396 fastq: 1.20.1 4528 2397 4529 - '@number-flow/svelte@0.4.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))': 4530 - dependencies: 4531 - esm-env: 1.2.2 4532 - number-flow: 0.6.0 4533 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 4534 - 4535 2398 '@optique/core@0.6.11': {} 4536 2399 4537 2400 '@optique/run@0.6.11': 4538 2401 dependencies: 4539 2402 '@optique/core': 0.6.11 4540 2403 4541 - '@oxc-project/runtime@0.115.0': {} 4542 - 4543 - '@oxc-project/types@0.115.0': {} 4544 - 4545 2404 '@oxc-project/types@0.124.0': {} 4546 - 4547 - '@polka/url@1.0.0-next.29': {} 4548 2405 4549 2406 '@poppinss/colors@4.1.6': 4550 2407 dependencies: ··· 4558 2415 4559 2416 '@poppinss/exception@1.2.3': {} 4560 2417 4561 - '@remirror/core-constants@3.0.0': {} 4562 - 4563 2418 '@rolldown/binding-android-arm64@1.0.0-rc.15': 4564 2419 optional: true 4565 2420 4566 - '@rolldown/binding-android-arm64@1.0.0-rc.9': 4567 - optional: true 4568 - 4569 2421 '@rolldown/binding-darwin-arm64@1.0.0-rc.15': 4570 2422 optional: true 4571 2423 4572 - '@rolldown/binding-darwin-arm64@1.0.0-rc.9': 4573 - optional: true 4574 - 4575 2424 '@rolldown/binding-darwin-x64@1.0.0-rc.15': 4576 2425 optional: true 4577 2426 4578 - '@rolldown/binding-darwin-x64@1.0.0-rc.9': 4579 - optional: true 4580 - 4581 2427 '@rolldown/binding-freebsd-x64@1.0.0-rc.15': 4582 2428 optional: true 4583 2429 4584 - '@rolldown/binding-freebsd-x64@1.0.0-rc.9': 4585 - optional: true 4586 - 4587 2430 '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15': 4588 2431 optional: true 4589 2432 4590 - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.9': 4591 - optional: true 4592 - 4593 2433 '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15': 4594 - optional: true 4595 - 4596 - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.9': 4597 2434 optional: true 4598 2435 4599 2436 '@rolldown/binding-linux-arm64-musl@1.0.0-rc.15': 4600 - optional: true 4601 - 4602 - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.9': 4603 2437 optional: true 4604 2438 4605 2439 '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15': 4606 2440 optional: true 4607 2441 4608 - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.9': 4609 - optional: true 4610 - 4611 2442 '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15': 4612 2443 optional: true 4613 2444 4614 - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.9': 4615 - optional: true 4616 - 4617 2445 '@rolldown/binding-linux-x64-gnu@1.0.0-rc.15': 4618 2446 optional: true 4619 2447 4620 - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.9': 4621 - optional: true 4622 - 4623 2448 '@rolldown/binding-linux-x64-musl@1.0.0-rc.15': 4624 2449 optional: true 4625 2450 4626 - '@rolldown/binding-linux-x64-musl@1.0.0-rc.9': 4627 - optional: true 4628 - 4629 2451 '@rolldown/binding-openharmony-arm64@1.0.0-rc.15': 4630 2452 optional: true 4631 2453 4632 - '@rolldown/binding-openharmony-arm64@1.0.0-rc.9': 4633 - optional: true 4634 - 4635 2454 '@rolldown/binding-wasm32-wasi@1.0.0-rc.15': 4636 2455 dependencies: 4637 2456 '@emnapi/core': 1.9.2 4638 2457 '@emnapi/runtime': 1.9.2 4639 2458 '@napi-rs/wasm-runtime': 1.1.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) 4640 - optional: true 4641 - 4642 - '@rolldown/binding-wasm32-wasi@1.0.0-rc.9': 4643 - dependencies: 4644 - '@napi-rs/wasm-runtime': 1.1.1 4645 2459 optional: true 4646 2460 4647 2461 '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15': 4648 2462 optional: true 4649 2463 4650 - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.9': 4651 - optional: true 4652 - 4653 2464 '@rolldown/binding-win32-x64-msvc@1.0.0-rc.15': 4654 2465 optional: true 4655 2466 4656 - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.9': 4657 - optional: true 4658 - 4659 2467 '@rolldown/pluginutils@1.0.0-rc.15': {} 4660 - 4661 - '@rolldown/pluginutils@1.0.0-rc.9': {} 4662 2468 4663 2469 '@rollup/rollup-android-arm-eabi@4.60.1': 4664 2470 optional: true ··· 4741 2547 4742 2548 '@standard-schema/spec@1.1.0': {} 4743 2549 4744 - '@sveltejs/acorn-typescript@1.0.9(acorn@8.16.0)': 4745 - dependencies: 4746 - acorn: 8.16.0 4747 - 4748 - '@sveltejs/adapter-cloudflare@7.2.8(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(wrangler@4.82.2(@cloudflare/workers-types@4.20260414.1))': 4749 - dependencies: 4750 - '@cloudflare/workers-types': 4.20260414.1 4751 - '@sveltejs/kit': 2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)) 4752 - worktop: 0.8.0-next.18 4753 - wrangler: 4.82.2(@cloudflare/workers-types@4.20260414.1) 4754 - 4755 - '@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0))': 4756 - dependencies: 4757 - '@standard-schema/spec': 1.1.0 4758 - '@sveltejs/acorn-typescript': 1.0.9(acorn@8.16.0) 4759 - '@sveltejs/vite-plugin-svelte': 7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)) 4760 - '@types/cookie': 0.6.0 4761 - acorn: 8.16.0 4762 - cookie: 0.6.0 4763 - devalue: 5.7.1 4764 - esm-env: 1.2.2 4765 - kleur: 4.1.5 4766 - magic-string: 0.30.21 4767 - mrmime: 2.0.1 4768 - set-cookie-parser: 3.1.0 4769 - sirv: 3.0.2 4770 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 4771 - vite: 8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0) 4772 - optionalDependencies: 4773 - typescript: 6.0.2 4774 - 4775 - '@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0))': 4776 - dependencies: 4777 - deepmerge: 4.3.1 4778 - magic-string: 0.30.21 4779 - obug: 2.1.1 4780 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 4781 - vite: 8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0) 4782 - vitefu: 1.1.3(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)) 4783 - 4784 - '@swc/helpers@0.5.21': 4785 - dependencies: 4786 - tslib: 2.8.1 4787 - 4788 - '@tailwindcss/forms@0.5.11(tailwindcss@4.2.2)': 4789 - dependencies: 4790 - mini-svg-data-uri: 1.4.4 4791 - tailwindcss: 4.2.2 4792 - 4793 - '@tailwindcss/node@4.2.2': 4794 - dependencies: 4795 - '@jridgewell/remapping': 2.3.5 4796 - enhanced-resolve: 5.20.1 4797 - jiti: 2.6.1 4798 - lightningcss: 1.32.0 4799 - magic-string: 0.30.21 4800 - source-map-js: 1.2.1 4801 - tailwindcss: 4.2.2 4802 - 4803 - '@tailwindcss/oxide-android-arm64@4.2.2': 4804 - optional: true 4805 - 4806 - '@tailwindcss/oxide-darwin-arm64@4.2.2': 4807 - optional: true 4808 - 4809 - '@tailwindcss/oxide-darwin-x64@4.2.2': 4810 - optional: true 4811 - 4812 - '@tailwindcss/oxide-freebsd-x64@4.2.2': 4813 - optional: true 4814 - 4815 - '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2': 4816 - optional: true 4817 - 4818 - '@tailwindcss/oxide-linux-arm64-gnu@4.2.2': 4819 - optional: true 4820 - 4821 - '@tailwindcss/oxide-linux-arm64-musl@4.2.2': 4822 - optional: true 4823 - 4824 - '@tailwindcss/oxide-linux-x64-gnu@4.2.2': 4825 - optional: true 4826 - 4827 - '@tailwindcss/oxide-linux-x64-musl@4.2.2': 4828 - optional: true 4829 - 4830 - '@tailwindcss/oxide-wasm32-wasi@4.2.2': 4831 - optional: true 4832 - 4833 - '@tailwindcss/oxide-win32-arm64-msvc@4.2.2': 4834 - optional: true 4835 - 4836 - '@tailwindcss/oxide-win32-x64-msvc@4.2.2': 4837 - optional: true 4838 - 4839 - '@tailwindcss/oxide@4.2.2': 4840 - optionalDependencies: 4841 - '@tailwindcss/oxide-android-arm64': 4.2.2 4842 - '@tailwindcss/oxide-darwin-arm64': 4.2.2 4843 - '@tailwindcss/oxide-darwin-x64': 4.2.2 4844 - '@tailwindcss/oxide-freebsd-x64': 4.2.2 4845 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.2 4846 - '@tailwindcss/oxide-linux-arm64-gnu': 4.2.2 4847 - '@tailwindcss/oxide-linux-arm64-musl': 4.2.2 4848 - '@tailwindcss/oxide-linux-x64-gnu': 4.2.2 4849 - '@tailwindcss/oxide-linux-x64-musl': 4.2.2 4850 - '@tailwindcss/oxide-wasm32-wasi': 4.2.2 4851 - '@tailwindcss/oxide-win32-arm64-msvc': 4.2.2 4852 - '@tailwindcss/oxide-win32-x64-msvc': 4.2.2 4853 - 4854 - '@tailwindcss/vite@4.2.2(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0))': 4855 - dependencies: 4856 - '@tailwindcss/node': 4.2.2 4857 - '@tailwindcss/oxide': 4.2.2 4858 - tailwindcss: 4.2.2 4859 - vite: 8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0) 4860 - 4861 - '@tiptap/core@3.22.3(@tiptap/pm@3.22.3)': 4862 - dependencies: 4863 - '@tiptap/pm': 3.22.3 4864 - 4865 - '@tiptap/extension-blockquote@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))': 4866 - dependencies: 4867 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 4868 - 4869 - '@tiptap/extension-bold@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))': 4870 - dependencies: 4871 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 4872 - 4873 - '@tiptap/extension-bubble-menu@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3)': 4874 - dependencies: 4875 - '@floating-ui/dom': 1.7.6 4876 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 4877 - '@tiptap/pm': 3.22.3 4878 - 4879 - '@tiptap/extension-bullet-list@3.22.3(@tiptap/extension-list@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3))': 4880 - dependencies: 4881 - '@tiptap/extension-list': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3) 4882 - 4883 - '@tiptap/extension-code-block-lowlight@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/extension-code-block@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3)(highlight.js@11.11.1)(lowlight@3.3.0)': 4884 - dependencies: 4885 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 4886 - '@tiptap/extension-code-block': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3) 4887 - '@tiptap/pm': 3.22.3 4888 - highlight.js: 11.11.1 4889 - lowlight: 3.3.0 4890 - 4891 - '@tiptap/extension-code-block@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3)': 4892 - dependencies: 4893 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 4894 - '@tiptap/pm': 3.22.3 4895 - 4896 - '@tiptap/extension-code@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))': 4897 - dependencies: 4898 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 4899 - 4900 - '@tiptap/extension-document@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))': 4901 - dependencies: 4902 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 4903 - 4904 - '@tiptap/extension-dropcursor@3.22.3(@tiptap/extensions@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3))': 4905 - dependencies: 4906 - '@tiptap/extensions': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3) 4907 - 4908 - '@tiptap/extension-floating-menu@3.22.3(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3)': 4909 - dependencies: 4910 - '@floating-ui/dom': 1.7.6 4911 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 4912 - '@tiptap/pm': 3.22.3 4913 - 4914 - '@tiptap/extension-gapcursor@3.22.3(@tiptap/extensions@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3))': 4915 - dependencies: 4916 - '@tiptap/extensions': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3) 4917 - 4918 - '@tiptap/extension-hard-break@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))': 4919 - dependencies: 4920 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 4921 - 4922 - '@tiptap/extension-heading@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))': 4923 - dependencies: 4924 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 4925 - 4926 - '@tiptap/extension-history@3.22.3(@tiptap/extensions@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3))': 4927 - dependencies: 4928 - '@tiptap/extensions': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3) 4929 - 4930 - '@tiptap/extension-horizontal-rule@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3)': 4931 - dependencies: 4932 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 4933 - '@tiptap/pm': 3.22.3 4934 - 4935 - '@tiptap/extension-image@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))': 4936 - dependencies: 4937 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 4938 - 4939 - '@tiptap/extension-italic@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))': 4940 - dependencies: 4941 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 4942 - 4943 - '@tiptap/extension-link@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3)': 4944 - dependencies: 4945 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 4946 - '@tiptap/pm': 3.22.3 4947 - linkifyjs: 4.3.2 4948 - 4949 - '@tiptap/extension-list-item@3.22.3(@tiptap/extension-list@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3))': 4950 - dependencies: 4951 - '@tiptap/extension-list': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3) 4952 - 4953 - '@tiptap/extension-list-keymap@3.22.3(@tiptap/extension-list@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3))': 4954 - dependencies: 4955 - '@tiptap/extension-list': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3) 4956 - 4957 - '@tiptap/extension-list@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3)': 4958 - dependencies: 4959 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 4960 - '@tiptap/pm': 3.22.3 4961 - 4962 - '@tiptap/extension-ordered-list@3.22.3(@tiptap/extension-list@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3))': 4963 - dependencies: 4964 - '@tiptap/extension-list': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3) 4965 - 4966 - '@tiptap/extension-paragraph@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))': 4967 - dependencies: 4968 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 4969 - 4970 - '@tiptap/extension-placeholder@3.22.3(@tiptap/extensions@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3))': 4971 - dependencies: 4972 - '@tiptap/extensions': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3) 4973 - 4974 - '@tiptap/extension-strike@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))': 4975 - dependencies: 4976 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 4977 - 4978 - '@tiptap/extension-text@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))': 4979 - dependencies: 4980 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 4981 - 4982 - '@tiptap/extension-typography@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))': 4983 - dependencies: 4984 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 4985 - 4986 - '@tiptap/extension-underline@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))': 4987 - dependencies: 4988 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 4989 - 4990 - '@tiptap/extensions@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3)': 4991 - dependencies: 4992 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 4993 - '@tiptap/pm': 3.22.3 4994 - 4995 - '@tiptap/markdown@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3)': 4996 - dependencies: 4997 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 4998 - '@tiptap/pm': 3.22.3 4999 - marked: 17.0.6 5000 - 5001 - '@tiptap/pm@3.22.3': 5002 - dependencies: 5003 - prosemirror-changeset: 2.4.1 5004 - prosemirror-collab: 1.3.1 5005 - prosemirror-commands: 1.7.1 5006 - prosemirror-dropcursor: 1.8.2 5007 - prosemirror-gapcursor: 1.4.1 5008 - prosemirror-history: 1.5.0 5009 - prosemirror-inputrules: 1.5.1 5010 - prosemirror-keymap: 1.2.3 5011 - prosemirror-markdown: 1.13.4 5012 - prosemirror-menu: 1.3.0 5013 - prosemirror-model: 1.25.4 5014 - prosemirror-schema-basic: 1.2.4 5015 - prosemirror-schema-list: 1.5.1 5016 - prosemirror-state: 1.4.4 5017 - prosemirror-tables: 1.8.5 5018 - prosemirror-trailing-node: 3.0.0(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8) 5019 - prosemirror-transform: 1.12.0 5020 - prosemirror-view: 1.41.8 5021 - 5022 - '@tiptap/starter-kit@3.22.3': 5023 - dependencies: 5024 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 5025 - '@tiptap/extension-blockquote': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3)) 5026 - '@tiptap/extension-bold': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3)) 5027 - '@tiptap/extension-bullet-list': 3.22.3(@tiptap/extension-list@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3)) 5028 - '@tiptap/extension-code': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3)) 5029 - '@tiptap/extension-code-block': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3) 5030 - '@tiptap/extension-document': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3)) 5031 - '@tiptap/extension-dropcursor': 3.22.3(@tiptap/extensions@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3)) 5032 - '@tiptap/extension-gapcursor': 3.22.3(@tiptap/extensions@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3)) 5033 - '@tiptap/extension-hard-break': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3)) 5034 - '@tiptap/extension-heading': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3)) 5035 - '@tiptap/extension-horizontal-rule': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3) 5036 - '@tiptap/extension-italic': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3)) 5037 - '@tiptap/extension-link': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3) 5038 - '@tiptap/extension-list': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3) 5039 - '@tiptap/extension-list-item': 3.22.3(@tiptap/extension-list@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3)) 5040 - '@tiptap/extension-list-keymap': 3.22.3(@tiptap/extension-list@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3)) 5041 - '@tiptap/extension-ordered-list': 3.22.3(@tiptap/extension-list@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3)) 5042 - '@tiptap/extension-paragraph': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3)) 5043 - '@tiptap/extension-strike': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3)) 5044 - '@tiptap/extension-text': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3)) 5045 - '@tiptap/extension-underline': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3)) 5046 - '@tiptap/extensions': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3) 5047 - '@tiptap/pm': 3.22.3 5048 - 5049 - '@tiptap/suggestion@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3)': 5050 - dependencies: 5051 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 5052 - '@tiptap/pm': 3.22.3 5053 - 5054 2550 '@tybys/wasm-util@0.10.1': 5055 2551 dependencies: 5056 2552 tslib: 2.8.1 ··· 5061 2557 '@types/deep-eql': 4.0.2 5062 2558 assertion-error: 2.0.1 5063 2559 5064 - '@types/cookie@0.6.0': {} 5065 - 5066 2560 '@types/deep-eql@4.0.2': {} 5067 2561 5068 - '@types/esrecurse@4.3.1': {} 5069 - 5070 2562 '@types/estree@1.0.8': {} 5071 2563 5072 - '@types/hast@3.0.4': 5073 - dependencies: 5074 - '@types/unist': 3.0.3 5075 - 5076 - '@types/json-schema@7.0.15': {} 5077 - 5078 - '@types/linkify-it@5.0.0': {} 5079 - 5080 - '@types/markdown-it@14.1.2': 5081 - dependencies: 5082 - '@types/linkify-it': 5.0.0 5083 - '@types/mdurl': 2.0.0 5084 - 5085 - '@types/mdurl@2.0.0': {} 5086 - 5087 2564 '@types/node@12.20.55': {} 5088 2565 5089 2566 '@types/node@25.5.0': ··· 5096 2573 pg-protocol: 1.13.0 5097 2574 pg-types: 2.2.0 5098 2575 5099 - '@types/trusted-types@2.0.7': {} 5100 - 5101 - '@types/unist@3.0.3': {} 5102 - 5103 - '@typescript-eslint/eslint-plugin@8.58.2(@typescript-eslint/parser@8.58.2(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2))(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2)': 5104 - dependencies: 5105 - '@eslint-community/regexpp': 4.12.2 5106 - '@typescript-eslint/parser': 8.58.2(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2) 5107 - '@typescript-eslint/scope-manager': 8.58.2 5108 - '@typescript-eslint/type-utils': 8.58.2(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2) 5109 - '@typescript-eslint/utils': 8.58.2(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2) 5110 - '@typescript-eslint/visitor-keys': 8.58.2 5111 - eslint: 10.2.0(jiti@2.6.1) 5112 - ignore: 7.0.5 5113 - natural-compare: 1.4.0 5114 - ts-api-utils: 2.5.0(typescript@6.0.2) 5115 - typescript: 6.0.2 5116 - transitivePeerDependencies: 5117 - - supports-color 5118 - 5119 - '@typescript-eslint/parser@8.58.2(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2)': 5120 - dependencies: 5121 - '@typescript-eslint/scope-manager': 8.58.2 5122 - '@typescript-eslint/types': 8.58.2 5123 - '@typescript-eslint/typescript-estree': 8.58.2(typescript@6.0.2) 5124 - '@typescript-eslint/visitor-keys': 8.58.2 5125 - debug: 4.4.3 5126 - eslint: 10.2.0(jiti@2.6.1) 5127 - typescript: 6.0.2 5128 - transitivePeerDependencies: 5129 - - supports-color 5130 - 5131 - '@typescript-eslint/project-service@8.58.2(typescript@6.0.2)': 5132 - dependencies: 5133 - '@typescript-eslint/tsconfig-utils': 8.58.2(typescript@6.0.2) 5134 - '@typescript-eslint/types': 8.58.2 5135 - debug: 4.4.3 5136 - typescript: 6.0.2 5137 - transitivePeerDependencies: 5138 - - supports-color 5139 - 5140 - '@typescript-eslint/scope-manager@8.58.2': 5141 - dependencies: 5142 - '@typescript-eslint/types': 8.58.2 5143 - '@typescript-eslint/visitor-keys': 8.58.2 5144 - 5145 - '@typescript-eslint/tsconfig-utils@8.58.2(typescript@6.0.2)': 5146 - dependencies: 5147 - typescript: 6.0.2 5148 - 5149 - '@typescript-eslint/type-utils@8.58.2(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2)': 5150 - dependencies: 5151 - '@typescript-eslint/types': 8.58.2 5152 - '@typescript-eslint/typescript-estree': 8.58.2(typescript@6.0.2) 5153 - '@typescript-eslint/utils': 8.58.2(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2) 5154 - debug: 4.4.3 5155 - eslint: 10.2.0(jiti@2.6.1) 5156 - ts-api-utils: 2.5.0(typescript@6.0.2) 5157 - typescript: 6.0.2 5158 - transitivePeerDependencies: 5159 - - supports-color 5160 - 5161 - '@typescript-eslint/types@8.58.2': {} 5162 - 5163 - '@typescript-eslint/typescript-estree@8.58.2(typescript@6.0.2)': 5164 - dependencies: 5165 - '@typescript-eslint/project-service': 8.58.2(typescript@6.0.2) 5166 - '@typescript-eslint/tsconfig-utils': 8.58.2(typescript@6.0.2) 5167 - '@typescript-eslint/types': 8.58.2 5168 - '@typescript-eslint/visitor-keys': 8.58.2 5169 - debug: 4.4.3 5170 - minimatch: 10.2.5 5171 - semver: 7.7.4 5172 - tinyglobby: 0.2.15 5173 - ts-api-utils: 2.5.0(typescript@6.0.2) 5174 - typescript: 6.0.2 5175 - transitivePeerDependencies: 5176 - - supports-color 5177 - 5178 - '@typescript-eslint/utils@8.58.2(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2)': 5179 - dependencies: 5180 - '@eslint-community/eslint-utils': 4.9.1(eslint@10.2.0(jiti@2.6.1)) 5181 - '@typescript-eslint/scope-manager': 8.58.2 5182 - '@typescript-eslint/types': 8.58.2 5183 - '@typescript-eslint/typescript-estree': 8.58.2(typescript@6.0.2) 5184 - eslint: 10.2.0(jiti@2.6.1) 5185 - typescript: 6.0.2 5186 - transitivePeerDependencies: 5187 - - supports-color 5188 - 5189 - '@typescript-eslint/visitor-keys@8.58.2': 5190 - dependencies: 5191 - '@typescript-eslint/types': 8.58.2 5192 - eslint-visitor-keys: 5.0.1 5193 - 5194 - '@use-gesture/core@10.3.1': {} 5195 - 5196 - '@use-gesture/vanilla@10.3.1': 5197 - dependencies: 5198 - '@use-gesture/core': 10.3.1 5199 - 5200 2576 '@vitest/expect@4.1.0': 5201 2577 dependencies: 5202 2578 '@standard-schema/spec': 1.1.0 ··· 5206 2582 chai: 6.2.2 5207 2583 tinyrainbow: 3.1.0 5208 2584 5209 - '@vitest/mocker@4.1.0(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.0)(tsx@4.21.0))': 2585 + '@vitest/mocker@4.1.0(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.0)(jiti@2.6.1)(tsx@4.21.0))': 5210 2586 dependencies: 5211 2587 '@vitest/spy': 4.1.0 5212 2588 estree-walker: 3.0.3 5213 2589 magic-string: 0.30.21 5214 2590 optionalDependencies: 5215 - vite: 8.0.0(@types/node@25.5.0)(esbuild@0.27.0)(tsx@4.21.0) 2591 + vite: 8.0.8(@types/node@25.5.0)(esbuild@0.27.0)(jiti@2.6.1)(tsx@4.21.0) 5216 2592 5217 2593 '@vitest/pretty-format@4.1.0': 5218 2594 dependencies: ··· 5238 2614 convert-source-map: 2.0.0 5239 2615 tinyrainbow: 3.1.0 5240 2616 5241 - acorn-jsx@5.3.2(acorn@8.16.0): 5242 - dependencies: 5243 - acorn: 8.16.0 5244 - 5245 2617 acorn@8.16.0: {} 5246 2618 5247 - ajv@6.14.0: 5248 - dependencies: 5249 - fast-deep-equal: 3.1.3 5250 - fast-json-stable-stringify: 2.1.0 5251 - json-schema-traverse: 0.4.1 5252 - uri-js: 4.4.1 5253 - 5254 2619 ansi-colors@4.1.3: {} 5255 2620 5256 2621 ansi-regex@5.0.1: {} ··· 5262 2627 sprintf-js: 1.0.3 5263 2628 5264 2629 argparse@2.0.1: {} 5265 - 5266 - aria-query@5.3.1: {} 5267 2630 5268 2631 array-union@2.1.0: {} 5269 2632 5270 2633 assertion-error@2.0.1: {} 5271 2634 5272 - axobject-query@4.1.0: {} 5273 - 5274 - balanced-match@4.0.4: {} 5275 - 5276 2635 better-path-resolve@1.0.0: 5277 2636 dependencies: 5278 2637 is-windows: 1.0.2 5279 2638 5280 - bits-ui@2.17.3(@internationalized/date@3.12.0)(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)): 5281 - dependencies: 5282 - '@floating-ui/core': 1.7.5 5283 - '@floating-ui/dom': 1.7.6 5284 - '@internationalized/date': 3.12.0 5285 - esm-env: 1.2.2 5286 - runed: 0.35.1(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 5287 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 5288 - svelte-toolbelt: 0.10.6(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 5289 - tabbable: 6.4.0 5290 - transitivePeerDependencies: 5291 - - '@sveltejs/kit' 5292 - 5293 2639 blake3-wasm@2.1.5: {} 5294 2640 5295 - brace-expansion@5.0.5: 5296 - dependencies: 5297 - balanced-match: 4.0.4 5298 - 5299 2641 braces@3.0.3: 5300 2642 dependencies: 5301 2643 fill-range: 7.1.1 ··· 5315 2657 dependencies: 5316 2658 readdirp: 4.1.2 5317 2659 5318 - clsx@2.1.1: {} 5319 - 5320 2660 commander@4.1.1: {} 5321 2661 5322 2662 confbox@0.1.8: {} ··· 5325 2665 5326 2666 convert-source-map@2.0.0: {} 5327 2667 5328 - cookie@0.6.0: {} 5329 - 5330 2668 cookie@1.1.1: {} 5331 2669 5332 - core-js@3.49.0: {} 5333 - 5334 - crelt@1.0.6: {} 5335 - 5336 2670 cross-spawn@7.0.6: 5337 2671 dependencies: 5338 2672 path-key: 3.1.1 5339 2673 shebang-command: 2.0.0 5340 2674 which: 2.0.2 5341 - 5342 - cssesc@3.0.0: {} 5343 - 5344 - custom-event-polyfill@1.0.7: {} 5345 2675 5346 2676 debug@4.4.3: 5347 2677 dependencies: 5348 2678 ms: 2.1.3 5349 2679 5350 - deep-is@0.1.4: {} 5351 - 5352 - deepmerge@4.3.1: {} 5353 - 5354 - dequal@2.0.3: {} 5355 - 5356 2680 detect-indent@6.1.0: {} 5357 2681 5358 2682 detect-libc@2.1.2: {} 5359 2683 5360 - devalue@5.7.1: {} 5361 - 5362 - devlop@1.1.0: 5363 - dependencies: 5364 - dequal: 2.0.3 5365 - 5366 2684 dir-glob@3.0.1: 5367 2685 dependencies: 5368 2686 path-type: 4.0.0 5369 2687 5370 - dompurify@3.4.0: 5371 - optionalDependencies: 5372 - '@types/trusted-types': 2.0.7 5373 - 5374 - emoji-picker-element@1.29.1: {} 5375 - 5376 - enhanced-resolve@5.20.1: 5377 - dependencies: 5378 - graceful-fs: 4.2.11 5379 - tapable: 2.3.2 5380 - 5381 2688 enquirer@2.4.1: 5382 2689 dependencies: 5383 2690 ansi-colors: 4.1.3 5384 2691 strip-ansi: 6.0.1 5385 - 5386 - entities@4.5.0: {} 5387 2692 5388 2693 error-stack-parser-es@1.0.5: {} 5389 2694 ··· 5418 2723 '@esbuild/win32-ia32': 0.27.0 5419 2724 '@esbuild/win32-x64': 0.27.0 5420 2725 5421 - esbuild@0.27.3: 5422 - optionalDependencies: 5423 - '@esbuild/aix-ppc64': 0.27.3 5424 - '@esbuild/android-arm': 0.27.3 5425 - '@esbuild/android-arm64': 0.27.3 5426 - '@esbuild/android-x64': 0.27.3 5427 - '@esbuild/darwin-arm64': 0.27.3 5428 - '@esbuild/darwin-x64': 0.27.3 5429 - '@esbuild/freebsd-arm64': 0.27.3 5430 - '@esbuild/freebsd-x64': 0.27.3 5431 - '@esbuild/linux-arm': 0.27.3 5432 - '@esbuild/linux-arm64': 0.27.3 5433 - '@esbuild/linux-ia32': 0.27.3 5434 - '@esbuild/linux-loong64': 0.27.3 5435 - '@esbuild/linux-mips64el': 0.27.3 5436 - '@esbuild/linux-ppc64': 0.27.3 5437 - '@esbuild/linux-riscv64': 0.27.3 5438 - '@esbuild/linux-s390x': 0.27.3 5439 - '@esbuild/linux-x64': 0.27.3 5440 - '@esbuild/netbsd-arm64': 0.27.3 5441 - '@esbuild/netbsd-x64': 0.27.3 5442 - '@esbuild/openbsd-arm64': 0.27.3 5443 - '@esbuild/openbsd-x64': 0.27.3 5444 - '@esbuild/openharmony-arm64': 0.27.3 5445 - '@esbuild/sunos-x64': 0.27.3 5446 - '@esbuild/win32-arm64': 0.27.3 5447 - '@esbuild/win32-ia32': 0.27.3 5448 - '@esbuild/win32-x64': 0.27.3 5449 - 5450 - escape-string-regexp@4.0.0: {} 5451 - 5452 - eslint-config-prettier@10.1.8(eslint@10.2.0(jiti@2.6.1)): 5453 - dependencies: 5454 - eslint: 10.2.0(jiti@2.6.1) 5455 - 5456 - eslint-plugin-svelte@3.17.0(eslint@10.2.0(jiti@2.6.1))(svelte@5.55.4(@typescript-eslint/types@8.58.2)): 5457 - dependencies: 5458 - '@eslint-community/eslint-utils': 4.9.1(eslint@10.2.0(jiti@2.6.1)) 5459 - '@jridgewell/sourcemap-codec': 1.5.5 5460 - eslint: 10.2.0(jiti@2.6.1) 5461 - esutils: 2.0.3 5462 - globals: 16.5.0 5463 - known-css-properties: 0.37.0 5464 - postcss: 8.5.8 5465 - postcss-load-config: 3.1.4(postcss@8.5.8) 5466 - postcss-safe-parser: 7.0.1(postcss@8.5.8) 5467 - semver: 7.7.4 5468 - svelte-eslint-parser: 1.6.0(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 5469 - optionalDependencies: 5470 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 5471 - transitivePeerDependencies: 5472 - - ts-node 5473 - 5474 - eslint-scope@8.4.0: 5475 - dependencies: 5476 - esrecurse: 4.3.0 5477 - estraverse: 5.3.0 5478 - 5479 - eslint-scope@9.1.2: 5480 - dependencies: 5481 - '@types/esrecurse': 4.3.1 5482 - '@types/estree': 1.0.8 5483 - esrecurse: 4.3.0 5484 - estraverse: 5.3.0 5485 - 5486 - eslint-visitor-keys@3.4.3: {} 5487 - 5488 - eslint-visitor-keys@4.2.1: {} 5489 - 5490 - eslint-visitor-keys@5.0.1: {} 5491 - 5492 - eslint@10.2.0(jiti@2.6.1): 5493 - dependencies: 5494 - '@eslint-community/eslint-utils': 4.9.1(eslint@10.2.0(jiti@2.6.1)) 5495 - '@eslint-community/regexpp': 4.12.2 5496 - '@eslint/config-array': 0.23.5 5497 - '@eslint/config-helpers': 0.5.5 5498 - '@eslint/core': 1.2.1 5499 - '@eslint/plugin-kit': 0.7.1 5500 - '@humanfs/node': 0.16.7 5501 - '@humanwhocodes/module-importer': 1.0.1 5502 - '@humanwhocodes/retry': 0.4.3 5503 - '@types/estree': 1.0.8 5504 - ajv: 6.14.0 5505 - cross-spawn: 7.0.6 5506 - debug: 4.4.3 5507 - escape-string-regexp: 4.0.0 5508 - eslint-scope: 9.1.2 5509 - eslint-visitor-keys: 5.0.1 5510 - espree: 11.2.0 5511 - esquery: 1.7.0 5512 - esutils: 2.0.3 5513 - fast-deep-equal: 3.1.3 5514 - file-entry-cache: 8.0.0 5515 - find-up: 5.0.0 5516 - glob-parent: 6.0.2 5517 - ignore: 5.3.2 5518 - imurmurhash: 0.1.4 5519 - is-glob: 4.0.3 5520 - json-stable-stringify-without-jsonify: 1.0.1 5521 - minimatch: 10.2.5 5522 - natural-compare: 1.4.0 5523 - optionator: 0.9.4 5524 - optionalDependencies: 5525 - jiti: 2.6.1 5526 - transitivePeerDependencies: 5527 - - supports-color 5528 - 5529 2726 esm-env@1.2.2: {} 5530 2727 5531 - espree@10.4.0: 5532 - dependencies: 5533 - acorn: 8.16.0 5534 - acorn-jsx: 5.3.2(acorn@8.16.0) 5535 - eslint-visitor-keys: 4.2.1 5536 - 5537 - espree@11.2.0: 5538 - dependencies: 5539 - acorn: 8.16.0 5540 - acorn-jsx: 5.3.2(acorn@8.16.0) 5541 - eslint-visitor-keys: 5.0.1 5542 - 5543 2728 esprima@4.0.1: {} 5544 2729 5545 - esquery@1.7.0: 5546 - dependencies: 5547 - estraverse: 5.3.0 5548 - 5549 - esrap@2.2.5(@typescript-eslint/types@8.58.2): 5550 - dependencies: 5551 - '@jridgewell/sourcemap-codec': 1.5.5 5552 - optionalDependencies: 5553 - '@typescript-eslint/types': 8.58.2 5554 - 5555 - esrecurse@4.3.0: 5556 - dependencies: 5557 - estraverse: 5.3.0 5558 - 5559 - estraverse@5.3.0: {} 5560 - 5561 2730 estree-walker@3.0.3: 5562 2731 dependencies: 5563 2732 '@types/estree': 1.0.8 5564 2733 5565 - esutils@2.0.3: {} 5566 - 5567 2734 event-target-polyfill@0.0.4: {} 5568 2735 5569 2736 expect-type@1.3.0: {} 5570 2737 5571 2738 extendable-error@0.1.7: {} 5572 - 5573 - fast-deep-equal@3.1.3: {} 5574 2739 5575 2740 fast-glob@3.3.3: 5576 2741 dependencies: ··· 5580 2745 merge2: 1.4.1 5581 2746 micromatch: 4.0.8 5582 2747 5583 - fast-json-stable-stringify@2.1.0: {} 5584 - 5585 - fast-levenshtein@2.0.6: {} 5586 - 5587 2748 fastq@1.20.1: 5588 2749 dependencies: 5589 2750 reusify: 1.1.0 ··· 5592 2753 optionalDependencies: 5593 2754 picomatch: 4.0.4 5594 2755 5595 - file-entry-cache@8.0.0: 5596 - dependencies: 5597 - flat-cache: 4.0.1 5598 - 5599 2756 fill-range@7.1.1: 5600 2757 dependencies: 5601 2758 to-regex-range: 5.0.1 ··· 5605 2762 locate-path: 5.0.0 5606 2763 path-exists: 4.0.0 5607 2764 5608 - find-up@5.0.0: 5609 - dependencies: 5610 - locate-path: 6.0.0 5611 - path-exists: 4.0.0 5612 - 5613 2765 fix-dts-default-cjs-exports@1.0.1: 5614 2766 dependencies: 5615 2767 magic-string: 0.30.21 5616 2768 mlly: 1.8.2 5617 2769 rollup: 4.60.1 5618 2770 5619 - flat-cache@4.0.1: 5620 - dependencies: 5621 - flatted: 3.4.2 5622 - keyv: 4.5.4 5623 - 5624 - flatted@3.4.2: {} 5625 - 5626 2771 fs-extra@7.0.1: 5627 2772 dependencies: 5628 2773 graceful-fs: 4.2.11 ··· 5646 2791 dependencies: 5647 2792 is-glob: 4.0.3 5648 2793 5649 - glob-parent@6.0.2: 5650 - dependencies: 5651 - is-glob: 4.0.3 5652 - 5653 - globals@16.5.0: {} 5654 - 5655 - globals@17.5.0: {} 5656 - 5657 2794 globby@11.1.0: 5658 2795 dependencies: 5659 2796 array-union: 2.1.0 ··· 5665 2802 5666 2803 graceful-fs@4.2.11: {} 5667 2804 5668 - highlight.js@11.11.1: {} 5669 - 5670 - hls.js@1.6.16: {} 5671 - 5672 2805 hono@4.12.8: {} 5673 2806 5674 2807 human-id@4.1.3: {} ··· 5679 2812 5680 2813 ignore@5.3.2: {} 5681 2814 5682 - ignore@7.0.5: {} 5683 - 5684 - imurmurhash@0.1.4: {} 5685 - 5686 - inline-style-parser@0.2.7: {} 5687 - 5688 - is-emoji-supported@0.0.5: {} 5689 - 5690 2815 is-extglob@2.1.1: {} 5691 2816 5692 2817 is-glob@4.0.3: ··· 5695 2820 5696 2821 is-number@7.0.0: {} 5697 2822 5698 - is-reference@3.0.3: 5699 - dependencies: 5700 - '@types/estree': 1.0.8 5701 - 5702 2823 is-subdir@1.2.0: 5703 2824 dependencies: 5704 2825 better-path-resolve: 1.0.0 ··· 5707 2828 5708 2829 isexe@2.0.0: {} 5709 2830 5710 - jiti@2.6.1: {} 2831 + jiti@2.6.1: 2832 + optional: true 5711 2833 5712 2834 joycon@3.1.1: {} 5713 2835 ··· 5720 2842 dependencies: 5721 2843 argparse: 2.0.1 5722 2844 5723 - json-buffer@3.0.1: {} 5724 - 5725 - json-schema-traverse@0.4.1: {} 5726 - 5727 - json-stable-stringify-without-jsonify@1.0.1: {} 5728 - 5729 2845 jsonfile@4.0.0: 5730 2846 optionalDependencies: 5731 2847 graceful-fs: 4.2.11 5732 2848 5733 - keyv@4.5.4: 5734 - dependencies: 5735 - json-buffer: 3.0.1 5736 - 5737 2849 kleur@4.1.5: {} 5738 - 5739 - known-css-properties@0.37.0: {} 5740 - 5741 - levn@0.4.1: 5742 - dependencies: 5743 - prelude-ls: 1.2.1 5744 - type-check: 0.4.0 5745 2850 5746 2851 lightningcss-android-arm64@1.32.0: 5747 2852 optional: true ··· 5792 2897 lightningcss-win32-arm64-msvc: 1.32.0 5793 2898 lightningcss-win32-x64-msvc: 1.32.0 5794 2899 5795 - lilconfig@2.1.0: {} 5796 - 5797 2900 lilconfig@3.1.3: {} 5798 2901 5799 2902 lines-and-columns@1.2.4: {} 5800 2903 5801 - linkify-it@5.0.0: 5802 - dependencies: 5803 - uc.micro: 2.1.0 5804 - 5805 - linkifyjs@4.3.2: {} 5806 - 5807 2904 load-tsconfig@0.2.5: {} 5808 - 5809 - loadjs@4.3.0: {} 5810 - 5811 - locate-character@3.0.0: {} 5812 2905 5813 2906 locate-path@5.0.0: 5814 2907 dependencies: 5815 2908 p-locate: 4.1.0 5816 2909 5817 - locate-path@6.0.0: 5818 - dependencies: 5819 - p-locate: 5.0.0 5820 - 5821 2910 lodash.startcase@4.4.0: {} 5822 2911 5823 - lowlight@3.3.0: 5824 - dependencies: 5825 - '@types/hast': 3.0.4 5826 - devlop: 1.1.0 5827 - highlight.js: 11.11.1 5828 - 5829 - lz-string@1.5.0: {} 5830 - 5831 2912 magic-string@0.30.21: 5832 2913 dependencies: 5833 2914 '@jridgewell/sourcemap-codec': 1.5.5 5834 2915 5835 - markdown-it@14.1.1: 5836 - dependencies: 5837 - argparse: 2.0.1 5838 - entities: 4.5.0 5839 - linkify-it: 5.0.0 5840 - mdurl: 2.0.0 5841 - punycode.js: 2.3.1 5842 - uc.micro: 2.1.0 5843 - 5844 - marked@17.0.6: {} 5845 - 5846 - mdurl@2.0.0: {} 5847 - 5848 2916 merge2@1.4.1: {} 5849 2917 5850 2918 micromatch@4.0.8: 5851 2919 dependencies: 5852 2920 braces: 3.0.3 5853 2921 picomatch: 2.3.2 5854 - 5855 - mini-svg-data-uri@1.4.4: {} 5856 2922 5857 2923 miniflare@4.20260205.0: 5858 2924 dependencies: ··· 5866 2932 - bufferutil 5867 2933 - utf-8-validate 5868 2934 5869 - miniflare@4.20260410.0: 5870 - dependencies: 5871 - '@cspotcode/source-map-support': 0.8.1 5872 - sharp: 0.34.5 5873 - undici: 7.24.4 5874 - workerd: 1.20260410.1 5875 - ws: 8.18.0 5876 - youch: 4.1.0-beta.10 5877 - transitivePeerDependencies: 5878 - - bufferutil 5879 - - utf-8-validate 5880 - 5881 - minimatch@10.2.5: 5882 - dependencies: 5883 - brace-expansion: 5.0.5 5884 - 5885 2935 mlly@1.8.2: 5886 2936 dependencies: 5887 2937 acorn: 8.16.0 ··· 5889 2939 pkg-types: 1.3.1 5890 2940 ufo: 1.6.3 5891 2941 5892 - mode-watcher@1.1.0(svelte@5.55.4(@typescript-eslint/types@8.58.2)): 5893 - dependencies: 5894 - runed: 0.25.0(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 5895 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 5896 - svelte-toolbelt: 0.7.1(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 5897 - 5898 2942 mri@1.2.0: {} 5899 - 5900 - mrmime@2.0.1: {} 5901 2943 5902 2944 ms@2.1.3: {} 5903 2945 ··· 5911 2953 5912 2954 nanoid@5.1.7: {} 5913 2955 5914 - natural-compare@1.4.0: {} 5915 - 5916 - number-flow@0.6.0: 5917 - dependencies: 5918 - esm-env: 1.2.2 5919 - 5920 2956 object-assign@4.1.1: {} 5921 2957 5922 2958 obug@2.1.1: {} 5923 2959 5924 - optionator@0.9.4: 5925 - dependencies: 5926 - deep-is: 0.1.4 5927 - fast-levenshtein: 2.0.6 5928 - levn: 0.4.1 5929 - prelude-ls: 1.2.1 5930 - type-check: 0.4.0 5931 - word-wrap: 1.2.5 5932 - 5933 - orderedmap@2.1.1: {} 5934 - 5935 2960 outdent@0.5.0: {} 5936 2961 5937 2962 p-filter@2.1.0: ··· 5942 2967 dependencies: 5943 2968 p-try: 2.2.0 5944 2969 5945 - p-limit@3.1.0: 5946 - dependencies: 5947 - yocto-queue: 0.1.0 5948 - 5949 2970 p-locate@4.1.0: 5950 2971 dependencies: 5951 2972 p-limit: 2.3.0 5952 2973 5953 - p-locate@5.0.0: 5954 - dependencies: 5955 - p-limit: 3.1.0 5956 - 5957 2974 p-map@2.1.0: {} 5958 2975 5959 2976 p-try@2.2.0: {} ··· 6029 3046 mlly: 1.8.2 6030 3047 pathe: 2.0.3 6031 3048 6032 - plyr@3.8.4: 6033 - dependencies: 6034 - core-js: 3.49.0 6035 - custom-event-polyfill: 1.0.7 6036 - loadjs: 4.3.0 6037 - rangetouch: 2.0.1 6038 - url-polyfill: 1.1.14 6039 - 6040 - postcss-load-config@3.1.4(postcss@8.5.8): 6041 - dependencies: 6042 - lilconfig: 2.1.0 6043 - yaml: 1.10.3 6044 - optionalDependencies: 6045 - postcss: 8.5.8 6046 - 6047 - postcss-load-config@6.0.1(postcss@8.5.8)(tsx@4.21.0): 3049 + postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0): 6048 3050 dependencies: 6049 3051 lilconfig: 3.1.3 6050 3052 optionalDependencies: 3053 + jiti: 2.6.1 6051 3054 postcss: 8.5.8 6052 3055 tsx: 4.21.0 6053 3056 6054 - postcss-safe-parser@7.0.1(postcss@8.5.8): 6055 - dependencies: 6056 - postcss: 8.5.8 6057 - 6058 - postcss-scss@4.0.9(postcss@8.5.8): 6059 - dependencies: 6060 - postcss: 8.5.8 6061 - 6062 - postcss-selector-parser@7.1.1: 6063 - dependencies: 6064 - cssesc: 3.0.0 6065 - util-deprecate: 1.0.2 6066 - 6067 3057 postcss@8.5.8: 6068 3058 dependencies: 6069 3059 nanoid: 3.3.11 ··· 6080 3070 dependencies: 6081 3071 xtend: 4.0.2 6082 3072 6083 - prelude-ls@1.2.1: {} 6084 - 6085 - prettier-plugin-svelte@3.5.1(prettier@3.8.1)(svelte@5.55.4(@typescript-eslint/types@8.58.2)): 6086 - dependencies: 6087 - prettier: 3.8.1 6088 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 6089 - 6090 - prettier-plugin-tailwindcss@0.7.2(prettier-plugin-svelte@3.5.1(prettier@3.8.1)(svelte@5.55.4(@typescript-eslint/types@8.58.2)))(prettier@3.8.1): 6091 - dependencies: 6092 - prettier: 3.8.1 6093 - optionalDependencies: 6094 - prettier-plugin-svelte: 3.5.1(prettier@3.8.1)(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 6095 - 6096 3073 prettier@2.8.8: {} 6097 3074 6098 3075 prettier@3.8.1: {} 6099 3076 6100 - prosemirror-changeset@2.4.1: 6101 - dependencies: 6102 - prosemirror-transform: 1.12.0 6103 - 6104 - prosemirror-collab@1.3.1: 6105 - dependencies: 6106 - prosemirror-state: 1.4.4 6107 - 6108 - prosemirror-commands@1.7.1: 6109 - dependencies: 6110 - prosemirror-model: 1.25.4 6111 - prosemirror-state: 1.4.4 6112 - prosemirror-transform: 1.12.0 6113 - 6114 - prosemirror-dropcursor@1.8.2: 6115 - dependencies: 6116 - prosemirror-state: 1.4.4 6117 - prosemirror-transform: 1.12.0 6118 - prosemirror-view: 1.41.8 6119 - 6120 - prosemirror-gapcursor@1.4.1: 6121 - dependencies: 6122 - prosemirror-keymap: 1.2.3 6123 - prosemirror-model: 1.25.4 6124 - prosemirror-state: 1.4.4 6125 - prosemirror-view: 1.41.8 6126 - 6127 - prosemirror-history@1.5.0: 6128 - dependencies: 6129 - prosemirror-state: 1.4.4 6130 - prosemirror-transform: 1.12.0 6131 - prosemirror-view: 1.41.8 6132 - rope-sequence: 1.3.4 6133 - 6134 - prosemirror-inputrules@1.5.1: 6135 - dependencies: 6136 - prosemirror-state: 1.4.4 6137 - prosemirror-transform: 1.12.0 6138 - 6139 - prosemirror-keymap@1.2.3: 6140 - dependencies: 6141 - prosemirror-state: 1.4.4 6142 - w3c-keyname: 2.2.8 6143 - 6144 - prosemirror-markdown@1.13.4: 6145 - dependencies: 6146 - '@types/markdown-it': 14.1.2 6147 - markdown-it: 14.1.1 6148 - prosemirror-model: 1.25.4 6149 - 6150 - prosemirror-menu@1.3.0: 6151 - dependencies: 6152 - crelt: 1.0.6 6153 - prosemirror-commands: 1.7.1 6154 - prosemirror-history: 1.5.0 6155 - prosemirror-state: 1.4.4 6156 - 6157 - prosemirror-model@1.25.4: 6158 - dependencies: 6159 - orderedmap: 2.1.1 6160 - 6161 - prosemirror-schema-basic@1.2.4: 6162 - dependencies: 6163 - prosemirror-model: 1.25.4 6164 - 6165 - prosemirror-schema-list@1.5.1: 6166 - dependencies: 6167 - prosemirror-model: 1.25.4 6168 - prosemirror-state: 1.4.4 6169 - prosemirror-transform: 1.12.0 6170 - 6171 - prosemirror-state@1.4.4: 6172 - dependencies: 6173 - prosemirror-model: 1.25.4 6174 - prosemirror-transform: 1.12.0 6175 - prosemirror-view: 1.41.8 6176 - 6177 - prosemirror-tables@1.8.5: 6178 - dependencies: 6179 - prosemirror-keymap: 1.2.3 6180 - prosemirror-model: 1.25.4 6181 - prosemirror-state: 1.4.4 6182 - prosemirror-transform: 1.12.0 6183 - prosemirror-view: 1.41.8 6184 - 6185 - prosemirror-trailing-node@3.0.0(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.8): 6186 - dependencies: 6187 - '@remirror/core-constants': 3.0.0 6188 - escape-string-regexp: 4.0.0 6189 - prosemirror-model: 1.25.4 6190 - prosemirror-state: 1.4.4 6191 - prosemirror-view: 1.41.8 6192 - 6193 - prosemirror-transform@1.12.0: 6194 - dependencies: 6195 - prosemirror-model: 1.25.4 6196 - 6197 - prosemirror-view@1.41.8: 6198 - dependencies: 6199 - prosemirror-model: 1.25.4 6200 - prosemirror-state: 1.4.4 6201 - prosemirror-transform: 1.12.0 6202 - 6203 - punycode.js@2.3.1: {} 6204 - 6205 - punycode@2.3.1: {} 6206 - 6207 3077 quansync@0.2.11: {} 6208 3078 6209 3079 queue-microtask@1.2.3: {} 6210 - 6211 - rangetouch@2.0.1: {} 6212 3080 6213 3081 read-yaml-file@1.1.0: 6214 3082 dependencies: ··· 6218 3086 strip-bom: 3.0.0 6219 3087 6220 3088 readdirp@4.1.2: {} 6221 - 6222 - regexparam@3.0.0: {} 6223 3089 6224 3090 resolve-from@5.0.0: {} 6225 3091 ··· 6248 3114 '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.15 6249 3115 '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.15 6250 3116 6251 - rolldown@1.0.0-rc.9: 6252 - dependencies: 6253 - '@oxc-project/types': 0.115.0 6254 - '@rolldown/pluginutils': 1.0.0-rc.9 6255 - optionalDependencies: 6256 - '@rolldown/binding-android-arm64': 1.0.0-rc.9 6257 - '@rolldown/binding-darwin-arm64': 1.0.0-rc.9 6258 - '@rolldown/binding-darwin-x64': 1.0.0-rc.9 6259 - '@rolldown/binding-freebsd-x64': 1.0.0-rc.9 6260 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.9 6261 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.9 6262 - '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.9 6263 - '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.9 6264 - '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.9 6265 - '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.9 6266 - '@rolldown/binding-linux-x64-musl': 1.0.0-rc.9 6267 - '@rolldown/binding-openharmony-arm64': 1.0.0-rc.9 6268 - '@rolldown/binding-wasm32-wasi': 1.0.0-rc.9 6269 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.9 6270 - '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.9 6271 - 6272 3117 rollup@4.60.1: 6273 3118 dependencies: 6274 3119 '@types/estree': 1.0.8 ··· 6300 3145 '@rollup/rollup-win32-x64-msvc': 4.60.1 6301 3146 fsevents: 2.3.3 6302 3147 6303 - rope-sequence@1.3.4: {} 6304 - 6305 3148 run-parallel@1.2.0: 6306 3149 dependencies: 6307 3150 queue-microtask: 1.2.3 6308 3151 6309 - runed@0.23.4(svelte@5.55.4(@typescript-eslint/types@8.58.2)): 6310 - dependencies: 6311 - esm-env: 1.2.2 6312 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 6313 - 6314 - runed@0.25.0(svelte@5.55.4(@typescript-eslint/types@8.58.2)): 6315 - dependencies: 6316 - esm-env: 1.2.2 6317 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 6318 - 6319 - runed@0.28.0(svelte@5.55.4(@typescript-eslint/types@8.58.2)): 6320 - dependencies: 6321 - esm-env: 1.2.2 6322 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 6323 - 6324 - runed@0.35.1(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)): 6325 - dependencies: 6326 - dequal: 2.0.3 6327 - esm-env: 1.2.2 6328 - lz-string: 1.5.0 6329 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 6330 - optionalDependencies: 6331 - '@sveltejs/kit': 2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)) 6332 - 6333 - sade@1.8.1: 6334 - dependencies: 6335 - mri: 1.2.0 6336 - 6337 3152 safer-buffer@2.1.2: {} 6338 3153 6339 3154 semver@7.7.4: {} 6340 - 6341 - set-cookie-parser@3.1.0: {} 6342 3155 6343 3156 sharp@0.34.5: 6344 3157 dependencies: ··· 6381 3194 6382 3195 signal-exit@4.1.0: {} 6383 3196 6384 - sirv@3.0.2: 6385 - dependencies: 6386 - '@polka/url': 1.0.0-next.29 6387 - mrmime: 2.0.1 6388 - totalist: 3.0.1 6389 - 6390 3197 slash@3.0.0: {} 6391 3198 6392 3199 source-map-js@1.2.1: {} ··· 6412 3219 6413 3220 strip-bom@3.0.0: {} 6414 3221 6415 - style-to-object@1.0.14: 6416 - dependencies: 6417 - inline-style-parser: 0.2.7 6418 - 6419 3222 sucrase@3.35.1: 6420 3223 dependencies: 6421 3224 '@jridgewell/gen-mapping': 0.3.13 ··· 6428 3231 6429 3232 supports-color@10.2.2: {} 6430 3233 6431 - svelte-check@4.4.6(picomatch@4.0.4)(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2): 6432 - dependencies: 6433 - '@jridgewell/trace-mapping': 0.3.31 6434 - chokidar: 4.0.3 6435 - fdir: 6.5.0(picomatch@4.0.4) 6436 - picocolors: 1.1.1 6437 - sade: 1.8.1 6438 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 6439 - typescript: 6.0.2 6440 - transitivePeerDependencies: 6441 - - picomatch 6442 - 6443 - svelte-eslint-parser@1.6.0(svelte@5.55.4(@typescript-eslint/types@8.58.2)): 6444 - dependencies: 6445 - eslint-scope: 8.4.0 6446 - eslint-visitor-keys: 4.2.1 6447 - espree: 10.4.0 6448 - postcss: 8.5.8 6449 - postcss-scss: 4.0.9(postcss@8.5.8) 6450 - postcss-selector-parser: 7.1.1 6451 - semver: 7.7.4 6452 - optionalDependencies: 6453 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 6454 - 6455 - svelte-sonner@1.1.0(svelte@5.55.4(@typescript-eslint/types@8.58.2)): 6456 - dependencies: 6457 - runed: 0.28.0(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 6458 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 6459 - 6460 - svelte-tiptap@3.0.1(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/extension-bubble-menu@3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3))(@tiptap/extension-floating-menu@3.22.3(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3)(svelte@5.55.4(@typescript-eslint/types@8.58.2)): 6461 - dependencies: 6462 - '@floating-ui/dom': 1.7.6 6463 - '@tiptap/core': 3.22.3(@tiptap/pm@3.22.3) 6464 - '@tiptap/extension-bubble-menu': 3.22.3(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3) 6465 - '@tiptap/extension-floating-menu': 3.22.3(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.3(@tiptap/pm@3.22.3))(@tiptap/pm@3.22.3) 6466 - '@tiptap/pm': 3.22.3 6467 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 6468 - 6469 - svelte-toolbelt@0.10.6(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)): 6470 - dependencies: 6471 - clsx: 2.1.1 6472 - runed: 0.35.1(@sveltejs/kit@2.57.1(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.4(@typescript-eslint/types@8.58.2))(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2))(typescript@6.0.2)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)))(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 6473 - style-to-object: 1.0.14 6474 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 6475 - transitivePeerDependencies: 6476 - - '@sveltejs/kit' 6477 - 6478 - svelte-toolbelt@0.7.1(svelte@5.55.4(@typescript-eslint/types@8.58.2)): 6479 - dependencies: 6480 - clsx: 2.1.1 6481 - runed: 0.23.4(svelte@5.55.4(@typescript-eslint/types@8.58.2)) 6482 - style-to-object: 1.0.14 6483 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 6484 - 6485 - svelte@5.55.4(@typescript-eslint/types@8.58.2): 6486 - dependencies: 6487 - '@jridgewell/remapping': 2.3.5 6488 - '@jridgewell/sourcemap-codec': 1.5.5 6489 - '@sveltejs/acorn-typescript': 1.0.9(acorn@8.16.0) 6490 - '@types/estree': 1.0.8 6491 - '@types/trusted-types': 2.0.7 6492 - acorn: 8.16.0 6493 - aria-query: 5.3.1 6494 - axobject-query: 4.1.0 6495 - clsx: 2.1.1 6496 - devalue: 5.7.1 6497 - esm-env: 1.2.2 6498 - esrap: 2.2.5(@typescript-eslint/types@8.58.2) 6499 - is-reference: 3.0.3 6500 - locate-character: 3.0.0 6501 - magic-string: 0.30.21 6502 - zimmerframe: 1.1.4 6503 - transitivePeerDependencies: 6504 - - '@typescript-eslint/types' 6505 - 6506 - tabbable@6.4.0: {} 6507 - 6508 - tailwind-merge@3.5.0: {} 6509 - 6510 - tailwind-variants@3.2.2(tailwind-merge@3.5.0)(tailwindcss@4.2.2): 6511 - dependencies: 6512 - tailwindcss: 4.2.2 6513 - optionalDependencies: 6514 - tailwind-merge: 3.5.0 6515 - 6516 - tailwindcss@4.2.2: {} 6517 - 6518 - tapable@2.3.2: {} 6519 - 6520 3234 term-size@2.2.1: {} 6521 3235 6522 3236 thenify-all@1.6.0: ··· 6544 3258 dependencies: 6545 3259 is-number: 7.0.0 6546 3260 6547 - totalist@3.0.1: {} 6548 - 6549 3261 tree-kill@1.2.2: {} 6550 - 6551 - ts-api-utils@2.5.0(typescript@6.0.2): 6552 - dependencies: 6553 - typescript: 6.0.2 6554 3262 6555 3263 ts-interface-checker@0.1.13: {} 6556 3264 6557 - tslib@2.8.1: {} 3265 + tslib@2.8.1: 3266 + optional: true 6558 3267 6559 - tsup@8.5.1(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3): 3268 + tsup@8.5.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3): 6560 3269 dependencies: 6561 3270 bundle-require: 5.1.0(esbuild@0.27.0) 6562 3271 cac: 6.7.14 ··· 6567 3276 fix-dts-default-cjs-exports: 1.0.1 6568 3277 joycon: 3.1.1 6569 3278 picocolors: 1.1.1 6570 - postcss-load-config: 6.0.1(postcss@8.5.8)(tsx@4.21.0) 3279 + postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0) 6571 3280 resolve-from: 5.0.0 6572 3281 rollup: 4.60.1 6573 3282 source-map: 0.7.6 ··· 6591 3300 optionalDependencies: 6592 3301 fsevents: 2.3.3 6593 3302 6594 - type-check@0.4.0: 6595 - dependencies: 6596 - prelude-ls: 1.2.1 6597 - 6598 3303 type-fest@4.41.0: {} 6599 3304 6600 - typescript-eslint@8.58.2(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2): 6601 - dependencies: 6602 - '@typescript-eslint/eslint-plugin': 8.58.2(@typescript-eslint/parser@8.58.2(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2))(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2) 6603 - '@typescript-eslint/parser': 8.58.2(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2) 6604 - '@typescript-eslint/typescript-estree': 8.58.2(typescript@6.0.2) 6605 - '@typescript-eslint/utils': 8.58.2(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2) 6606 - eslint: 10.2.0(jiti@2.6.1) 6607 - typescript: 6.0.2 6608 - transitivePeerDependencies: 6609 - - supports-color 6610 - 6611 3305 typescript@5.9.3: {} 6612 - 6613 - typescript@6.0.2: {} 6614 - 6615 - uc.micro@2.1.0: {} 6616 3306 6617 3307 ufo@1.6.3: {} 6618 3308 ··· 6620 3310 6621 3311 undici@7.18.2: {} 6622 3312 6623 - undici@7.24.4: {} 6624 - 6625 3313 unenv@2.0.0-rc.24: 6626 3314 dependencies: 6627 3315 pathe: 2.0.3 ··· 6630 3318 6631 3319 universalify@0.1.2: {} 6632 3320 6633 - uri-js@4.4.1: 6634 - dependencies: 6635 - punycode: 2.3.1 6636 - 6637 - url-polyfill@1.1.14: {} 6638 - 6639 - util-deprecate@1.0.2: {} 6640 - 6641 - valibot@1.3.1(typescript@6.0.2): 6642 - optionalDependencies: 6643 - typescript: 6.0.2 6644 - 6645 - vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.0)(tsx@4.21.0): 6646 - dependencies: 6647 - '@oxc-project/runtime': 0.115.0 6648 - lightningcss: 1.32.0 6649 - picomatch: 4.0.3 6650 - postcss: 8.5.8 6651 - rolldown: 1.0.0-rc.9 6652 - tinyglobby: 0.2.15 6653 - optionalDependencies: 6654 - '@types/node': 25.5.0 6655 - esbuild: 0.27.0 6656 - fsevents: 2.3.3 6657 - tsx: 4.21.0 6658 - 6659 - vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0): 3321 + vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.0)(jiti@2.6.1)(tsx@4.21.0): 6660 3322 dependencies: 6661 3323 lightningcss: 1.32.0 6662 3324 picomatch: 4.0.4 ··· 6665 3327 tinyglobby: 0.2.15 6666 3328 optionalDependencies: 6667 3329 '@types/node': 25.5.0 6668 - esbuild: 0.27.3 3330 + esbuild: 0.27.0 6669 3331 fsevents: 2.3.3 6670 3332 jiti: 2.6.1 6671 3333 tsx: 4.21.0 6672 3334 6673 - vitefu@1.1.3(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)): 6674 - optionalDependencies: 6675 - vite: 8.0.8(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0) 6676 - 6677 - vitest@4.1.0(@types/node@25.5.0)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.0)(tsx@4.21.0)): 3335 + vitest@4.1.0(@types/node@25.5.0)(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.0)(jiti@2.6.1)(tsx@4.21.0)): 6678 3336 dependencies: 6679 3337 '@vitest/expect': 4.1.0 6680 - '@vitest/mocker': 4.1.0(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.0)(tsx@4.21.0)) 3338 + '@vitest/mocker': 4.1.0(vite@8.0.8(@types/node@25.5.0)(esbuild@0.27.0)(jiti@2.6.1)(tsx@4.21.0)) 6681 3339 '@vitest/pretty-format': 4.1.0 6682 3340 '@vitest/runner': 4.1.0 6683 3341 '@vitest/snapshot': 4.1.0 ··· 6694 3352 tinyexec: 1.0.4 6695 3353 tinyglobby: 0.2.15 6696 3354 tinyrainbow: 3.1.0 6697 - vite: 8.0.0(@types/node@25.5.0)(esbuild@0.27.0)(tsx@4.21.0) 3355 + vite: 8.0.8(@types/node@25.5.0)(esbuild@0.27.0)(jiti@2.6.1)(tsx@4.21.0) 6698 3356 why-is-node-running: 2.3.0 6699 3357 optionalDependencies: 6700 3358 '@types/node': 25.5.0 6701 3359 transitivePeerDependencies: 6702 3360 - msw 6703 3361 6704 - w3c-keyname@2.2.8: {} 6705 - 6706 - web-haptics@0.0.6(svelte@5.55.4(@typescript-eslint/types@8.58.2)): 6707 - optionalDependencies: 6708 - svelte: 5.55.4(@typescript-eslint/types@8.58.2) 6709 - 6710 3362 which@2.0.2: 6711 3363 dependencies: 6712 3364 isexe: 2.0.0 ··· 6716 3368 siginfo: 2.0.0 6717 3369 stackback: 0.0.2 6718 3370 6719 - word-wrap@1.2.5: {} 6720 - 6721 3371 workerd@1.20260205.0: 6722 3372 optionalDependencies: 6723 3373 '@cloudflare/workerd-darwin-64': 1.20260205.0 ··· 6726 3376 '@cloudflare/workerd-linux-arm64': 1.20260205.0 6727 3377 '@cloudflare/workerd-windows-64': 1.20260205.0 6728 3378 6729 - workerd@1.20260410.1: 6730 - optionalDependencies: 6731 - '@cloudflare/workerd-darwin-64': 1.20260410.1 6732 - '@cloudflare/workerd-darwin-arm64': 1.20260410.1 6733 - '@cloudflare/workerd-linux-64': 1.20260410.1 6734 - '@cloudflare/workerd-linux-arm64': 1.20260410.1 6735 - '@cloudflare/workerd-windows-64': 1.20260410.1 6736 - 6737 - worktop@0.8.0-next.18: 6738 - dependencies: 6739 - mrmime: 2.0.1 6740 - regexparam: 3.0.0 6741 - 6742 3379 wrangler@4.63.0(@cloudflare/workers-types@4.20260205.0): 6743 3380 dependencies: 6744 3381 '@cloudflare/kv-asset-handler': 0.4.2 ··· 6756 3393 - bufferutil 6757 3394 - utf-8-validate 6758 3395 6759 - wrangler@4.82.2(@cloudflare/workers-types@4.20260414.1): 6760 - dependencies: 6761 - '@cloudflare/kv-asset-handler': 0.4.2 6762 - '@cloudflare/unenv-preset': 2.16.0(unenv@2.0.0-rc.24)(workerd@1.20260410.1) 6763 - blake3-wasm: 2.1.5 6764 - esbuild: 0.27.3 6765 - miniflare: 4.20260410.0 6766 - path-to-regexp: 6.3.0 6767 - unenv: 2.0.0-rc.24 6768 - workerd: 1.20260410.1 6769 - optionalDependencies: 6770 - '@cloudflare/workers-types': 4.20260414.1 6771 - fsevents: 2.3.3 6772 - transitivePeerDependencies: 6773 - - bufferutil 6774 - - utf-8-validate 6775 - 6776 3396 ws@8.18.0: {} 6777 3397 6778 3398 xtend@4.0.2: {} 6779 3399 6780 - yaml@1.10.3: {} 6781 - 6782 - yocto-queue@0.1.0: {} 6783 - 6784 3400 yocto-queue@1.2.2: {} 6785 3401 6786 3402 youch-core@0.3.3: ··· 6795 3411 '@speed-highlight/core': 1.2.14 6796 3412 cookie: 1.1.1 6797 3413 youch-core: 0.3.3 6798 - 6799 - zimmerframe@1.1.4: {}
+24
realtime-lexicon-templates/subscribe.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "tools.atmo.realtime.subscribe", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Open a streaming subscription. Responds with Server-Sent Events by default, or upgrades to WebSocket when the request carries `Upgrade: websocket`. Auth via `?ticket=` (browser) or `Authorization: Bearer <JWT>` (server-side). The stream closes with a final `member.removed` event if the caller loses access mid-stream.", 8 + "parameters": { 9 + "type": "params", 10 + "properties": { 11 + "ticket": { "type": "string", "description": "Subscription ticket from `.ticket`. Required if no Authorization header." }, 12 + "topic": { "type": "string", "description": "Optional: restrict the stream to a single topic (must be in the ticket). Required on the JWT path." }, 13 + "collection": { "type": "string", "format": "nsid", "description": "Optional: drop `record.*` events whose collection doesn't match." } 14 + } 15 + }, 16 + "errors": [ 17 + { "name": "AuthRequired" }, 18 + { "name": "Forbidden" }, 19 + { "name": "InvalidRequest" }, 20 + { "name": "NotFound" } 21 + ] 22 + } 23 + } 24 + }
+40
realtime-lexicon-templates/ticket.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "tools.atmo.realtime.ticket", 4 + "defs": { 5 + "main": { 6 + "type": "procedure", 7 + "description": "Mint a short-lived subscription ticket for the given topic. The caller's access is checked and — for `community:<did>` topics — expanded to the concrete list of `space:<uri>` topics the caller can see. Server-side callers may skip tickets and use their JWT directly on `.subscribe`.", 8 + "input": { 9 + "encoding": "application/json", 10 + "schema": { 11 + "type": "object", 12 + "required": ["topic"], 13 + "properties": { 14 + "topic": { 15 + "type": "string", 16 + "description": "Requested topic. One of `space:<uri>`, `community:<did>`, `actor:<did>` (self-only in v1)." 17 + } 18 + } 19 + } 20 + }, 21 + "output": { 22 + "encoding": "application/json", 23 + "schema": { 24 + "type": "object", 25 + "required": ["ticket", "topics", "expiresAt"], 26 + "properties": { 27 + "ticket": { "type": "string", "description": "HMAC-signed opaque token. Passed as `?ticket=` on `.subscribe`." }, 28 + "topics": { "type": "array", "items": { "type": "string" }, "description": "Concrete delivery topics authorized by this ticket." }, 29 + "expiresAt": { "type": "integer", "description": "Unix ms." } 30 + } 31 + } 32 + }, 33 + "errors": [ 34 + { "name": "Forbidden" }, 35 + { "name": "NotFound" }, 36 + { "name": "NotSupported" } 37 + ] 38 + } 39 + } 40 + }
+294
src/core/realtime/durable-object.ts
··· 1 + /** Durable Object backend for realtime PubSub. 2 + * 3 + * Two pieces live here: 4 + * 1. `RealtimePubSubDO` — the DO class. Ship it from your Worker via 5 + * `export { RealtimePubSubDO } from "@atmo-dev/contrail";` and bind it in 6 + * your `wrangler.toml`. One DO = one topic; addressed by name. 7 + * 2. `DurableObjectPubSub` — client-side adapter implementing the PubSub 8 + * interface against a DO namespace binding. 9 + * 10 + * Wire format between Worker and DO (internal, not a stable public contract): 11 + * POST /publish — body = RealtimeEvent JSON 12 + * GET /subscribe — server-sent events stream, optionally with 13 + * `Upgrade: websocket` for WS connections. 14 + * Auth/ACL is already checked at the Worker edge; 15 + * the DO trusts anything that reaches it. */ 16 + 17 + import type { PubSub, RealtimeEvent } from "./types"; 18 + 19 + // ---- Minimal structural typings so we don't depend on @cloudflare/workers-types 20 + // at the library level. Callers on Workers will have proper types. 21 + // ---------------------------------------------------------------------------- 22 + 23 + export interface DurableObjectId { 24 + toString(): string; 25 + } 26 + 27 + export interface DurableObjectStub { 28 + fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>; 29 + } 30 + 31 + export interface DurableObjectNamespace { 32 + idFromName(name: string): DurableObjectId; 33 + get(id: DurableObjectId): DurableObjectStub; 34 + } 35 + 36 + export interface DurableObjectState { 37 + acceptWebSocket(ws: any, tags?: string[]): void; 38 + getWebSockets(tag?: string): any[]; 39 + } 40 + 41 + // ---------------------------------------------------------------------------- 42 + // Client adapter 43 + // ---------------------------------------------------------------------------- 44 + 45 + export class DurableObjectPubSub implements PubSub { 46 + constructor(private readonly namespace: DurableObjectNamespace) {} 47 + 48 + private stub(topic: string): DurableObjectStub { 49 + return this.namespace.get(this.namespace.idFromName(topic)); 50 + } 51 + 52 + async publish(event: RealtimeEvent): Promise<void> { 53 + const res = await this.stub(event.topic).fetch("https://do/publish", { 54 + method: "POST", 55 + headers: { "content-type": "application/json" }, 56 + body: JSON.stringify(event), 57 + }); 58 + if (!res.ok) { 59 + // Consume the body so the edge doesn't hold a dangling response. 60 + await res.text().catch(() => ""); 61 + throw new Error(`DO publish failed (${res.status})`); 62 + } 63 + } 64 + 65 + /** In-Worker server-side subscribe. Browsers should hit the SSE endpoint 66 + * directly; this is the path for an in-process consumer that wants an 67 + * AsyncIterable (tests, bots embedded in the Worker). */ 68 + subscribe(topic: string, signal?: AbortSignal): AsyncIterable<RealtimeEvent> { 69 + const stub = this.stub(topic); 70 + return { 71 + [Symbol.asyncIterator]() { 72 + return pullIterator(stub, signal); 73 + }, 74 + }; 75 + } 76 + } 77 + 78 + function pullIterator( 79 + stub: DurableObjectStub, 80 + signal?: AbortSignal 81 + ): AsyncIterator<RealtimeEvent> { 82 + let reader: ReadableStreamDefaultReader<Uint8Array> | null = null; 83 + let buf = ""; 84 + const decoder = new TextDecoder(); 85 + const ac = new AbortController(); 86 + if (signal) { 87 + if (signal.aborted) ac.abort(); 88 + else signal.addEventListener("abort", () => ac.abort(), { once: true }); 89 + } 90 + 91 + const open = async () => { 92 + const res = await stub.fetch("https://do/subscribe", { 93 + method: "GET", 94 + headers: { accept: "text/event-stream" }, 95 + signal: ac.signal, 96 + }); 97 + if (!res.ok || !res.body) throw new Error(`DO subscribe failed (${res.status})`); 98 + reader = res.body.getReader(); 99 + }; 100 + 101 + return { 102 + async next(): Promise<IteratorResult<RealtimeEvent>> { 103 + if (!reader) await open(); 104 + while (true) { 105 + // Drain buffered frames. 106 + while (true) { 107 + const sep = buf.indexOf("\n\n"); 108 + if (sep < 0) break; 109 + const frame = buf.slice(0, sep); 110 + buf = buf.slice(sep + 2); 111 + let data: string | null = null; 112 + for (const line of frame.split("\n")) { 113 + if (line.startsWith(":")) continue; 114 + if (line.startsWith("data:")) data = line.slice(5).trim(); 115 + } 116 + if (data) { 117 + try { 118 + return { value: JSON.parse(data) as RealtimeEvent, done: false }; 119 + } catch { 120 + /* skip malformed */ 121 + } 122 + } 123 + } 124 + if (ac.signal.aborted) return { value: undefined, done: true }; 125 + const r = await reader!.read(); 126 + if (r.done) return { value: undefined, done: true }; 127 + buf += decoder.decode(r.value, { stream: true }); 128 + } 129 + }, 130 + async return(): Promise<IteratorResult<RealtimeEvent>> { 131 + ac.abort(); 132 + try { 133 + await reader?.cancel(); 134 + } catch { 135 + /* ignore */ 136 + } 137 + return { value: undefined, done: true }; 138 + }, 139 + }; 140 + } 141 + 142 + // ---------------------------------------------------------------------------- 143 + // Durable Object class 144 + // ---------------------------------------------------------------------------- 145 + 146 + /** The Durable Object implementation. Each DO instance owns the fan-out for 147 + * exactly one topic. WebSocket connections are stored via the Hibernation 148 + * API (`state.acceptWebSocket`) so idle rooms cost near-zero. 149 + * 150 + * This class intentionally avoids the `DurableObject` base class so we don't 151 + * have to depend on @cloudflare/workers-types at the library level — users 152 + * wire it up directly in their Worker entry. */ 153 + export class RealtimePubSubDO { 154 + constructor( 155 + protected readonly state: DurableObjectState, 156 + _env?: unknown 157 + ) {} 158 + 159 + /** Worker entry delegates `fetch` to this method. */ 160 + async fetch(request: Request): Promise<Response> { 161 + const url = new URL(request.url); 162 + if (request.method === "POST" && url.pathname === "/publish") { 163 + let event: RealtimeEvent; 164 + try { 165 + event = (await request.json()) as RealtimeEvent; 166 + } catch { 167 + return new Response(JSON.stringify({ error: "InvalidRequest" }), { status: 400 }); 168 + } 169 + this.publishEvent(event); 170 + return new Response("{}", { status: 200 }); 171 + } 172 + if (request.method === "GET" && url.pathname === "/subscribe") { 173 + const did = url.searchParams.get("did") ?? undefined; 174 + if (request.headers.get("Upgrade")?.toLowerCase() === "websocket") { 175 + const Pair = (globalThis as unknown as { WebSocketPair?: any }).WebSocketPair; 176 + if (!Pair) return new Response("websockets require Workers", { status: 426 }); 177 + const pair = new Pair(); 178 + this.acceptWebSocketSubscriber(pair[1], did); 179 + return new Response(null, { 180 + status: 101, 181 + // @ts-expect-error Workers-specific init field 182 + webSocket: pair[0], 183 + }); 184 + } 185 + return this.openSseResponse(did); 186 + } 187 + return new Response("not found", { status: 404 }); 188 + } 189 + 190 + /** Fan-out an event to every connected subscriber (WS + SSE). 191 + * Public so tests + advanced callers can skip the HTTP layer. */ 192 + publishEvent(event: RealtimeEvent): void { 193 + const payload = JSON.stringify(event); 194 + const frame = `event: ${event.kind}\ndata: ${payload}\n\n`; 195 + 196 + for (const ws of this.state.getWebSockets()) { 197 + try { 198 + ws.send(payload); 199 + } catch { 200 + /* ignore — socket may be closing */ 201 + } 202 + const attachment = getAttachment(ws); 203 + if ( 204 + event.kind === "member.removed" && 205 + attachment?.did && 206 + event.payload.did === attachment.did 207 + ) { 208 + try { 209 + ws.close(4003, "membership-revoked"); 210 + } catch { 211 + /* ignore */ 212 + } 213 + } 214 + } 215 + for (const entry of this.sseControllers) { 216 + try { 217 + entry.controller.enqueue(this.encoder.encode(frame)); 218 + } catch { 219 + /* drop; cleanup happens on the subscribe-side */ 220 + } 221 + if ( 222 + event.kind === "member.removed" && 223 + entry.did && 224 + event.payload.did === entry.did 225 + ) { 226 + try { 227 + entry.controller.close(); 228 + } catch { 229 + /* ignore */ 230 + } 231 + } 232 + } 233 + } 234 + 235 + /** Register a server-side WebSocket as a subscriber. Wires the DID attachment. */ 236 + acceptWebSocketSubscriber(serverWs: any, did?: string): void { 237 + this.state.acceptWebSocket(serverWs, did ? [did] : undefined); 238 + if (did) setAttachment(serverWs, { did }); 239 + } 240 + 241 + /** Open an SSE subscriber; returns the streaming Response. */ 242 + openSseResponse(did?: string): Response { 243 + let entry: SseEntry; 244 + const stream = new ReadableStream<Uint8Array>({ 245 + start: (controller) => { 246 + entry = { controller, did }; 247 + this.sseControllers.add(entry); 248 + controller.enqueue(this.encoder.encode(`: open\n\n`)); 249 + }, 250 + cancel: () => { 251 + this.sseControllers.delete(entry); 252 + }, 253 + }); 254 + return new Response(stream, { 255 + status: 200, 256 + headers: { 257 + "content-type": "text/event-stream", 258 + "cache-control": "no-cache, no-transform", 259 + connection: "keep-alive", 260 + }, 261 + }); 262 + } 263 + 264 + private readonly sseControllers = new Set<SseEntry>(); 265 + private readonly encoder = new TextEncoder(); 266 + } 267 + 268 + interface SseEntry { 269 + controller: ReadableStreamDefaultController<Uint8Array>; 270 + did: string | undefined; 271 + } 272 + 273 + interface WsAttachment { 274 + did?: string; 275 + } 276 + 277 + function setAttachment(ws: any, attachment: WsAttachment): void { 278 + try { 279 + ws.serializeAttachment?.(attachment); 280 + } catch { 281 + /* non-hibernating socket — fall back to a direct property */ 282 + ws.__attachment = attachment; 283 + } 284 + } 285 + 286 + function getAttachment(ws: any): WsAttachment | null { 287 + try { 288 + const a = ws.deserializeAttachment?.(); 289 + if (a) return a as WsAttachment; 290 + } catch { 291 + /* ignore */ 292 + } 293 + return (ws.__attachment as WsAttachment | undefined) ?? null; 294 + }
+116
src/core/realtime/in-memory.ts
··· 1 + import type { PubSub, RealtimeEvent } from "./types"; 2 + import { DEFAULT_QUEUE_BOUND } from "./types"; 3 + 4 + /** Single-process PubSub backed by in-memory subscriber sets. 5 + * 6 + * Each subscriber owns a bounded queue; when full, oldest events are dropped. 7 + * `publish` returns once every subscriber has been offered the event — it 8 + * never awaits a subscriber's consumption, so a slow consumer can't block 9 + * producers. The cost of that guarantee is the drop-oldest policy. */ 10 + export class InMemoryPubSub implements PubSub { 11 + private readonly subscribers = new Map<string, Set<Subscriber>>(); 12 + private readonly queueBound: number; 13 + 14 + constructor(opts: { queueBound?: number } = {}) { 15 + this.queueBound = opts.queueBound ?? DEFAULT_QUEUE_BOUND; 16 + } 17 + 18 + async publish(event: RealtimeEvent): Promise<void> { 19 + const set = this.subscribers.get(event.topic); 20 + if (!set) return; 21 + for (const sub of set) sub.push(event); 22 + } 23 + 24 + subscribe(topic: string, signal?: AbortSignal): AsyncIterable<RealtimeEvent> { 25 + const sub = new Subscriber(this.queueBound); 26 + let set = this.subscribers.get(topic); 27 + if (!set) { 28 + set = new Set(); 29 + this.subscribers.set(topic, set); 30 + } 31 + set.add(sub); 32 + 33 + const cleanup = () => { 34 + sub.close(); 35 + const s = this.subscribers.get(topic); 36 + if (s) { 37 + s.delete(sub); 38 + if (s.size === 0) this.subscribers.delete(topic); 39 + } 40 + }; 41 + 42 + if (signal) { 43 + if (signal.aborted) cleanup(); 44 + else signal.addEventListener("abort", cleanup, { once: true }); 45 + } 46 + 47 + return sub.iterate(cleanup); 48 + } 49 + 50 + /** Test-only: current subscriber count for a topic. */ 51 + subscriberCount(topic: string): number { 52 + return this.subscribers.get(topic)?.size ?? 0; 53 + } 54 + } 55 + 56 + class Subscriber { 57 + private readonly queue: RealtimeEvent[] = []; 58 + private pending: ((v: RealtimeEvent | null) => void) | null = null; 59 + private closed = false; 60 + /** Number of events dropped because the queue was full. The consumer can 61 + * observe a gap by comparing monotonic event timestamps; exposing the 62 + * count on a side channel is future work. */ 63 + public droppedCount = 0; 64 + 65 + constructor(private readonly bound: number) {} 66 + 67 + push(event: RealtimeEvent): void { 68 + if (this.closed) return; 69 + if (this.pending) { 70 + const p = this.pending; 71 + this.pending = null; 72 + p(event); 73 + return; 74 + } 75 + if (this.queue.length >= this.bound) { 76 + this.queue.shift(); 77 + this.droppedCount += 1; 78 + } 79 + this.queue.push(event); 80 + } 81 + 82 + close(): void { 83 + if (this.closed) return; 84 + this.closed = true; 85 + if (this.pending) { 86 + const p = this.pending; 87 + this.pending = null; 88 + p(null); 89 + } 90 + } 91 + 92 + iterate(cleanup: () => void): AsyncIterable<RealtimeEvent> { 93 + const self = this; 94 + return { 95 + [Symbol.asyncIterator]() { 96 + return { 97 + async next(): Promise<IteratorResult<RealtimeEvent>> { 98 + if (self.queue.length > 0) { 99 + return { value: self.queue.shift()!, done: false }; 100 + } 101 + if (self.closed) return { value: undefined, done: true }; 102 + const event = await new Promise<RealtimeEvent | null>((resolve) => { 103 + self.pending = resolve; 104 + }); 105 + if (event === null) return { value: undefined, done: true }; 106 + return { value: event, done: false }; 107 + }, 108 + async return(): Promise<IteratorResult<RealtimeEvent>> { 109 + cleanup(); 110 + return { value: undefined, done: true }; 111 + }, 112 + }; 113 + }, 114 + }; 115 + } 116 + }
+37
src/core/realtime/index.ts
··· 1 + export { registerRealtimeRoutes } from "./router"; 2 + export type { RealtimeRoutesOptions } from "./router"; 3 + export { InMemoryPubSub } from "./in-memory"; 4 + export { DurableObjectPubSub, RealtimePubSubDO } from "./durable-object"; 5 + export type { 6 + DurableObjectId, 7 + DurableObjectNamespace, 8 + DurableObjectStub, 9 + DurableObjectState, 10 + } from "./durable-object"; 11 + export { TicketSigner } from "./ticket"; 12 + export type { TicketPayload } from "./ticket"; 13 + export { wrapWithPublishing } from "./publishing-adapter"; 14 + export { sseResponse } from "./sse"; 15 + export { pumpWebSocket } from "./websocket"; 16 + export type { WebSocketLike } from "./websocket"; 17 + export { mergeAsyncIterables } from "./merge"; 18 + export { resolveTopicForCaller } from "./resolve"; 19 + export type { TopicResolution, TopicResolutionContext, TopicResolutionError } from "./resolve"; 20 + export type { 21 + PubSub, 22 + RealtimeConfig, 23 + RealtimeEvent, 24 + RealtimeEventKind, 25 + } from "./types"; 26 + export { 27 + actorTopic, 28 + collectionTopic, 29 + communityTopic, 30 + parseCommunityTopic, 31 + parseSpaceTopic, 32 + spaceTopic, 33 + isCommunityTopic, 34 + DEFAULT_KEEPALIVE_MS, 35 + DEFAULT_QUEUE_BOUND, 36 + DEFAULT_TICKET_TTL_MS, 37 + } from "./types";
+77
src/core/realtime/merge.ts
··· 1 + /** Merge N AsyncIterables into one, interleaving events as they arrive. 2 + * Terminates when every source terminates, or when `signal` aborts. */ 3 + 4 + export function mergeAsyncIterables<T>( 5 + sources: AsyncIterable<T>[], 6 + signal?: AbortSignal 7 + ): AsyncIterable<T> { 8 + if (sources.length === 0) { 9 + return { 10 + async *[Symbol.asyncIterator]() { 11 + /* nothing to yield */ 12 + }, 13 + }; 14 + } 15 + 16 + return { 17 + [Symbol.asyncIterator]() { 18 + const iterators = sources.map((s) => s[Symbol.asyncIterator]()); 19 + // One in-flight next() per source, racing each other. 20 + type Slot = { 21 + idx: number; 22 + promise: Promise<{ idx: number; result: IteratorResult<T> }>; 23 + }; 24 + const pending = new Map<number, Slot>(); 25 + let doneCount = 0; 26 + 27 + const schedule = (idx: number) => { 28 + const slot: Slot = { 29 + idx, 30 + promise: iterators[idx]! 31 + .next() 32 + .then((result) => ({ idx, result })), 33 + }; 34 + pending.set(idx, slot); 35 + }; 36 + 37 + for (let i = 0; i < iterators.length; i++) schedule(i); 38 + 39 + const cleanup = () => { 40 + for (const it of iterators) { 41 + try { 42 + it.return?.(); 43 + } catch { 44 + /* ignore */ 45 + } 46 + } 47 + }; 48 + 49 + if (signal) { 50 + if (signal.aborted) cleanup(); 51 + else signal.addEventListener("abort", cleanup, { once: true }); 52 + } 53 + 54 + return { 55 + async next(): Promise<IteratorResult<T>> { 56 + while (pending.size > 0) { 57 + const slots = [...pending.values()]; 58 + const { idx, result } = await Promise.race(slots.map((s) => s.promise)); 59 + pending.delete(idx); 60 + if (result.done) { 61 + doneCount += 1; 62 + if (doneCount === iterators.length) return { value: undefined, done: true }; 63 + continue; 64 + } 65 + schedule(idx); 66 + return { value: result.value, done: false }; 67 + } 68 + return { value: undefined, done: true }; 69 + }, 70 + async return(): Promise<IteratorResult<T>> { 71 + cleanup(); 72 + return { value: undefined, done: true }; 73 + }, 74 + }; 75 + }, 76 + }; 77 + }
+139
src/core/realtime/publishing-adapter.ts
··· 1 + /** Decorator that wraps a spaces StorageAdapter and publishes realtime events 2 + * after successful writes. Spaces and community modules stay unaware of 3 + * realtime; the decorator is the only integration seam. */ 4 + 5 + import type { StorageAdapter, SpaceMemberRow } from "../spaces/types"; 6 + import type { PubSub, RealtimeEvent } from "./types"; 7 + import { communityTopic, spaceTopic } from "./types"; 8 + 9 + export interface PublishingAdapterOptions { 10 + /** Optional lookup: given a space's ownerDid, return true if that DID is a 11 + * community in the local `communities` table. When provided, writes also 12 + * publish to `community:<ownerDid>` so subscribers who expanded that alias 13 + * at ticket-mint time receive the event. 14 + * 15 + * The lookup is expected to be cheap (cached in the caller) — the decorator 16 + * calls it on every write. */ 17 + isCommunityDid?: (did: string) => Promise<boolean> | boolean; 18 + } 19 + 20 + export function wrapWithPublishing( 21 + inner: StorageAdapter, 22 + pubsub: PubSub, 23 + opts: PublishingAdapterOptions = {} 24 + ): StorageAdapter { 25 + const publishSpaceAndCommunity = async ( 26 + spaceUri: string, 27 + ownerDid: string | null, 28 + build: (topic: string) => RealtimeEvent 29 + ): Promise<void> => { 30 + await pubsub.publish(build(spaceTopic(spaceUri))); 31 + if (ownerDid && opts.isCommunityDid && (await opts.isCommunityDid(ownerDid))) { 32 + await pubsub.publish(build(communityTopic(ownerDid))); 33 + } 34 + }; 35 + 36 + const ownerOf = async (spaceUri: string): Promise<string | null> => { 37 + const s = await inner.getSpace(spaceUri); 38 + return s?.ownerDid ?? null; 39 + }; 40 + 41 + const wrapped: StorageAdapter = { 42 + ...inner, 43 + createSpace: inner.createSpace.bind(inner), 44 + getSpace: inner.getSpace.bind(inner), 45 + listSpaces: inner.listSpaces.bind(inner), 46 + deleteSpace: inner.deleteSpace.bind(inner), 47 + updateSpaceAppPolicy: inner.updateSpaceAppPolicy.bind(inner), 48 + getMember: inner.getMember.bind(inner), 49 + listMembers: inner.listMembers.bind(inner), 50 + createInvite: inner.createInvite.bind(inner), 51 + listInvites: inner.listInvites.bind(inner), 52 + revokeInvite: inner.revokeInvite.bind(inner), 53 + getInvite: inner.getInvite.bind(inner), 54 + redeemInvite: inner.redeemInvite.bind(inner), 55 + getRecord: inner.getRecord.bind(inner), 56 + listRecords: inner.listRecords.bind(inner), 57 + listCollections: inner.listCollections.bind(inner), 58 + 59 + async addMember(spaceUri, did, addedBy) { 60 + await inner.addMember(spaceUri, did, addedBy); 61 + const owner = await ownerOf(spaceUri); 62 + const now = Date.now(); 63 + await publishSpaceAndCommunity(spaceUri, owner, (topic) => ({ 64 + topic, 65 + kind: "member.added", 66 + payload: { spaceUri, did }, 67 + ts: now, 68 + })); 69 + }, 70 + 71 + async removeMember(spaceUri, did) { 72 + await inner.removeMember(spaceUri, did); 73 + const owner = await ownerOf(spaceUri); 74 + const now = Date.now(); 75 + await publishSpaceAndCommunity(spaceUri, owner, (topic) => ({ 76 + topic, 77 + kind: "member.removed", 78 + payload: { spaceUri, did }, 79 + ts: now, 80 + })); 81 + }, 82 + 83 + async applyMembershipDiff(spaceUri, adds, removes, addedBy) { 84 + await inner.applyMembershipDiff(spaceUri, adds, removes, addedBy); 85 + if (adds.length === 0 && removes.length === 0) return; 86 + const owner = await ownerOf(spaceUri); 87 + const now = Date.now(); 88 + for (const did of adds) { 89 + await publishSpaceAndCommunity(spaceUri, owner, (topic) => ({ 90 + topic, 91 + kind: "member.added", 92 + payload: { spaceUri, did }, 93 + ts: now, 94 + })); 95 + } 96 + for (const did of removes) { 97 + await publishSpaceAndCommunity(spaceUri, owner, (topic) => ({ 98 + topic, 99 + kind: "member.removed", 100 + payload: { spaceUri, did }, 101 + ts: now, 102 + })); 103 + } 104 + }, 105 + 106 + async putRecord(record) { 107 + await inner.putRecord(record); 108 + const owner = await ownerOf(record.spaceUri); 109 + const now = Date.now(); 110 + await publishSpaceAndCommunity(record.spaceUri, owner, (topic) => ({ 111 + topic, 112 + kind: "record.created", 113 + payload: { 114 + spaceUri: record.spaceUri, 115 + collection: record.collection, 116 + authorDid: record.authorDid, 117 + rkey: record.rkey, 118 + }, 119 + ts: now, 120 + })); 121 + }, 122 + 123 + async deleteRecord(spaceUri, collection, authorDid, rkey) { 124 + await inner.deleteRecord(spaceUri, collection, authorDid, rkey); 125 + const owner = await ownerOf(spaceUri); 126 + const now = Date.now(); 127 + await publishSpaceAndCommunity(spaceUri, owner, (topic) => ({ 128 + topic, 129 + kind: "record.deleted", 130 + payload: { spaceUri, collection, authorDid, rkey }, 131 + ts: now, 132 + })); 133 + }, 134 + }; 135 + return wrapped; 136 + } 137 + 138 + // Keep this import hint for types that downstream code might pull from here. 139 + export type { SpaceMemberRow };
+90
src/core/realtime/resolve.ts
··· 1 + /** Resolve a raw topic request (as given by a caller) to the concrete set of 2 + * delivery topics they are authorized to subscribe to. 3 + * 4 + * Rules (v1): 5 + * - `space:<uri>` → allowed iff caller is owner or a member of the space. 6 + * - `community:<did>` → expanded to `space:<uri>` for every space in the 7 + * community reachable by the caller (direct grants 8 + * or via delegation). `resolveReachableSpaces` 9 + * already has exactly this semantics. 10 + * - `actor:<did>` → self-only in v1. 11 + * - `collection:<nsid>` → rejected unless the deployment opts in 12 + * (not yet implemented). */ 13 + 14 + import type { StorageAdapter } from "../spaces/types"; 15 + import type { CommunityAdapter } from "../community/adapter"; 16 + import { resolveReachableSpaces } from "../community/acl"; 17 + import { spaceTopic, parseCommunityTopic, parseSpaceTopic } from "./types"; 18 + 19 + export interface TopicResolutionContext { 20 + spaces: StorageAdapter; 21 + /** May be null if the community module is not enabled. */ 22 + community: CommunityAdapter | null; 23 + } 24 + 25 + export interface TopicResolution { 26 + ok: true; 27 + topics: string[]; 28 + } 29 + 30 + export interface TopicResolutionError { 31 + ok: false; 32 + error: "Forbidden" | "InvalidRequest" | "NotFound" | "NotSupported"; 33 + reason: string; 34 + } 35 + 36 + export async function resolveTopicForCaller( 37 + rawTopic: string, 38 + callerDid: string, 39 + ctx: TopicResolutionContext 40 + ): Promise<TopicResolution | TopicResolutionError> { 41 + // space:<uri> 42 + const spaceUri = parseSpaceTopic(rawTopic); 43 + if (spaceUri) { 44 + const space = await ctx.spaces.getSpace(spaceUri); 45 + if (!space) return { ok: false, error: "NotFound", reason: "space-not-found" }; 46 + if (space.ownerDid === callerDid) return { ok: true, topics: [rawTopic] }; 47 + const member = await ctx.spaces.getMember(spaceUri, callerDid); 48 + if (!member) return { ok: false, error: "Forbidden", reason: "not-member" }; 49 + return { ok: true, topics: [rawTopic] }; 50 + } 51 + 52 + // community:<did> 53 + const communityDid = parseCommunityTopic(rawTopic); 54 + if (communityDid) { 55 + if (!ctx.community) { 56 + return { ok: false, error: "NotSupported", reason: "community-module-disabled" }; 57 + } 58 + const row = await ctx.community.getCommunity(communityDid); 59 + if (!row) return { ok: false, error: "NotFound", reason: "community-not-found" }; 60 + const reachable = await resolveReachableSpaces(ctx.community, callerDid); 61 + // Filter to spaces owned by THIS community — reachable may include spaces 62 + // from other communities via cross-community delegation. 63 + const ownedList = await ctx.spaces.listSpaces({ ownerDid: communityDid, limit: 1000 }); 64 + const owned: Set<string> = new Set(ownedList.spaces.map((s) => s.uri)); 65 + const topics: string[] = []; 66 + for (const uri of reachable) { 67 + if (owned.has(uri)) topics.push(spaceTopic(uri)); 68 + } 69 + if (topics.length === 0) { 70 + return { ok: false, error: "Forbidden", reason: "no-reachable-spaces-in-community" }; 71 + } 72 + return { ok: true, topics }; 73 + } 74 + 75 + // actor:<did> — self-only in v1. 76 + if (rawTopic.startsWith("actor:")) { 77 + const did = rawTopic.slice("actor:".length); 78 + if (did !== callerDid) { 79 + return { ok: false, error: "Forbidden", reason: "actor-self-only" }; 80 + } 81 + return { ok: true, topics: [rawTopic] }; 82 + } 83 + 84 + // collection:<nsid> — public firehose, not exposed in v1. 85 + if (rawTopic.startsWith("collection:")) { 86 + return { ok: false, error: "NotSupported", reason: "collection-firehose-disabled" }; 87 + } 88 + 89 + return { ok: false, error: "InvalidRequest", reason: "unknown-topic" }; 90 + }
+221
src/core/realtime/router.ts
··· 1 + /** Realtime XRPC routes: ticket mint + subscribe (SSE | WS). */ 2 + 3 + import type { Context, Hono, MiddlewareHandler } from "hono"; 4 + import type { ContrailConfig } from "../types"; 5 + import type { ServiceAuth } from "../spaces/auth"; 6 + import type { StorageAdapter } from "../spaces/types"; 7 + import type { CommunityAdapter } from "../community/adapter"; 8 + import { InMemoryPubSub } from "./in-memory"; 9 + import { TicketSigner } from "./ticket"; 10 + import { sseResponse } from "./sse"; 11 + import { pumpWebSocket, type WebSocketLike } from "./websocket"; 12 + import { mergeAsyncIterables } from "./merge"; 13 + import { resolveTopicForCaller } from "./resolve"; 14 + import type { PubSub, RealtimeEvent } from "./types"; 15 + import { DEFAULT_TICKET_TTL_MS, DEFAULT_KEEPALIVE_MS } from "./types"; 16 + 17 + export interface RealtimeRoutesOptions { 18 + /** Required: auth middleware for `<ns>.realtime.ticket` (JWT required). 19 + * The subscribe endpoint uses the *ticket* path primarily, so it does not 20 + * require this middleware — but bots can subscribe with Authorization 21 + * header, in which case this middleware is used as a fallback. */ 22 + authMiddleware: MiddlewareHandler; 23 + pubsub?: PubSub; 24 + } 25 + 26 + /** WebSocketPair exists on Cloudflare Workers; on Node/Bun it's absent. 27 + * When absent, a platform-provided WebSocket accept hook is used instead. */ 28 + interface WebSocketPairCtor { 29 + new (): { 0: WebSocketLike & { accept?: () => void }; 1: WebSocketLike & { accept?: () => void } }; 30 + } 31 + 32 + export function registerRealtimeRoutes( 33 + app: Hono, 34 + config: ContrailConfig, 35 + spaces: StorageAdapter, 36 + community: CommunityAdapter | null, 37 + options: RealtimeRoutesOptions 38 + ): void { 39 + const cfg = config.realtime; 40 + if (!cfg) return; 41 + 42 + const pubsub: PubSub = options.pubsub ?? cfg.pubsub ?? new InMemoryPubSub({ queueBound: cfg.queueBound }); 43 + const signer = new TicketSigner(cfg.ticketSecret); 44 + const ticketTtl = cfg.ticketTtlMs ?? DEFAULT_TICKET_TTL_MS; 45 + const keepaliveMs = cfg.keepaliveMs ?? DEFAULT_KEEPALIVE_MS; 46 + 47 + const NS = `${config.namespace}.realtime`; 48 + 49 + // POST /<ns>.realtime.ticket — { topic } → { ticket, topics, expiresAt } 50 + app.post(`/xrpc/${NS}.ticket`, options.authMiddleware, async (c) => { 51 + const sa = getAuth(c); 52 + const body = (await c.req.json().catch(() => null)) as { topic?: string } | null; 53 + if (!body?.topic) { 54 + return c.json({ error: "InvalidRequest", message: "topic required" }, 400); 55 + } 56 + const resolved = await resolveTopicForCaller(body.topic, sa.issuer, { spaces, community }); 57 + if (!resolved.ok) { 58 + const status = resolved.error === "NotFound" ? 404 : resolved.error === "Forbidden" ? 403 : 400; 59 + return c.json({ error: resolved.error, reason: resolved.reason }, status); 60 + } 61 + const ticket = await signer.sign({ 62 + topics: resolved.topics, 63 + did: sa.issuer, 64 + ttlMs: ticketTtl, 65 + }); 66 + return c.json({ 67 + ticket, 68 + topics: resolved.topics, 69 + expiresAt: Date.now() + ticketTtl, 70 + }); 71 + }); 72 + 73 + // GET /<ns>.realtime.subscribe — SSE or WS, driven by ?ticket= or JWT. 74 + app.get(`/xrpc/${NS}.subscribe`, async (c) => { 75 + const url = new URL(c.req.url); 76 + const ticketParam = url.searchParams.get("ticket"); 77 + const collectionFilter = url.searchParams.get("collection"); 78 + 79 + let callerDid: string; 80 + let topics: string[]; 81 + 82 + if (ticketParam) { 83 + const payload = await signer.verify(ticketParam); 84 + if (!payload) { 85 + return c.json({ error: "AuthRequired", reason: "invalid-or-expired-ticket" }, 401); 86 + } 87 + callerDid = payload.did; 88 + topics = payload.topics; 89 + // Optional: narrow to topics the query explicitly requests. 90 + const requested = url.searchParams.get("topic"); 91 + if (requested) { 92 + if (!payload.topics.includes(requested)) { 93 + return c.json({ error: "Forbidden", reason: "topic-not-in-ticket" }, 403); 94 + } 95 + topics = [requested]; 96 + } 97 + } else { 98 + // JWT path for server-side bots. Requires the auth middleware to have 99 + // run and attached `serviceAuth` to the context — so we invoke it 100 + // inline. 101 + const runAuth = options.authMiddleware; 102 + let authed = false; 103 + await runAuth(c, async () => { 104 + authed = true; 105 + }); 106 + if (!authed) return c.res; // middleware already responded with 401 107 + const sa = getAuth(c); 108 + callerDid = sa.issuer; 109 + const topic = url.searchParams.get("topic"); 110 + if (!topic) { 111 + return c.json({ error: "InvalidRequest", message: "topic required" }, 400); 112 + } 113 + const resolved = await resolveTopicForCaller(topic, callerDid, { spaces, community }); 114 + if (!resolved.ok) { 115 + const status = resolved.error === "NotFound" ? 404 : resolved.error === "Forbidden" ? 403 : 400; 116 + return c.json({ error: resolved.error, reason: resolved.reason }, status); 117 + } 118 + topics = resolved.topics; 119 + } 120 + 121 + if (topics.length === 0) { 122 + return c.json({ error: "InvalidRequest", reason: "no-topics" }, 400); 123 + } 124 + 125 + // Build the merged iterable, with an inline filter that closes the stream 126 + // on a matching `member.removed` event (self-kick on revocation). 127 + const ac = new AbortController(); 128 + const signals: AbortSignal[] = [ac.signal]; 129 + const reqSignal = c.req.raw.signal; 130 + if (reqSignal) signals.push(reqSignal); 131 + const combined = anySignal(signals); 132 + 133 + const sources = topics.map((t) => pubsub.subscribe(t, combined)); 134 + const merged = withSelfKickAndFilter( 135 + mergeAsyncIterables(sources, combined), 136 + callerDid, 137 + collectionFilter, 138 + ac 139 + ); 140 + 141 + // Content negotiation: Upgrade: websocket → WS, else SSE. 142 + if (c.req.header("Upgrade")?.toLowerCase() === "websocket") { 143 + const Pair = (globalThis as unknown as { WebSocketPair?: WebSocketPairCtor }) 144 + .WebSocketPair; 145 + if (!Pair) { 146 + return c.json( 147 + { error: "NotSupported", reason: "websockets-require-worker-or-ws-adapter" }, 148 + 426 149 + ); 150 + } 151 + const pair = new Pair(); 152 + const clientWs = pair[0]; 153 + const serverWs = pair[1]; 154 + serverWs.accept?.(); 155 + // Pump in the background; don't await. 156 + void pumpWebSocket(serverWs, merged, combined, { keepaliveMs }); 157 + return new Response(null, { 158 + status: 101, 159 + // Hono/undici-compat: some runtimes honor `webSocket` on the init. 160 + // @ts-expect-error - Workers-specific init field 161 + webSocket: clientWs, 162 + }); 163 + } 164 + 165 + return sseResponse(merged, combined, { keepaliveMs }); 166 + }); 167 + } 168 + 169 + // ============================================================================ 170 + // Helpers 171 + // ============================================================================ 172 + 173 + function getAuth(c: Context): ServiceAuth { 174 + const a = c.get("serviceAuth") as ServiceAuth | undefined; 175 + if (!a) throw new Error("service auth not set"); 176 + return a; 177 + } 178 + 179 + /** Merge multiple AbortSignals into one. Aborts when any source aborts. */ 180 + function anySignal(signals: AbortSignal[]): AbortSignal { 181 + const ac = new AbortController(); 182 + for (const s of signals) { 183 + if (s.aborted) { 184 + ac.abort(); 185 + return ac.signal; 186 + } 187 + s.addEventListener("abort", () => ac.abort(), { once: true }); 188 + } 189 + return ac.signal; 190 + } 191 + 192 + /** Wrap an iterable: drop events that don't pass the collection filter (if 193 + * any), and close the outer controller as soon as we see a `member.removed` 194 + * for the caller's own DID. */ 195 + function withSelfKickAndFilter( 196 + source: AsyncIterable<RealtimeEvent>, 197 + callerDid: string, 198 + collectionFilter: string | null, 199 + ac: AbortController 200 + ): AsyncIterable<RealtimeEvent> { 201 + return { 202 + async *[Symbol.asyncIterator]() { 203 + for await (const event of source) { 204 + if (event.kind === "member.removed" && event.payload.did === callerDid) { 205 + // Deliver the kick event so the client sees why, then close. 206 + yield event; 207 + ac.abort(); 208 + return; 209 + } 210 + if ( 211 + collectionFilter && 212 + (event.kind === "record.created" || event.kind === "record.deleted") && 213 + event.payload.collection !== collectionFilter 214 + ) { 215 + continue; 216 + } 217 + yield event; 218 + } 219 + }, 220 + }; 221 + }
+98
src/core/realtime/sse.ts
··· 1 + /** Server-Sent Events transport. 2 + * 3 + * Wraps an AsyncIterable<RealtimeEvent> as a streaming Response. The caller 4 + * (the router) has already done auth and has an AbortSignal it can use to 5 + * tear the stream down (e.g. on `member.removed` for the subscriber's DID). */ 6 + 7 + import type { RealtimeEvent } from "./types"; 8 + import { DEFAULT_KEEPALIVE_MS } from "./types"; 9 + 10 + export interface SseOptions { 11 + keepaliveMs?: number; 12 + /** Called before the stream closes. Useful for cleanup that the caller 13 + * can't do via the signal (e.g. removing a subscriber from a set). */ 14 + onClose?: () => void; 15 + } 16 + 17 + export function sseResponse( 18 + iter: AsyncIterable<RealtimeEvent>, 19 + signal: AbortSignal, 20 + opts: SseOptions = {} 21 + ): Response { 22 + const keepaliveMs = opts.keepaliveMs ?? DEFAULT_KEEPALIVE_MS; 23 + const encoder = new TextEncoder(); 24 + 25 + const stream = new ReadableStream<Uint8Array>({ 26 + start(controller) { 27 + let closed = false; 28 + let keepalive: ReturnType<typeof setInterval> | null = null; 29 + 30 + const close = () => { 31 + if (closed) return; 32 + closed = true; 33 + if (keepalive) clearInterval(keepalive); 34 + try { 35 + controller.close(); 36 + } catch { 37 + /* already closed */ 38 + } 39 + opts.onClose?.(); 40 + }; 41 + 42 + signal.addEventListener("abort", close, { once: true }); 43 + 44 + keepalive = setInterval(() => { 45 + if (closed) return; 46 + try { 47 + controller.enqueue(encoder.encode(`: keepalive\n\n`)); 48 + } catch { 49 + close(); 50 + } 51 + }, keepaliveMs); 52 + 53 + (async () => { 54 + // Opening comment — helps some clients / proxies initialize promptly. 55 + controller.enqueue(encoder.encode(`: open\n\n`)); 56 + try { 57 + for await (const event of iter) { 58 + if (closed) break; 59 + controller.enqueue(encoder.encode(frameEvent(event))); 60 + } 61 + } catch (err) { 62 + if (!closed) { 63 + try { 64 + controller.enqueue( 65 + encoder.encode( 66 + `event: error\ndata: ${JSON.stringify({ 67 + message: err instanceof Error ? err.message : String(err), 68 + })}\n\n` 69 + ) 70 + ); 71 + } catch { 72 + /* stream already torn down */ 73 + } 74 + } 75 + } finally { 76 + close(); 77 + } 78 + })(); 79 + }, 80 + cancel() { 81 + opts.onClose?.(); 82 + }, 83 + }); 84 + 85 + return new Response(stream, { 86 + status: 200, 87 + headers: { 88 + "content-type": "text/event-stream", 89 + "cache-control": "no-cache, no-transform", 90 + connection: "keep-alive", 91 + "x-accel-buffering": "no", 92 + }, 93 + }); 94 + } 95 + 96 + function frameEvent(event: RealtimeEvent): string { 97 + return `event: ${event.kind}\ndata: ${JSON.stringify(event)}\n\n`; 98 + }
+159
src/core/realtime/ticket.ts
··· 1 + /** Subscription tickets — HMAC-signed short-lived `{topics, did, exp}` blobs. 2 + * 3 + * Wire format: `<payload>.<sig>` where 4 + * payload = base64url(JSON({ topics, did, exp, iat })) 5 + * sig = base64url(HMAC-SHA256(key, payload)) 6 + * 7 + * Tickets are integrity-only (not encrypted). Browsers use them because 8 + * EventSource / WebSocket can't send Authorization headers; server-side 9 + * consumers skip the ticket dance and send their JWT directly. */ 10 + 11 + export interface TicketPayload { 12 + /** Concrete delivery topics this ticket authorizes. `community:<did>` is 13 + * expanded to the caller's visible spaces before signing — a ticket never 14 + * carries a community alias. */ 15 + topics: string[]; 16 + did: string; 17 + /** Unix ms. */ 18 + exp: number; 19 + /** Unix ms — useful for debugging; ignored on verify. */ 20 + iat: number; 21 + } 22 + 23 + function normalizeSecret(secret: Uint8Array | string): Uint8Array { 24 + if (typeof secret !== "string") { 25 + if (secret.length !== 32) { 26 + throw new Error(`realtime ticketSecret must be 32 bytes, got ${secret.length}`); 27 + } 28 + return secret; 29 + } 30 + // 64 hex chars would also round-trip as base64 (to 48 bytes). Prefer hex 31 + // when the input matches the hex alphabet exactly; fall back to base64. 32 + const hex = tryHex(secret); 33 + if (hex && hex.length === 32) return hex; 34 + const b64 = tryBase64(secret); 35 + if (b64 && b64.length === 32) return b64; 36 + if (hex || b64) { 37 + const got = (hex ?? b64)!.length; 38 + throw new Error(`realtime ticketSecret must decode to 32 bytes, got ${got}`); 39 + } 40 + throw new Error("realtime ticketSecret must be a 32-byte Uint8Array or base64/hex string"); 41 + } 42 + 43 + function tryBase64(s: string): Uint8Array | null { 44 + try { 45 + const normal = s.replace(/-/g, "+").replace(/_/g, "/"); 46 + const padded = normal + "=".repeat((4 - (normal.length % 4)) % 4); 47 + if (!/^[A-Za-z0-9+/]*=*$/.test(padded)) return null; 48 + const bin = atob(padded); 49 + const out = new Uint8Array(bin.length); 50 + for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i); 51 + return out; 52 + } catch { 53 + return null; 54 + } 55 + } 56 + 57 + function tryHex(s: string): Uint8Array | null { 58 + if (!/^[0-9a-fA-F]+$/.test(s) || s.length % 2 !== 0) return null; 59 + const out = new Uint8Array(s.length / 2); 60 + for (let i = 0; i < out.length; i++) { 61 + out[i] = parseInt(s.slice(i * 2, i * 2 + 2), 16); 62 + } 63 + return out; 64 + } 65 + 66 + function b64urlFromBytes(bytes: Uint8Array): string { 67 + let bin = ""; 68 + for (let i = 0; i < bytes.length; i++) bin += String.fromCharCode(bytes[i]!); 69 + return btoa(bin).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""); 70 + } 71 + 72 + function b64urlToBytes(s: string): Uint8Array { 73 + const normal = s.replace(/-/g, "+").replace(/_/g, "/"); 74 + const padded = normal + "=".repeat((4 - (normal.length % 4)) % 4); 75 + const bin = atob(padded); 76 + const out = new Uint8Array(bin.length); 77 + for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i); 78 + return out; 79 + } 80 + 81 + function b64urlFromString(s: string): string { 82 + return b64urlFromBytes(new TextEncoder().encode(s)); 83 + } 84 + 85 + function stringFromB64url(s: string): string { 86 + return new TextDecoder().decode(b64urlToBytes(s)); 87 + } 88 + 89 + function constantTimeEq(a: Uint8Array, b: Uint8Array): boolean { 90 + if (a.length !== b.length) return false; 91 + let diff = 0; 92 + for (let i = 0; i < a.length; i++) diff |= a[i]! ^ b[i]!; 93 + return diff === 0; 94 + } 95 + 96 + export class TicketSigner { 97 + private readonly keyPromise: Promise<CryptoKey>; 98 + 99 + constructor(secret: Uint8Array | string) { 100 + const raw = normalizeSecret(secret); 101 + this.keyPromise = crypto.subtle.importKey( 102 + "raw", 103 + raw as BufferSource, 104 + { name: "HMAC", hash: "SHA-256" }, 105 + false, 106 + ["sign", "verify"] 107 + ); 108 + } 109 + 110 + async sign(input: { topics: string[]; did: string; ttlMs: number }): Promise<string> { 111 + const now = Date.now(); 112 + const payload: TicketPayload = { 113 + topics: input.topics, 114 + did: input.did, 115 + exp: now + input.ttlMs, 116 + iat: now, 117 + }; 118 + const payloadPart = b64urlFromString(JSON.stringify(payload)); 119 + const sig = await crypto.subtle.sign( 120 + "HMAC", 121 + await this.keyPromise, 122 + new TextEncoder().encode(payloadPart) as BufferSource 123 + ); 124 + const sigPart = b64urlFromBytes(new Uint8Array(sig)); 125 + return `${payloadPart}.${sigPart}`; 126 + } 127 + 128 + /** Returns the decoded payload if the ticket is valid + unexpired, else null. */ 129 + async verify(ticket: string): Promise<TicketPayload | null> { 130 + const dot = ticket.indexOf("."); 131 + if (dot < 0) return null; 132 + const payloadPart = ticket.slice(0, dot); 133 + const sigPart = ticket.slice(dot + 1); 134 + let expectedSig: Uint8Array; 135 + try { 136 + expectedSig = b64urlToBytes(sigPart); 137 + } catch { 138 + return null; 139 + } 140 + const computedRaw = await crypto.subtle.sign( 141 + "HMAC", 142 + await this.keyPromise, 143 + new TextEncoder().encode(payloadPart) as BufferSource 144 + ); 145 + const computed = new Uint8Array(computedRaw); 146 + if (!constantTimeEq(expectedSig, computed)) return null; 147 + let parsed: TicketPayload; 148 + try { 149 + parsed = JSON.parse(stringFromB64url(payloadPart)); 150 + } catch { 151 + return null; 152 + } 153 + if (!parsed || !Array.isArray(parsed.topics) || typeof parsed.did !== "string") { 154 + return null; 155 + } 156 + if (typeof parsed.exp !== "number" || parsed.exp <= Date.now()) return null; 157 + return parsed; 158 + } 159 + }
+95
src/core/realtime/types.ts
··· 1 + /** Realtime module — canonical types + interfaces. See docs/realtime.md. */ 2 + 3 + /** Discriminated union of every event kind that flows through the PubSub. */ 4 + export type RealtimeEvent = 5 + | { 6 + topic: string; 7 + kind: "record.created"; 8 + payload: { spaceUri: string; collection: string; authorDid: string; rkey: string }; 9 + ts: number; 10 + } 11 + | { 12 + topic: string; 13 + kind: "record.deleted"; 14 + payload: { spaceUri: string; collection: string; authorDid: string; rkey: string }; 15 + ts: number; 16 + } 17 + | { 18 + topic: string; 19 + kind: "member.added"; 20 + payload: { spaceUri: string; did: string }; 21 + ts: number; 22 + } 23 + | { 24 + topic: string; 25 + kind: "member.removed"; 26 + payload: { spaceUri: string; did: string }; 27 + ts: number; 28 + }; 29 + 30 + export type RealtimeEventKind = RealtimeEvent["kind"]; 31 + 32 + /** Core pubsub abstraction. Implementations: InMemoryPubSub, DurableObjectPubSub. */ 33 + export interface PubSub { 34 + publish(event: RealtimeEvent): Promise<void>; 35 + /** Stream events on the topic until the signal aborts (or the iterator is 36 + * returned/broken out of). Implementations use a bounded per-subscriber 37 + * queue with drop-oldest semantics — a slow subscriber can't stall publishers. */ 38 + subscribe(topic: string, signal?: AbortSignal): AsyncIterable<RealtimeEvent>; 39 + } 40 + 41 + // ---- Canonical topic strings ----------------------------------------------- 42 + // `community:<did>` is an alias resolved at ticket-mint time to the concrete 43 + // set of `space:<uri>` topics the caller can see; it is never a real delivery 44 + // topic. The other three are real. 45 + 46 + export function spaceTopic(uri: string): string { 47 + return `space:${uri}`; 48 + } 49 + 50 + export function communityTopic(did: string): string { 51 + return `community:${did}`; 52 + } 53 + 54 + export function collectionTopic(nsid: string): string { 55 + return `collection:${nsid}`; 56 + } 57 + 58 + export function actorTopic(did: string): string { 59 + return `actor:${did}`; 60 + } 61 + 62 + export function isCommunityTopic(topic: string): boolean { 63 + return topic.startsWith("community:"); 64 + } 65 + 66 + export function parseCommunityTopic(topic: string): string | null { 67 + return isCommunityTopic(topic) ? topic.slice("community:".length) : null; 68 + } 69 + 70 + export function parseSpaceTopic(topic: string): string | null { 71 + return topic.startsWith("space:") ? topic.slice("space:".length) : null; 72 + } 73 + 74 + // ---- Config ----------------------------------------------------------------- 75 + 76 + export interface RealtimeConfig { 77 + /** Backing pubsub. Default: new InMemoryPubSub() (single-process only). On 78 + * Workers, pass `new DurableObjectPubSub(env.REALTIME)`. */ 79 + pubsub?: PubSub; 80 + /** HMAC secret used to sign subscription tickets. 32 bytes. Accepts raw 81 + * Uint8Array or base64 / hex string. Envelope-encrypts nothing — tickets 82 + * are integrity-only, not confidential. */ 83 + ticketSecret: Uint8Array | string; 84 + /** Ticket lifetime in ms. Default 120_000 (2 minutes). */ 85 + ticketTtlMs?: number; 86 + /** SSE/WS keepalive interval in ms. Default 15_000. */ 87 + keepaliveMs?: number; 88 + /** Per-subscriber queue bound. Default 1024. Events beyond this are dropped 89 + * oldest-first and the subscriber receives a `lag` signal (out of band). */ 90 + queueBound?: number; 91 + } 92 + 93 + export const DEFAULT_TICKET_TTL_MS = 120_000; 94 + export const DEFAULT_KEEPALIVE_MS = 15_000; 95 + export const DEFAULT_QUEUE_BOUND = 1024;
+84
src/core/realtime/websocket.ts
··· 1 + /** WebSocket transport. 2 + * 3 + * Accepts a new WebSocket connection (either via `WebSocketPair` on Workers 4 + * or a platform-provided server-side socket) and pumps events to it from an 5 + * AsyncIterable<RealtimeEvent>. Messages are UTF-8 JSON, one event per frame. 6 + * 7 + * Close codes (subset, RFC 6455 + app-custom): 8 + * - 4001: server error pumping 9 + * - 4003: membership revoked 10 + * - 4008: ticket/auth invalid (used by the router, not here) 11 + */ 12 + 13 + import type { RealtimeEvent } from "./types"; 14 + import { DEFAULT_KEEPALIVE_MS } from "./types"; 15 + 16 + export interface WebSocketLike { 17 + send(data: string): void; 18 + close(code?: number, reason?: string): void; 19 + addEventListener(type: "message" | "close" | "error", listener: (ev: any) => void): void; 20 + } 21 + 22 + export interface WebSocketPumpOptions { 23 + keepaliveMs?: number; 24 + onClose?: () => void; 25 + } 26 + 27 + /** Pump events from `iter` to `ws` until the signal aborts or the iter ends. 28 + * Caller is responsible for having already accept()ed the socket. */ 29 + export async function pumpWebSocket( 30 + ws: WebSocketLike, 31 + iter: AsyncIterable<RealtimeEvent>, 32 + signal: AbortSignal, 33 + opts: WebSocketPumpOptions = {} 34 + ): Promise<void> { 35 + const keepaliveMs = opts.keepaliveMs ?? DEFAULT_KEEPALIVE_MS; 36 + let closed = false; 37 + 38 + const close = (code?: number, reason?: string) => { 39 + if (closed) return; 40 + closed = true; 41 + try { 42 + ws.close(code, reason); 43 + } catch { 44 + /* already closed */ 45 + } 46 + opts.onClose?.(); 47 + }; 48 + 49 + ws.addEventListener("close", () => { 50 + closed = true; 51 + opts.onClose?.(); 52 + }); 53 + ws.addEventListener("error", () => { 54 + closed = true; 55 + opts.onClose?.(); 56 + }); 57 + signal.addEventListener("abort", () => close(1000, "aborted"), { once: true }); 58 + 59 + const keepalive = setInterval(() => { 60 + if (closed) return; 61 + try { 62 + ws.send(JSON.stringify({ kind: "$keepalive" })); 63 + } catch { 64 + close(); 65 + } 66 + }, keepaliveMs); 67 + 68 + try { 69 + for await (const event of iter) { 70 + if (closed) break; 71 + try { 72 + ws.send(JSON.stringify(event)); 73 + } catch { 74 + close(4001, "send-failed"); 75 + break; 76 + } 77 + } 78 + } catch { 79 + close(4001, "pump-error"); 80 + } finally { 81 + clearInterval(keepalive); 82 + close(); 83 + } 84 + }
+54 -1
src/core/router/index.ts
··· 14 14 import type { ServiceJwtVerifier } from "@atcute/xrpc-server/auth"; 15 15 import { registerCommunityRoutes } from "../community/router"; 16 16 import type { CommunityRoutesOptions } from "../community/router"; 17 + import { CommunityAdapter } from "../community/adapter"; 18 + import { registerRealtimeRoutes } from "../realtime/router"; 19 + import type { RealtimeRoutesOptions } from "../realtime/router"; 20 + import { InMemoryPubSub } from "../realtime/in-memory"; 21 + import { wrapWithPublishing } from "../realtime/publishing-adapter"; 22 + import type { PubSub } from "../realtime/types"; 17 23 import { resolveActor } from "../identity"; 18 24 import { resolveProfiles } from "./profiles"; 19 25 import { backfillUser } from "../backfill"; ··· 26 32 export interface CreateAppOptions { 27 33 spaces?: SpacesRoutesOptions; 28 34 community?: CommunityRoutesOptions; 35 + realtime?: Partial<RealtimeRoutesOptions>; 29 36 /** Separate DB for the spaces tables. Defaults to `db`. */ 30 37 spacesDb?: Database; 31 38 /** Full spaces context override (escape hatch for tests). */ ··· 72 79 // Shared spaces context — verifier + adapter — reused by both the per-collection 73 80 // routes (for `?spaceUri=...` dispatch) and the `<ns>.space.*` routes. 74 81 const spacesDb = options.spacesDb ?? db; 75 - const spacesCtx: SpacesContext | null = 82 + let spacesCtx: SpacesContext | null = 76 83 options.spacesCtx !== undefined 77 84 ? options.spacesCtx 78 85 : config.spaces ··· 82 89 } 83 90 : null; 84 91 92 + // Realtime pubsub is built up-front so the publishing decorator can reference 93 + // it. The subscribe endpoint uses the same instance. 94 + let realtimePubsub: PubSub | null = null; 95 + if (config.realtime && spacesCtx) { 96 + realtimePubsub = 97 + options.realtime?.pubsub ?? config.realtime.pubsub ?? new InMemoryPubSub({ 98 + queueBound: config.realtime.queueBound, 99 + }); 100 + const communityAdapter = config.community ? new CommunityAdapter(spacesDb) : null; 101 + const isCommunityDid = communityAdapter 102 + ? cachedIsCommunityDid(communityAdapter) 103 + : undefined; 104 + spacesCtx = { 105 + ...spacesCtx, 106 + adapter: wrapWithPublishing(spacesCtx.adapter, realtimePubsub, { isCommunityDid }), 107 + }; 108 + } 109 + 85 110 registerAdminRoutes(app, db, config); 86 111 registerCollectionRoutes(app, db, config, spacesCtx); 87 112 registerFeedRoutes(app, db, config); ··· 103 128 ); 104 129 } 105 130 131 + if (config.realtime && spacesCtx && realtimePubsub) { 132 + const authMiddleware = 133 + options.realtime?.authMiddleware ?? 134 + options.spaces?.authMiddleware ?? 135 + createServiceAuthMiddleware(spacesCtx.verifier); 136 + const communityAdapter = config.community ? new CommunityAdapter(spacesDb) : null; 137 + registerRealtimeRoutes(app, config, spacesCtx.adapter, communityAdapter, { 138 + authMiddleware, 139 + pubsub: realtimePubsub, 140 + }); 141 + } 142 + 106 143 return app; 107 144 } 145 + 146 + function cachedIsCommunityDid( 147 + community: CommunityAdapter 148 + ): (did: string) => Promise<boolean> { 149 + const TTL = 60_000; 150 + const cache = new Map<string, { value: boolean; expires: number }>(); 151 + return async (did: string) => { 152 + const now = Date.now(); 153 + const hit = cache.get(did); 154 + if (hit && hit.expires > now) return hit.value; 155 + const row = await community.getCommunity(did); 156 + const value = row != null; 157 + cache.set(did, { value, expires: now + TTL }); 158 + return value; 159 + }; 160 + }
+3
src/core/types.ts
··· 158 158 /** Community module configuration. When set, the service exposes community XRPCs 159 159 * for managing community-owned spaces and tiered access levels. Requires `spaces`. */ 160 160 community?: import("./community/types").CommunityConfig; 161 + /** Realtime module configuration. When set, the service exposes ticket + SSE/WS 162 + * subscribe XRPCs, and wraps the spaces adapter to publish events after writes. */ 163 + realtime?: import("./realtime/types").RealtimeConfig; 161 164 /** Customize the auto-generated `<namespace>.permissionSet` lexicon. */ 162 165 permissionSet?: PermissionSetConfig; 163 166 }
+53
src/generate.ts
··· 51 51 return null; 52 52 } 53 53 54 + function findRealtimeTemplatesDir(rootDir: string): string | null { 55 + const candidates = [ 56 + join(rootDir, "realtime-lexicon-templates"), 57 + join(rootDir, "node_modules/@atmo-dev/contrail/realtime-lexicon-templates"), 58 + ]; 59 + for (const p of candidates) { 60 + if (existsSync(p)) return p; 61 + } 62 + return null; 63 + } 64 + 54 65 /** Yield all JSON files under a directory (recursive). */ 55 66 function* walkJson(dir: string): Generator<string> { 56 67 for (const entry of readdirSync(dir, { withFileTypes: true })) { ··· 753 764 for (const [k, v] of Object.entries(obj)) { 754 765 if (k === "ref" && typeof v === "string" && v.startsWith("tools.atmo.community")) { 755 766 out[k] = v.replace(/^tools\.atmo\.community/, `${ns}.community`); 767 + } else if (k === "id" && typeof v === "string" && templateIdRe.test(v)) { 768 + out[k] = idReplace(v); 769 + } else { 770 + out[k] = rewriteRefs(v); 771 + } 772 + } 773 + return out; 774 + } 775 + return obj; 776 + }; 777 + 778 + for (const file of walkJson(templatesDir)) { 779 + const doc = JSON.parse(readFileSync(file, "utf-8")); 780 + if (typeof doc.id !== "string" || !templateIdRe.test(doc.id)) continue; 781 + const newId = idReplace(doc.id); 782 + const rewritten = rewriteRefs({ ...doc, id: newId }); 783 + writeLexicon(newId, rewritten); 784 + } 785 + } 786 + } 787 + 788 + // --- Realtime: instantiate library templates under <ns>.realtime.* --- 789 + 790 + if (config.realtime) { 791 + log("Generating realtime endpoints..."); 792 + const templatesDir = findRealtimeTemplatesDir(rootDir); 793 + if (!templatesDir) { 794 + log(" (realtime templates not found — skipping)"); 795 + } else { 796 + const templateIdRe = /^tools\.atmo\.realtime(\.[A-Za-z0-9.]+)?$/; 797 + const idReplace = (id: string) => 798 + id.startsWith("tools.atmo.realtime") 799 + ? id.replace(/^tools\.atmo\.realtime/, `${ns}.realtime`) 800 + : id; 801 + 802 + const rewriteRefs = (obj: any): any => { 803 + if (Array.isArray(obj)) return obj.map(rewriteRefs); 804 + if (obj && typeof obj === "object") { 805 + const out: any = {}; 806 + for (const [k, v] of Object.entries(obj)) { 807 + if (k === "ref" && typeof v === "string" && v.startsWith("tools.atmo.realtime")) { 808 + out[k] = v.replace(/^tools\.atmo\.realtime/, `${ns}.realtime`); 756 809 } else if (k === "id" && typeof v === "string" && templateIdRe.test(v)) { 757 810 out[k] = idReplace(v); 758 811 } else {
+23
src/index.ts
··· 50 50 export { HostedAdapter } from "./core/spaces/adapter"; 51 51 export { nextTid } from "./core/spaces/tid"; 52 52 export { generateInviteToken, hashInviteToken } from "./core/spaces/invite-token"; 53 + 54 + // Realtime 55 + export type { 56 + PubSub, 57 + RealtimeConfig, 58 + RealtimeEvent, 59 + RealtimeEventKind, 60 + } from "./core/realtime/types"; 61 + export { 62 + InMemoryPubSub, 63 + DurableObjectPubSub, 64 + RealtimePubSubDO, 65 + TicketSigner, 66 + wrapWithPublishing, 67 + sseResponse, 68 + pumpWebSocket, 69 + mergeAsyncIterables, 70 + resolveTopicForCaller, 71 + actorTopic, 72 + collectionTopic, 73 + communityTopic, 74 + spaceTopic, 75 + } from "./core/realtime";
+238
tests/realtime-durable-object.test.ts
··· 1 + /** Unit tests for the DO class and the DO client adapter. 2 + * 3 + * We don't run wrangler here — instead we hand-roll a tiny fake `DurableObjectState` 4 + * and fake WebSocket pair so we can drive the class's public `fetch` method 5 + * directly. That's enough to verify routing, fan-out, kick-on-remove, and the 6 + * client-side SSE pull iterator. */ 7 + 8 + import { describe, it, expect } from "vitest"; 9 + import { 10 + DurableObjectPubSub, 11 + RealtimePubSubDO, 12 + type DurableObjectState, 13 + type DurableObjectNamespace, 14 + type DurableObjectStub, 15 + } from "../src/core/realtime/durable-object"; 16 + import type { RealtimeEvent } from "../src/core/realtime/types"; 17 + 18 + // ---- Fakes ----------------------------------------------------------------- 19 + 20 + class FakeWebSocket { 21 + public readonly sent: string[] = []; 22 + public closedCode: number | undefined; 23 + private attachment: unknown = null; 24 + serializeAttachment(a: unknown): void { 25 + this.attachment = a; 26 + } 27 + deserializeAttachment(): unknown { 28 + return this.attachment; 29 + } 30 + send(s: string): void { 31 + this.sent.push(s); 32 + } 33 + close(code?: number): void { 34 + this.closedCode = code; 35 + } 36 + // For the test harness — required so the class can upgrade an incoming request. 37 + accept(): void {} 38 + } 39 + 40 + class FakeState implements DurableObjectState { 41 + private readonly sockets: FakeWebSocket[] = []; 42 + acceptWebSocket(ws: FakeWebSocket): void { 43 + this.sockets.push(ws); 44 + } 45 + getWebSockets(): FakeWebSocket[] { 46 + return this.sockets; 47 + } 48 + } 49 + 50 + function mkEvent(overrides: Partial<RealtimeEvent> = {}): RealtimeEvent { 51 + return { 52 + topic: "space:at://x/y/z", 53 + kind: "record.created", 54 + payload: { spaceUri: "at://x/y/z", collection: "c", authorDid: "did:plc:x", rkey: "r" }, 55 + ts: 1, 56 + ...(overrides as any), 57 + }; 58 + } 59 + 60 + // ---- DO class tests -------------------------------------------------------- 61 + 62 + describe("RealtimePubSubDO — publish/fanout", () => { 63 + it("fans out publishEvent to all accepted websockets", async () => { 64 + const state = new FakeState(); 65 + const doInstance = new RealtimePubSubDO(state); 66 + 67 + for (const did of ["did:plc:a", "did:plc:b"]) { 68 + doInstance.acceptWebSocketSubscriber(new FakeWebSocket(), did); 69 + } 70 + 71 + doInstance.publishEvent(mkEvent({ ts: 42 })); 72 + 73 + const sockets = state.getWebSockets(); 74 + expect(sockets).toHaveLength(2); 75 + for (const ws of sockets) { 76 + expect(ws.sent).toHaveLength(1); 77 + expect(JSON.parse(ws.sent[0]!).ts).toBe(42); 78 + } 79 + }); 80 + 81 + it("kicks WS whose attachment.did matches a member.removed event", async () => { 82 + const state = new FakeState(); 83 + const doInstance = new RealtimePubSubDO(state); 84 + 85 + doInstance.acceptWebSocketSubscriber(new FakeWebSocket(), "did:plc:kickme"); 86 + doInstance.acceptWebSocketSubscriber(new FakeWebSocket(), "did:plc:stay"); 87 + 88 + doInstance.publishEvent({ 89 + topic: "space:x", 90 + kind: "member.removed", 91 + payload: { spaceUri: "at://x/y/z", did: "did:plc:kickme" }, 92 + ts: 1, 93 + }); 94 + 95 + const [kicked, staying] = state.getWebSockets(); 96 + expect(kicked!.closedCode).toBe(4003); 97 + expect(staying!.closedCode).toBeUndefined(); 98 + }); 99 + 100 + it("delivers SSE to pull-style subscribers and closes the stream on self-kick", async () => { 101 + const state = new FakeState(); 102 + const doInstance = new RealtimePubSubDO(state); 103 + 104 + const subRes = doInstance.openSseResponse("did:plc:self"); 105 + expect(subRes.status).toBe(200); 106 + const reader = subRes.body!.getReader(); 107 + 108 + const collect = async (target: number) => { 109 + const decoder = new TextDecoder(); 110 + const events: RealtimeEvent[] = []; 111 + let buf = ""; 112 + while (events.length < target) { 113 + const { value, done } = await reader.read(); 114 + if (value) buf += decoder.decode(value, { stream: true }); 115 + if (done) break; 116 + while (true) { 117 + const sep = buf.indexOf("\n\n"); 118 + if (sep < 0) break; 119 + const frame = buf.slice(0, sep); 120 + buf = buf.slice(sep + 2); 121 + for (const line of frame.split("\n")) { 122 + if (line.startsWith("data:")) { 123 + try { events.push(JSON.parse(line.slice(5).trim())); } catch {} 124 + } 125 + } 126 + } 127 + } 128 + return events; 129 + }; 130 + 131 + // Publish a regular event, then a self-targeting member.removed. 132 + doInstance.publishEvent(mkEvent({ ts: 7 })); 133 + doInstance.publishEvent({ 134 + topic: "space:x", 135 + kind: "member.removed", 136 + payload: { spaceUri: "at://x/y/z", did: "did:plc:self" }, 137 + ts: 8, 138 + }); 139 + 140 + const events = await collect(2); 141 + expect(events.map((e) => e.kind)).toEqual(["record.created", "member.removed"]); 142 + 143 + // Stream should be closed after the self-kick. 144 + const tail = await reader.read(); 145 + expect(tail.done).toBe(true); 146 + }); 147 + }); 148 + 149 + // ---- Client adapter tests -------------------------------------------------- 150 + 151 + describe("DurableObjectPubSub — client adapter", () => { 152 + it("routes publish to the correct DO by topic name", async () => { 153 + const calls: Array<{ name: string; url: string; init?: RequestInit }> = []; 154 + const stubFor = (name: string): DurableObjectStub => ({ 155 + async fetch(input, init) { 156 + const url = typeof input === "string" ? input : (input as URL | Request).toString(); 157 + calls.push({ name, url, init }); 158 + return new Response("{}", { status: 200 }); 159 + }, 160 + }); 161 + const ns: DurableObjectNamespace = { 162 + idFromName: (n: string) => ({ toString: () => n }), 163 + get: (id) => stubFor(id.toString()), 164 + }; 165 + const ps = new DurableObjectPubSub(ns); 166 + 167 + await ps.publish(mkEvent({ topic: "space:a" })); 168 + await ps.publish(mkEvent({ topic: "community:c1" })); 169 + 170 + expect(calls).toHaveLength(2); 171 + expect(calls[0]!.name).toBe("space:a"); 172 + expect(calls[0]!.url).toContain("/publish"); 173 + expect(calls[1]!.name).toBe("community:c1"); 174 + }); 175 + 176 + it("subscribes via SSE and pulls parsed events", async () => { 177 + // Simulate a DO that streams two SSE events, then ends. 178 + const stream = new ReadableStream<Uint8Array>({ 179 + start(controller) { 180 + const enc = new TextEncoder(); 181 + controller.enqueue(enc.encode(": open\n\n")); 182 + controller.enqueue( 183 + enc.encode(`event: record.created\ndata: ${JSON.stringify(mkEvent({ ts: 1 }))}\n\n`) 184 + ); 185 + controller.enqueue( 186 + enc.encode(`event: record.created\ndata: ${JSON.stringify(mkEvent({ ts: 2 }))}\n\n`) 187 + ); 188 + controller.close(); 189 + }, 190 + }); 191 + const stubFor = (): DurableObjectStub => ({ 192 + async fetch() { 193 + return new Response(stream, { status: 200 }); 194 + }, 195 + }); 196 + const ns: DurableObjectNamespace = { 197 + idFromName: (n) => ({ toString: () => n }), 198 + get: () => stubFor(), 199 + }; 200 + const ps = new DurableObjectPubSub(ns); 201 + 202 + const received: RealtimeEvent[] = []; 203 + for await (const e of ps.subscribe("space:a")) { 204 + received.push(e); 205 + } 206 + expect(received.map((e) => e.ts)).toEqual([1, 2]); 207 + }); 208 + 209 + it("ends the pull iterator when return() is called", async () => { 210 + let canceled = false; 211 + const stream = new ReadableStream<Uint8Array>({ 212 + start() { 213 + /* never emits */ 214 + }, 215 + cancel() { 216 + canceled = true; 217 + }, 218 + }); 219 + const ns: DurableObjectNamespace = { 220 + idFromName: (n) => ({ toString: () => n }), 221 + get: () => ({ 222 + async fetch() { 223 + return new Response(stream, { status: 200 }); 224 + }, 225 + }), 226 + }; 227 + const ps = new DurableObjectPubSub(ns); 228 + const iter = ps.subscribe("space:a")[Symbol.asyncIterator](); 229 + // Kick off open() so reader exists, then explicitly return. 230 + const next = iter.next(); 231 + // Let the iterator attach its reader before returning. 232 + await new Promise((r) => setTimeout(r, 0)); 233 + await iter.return!(); 234 + const r = await next; 235 + expect(r.done).toBe(true); 236 + expect(canceled).toBe(true); 237 + }); 238 + });
+305
tests/realtime-e2e.test.ts
··· 1 + import { describe, it, expect, beforeAll } from "vitest"; 2 + import { Hono } from "hono"; 3 + import type { MiddlewareHandler } from "hono"; 4 + import { createSqliteDatabase } from "../src/adapters/sqlite"; 5 + import { initSchema } from "../src/core/db/schema"; 6 + import { createApp } from "../src/core/router"; 7 + import { resolveConfig } from "../src/core/types"; 8 + import type { ContrailConfig } from "../src/core/types"; 9 + import type { RealtimeEvent } from "../src/core/realtime/types"; 10 + 11 + const ALICE = "did:plc:alice"; 12 + const BOB = "did:plc:bob"; 13 + const CHARLIE = "did:plc:charlie"; 14 + 15 + const MASTER_KEY = new Uint8Array(32).fill(5); 16 + const REALTIME_SECRET = new Uint8Array(32).fill(9); 17 + 18 + const CONFIG: ContrailConfig = { 19 + namespace: "test.rt", 20 + collections: { message: { collection: "app.event.message" } }, 21 + spaces: { 22 + type: "tools.atmo.event.space", 23 + serviceDid: "did:web:test.example#svc", 24 + }, 25 + community: { 26 + masterKey: MASTER_KEY, 27 + plcDirectory: "https://plc.test", 28 + fetch: mockFetch, 29 + resolver: mockResolver(), 30 + }, 31 + realtime: { 32 + ticketSecret: REALTIME_SECRET, 33 + keepaliveMs: 60_000, 34 + }, 35 + }; 36 + 37 + function mockResolver(): any { 38 + return { 39 + resolve: async (_did: string) => ({ 40 + id: _did, 41 + service: [ 42 + { id: "#atproto_pds", type: "AtprotoPersonalDataServer", serviceEndpoint: "https://pds.test" }, 43 + ], 44 + }), 45 + }; 46 + } 47 + 48 + async function mockFetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response> { 49 + const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url; 50 + if (url.endsWith("/xrpc/com.atproto.server.createSession")) { 51 + return new Response( 52 + JSON.stringify({ accessJwt: "a.b.c", refreshJwt: "r.r.r", did: "did:plc:community" }), 53 + { status: 200, headers: { "content-type": "application/json" } } 54 + ); 55 + } 56 + if (url.startsWith("https://plc.test/")) return new Response("{}", { status: 200 }); 57 + return new Response("not found", { status: 404 }); 58 + } 59 + 60 + function fakeAuth(): MiddlewareHandler { 61 + return async (c, next) => { 62 + const did = c.req.header("X-Test-Did"); 63 + if (!did) return c.json({ error: "AuthRequired" }, 401); 64 + c.set("serviceAuth", { issuer: did, audience: CONFIG.spaces!.serviceDid, lxm: undefined }); 65 + await next(); 66 + }; 67 + } 68 + 69 + async function makeApp(): Promise<Hono> { 70 + const db = createSqliteDatabase(":memory:"); 71 + const resolved = resolveConfig(CONFIG); 72 + await initSchema(db, resolved); 73 + return createApp(db, resolved, { 74 + spaces: { authMiddleware: fakeAuth() }, 75 + }); 76 + } 77 + 78 + function call( 79 + app: Hono, 80 + method: string, 81 + path: string, 82 + did: string | null, 83 + body?: any, 84 + extraHeaders: Record<string, string> = {} 85 + ): Promise<Response> { 86 + const headers: Record<string, string> = { ...extraHeaders }; 87 + if (did) headers["X-Test-Did"] = did; 88 + if (body !== undefined) headers["Content-Type"] = "application/json"; 89 + return app.fetch( 90 + new Request(`http://localhost${path}`, { 91 + method, 92 + headers, 93 + body: body !== undefined ? JSON.stringify(body) : undefined, 94 + }) 95 + ); 96 + } 97 + 98 + /** Open an SSE stream and return an async iterator over decoded events. */ 99 + async function openSse( 100 + app: Hono, 101 + path: string, 102 + did: string | null = null 103 + ): Promise<{ 104 + res: Response; 105 + events: AsyncIterator<RealtimeEvent>; 106 + close: () => void; 107 + }> { 108 + const ac = new AbortController(); 109 + const headers: Record<string, string> = {}; 110 + if (did) headers["X-Test-Did"] = did; 111 + const res = await app.fetch( 112 + new Request(`http://localhost${path}`, { method: "GET", headers, signal: ac.signal }) 113 + ); 114 + if (!res.ok) { 115 + throw new Error(`SSE open failed: ${res.status} ${await res.text()}`); 116 + } 117 + const reader = res.body!.getReader(); 118 + const decoder = new TextDecoder(); 119 + let buf = ""; 120 + const iter: AsyncIterator<RealtimeEvent> = { 121 + async next() { 122 + // Read frames until we get an event with valid JSON data. 123 + while (true) { 124 + // Parse any complete frames already buffered. 125 + while (true) { 126 + const sep = buf.indexOf("\n\n"); 127 + if (sep < 0) break; 128 + const frame = buf.slice(0, sep); 129 + buf = buf.slice(sep + 2); 130 + const lines = frame.split("\n"); 131 + let data: string | null = null; 132 + for (const line of lines) { 133 + if (line.startsWith(":")) continue; // comment / keepalive 134 + if (line.startsWith("data:")) data = line.slice(5).trim(); 135 + } 136 + if (data) { 137 + return { value: JSON.parse(data) as RealtimeEvent, done: false }; 138 + } 139 + } 140 + const r = await reader.read(); 141 + if (r.done) return { value: undefined, done: true }; 142 + buf += decoder.decode(r.value, { stream: true }); 143 + } 144 + }, 145 + async return() { 146 + ac.abort(); 147 + try { await reader.cancel(); } catch { /* */ } 148 + return { value: undefined, done: true }; 149 + }, 150 + }; 151 + return { res, events: iter, close: () => { ac.abort(); reader.cancel().catch(() => {}); } }; 152 + } 153 + 154 + async function createSpace(app: Hono, owner: string, key?: string): Promise<string> { 155 + const res = await call(app, "POST", "/xrpc/test.rt.space.createSpace", owner, { key }); 156 + expect(res.status).toBe(200); 157 + return ((await res.json()) as any).space.uri; 158 + } 159 + 160 + async function mintTicket(app: Hono, did: string, topic: string): Promise<{ ticket: string; topics: string[] }> { 161 + const res = await call(app, "POST", "/xrpc/test.rt.realtime.ticket", did, { topic }); 162 + expect(res.status).toBe(200); 163 + return (await res.json()) as any; 164 + } 165 + 166 + describe("realtime e2e (in-memory pubsub, SSE transport)", () => { 167 + let app: Hono; 168 + 169 + beforeAll(async () => { 170 + app = await makeApp(); 171 + }); 172 + 173 + it("ticket+SSE: owner subscribes and receives record.created", async () => { 174 + const spaceUri = await createSpace(app, ALICE); 175 + const { ticket } = await mintTicket(app, ALICE, `space:${spaceUri}`); 176 + const { events, close } = await openSse( 177 + app, 178 + `/xrpc/test.rt.realtime.subscribe?ticket=${encodeURIComponent(ticket)}` 179 + ); 180 + // Publish a record. 181 + const put = await call(app, "POST", "/xrpc/test.rt.space.putRecord", ALICE, { 182 + spaceUri, 183 + collection: "app.event.message", 184 + record: { text: "hello" }, 185 + }); 186 + expect(put.status).toBe(200); 187 + const next = await events.next(); 188 + expect(next.done).toBe(false); 189 + expect((next.value as RealtimeEvent).kind).toBe("record.created"); 190 + close(); 191 + }); 192 + 193 + it("non-member cannot mint a ticket for a space they don't belong to", async () => { 194 + const spaceUri = await createSpace(app, ALICE, "members-only"); 195 + const res = await call(app, "POST", "/xrpc/test.rt.realtime.ticket", BOB, { 196 + topic: `space:${spaceUri}`, 197 + }); 198 + expect(res.status).toBe(403); 199 + }); 200 + 201 + it("JWT path (bot): subscribe without a ticket using Authorization-equivalent", async () => { 202 + const spaceUri = await createSpace(app, ALICE, "bot-space"); 203 + const { events, close } = await openSse( 204 + app, 205 + `/xrpc/test.rt.realtime.subscribe?topic=${encodeURIComponent("space:" + spaceUri)}`, 206 + ALICE 207 + ); 208 + await call(app, "POST", "/xrpc/test.rt.space.putRecord", ALICE, { 209 + spaceUri, 210 + collection: "app.event.message", 211 + record: { text: "from-bot" }, 212 + }); 213 + const next = await events.next(); 214 + expect((next.value as RealtimeEvent).kind).toBe("record.created"); 215 + close(); 216 + }); 217 + 218 + it("collection filter drops non-matching record events", async () => { 219 + const spaceUri = await createSpace(app, ALICE, "filter-space"); 220 + const { events, close } = await openSse( 221 + app, 222 + `/xrpc/test.rt.realtime.subscribe?topic=${encodeURIComponent("space:" + spaceUri)}&collection=app.event.message`, 223 + ALICE 224 + ); 225 + // Write one matching record — should arrive. 226 + await call(app, "POST", "/xrpc/test.rt.space.putRecord", ALICE, { 227 + spaceUri, 228 + collection: "app.event.message", 229 + record: { text: "match" }, 230 + }); 231 + const ev = await events.next(); 232 + expect((ev.value as RealtimeEvent).kind).toBe("record.created"); 233 + expect((ev.value as RealtimeEvent & { kind: "record.created" }).payload.collection).toBe( 234 + "app.event.message" 235 + ); 236 + close(); 237 + }); 238 + 239 + it("member.removed kicks the subscriber's stream", async () => { 240 + const spaceUri = await createSpace(app, ALICE, "kick-space"); 241 + // Add Bob as a member. 242 + await call(app, "POST", "/xrpc/test.rt.space.addMember", ALICE, { spaceUri, did: BOB }); 243 + const { ticket } = await mintTicket(app, BOB, `space:${spaceUri}`); 244 + const { events, close } = await openSse( 245 + app, 246 + `/xrpc/test.rt.realtime.subscribe?ticket=${encodeURIComponent(ticket)}` 247 + ); 248 + // Remove Bob. 249 + const rm = await call(app, "POST", "/xrpc/test.rt.space.removeMember", ALICE, { 250 + spaceUri, 251 + did: BOB, 252 + }); 253 + expect(rm.status).toBe(200); 254 + // The next event Bob receives should be his own member.removed, and then 255 + // the stream should close. 256 + const ev = await events.next(); 257 + expect(ev.done).toBe(false); 258 + expect((ev.value as RealtimeEvent).kind).toBe("member.removed"); 259 + const done = await events.next(); 260 + expect(done.done).toBe(true); 261 + close(); 262 + }); 263 + 264 + it("invalid/expired ticket is rejected", async () => { 265 + const res = await app.fetch( 266 + new Request(`http://localhost/xrpc/test.rt.realtime.subscribe?ticket=bad.blob`, { 267 + method: "GET", 268 + }) 269 + ); 270 + expect(res.status).toBe(401); 271 + }); 272 + 273 + it("community:<did> alias expands to reachable spaces", async () => { 274 + // Adopt a community, create two child spaces, grant Charlie member on one. 275 + const adoptRes = await call(app, "POST", "/xrpc/test.rt.community.adopt", ALICE, { 276 + identifier: "did:plc:community", 277 + appPassword: "anything", // mockFetch returns 200 for createSession 278 + }); 279 + expect(adoptRes.status).toBe(200); 280 + const { communityDid } = (await adoptRes.json()) as any; 281 + 282 + const c1 = await call(app, "POST", "/xrpc/test.rt.community.space.create", ALICE, { 283 + communityDid, 284 + key: "general", 285 + }); 286 + expect(c1.status).toBe(200); 287 + const general = ((await c1.json()) as any).space.uri as string; 288 + 289 + // Grant Charlie as member in general. 290 + const g = await call(app, "POST", "/xrpc/test.rt.community.space.grant", ALICE, { 291 + spaceUri: general, 292 + subject: { did: CHARLIE }, 293 + accessLevel: "member", 294 + }); 295 + expect(g.status).toBe(200); 296 + 297 + // Charlie mints a community-alias ticket; should expand to [space:general]. 298 + const ticketRes = await call(app, "POST", "/xrpc/test.rt.realtime.ticket", CHARLIE, { 299 + topic: `community:${communityDid}`, 300 + }); 301 + expect(ticketRes.status).toBe(200); 302 + const body = (await ticketRes.json()) as any; 303 + expect(body.topics).toContain(`space:${general}`); 304 + }); 305 + });
+144
tests/realtime-foundations.test.ts
··· 1 + import { describe, it, expect } from "vitest"; 2 + import { InMemoryPubSub } from "../src/core/realtime/in-memory"; 3 + import { TicketSigner } from "../src/core/realtime/ticket"; 4 + import type { RealtimeEvent } from "../src/core/realtime/types"; 5 + import { spaceTopic } from "../src/core/realtime/types"; 6 + 7 + const SECRET = new Uint8Array(32).fill(3); 8 + 9 + function mk(topic: string, n: number): RealtimeEvent { 10 + return { 11 + topic, 12 + kind: "record.created", 13 + payload: { 14 + spaceUri: "at://x/y/z", 15 + collection: "c", 16 + authorDid: "did:plc:x", 17 + rkey: String(n), 18 + }, 19 + ts: n, 20 + }; 21 + } 22 + 23 + describe("InMemoryPubSub", () => { 24 + it("delivers events to a subscriber on the same topic", async () => { 25 + const ps = new InMemoryPubSub(); 26 + const topic = spaceTopic("at://x/y/z"); 27 + const it = ps.subscribe(topic)[Symbol.asyncIterator](); 28 + await ps.publish(mk(topic, 1)); 29 + const r = await it.next(); 30 + expect(r.done).toBe(false); 31 + expect((r.value as RealtimeEvent).ts).toBe(1); 32 + await it.return?.(); 33 + }); 34 + 35 + it("fans out to multiple subscribers on the same topic", async () => { 36 + const ps = new InMemoryPubSub(); 37 + const topic = spaceTopic("at://x/y/z"); 38 + const a = ps.subscribe(topic)[Symbol.asyncIterator](); 39 + const b = ps.subscribe(topic)[Symbol.asyncIterator](); 40 + await ps.publish(mk(topic, 42)); 41 + const [ra, rb] = await Promise.all([a.next(), b.next()]); 42 + expect((ra.value as RealtimeEvent).ts).toBe(42); 43 + expect((rb.value as RealtimeEvent).ts).toBe(42); 44 + await a.return?.(); 45 + await b.return?.(); 46 + }); 47 + 48 + it("does not cross topics", async () => { 49 + const ps = new InMemoryPubSub(); 50 + const topic = spaceTopic("at://x/y/z"); 51 + const other = spaceTopic("at://x/y/other"); 52 + const it = ps.subscribe(topic)[Symbol.asyncIterator](); 53 + await ps.publish(mk(other, 99)); 54 + await ps.publish(mk(topic, 1)); 55 + const r = await it.next(); 56 + expect((r.value as RealtimeEvent).ts).toBe(1); 57 + await it.return?.(); 58 + }); 59 + 60 + it("drops oldest when queue bound is reached", async () => { 61 + const ps = new InMemoryPubSub({ queueBound: 2 }); 62 + const topic = spaceTopic("at://x/y/z"); 63 + const it = ps.subscribe(topic)[Symbol.asyncIterator](); 64 + // Fill past the bound before the consumer starts reading. 65 + for (let i = 1; i <= 5; i++) await ps.publish(mk(topic, i)); 66 + const seen: number[] = []; 67 + for (let i = 0; i < 2; i++) { 68 + const r = await it.next(); 69 + seen.push((r.value as RealtimeEvent).ts); 70 + } 71 + // Queue bound = 2: the last two events survive (3 was dropped before 4, etc.). 72 + expect(seen).toEqual([4, 5]); 73 + await it.return?.(); 74 + }); 75 + 76 + it("cleans up subscribers on return()", async () => { 77 + const ps = new InMemoryPubSub(); 78 + const topic = spaceTopic("at://x/y/z"); 79 + const it = ps.subscribe(topic)[Symbol.asyncIterator](); 80 + expect(ps.subscriberCount(topic)).toBe(1); 81 + await it.return?.(); 82 + expect(ps.subscriberCount(topic)).toBe(0); 83 + }); 84 + 85 + it("cleans up subscribers when the abort signal fires", async () => { 86 + const ps = new InMemoryPubSub(); 87 + const topic = spaceTopic("at://x/y/z"); 88 + const ac = new AbortController(); 89 + const iter = ps.subscribe(topic, ac.signal); 90 + const it = iter[Symbol.asyncIterator](); 91 + // Start a pending read, then abort. 92 + const next = it.next(); 93 + ac.abort(); 94 + const r = await next; 95 + expect(r.done).toBe(true); 96 + expect(ps.subscriberCount(topic)).toBe(0); 97 + }); 98 + }); 99 + 100 + describe("TicketSigner", () => { 101 + it("round-trips a signed ticket", async () => { 102 + const signer = new TicketSigner(SECRET); 103 + const t = await signer.sign({ topics: ["space:a", "space:b"], did: "did:plc:bob", ttlMs: 60_000 }); 104 + const payload = await signer.verify(t); 105 + expect(payload).not.toBeNull(); 106 + expect(payload!.did).toBe("did:plc:bob"); 107 + expect(payload!.topics).toEqual(["space:a", "space:b"]); 108 + }); 109 + 110 + it("rejects a tampered payload", async () => { 111 + const signer = new TicketSigner(SECRET); 112 + const t = await signer.sign({ topics: ["space:a"], did: "did:plc:bob", ttlMs: 60_000 }); 113 + // Replace payload half while keeping original sig — corrupt. 114 + const tampered = t.replace(/^[^.]+/, "AAAA"); 115 + expect(await signer.verify(tampered)).toBeNull(); 116 + }); 117 + 118 + it("rejects signatures from a different secret", async () => { 119 + const a = new TicketSigner(SECRET); 120 + const b = new TicketSigner(new Uint8Array(32).fill(4)); 121 + const t = await a.sign({ topics: ["space:a"], did: "did:plc:bob", ttlMs: 60_000 }); 122 + expect(await b.verify(t)).toBeNull(); 123 + }); 124 + 125 + it("rejects expired tickets", async () => { 126 + const signer = new TicketSigner(SECRET); 127 + const t = await signer.sign({ topics: ["space:a"], did: "did:plc:bob", ttlMs: -1 }); 128 + expect(await signer.verify(t)).toBeNull(); 129 + }); 130 + 131 + it("rejects malformed tickets", async () => { 132 + const signer = new TicketSigner(SECRET); 133 + expect(await signer.verify("")).toBeNull(); 134 + expect(await signer.verify("nodot")).toBeNull(); 135 + expect(await signer.verify("abc.def")).toBeNull(); 136 + }); 137 + 138 + it("accepts secrets as base64 / hex strings", async () => { 139 + const hex = "03".repeat(32); 140 + const signer = new TicketSigner(hex); 141 + const t = await signer.sign({ topics: ["x"], did: "d", ttlMs: 60_000 }); 142 + expect(await signer.verify(t)).not.toBeNull(); 143 + }); 144 + });