an appview-less Bluesky client using Constellation and PDS Queries reddwarf.app
frontend spa bluesky reddwarf microcosm

Compare changes

Choose any two refs to compare.

+22 -4
README.md
··· 1 1 # Red Dwarf 2 2 Red Dwarf is a Bluesky client that does not use any AppView servers, instead it gathers the data from [Constellation](https://constellation.microcosm.blue/) and each users' PDS. 3 3 4 - ![screenshot of red dwarf](/public/screenshot.png) 4 + ![screenshot of red dwarf](/public/screenshot.jpg) 5 5 6 6 huge thanks to [Microcosm](https://microcosm.blue/) for making this possible 7 7 8 8 ## running dev and build 9 9 in the `vite.config.ts` file you should change these values 10 10 ```ts 11 - const PROD_URL = "https://reddwarf.whey.party" 11 + const PROD_URL = "https://reddwarf.app" 12 12 const DEV_URL = "https://local3768forumtest.whey.party" 13 13 ``` 14 14 the PROD_URL is what will compile your oauth client metadata so it is very important to change that. same for DEV_URL if you are using a tunnel for dev work ··· 52 52 and for list feeds, you can just use something like graze or skyfeed to input a list of users and output a custom feed 53 53 54 54 ## Tanstack Router 55 - it does the job, nothing very specific was used here 55 + something specific was used here 56 + 57 + so tanstack router is used as the base, but the home route is using tanstack-router-keepalive to preserve the route for better responsiveness, and it also saves scroll position of feeds into jotai (persistent) 58 + 59 + i previously used a tanstack router loader to ensure the tanstack query cache is ready to prevent scroll jumps but it is way too slow so i replaced it with tanstack-router-keepalive 60 + 61 + ## Icons 62 + this project uses Material icons. do not the light variant. sometimes i use `Mdi` if the icon needed doesnt exist in `MaterialSymbols` 56 63 57 - im planning to use the loader system on select pages to prevent loss of scroll positon and state though its really complex so i havent done it yet but the migration to tanstack query is a huge first step towards this goal 64 + the project uses unplugin icon auto import, so you can just use the component and itll just work! 65 + 66 + the format is: 67 + ```tsx 68 + <IconMaterialSymbols{icon name here} /> 69 + // or 70 + <IconMdi{icon name here} /> 71 + ``` 72 + 73 + you can get the full list of icon names from iconify ([Material Symbols](https://icon-sets.iconify.design/material-symbols/) or [MDI](https://icon-sets.iconify.design/mdi/)) 74 + 75 + while it is nice to keep everything consistent by using material icons, if the icon you need is not provided by either material symbols nor mdi, you are allowed to just grab any icon from any pack (please do prioritize icons that fit in)
+59
eslint.config.ts
··· 1 + import eslintJs from "@eslint/js"; 2 + import eslintReact from "@eslint-react/eslint-plugin"; 3 + import { defineConfig } from "eslint/config"; 4 + import reactHooks from "eslint-plugin-react-hooks"; 5 + import simpleImportSort from "eslint-plugin-simple-import-sort"; 6 + import unusedImports from "eslint-plugin-unused-imports"; 7 + import tseslint from "typescript-eslint"; 8 + 9 + export default defineConfig([ 10 + { 11 + files: ["**/*.ts", "**/*.tsx"], 12 + extends: [ 13 + eslintJs.configs.recommended, 14 + tseslint.configs.recommended, 15 + eslintReact.configs["recommended-typescript"], 16 + reactHooks.configs.flat["recommended-latest"], 17 + ], 18 + plugins: { 19 + "react-hooks": reactHooks, 20 + "simple-import-sort": simpleImportSort, 21 + "unused-imports": unusedImports, 22 + }, 23 + languageOptions: { 24 + parser: tseslint.parser, 25 + parserOptions: { 26 + projectService: true, 27 + tsconfigRootDir: import.meta.dirname, 28 + }, 29 + }, 30 + rules: { 31 + // Unused imports 32 + "unused-imports/no-unused-imports": "error", 33 + "unused-imports/no-unused-vars": [ 34 + "warn", 35 + { 36 + vars: "all", 37 + varsIgnorePattern: "^_", 38 + args: "after-used", 39 + argsIgnorePattern: "^_", 40 + }, 41 + ], 42 + 43 + // Auto sort imports 44 + "simple-import-sort/imports": "error", 45 + "simple-import-sort/exports": "error", 46 + 47 + 48 + "@typescript-eslint/no-unused-vars": [ 49 + "warn", 50 + { 51 + argsIgnorePattern: "^_", 52 + varsIgnorePattern: "^_", 53 + caughtErrorsIgnorePattern: "^_", 54 + }, 55 + ], 56 + "@typescript-eslint/no-explicit-any": "warn", 57 + }, 58 + }, 59 + ]);
+1 -1
index.html
··· 4 4 <meta charset="UTF-8" /> 5 5 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 6 6 <link rel="icon" href="/favicon.ico" /> 7 - <meta name="theme-color" content="#000000" /> 7 + <meta name="theme-color" content="#180001" /> 8 8 <meta 9 9 name="description" 10 10 content="an appview-less Bluesky client using Constellation and PDS Queries"
+1 -1
oauthdev.mts
··· 42 42 43 43 fs.writeFileSync(outputPath, JSON.stringify(metadata, null, 2)); 44 44 45 - console.log(`โœ… Generated client-metadata.json for ${appOrigin}`); 45 + // /*mass comment*/ console.log(`โœ… Generated client-metadata.json for ${appOrigin}`); 46 46 }, 47 47 }; 48 48 }
+8793 -21
package-lock.json
··· 8 8 "dependencies": { 9 9 "@atproto/api": "^0.16.6", 10 10 "@atproto/oauth-client-browser": "^0.3.33", 11 + "@radix-ui/react-dialog": "^1.1.15", 12 + "@radix-ui/react-dropdown-menu": "^2.1.16", 13 + "@radix-ui/react-hover-card": "^1.1.15", 14 + "@radix-ui/react-slider": "^1.3.6", 11 15 "@tailwindcss/vite": "^4.0.6", 12 16 "@tanstack/query-sync-storage-persister": "^5.85.6", 13 17 "@tanstack/react-devtools": "^0.2.2", ··· 16 20 "@tanstack/react-router": "^1.130.2", 17 21 "@tanstack/react-router-devtools": "^1.131.5", 18 22 "@tanstack/router-plugin": "^1.121.2", 23 + "dompurify": "^3.3.0", 24 + "i": "^0.3.7", 19 25 "idb-keyval": "^6.2.2", 20 26 "jotai": "^2.13.1", 27 + "npm": "^11.6.2", 28 + "radix-ui": "^1.4.3", 21 29 "react": "^19.0.0", 22 30 "react-dom": "^19.0.0", 23 31 "react-player": "^3.3.2", 24 - "tailwindcss": "^4.0.6" 32 + "tailwindcss": "^4.0.6", 33 + "tanstack-router-keepalive": "^1.0.0" 25 34 }, 26 35 "devDependencies": { 36 + "@eslint-react/eslint-plugin": "^2.2.1", 37 + "@iconify-icon/react": "^3.0.1", 38 + "@iconify-json/material-symbols": "^1.2.42", 39 + "@iconify-json/mdi": "^1.2.3", 40 + "@iconify/json": "^2.2.396", 41 + "@svgr/core": "^8.1.0", 42 + "@svgr/plugin-jsx": "^8.1.0", 27 43 "@testing-library/dom": "^10.4.0", 28 44 "@testing-library/react": "^16.2.0", 29 45 "@types/node": "^24.3.0", 30 46 "@types/react": "^19.0.8", 31 47 "@types/react-dom": "^19.0.3", 48 + "@typescript-eslint/eslint-plugin": "^8.46.1", 49 + "@typescript-eslint/parser": "^8.46.1", 32 50 "@vitejs/plugin-react": "^4.3.4", 51 + "babel-plugin-react-compiler": "^1.0.0", 52 + "eslint-plugin-react": "^7.37.5", 53 + "eslint-plugin-react-hooks": "^7.0.0", 54 + "eslint-plugin-simple-import-sort": "^12.1.1", 55 + "eslint-plugin-unused-imports": "^4.2.0", 33 56 "jsdom": "^26.0.0", 34 57 "prettier": "^3.6.2", 35 58 "typescript": "^5.7.2", 59 + "typescript-eslint": "^8.46.1", 60 + "unplugin-auto-import": "^20.2.0", 61 + "unplugin-icons": "^22.4.2", 36 62 "vite": "^6.3.5", 37 63 "vitest": "^3.0.5", 38 64 "web-vitals": "^4.2.4" ··· 49 75 }, 50 76 "engines": { 51 77 "node": ">=6.0.0" 78 + } 79 + }, 80 + "node_modules/@antfu/install-pkg": { 81 + "version": "1.1.0", 82 + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz", 83 + "integrity": "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==", 84 + "dev": true, 85 + "license": "MIT", 86 + "dependencies": { 87 + "package-manager-detector": "^1.3.0", 88 + "tinyexec": "^1.0.1" 89 + }, 90 + "funding": { 91 + "url": "https://github.com/sponsors/antfu" 92 + } 93 + }, 94 + "node_modules/@antfu/install-pkg/node_modules/tinyexec": { 95 + "version": "1.0.1", 96 + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz", 97 + "integrity": "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==", 98 + "dev": true, 99 + "license": "MIT" 100 + }, 101 + "node_modules/@antfu/utils": { 102 + "version": "9.3.0", 103 + "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-9.3.0.tgz", 104 + "integrity": "sha512-9hFT4RauhcUzqOE4f1+frMKLZrgNog5b06I7VmZQV1BkvwvqrbC8EBZf3L1eEL2AKb6rNKjER0sEvJiSP1FXEA==", 105 + "dev": true, 106 + "license": "MIT", 107 + "funding": { 108 + "url": "https://github.com/sponsors/antfu" 52 109 } 53 110 }, 54 111 "node_modules/@asamuzakjp/css-color": { ··· 1269 1326 "node": ">=18" 1270 1327 } 1271 1328 }, 1329 + "node_modules/@eslint-community/eslint-utils": { 1330 + "version": "4.9.0", 1331 + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", 1332 + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", 1333 + "dev": true, 1334 + "license": "MIT", 1335 + "dependencies": { 1336 + "eslint-visitor-keys": "^3.4.3" 1337 + }, 1338 + "engines": { 1339 + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 1340 + }, 1341 + "funding": { 1342 + "url": "https://opencollective.com/eslint" 1343 + }, 1344 + "peerDependencies": { 1345 + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" 1346 + } 1347 + }, 1348 + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { 1349 + "version": "3.4.3", 1350 + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", 1351 + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", 1352 + "dev": true, 1353 + "license": "Apache-2.0", 1354 + "engines": { 1355 + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 1356 + }, 1357 + "funding": { 1358 + "url": "https://opencollective.com/eslint" 1359 + } 1360 + }, 1361 + "node_modules/@eslint-community/regexpp": { 1362 + "version": "4.12.1", 1363 + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", 1364 + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", 1365 + "dev": true, 1366 + "license": "MIT", 1367 + "engines": { 1368 + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" 1369 + } 1370 + }, 1371 + "node_modules/@eslint-react/ast": { 1372 + "version": "2.2.1", 1373 + "resolved": "https://registry.npmjs.org/@eslint-react/ast/-/ast-2.2.1.tgz", 1374 + "integrity": "sha512-bjzSAdtTT/gIU0/olh8Kki57Mnadl5BIjJxcA3wqxcAvNwYAt3yl0CM4LRqVqW4kJneslCNqB5UriRJJPSKhuA==", 1375 + "dev": true, 1376 + "license": "MIT", 1377 + "dependencies": { 1378 + "@eslint-react/eff": "2.2.1", 1379 + "@typescript-eslint/types": "^8.46.0", 1380 + "@typescript-eslint/typescript-estree": "^8.46.0", 1381 + "@typescript-eslint/utils": "^8.46.0", 1382 + "string-ts": "^2.2.1" 1383 + }, 1384 + "engines": { 1385 + "node": ">=20.19.0" 1386 + } 1387 + }, 1388 + "node_modules/@eslint-react/core": { 1389 + "version": "2.2.1", 1390 + "resolved": "https://registry.npmjs.org/@eslint-react/core/-/core-2.2.1.tgz", 1391 + "integrity": "sha512-slP1G7sReKgijlDx56SDhgkpS6OjoNCEqItuY6Ayo4viIIYMyQ5LkPJ2BJ5xbBxSklyszQ/yP+8UFDK6uzYChQ==", 1392 + "dev": true, 1393 + "license": "MIT", 1394 + "dependencies": { 1395 + "@eslint-react/ast": "2.2.1", 1396 + "@eslint-react/eff": "2.2.1", 1397 + "@eslint-react/shared": "2.2.1", 1398 + "@eslint-react/var": "2.2.1", 1399 + "@typescript-eslint/scope-manager": "^8.46.0", 1400 + "@typescript-eslint/types": "^8.46.0", 1401 + "@typescript-eslint/utils": "^8.46.0", 1402 + "birecord": "^0.1.1", 1403 + "ts-pattern": "^5.8.0" 1404 + }, 1405 + "engines": { 1406 + "node": ">=20.19.0" 1407 + } 1408 + }, 1409 + "node_modules/@eslint-react/eff": { 1410 + "version": "2.2.1", 1411 + "resolved": "https://registry.npmjs.org/@eslint-react/eff/-/eff-2.2.1.tgz", 1412 + "integrity": "sha512-u9IJB9O8Jwo4b40CLIoF1HePsOvFLdbRKdCVUBEv2TPihae/ltYRD45mCI0bHLroYUxevC1nvD/cQRfwJPH0zg==", 1413 + "dev": true, 1414 + "license": "MIT", 1415 + "engines": { 1416 + "node": ">=20.19.0" 1417 + } 1418 + }, 1419 + "node_modules/@eslint-react/eslint-plugin": { 1420 + "version": "2.2.1", 1421 + "resolved": "https://registry.npmjs.org/@eslint-react/eslint-plugin/-/eslint-plugin-2.2.1.tgz", 1422 + "integrity": "sha512-BjIwFBvgo2b8d5KaTm3qkqKHMFT0HJmAYUZ6TT5j+C/2lWQK3mANxoPwD9Kq4tuI/zw5dINyKxQp6Kr8yGybHQ==", 1423 + "dev": true, 1424 + "license": "MIT", 1425 + "dependencies": { 1426 + "@eslint-react/eff": "2.2.1", 1427 + "@eslint-react/shared": "2.2.1", 1428 + "@typescript-eslint/scope-manager": "^8.46.0", 1429 + "@typescript-eslint/type-utils": "^8.46.0", 1430 + "@typescript-eslint/types": "^8.46.0", 1431 + "@typescript-eslint/utils": "^8.46.0", 1432 + "eslint-plugin-react-dom": "2.2.1", 1433 + "eslint-plugin-react-hooks-extra": "2.2.1", 1434 + "eslint-plugin-react-naming-convention": "2.2.1", 1435 + "eslint-plugin-react-web-api": "2.2.1", 1436 + "eslint-plugin-react-x": "2.2.1", 1437 + "ts-api-utils": "^2.1.0" 1438 + }, 1439 + "engines": { 1440 + "node": ">=20.19.0" 1441 + }, 1442 + "peerDependencies": { 1443 + "eslint": "^9.37.0", 1444 + "typescript": "^5.9.3" 1445 + } 1446 + }, 1447 + "node_modules/@eslint-react/shared": { 1448 + "version": "2.2.1", 1449 + "resolved": "https://registry.npmjs.org/@eslint-react/shared/-/shared-2.2.1.tgz", 1450 + "integrity": "sha512-YxYo4Svw2OzV0XDj4HLJKcmB4vtAyQghSE1ZFKN5i90CIbfp/RYBNK6VVrIbxtXu6tAsJ0lSBZiepHfn3i/l8w==", 1451 + "dev": true, 1452 + "license": "MIT", 1453 + "dependencies": { 1454 + "@eslint-react/eff": "2.2.1", 1455 + "@typescript-eslint/utils": "^8.46.0", 1456 + "ts-pattern": "^5.8.0", 1457 + "zod": "^4.1.12" 1458 + }, 1459 + "engines": { 1460 + "node": ">=20.19.0" 1461 + } 1462 + }, 1463 + "node_modules/@eslint-react/shared/node_modules/zod": { 1464 + "version": "4.1.12", 1465 + "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz", 1466 + "integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==", 1467 + "dev": true, 1468 + "license": "MIT", 1469 + "funding": { 1470 + "url": "https://github.com/sponsors/colinhacks" 1471 + } 1472 + }, 1473 + "node_modules/@eslint-react/var": { 1474 + "version": "2.2.1", 1475 + "resolved": "https://registry.npmjs.org/@eslint-react/var/-/var-2.2.1.tgz", 1476 + "integrity": "sha512-u5o1z01mNE0F+6DG1sDPnIGDbTaI3s0IOJnGCU4FfcsH7DOf96F4aB1szdJfznJBgVCrcBbyhO9oKKlYZoW0hQ==", 1477 + "dev": true, 1478 + "license": "MIT", 1479 + "dependencies": { 1480 + "@eslint-react/ast": "2.2.1", 1481 + "@eslint-react/eff": "2.2.1", 1482 + "@typescript-eslint/scope-manager": "^8.46.0", 1483 + "@typescript-eslint/types": "^8.46.0", 1484 + "@typescript-eslint/utils": "^8.46.0", 1485 + "ts-pattern": "^5.8.0" 1486 + }, 1487 + "engines": { 1488 + "node": ">=20.19.0" 1489 + } 1490 + }, 1491 + "node_modules/@eslint/config-array": { 1492 + "version": "0.21.0", 1493 + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", 1494 + "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", 1495 + "dev": true, 1496 + "license": "Apache-2.0", 1497 + "peer": true, 1498 + "dependencies": { 1499 + "@eslint/object-schema": "^2.1.6", 1500 + "debug": "^4.3.1", 1501 + "minimatch": "^3.1.2" 1502 + }, 1503 + "engines": { 1504 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1505 + } 1506 + }, 1507 + "node_modules/@eslint/config-helpers": { 1508 + "version": "0.4.0", 1509 + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.0.tgz", 1510 + "integrity": "sha512-WUFvV4WoIwW8Bv0KeKCIIEgdSiFOsulyN0xrMu+7z43q/hkOLXjvb5u7UC9jDxvRzcrbEmuZBX5yJZz1741jog==", 1511 + "dev": true, 1512 + "license": "Apache-2.0", 1513 + "peer": true, 1514 + "dependencies": { 1515 + "@eslint/core": "^0.16.0" 1516 + }, 1517 + "engines": { 1518 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1519 + } 1520 + }, 1521 + "node_modules/@eslint/core": { 1522 + "version": "0.16.0", 1523 + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.16.0.tgz", 1524 + "integrity": "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==", 1525 + "dev": true, 1526 + "license": "Apache-2.0", 1527 + "peer": true, 1528 + "dependencies": { 1529 + "@types/json-schema": "^7.0.15" 1530 + }, 1531 + "engines": { 1532 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1533 + } 1534 + }, 1535 + "node_modules/@eslint/eslintrc": { 1536 + "version": "3.3.1", 1537 + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", 1538 + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", 1539 + "dev": true, 1540 + "license": "MIT", 1541 + "peer": true, 1542 + "dependencies": { 1543 + "ajv": "^6.12.4", 1544 + "debug": "^4.3.2", 1545 + "espree": "^10.0.1", 1546 + "globals": "^14.0.0", 1547 + "ignore": "^5.2.0", 1548 + "import-fresh": "^3.2.1", 1549 + "js-yaml": "^4.1.0", 1550 + "minimatch": "^3.1.2", 1551 + "strip-json-comments": "^3.1.1" 1552 + }, 1553 + "engines": { 1554 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1555 + }, 1556 + "funding": { 1557 + "url": "https://opencollective.com/eslint" 1558 + } 1559 + }, 1560 + "node_modules/@eslint/js": { 1561 + "version": "9.37.0", 1562 + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.37.0.tgz", 1563 + "integrity": "sha512-jaS+NJ+hximswBG6pjNX0uEJZkrT0zwpVi3BA3vX22aFGjJjmgSTSmPpZCRKmoBL5VY/M6p0xsSJx7rk7sy5gg==", 1564 + "dev": true, 1565 + "license": "MIT", 1566 + "peer": true, 1567 + "engines": { 1568 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1569 + }, 1570 + "funding": { 1571 + "url": "https://eslint.org/donate" 1572 + } 1573 + }, 1574 + "node_modules/@eslint/object-schema": { 1575 + "version": "2.1.6", 1576 + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", 1577 + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", 1578 + "dev": true, 1579 + "license": "Apache-2.0", 1580 + "peer": true, 1581 + "engines": { 1582 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1583 + } 1584 + }, 1585 + "node_modules/@eslint/plugin-kit": { 1586 + "version": "0.4.0", 1587 + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.0.tgz", 1588 + "integrity": "sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==", 1589 + "dev": true, 1590 + "license": "Apache-2.0", 1591 + "peer": true, 1592 + "dependencies": { 1593 + "@eslint/core": "^0.16.0", 1594 + "levn": "^0.4.1" 1595 + }, 1596 + "engines": { 1597 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1598 + } 1599 + }, 1600 + "node_modules/@floating-ui/core": { 1601 + "version": "1.7.3", 1602 + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz", 1603 + "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", 1604 + "dependencies": { 1605 + "@floating-ui/utils": "^0.2.10" 1606 + } 1607 + }, 1608 + "node_modules/@floating-ui/dom": { 1609 + "version": "1.7.4", 1610 + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz", 1611 + "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", 1612 + "dependencies": { 1613 + "@floating-ui/core": "^1.7.3", 1614 + "@floating-ui/utils": "^0.2.10" 1615 + } 1616 + }, 1617 + "node_modules/@floating-ui/react-dom": { 1618 + "version": "2.1.6", 1619 + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz", 1620 + "integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==", 1621 + "dependencies": { 1622 + "@floating-ui/dom": "^1.7.4" 1623 + }, 1624 + "peerDependencies": { 1625 + "react": ">=16.8.0", 1626 + "react-dom": ">=16.8.0" 1627 + } 1628 + }, 1629 + "node_modules/@floating-ui/utils": { 1630 + "version": "0.2.10", 1631 + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", 1632 + "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==" 1633 + }, 1634 + "node_modules/@humanfs/core": { 1635 + "version": "0.19.1", 1636 + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", 1637 + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", 1638 + "dev": true, 1639 + "license": "Apache-2.0", 1640 + "peer": true, 1641 + "engines": { 1642 + "node": ">=18.18.0" 1643 + } 1644 + }, 1645 + "node_modules/@humanfs/node": { 1646 + "version": "0.16.7", 1647 + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", 1648 + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", 1649 + "dev": true, 1650 + "license": "Apache-2.0", 1651 + "peer": true, 1652 + "dependencies": { 1653 + "@humanfs/core": "^0.19.1", 1654 + "@humanwhocodes/retry": "^0.4.0" 1655 + }, 1656 + "engines": { 1657 + "node": ">=18.18.0" 1658 + } 1659 + }, 1660 + "node_modules/@humanwhocodes/module-importer": { 1661 + "version": "1.0.1", 1662 + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", 1663 + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", 1664 + "dev": true, 1665 + "license": "Apache-2.0", 1666 + "peer": true, 1667 + "engines": { 1668 + "node": ">=12.22" 1669 + }, 1670 + "funding": { 1671 + "type": "github", 1672 + "url": "https://github.com/sponsors/nzakas" 1673 + } 1674 + }, 1675 + "node_modules/@humanwhocodes/retry": { 1676 + "version": "0.4.3", 1677 + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", 1678 + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", 1679 + "dev": true, 1680 + "license": "Apache-2.0", 1681 + "peer": true, 1682 + "engines": { 1683 + "node": ">=18.18" 1684 + }, 1685 + "funding": { 1686 + "type": "github", 1687 + "url": "https://github.com/sponsors/nzakas" 1688 + } 1689 + }, 1690 + "node_modules/@iconify-icon/react": { 1691 + "version": "3.0.1", 1692 + "resolved": "https://registry.npmjs.org/@iconify-icon/react/-/react-3.0.1.tgz", 1693 + "integrity": "sha512-/4CAVpk8HDyKS78r1G0rZhML7hI6jLxb8kAmjEXsCtuVUDwdGqicGCRg0T14mqeHNImrQPR49MhbuSSS++JlUA==", 1694 + "dev": true, 1695 + "license": "MIT", 1696 + "dependencies": { 1697 + "iconify-icon": "^3.0.1" 1698 + }, 1699 + "funding": { 1700 + "url": "https://github.com/sponsors/cyberalien" 1701 + }, 1702 + "peerDependencies": { 1703 + "react": ">=16" 1704 + } 1705 + }, 1706 + "node_modules/@iconify-json/material-symbols": { 1707 + "version": "1.2.42", 1708 + "resolved": "https://registry.npmjs.org/@iconify-json/material-symbols/-/material-symbols-1.2.42.tgz", 1709 + "integrity": "sha512-FDRfnQqy8iXaq/swVPFWaHftqP9tk3qDCRhC30s3UZL2j4mvGZk5gVECRXCkZv5jnsAiTpZxGQM8HrMiwE7GtA==", 1710 + "dev": true, 1711 + "license": "Apache-2.0", 1712 + "dependencies": { 1713 + "@iconify/types": "*" 1714 + } 1715 + }, 1716 + "node_modules/@iconify-json/mdi": { 1717 + "version": "1.2.3", 1718 + "resolved": "https://registry.npmjs.org/@iconify-json/mdi/-/mdi-1.2.3.tgz", 1719 + "integrity": "sha512-O3cLwbDOK7NNDf2ihaQOH5F9JglnulNDFV7WprU2dSoZu3h3cWH//h74uQAB87brHmvFVxIOkuBX2sZSzYhScg==", 1720 + "dev": true, 1721 + "license": "Apache-2.0", 1722 + "dependencies": { 1723 + "@iconify/types": "*" 1724 + } 1725 + }, 1726 + "node_modules/@iconify/json": { 1727 + "version": "2.2.396", 1728 + "resolved": "https://registry.npmjs.org/@iconify/json/-/json-2.2.396.tgz", 1729 + "integrity": "sha512-tijg77JFuYIt32S9N8p7La8C0zp9zKZsX6UP8ip5GVB1F6Mp3pZA5Vc5eAquTY50NoDJX58U6z4Qn3d6Wyossg==", 1730 + "dev": true, 1731 + "license": "MIT", 1732 + "dependencies": { 1733 + "@iconify/types": "*", 1734 + "pathe": "^2.0.0" 1735 + } 1736 + }, 1737 + "node_modules/@iconify/types": { 1738 + "version": "2.0.0", 1739 + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", 1740 + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", 1741 + "dev": true, 1742 + "license": "MIT" 1743 + }, 1744 + "node_modules/@iconify/utils": { 1745 + "version": "3.0.2", 1746 + "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-3.0.2.tgz", 1747 + "integrity": "sha512-EfJS0rLfVuRuJRn4psJHtK2A9TqVnkxPpHY6lYHiB9+8eSuudsxbwMiavocG45ujOo6FJ+CIRlRnlOGinzkaGQ==", 1748 + "dev": true, 1749 + "license": "MIT", 1750 + "dependencies": { 1751 + "@antfu/install-pkg": "^1.1.0", 1752 + "@antfu/utils": "^9.2.0", 1753 + "@iconify/types": "^2.0.0", 1754 + "debug": "^4.4.1", 1755 + "globals": "^15.15.0", 1756 + "kolorist": "^1.8.0", 1757 + "local-pkg": "^1.1.1", 1758 + "mlly": "^1.7.4" 1759 + } 1760 + }, 1761 + "node_modules/@iconify/utils/node_modules/globals": { 1762 + "version": "15.15.0", 1763 + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", 1764 + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", 1765 + "dev": true, 1766 + "license": "MIT", 1767 + "engines": { 1768 + "node": ">=18" 1769 + }, 1770 + "funding": { 1771 + "url": "https://github.com/sponsors/sindresorhus" 1772 + } 1773 + }, 1272 1774 "node_modules/@isaacs/fs-minipass": { 1273 1775 "version": "4.0.1", 1274 1776 "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", ··· 1394 1896 "mux-embed": "^5.8.3" 1395 1897 } 1396 1898 }, 1899 + "node_modules/@nodelib/fs.scandir": { 1900 + "version": "2.1.5", 1901 + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 1902 + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 1903 + "dev": true, 1904 + "license": "MIT", 1905 + "dependencies": { 1906 + "@nodelib/fs.stat": "2.0.5", 1907 + "run-parallel": "^1.1.9" 1908 + }, 1909 + "engines": { 1910 + "node": ">= 8" 1911 + } 1912 + }, 1913 + "node_modules/@nodelib/fs.stat": { 1914 + "version": "2.0.5", 1915 + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 1916 + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 1917 + "dev": true, 1918 + "license": "MIT", 1919 + "engines": { 1920 + "node": ">= 8" 1921 + } 1922 + }, 1923 + "node_modules/@nodelib/fs.walk": { 1924 + "version": "1.2.8", 1925 + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 1926 + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 1927 + "dev": true, 1928 + "license": "MIT", 1929 + "dependencies": { 1930 + "@nodelib/fs.scandir": "2.1.5", 1931 + "fastq": "^1.6.0" 1932 + }, 1933 + "engines": { 1934 + "node": ">= 8" 1935 + } 1936 + }, 1937 + "node_modules/@radix-ui/number": { 1938 + "version": "1.1.1", 1939 + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", 1940 + "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==" 1941 + }, 1942 + "node_modules/@radix-ui/primitive": { 1943 + "version": "1.1.3", 1944 + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", 1945 + "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==" 1946 + }, 1947 + "node_modules/@radix-ui/react-accessible-icon": { 1948 + "version": "1.1.7", 1949 + "resolved": "https://registry.npmjs.org/@radix-ui/react-accessible-icon/-/react-accessible-icon-1.1.7.tgz", 1950 + "integrity": "sha512-XM+E4WXl0OqUJFovy6GjmxxFyx9opfCAIUku4dlKRd5YEPqt4kALOkQOp0Of6reHuUkJuiPBEc5k0o4z4lTC8A==", 1951 + "dependencies": { 1952 + "@radix-ui/react-visually-hidden": "1.2.3" 1953 + }, 1954 + "peerDependencies": { 1955 + "@types/react": "*", 1956 + "@types/react-dom": "*", 1957 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 1958 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 1959 + }, 1960 + "peerDependenciesMeta": { 1961 + "@types/react": { 1962 + "optional": true 1963 + }, 1964 + "@types/react-dom": { 1965 + "optional": true 1966 + } 1967 + } 1968 + }, 1969 + "node_modules/@radix-ui/react-accordion": { 1970 + "version": "1.2.12", 1971 + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.12.tgz", 1972 + "integrity": "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==", 1973 + "dependencies": { 1974 + "@radix-ui/primitive": "1.1.3", 1975 + "@radix-ui/react-collapsible": "1.1.12", 1976 + "@radix-ui/react-collection": "1.1.7", 1977 + "@radix-ui/react-compose-refs": "1.1.2", 1978 + "@radix-ui/react-context": "1.1.2", 1979 + "@radix-ui/react-direction": "1.1.1", 1980 + "@radix-ui/react-id": "1.1.1", 1981 + "@radix-ui/react-primitive": "2.1.3", 1982 + "@radix-ui/react-use-controllable-state": "1.2.2" 1983 + }, 1984 + "peerDependencies": { 1985 + "@types/react": "*", 1986 + "@types/react-dom": "*", 1987 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 1988 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 1989 + }, 1990 + "peerDependenciesMeta": { 1991 + "@types/react": { 1992 + "optional": true 1993 + }, 1994 + "@types/react-dom": { 1995 + "optional": true 1996 + } 1997 + } 1998 + }, 1999 + "node_modules/@radix-ui/react-alert-dialog": { 2000 + "version": "1.1.15", 2001 + "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.15.tgz", 2002 + "integrity": "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==", 2003 + "dependencies": { 2004 + "@radix-ui/primitive": "1.1.3", 2005 + "@radix-ui/react-compose-refs": "1.1.2", 2006 + "@radix-ui/react-context": "1.1.2", 2007 + "@radix-ui/react-dialog": "1.1.15", 2008 + "@radix-ui/react-primitive": "2.1.3", 2009 + "@radix-ui/react-slot": "1.2.3" 2010 + }, 2011 + "peerDependencies": { 2012 + "@types/react": "*", 2013 + "@types/react-dom": "*", 2014 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2015 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2016 + }, 2017 + "peerDependenciesMeta": { 2018 + "@types/react": { 2019 + "optional": true 2020 + }, 2021 + "@types/react-dom": { 2022 + "optional": true 2023 + } 2024 + } 2025 + }, 2026 + "node_modules/@radix-ui/react-arrow": { 2027 + "version": "1.1.7", 2028 + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", 2029 + "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", 2030 + "dependencies": { 2031 + "@radix-ui/react-primitive": "2.1.3" 2032 + }, 2033 + "peerDependencies": { 2034 + "@types/react": "*", 2035 + "@types/react-dom": "*", 2036 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2037 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2038 + }, 2039 + "peerDependenciesMeta": { 2040 + "@types/react": { 2041 + "optional": true 2042 + }, 2043 + "@types/react-dom": { 2044 + "optional": true 2045 + } 2046 + } 2047 + }, 2048 + "node_modules/@radix-ui/react-aspect-ratio": { 2049 + "version": "1.1.7", 2050 + "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.7.tgz", 2051 + "integrity": "sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g==", 2052 + "dependencies": { 2053 + "@radix-ui/react-primitive": "2.1.3" 2054 + }, 2055 + "peerDependencies": { 2056 + "@types/react": "*", 2057 + "@types/react-dom": "*", 2058 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2059 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2060 + }, 2061 + "peerDependenciesMeta": { 2062 + "@types/react": { 2063 + "optional": true 2064 + }, 2065 + "@types/react-dom": { 2066 + "optional": true 2067 + } 2068 + } 2069 + }, 2070 + "node_modules/@radix-ui/react-avatar": { 2071 + "version": "1.1.10", 2072 + "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.10.tgz", 2073 + "integrity": "sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==", 2074 + "dependencies": { 2075 + "@radix-ui/react-context": "1.1.2", 2076 + "@radix-ui/react-primitive": "2.1.3", 2077 + "@radix-ui/react-use-callback-ref": "1.1.1", 2078 + "@radix-ui/react-use-is-hydrated": "0.1.0", 2079 + "@radix-ui/react-use-layout-effect": "1.1.1" 2080 + }, 2081 + "peerDependencies": { 2082 + "@types/react": "*", 2083 + "@types/react-dom": "*", 2084 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2085 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2086 + }, 2087 + "peerDependenciesMeta": { 2088 + "@types/react": { 2089 + "optional": true 2090 + }, 2091 + "@types/react-dom": { 2092 + "optional": true 2093 + } 2094 + } 2095 + }, 2096 + "node_modules/@radix-ui/react-checkbox": { 2097 + "version": "1.3.3", 2098 + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz", 2099 + "integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==", 2100 + "dependencies": { 2101 + "@radix-ui/primitive": "1.1.3", 2102 + "@radix-ui/react-compose-refs": "1.1.2", 2103 + "@radix-ui/react-context": "1.1.2", 2104 + "@radix-ui/react-presence": "1.1.5", 2105 + "@radix-ui/react-primitive": "2.1.3", 2106 + "@radix-ui/react-use-controllable-state": "1.2.2", 2107 + "@radix-ui/react-use-previous": "1.1.1", 2108 + "@radix-ui/react-use-size": "1.1.1" 2109 + }, 2110 + "peerDependencies": { 2111 + "@types/react": "*", 2112 + "@types/react-dom": "*", 2113 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2114 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2115 + }, 2116 + "peerDependenciesMeta": { 2117 + "@types/react": { 2118 + "optional": true 2119 + }, 2120 + "@types/react-dom": { 2121 + "optional": true 2122 + } 2123 + } 2124 + }, 2125 + "node_modules/@radix-ui/react-collapsible": { 2126 + "version": "1.1.12", 2127 + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz", 2128 + "integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==", 2129 + "dependencies": { 2130 + "@radix-ui/primitive": "1.1.3", 2131 + "@radix-ui/react-compose-refs": "1.1.2", 2132 + "@radix-ui/react-context": "1.1.2", 2133 + "@radix-ui/react-id": "1.1.1", 2134 + "@radix-ui/react-presence": "1.1.5", 2135 + "@radix-ui/react-primitive": "2.1.3", 2136 + "@radix-ui/react-use-controllable-state": "1.2.2", 2137 + "@radix-ui/react-use-layout-effect": "1.1.1" 2138 + }, 2139 + "peerDependencies": { 2140 + "@types/react": "*", 2141 + "@types/react-dom": "*", 2142 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2143 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2144 + }, 2145 + "peerDependenciesMeta": { 2146 + "@types/react": { 2147 + "optional": true 2148 + }, 2149 + "@types/react-dom": { 2150 + "optional": true 2151 + } 2152 + } 2153 + }, 2154 + "node_modules/@radix-ui/react-collection": { 2155 + "version": "1.1.7", 2156 + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", 2157 + "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", 2158 + "dependencies": { 2159 + "@radix-ui/react-compose-refs": "1.1.2", 2160 + "@radix-ui/react-context": "1.1.2", 2161 + "@radix-ui/react-primitive": "2.1.3", 2162 + "@radix-ui/react-slot": "1.2.3" 2163 + }, 2164 + "peerDependencies": { 2165 + "@types/react": "*", 2166 + "@types/react-dom": "*", 2167 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2168 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2169 + }, 2170 + "peerDependenciesMeta": { 2171 + "@types/react": { 2172 + "optional": true 2173 + }, 2174 + "@types/react-dom": { 2175 + "optional": true 2176 + } 2177 + } 2178 + }, 2179 + "node_modules/@radix-ui/react-compose-refs": { 2180 + "version": "1.1.2", 2181 + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", 2182 + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", 2183 + "peerDependencies": { 2184 + "@types/react": "*", 2185 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2186 + }, 2187 + "peerDependenciesMeta": { 2188 + "@types/react": { 2189 + "optional": true 2190 + } 2191 + } 2192 + }, 2193 + "node_modules/@radix-ui/react-context": { 2194 + "version": "1.1.2", 2195 + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", 2196 + "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", 2197 + "peerDependencies": { 2198 + "@types/react": "*", 2199 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2200 + }, 2201 + "peerDependenciesMeta": { 2202 + "@types/react": { 2203 + "optional": true 2204 + } 2205 + } 2206 + }, 2207 + "node_modules/@radix-ui/react-context-menu": { 2208 + "version": "2.2.16", 2209 + "resolved": "https://registry.npmjs.org/@radix-ui/react-context-menu/-/react-context-menu-2.2.16.tgz", 2210 + "integrity": "sha512-O8morBEW+HsVG28gYDZPTrT9UUovQUlJue5YO836tiTJhuIWBm/zQHc7j388sHWtdH/xUZurK9olD2+pcqx5ww==", 2211 + "dependencies": { 2212 + "@radix-ui/primitive": "1.1.3", 2213 + "@radix-ui/react-context": "1.1.2", 2214 + "@radix-ui/react-menu": "2.1.16", 2215 + "@radix-ui/react-primitive": "2.1.3", 2216 + "@radix-ui/react-use-callback-ref": "1.1.1", 2217 + "@radix-ui/react-use-controllable-state": "1.2.2" 2218 + }, 2219 + "peerDependencies": { 2220 + "@types/react": "*", 2221 + "@types/react-dom": "*", 2222 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2223 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2224 + }, 2225 + "peerDependenciesMeta": { 2226 + "@types/react": { 2227 + "optional": true 2228 + }, 2229 + "@types/react-dom": { 2230 + "optional": true 2231 + } 2232 + } 2233 + }, 2234 + "node_modules/@radix-ui/react-dialog": { 2235 + "version": "1.1.15", 2236 + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz", 2237 + "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==", 2238 + "dependencies": { 2239 + "@radix-ui/primitive": "1.1.3", 2240 + "@radix-ui/react-compose-refs": "1.1.2", 2241 + "@radix-ui/react-context": "1.1.2", 2242 + "@radix-ui/react-dismissable-layer": "1.1.11", 2243 + "@radix-ui/react-focus-guards": "1.1.3", 2244 + "@radix-ui/react-focus-scope": "1.1.7", 2245 + "@radix-ui/react-id": "1.1.1", 2246 + "@radix-ui/react-portal": "1.1.9", 2247 + "@radix-ui/react-presence": "1.1.5", 2248 + "@radix-ui/react-primitive": "2.1.3", 2249 + "@radix-ui/react-slot": "1.2.3", 2250 + "@radix-ui/react-use-controllable-state": "1.2.2", 2251 + "aria-hidden": "^1.2.4", 2252 + "react-remove-scroll": "^2.6.3" 2253 + }, 2254 + "peerDependencies": { 2255 + "@types/react": "*", 2256 + "@types/react-dom": "*", 2257 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2258 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2259 + }, 2260 + "peerDependenciesMeta": { 2261 + "@types/react": { 2262 + "optional": true 2263 + }, 2264 + "@types/react-dom": { 2265 + "optional": true 2266 + } 2267 + } 2268 + }, 2269 + "node_modules/@radix-ui/react-direction": { 2270 + "version": "1.1.1", 2271 + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", 2272 + "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", 2273 + "peerDependencies": { 2274 + "@types/react": "*", 2275 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2276 + }, 2277 + "peerDependenciesMeta": { 2278 + "@types/react": { 2279 + "optional": true 2280 + } 2281 + } 2282 + }, 2283 + "node_modules/@radix-ui/react-dismissable-layer": { 2284 + "version": "1.1.11", 2285 + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", 2286 + "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==", 2287 + "dependencies": { 2288 + "@radix-ui/primitive": "1.1.3", 2289 + "@radix-ui/react-compose-refs": "1.1.2", 2290 + "@radix-ui/react-primitive": "2.1.3", 2291 + "@radix-ui/react-use-callback-ref": "1.1.1", 2292 + "@radix-ui/react-use-escape-keydown": "1.1.1" 2293 + }, 2294 + "peerDependencies": { 2295 + "@types/react": "*", 2296 + "@types/react-dom": "*", 2297 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2298 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2299 + }, 2300 + "peerDependenciesMeta": { 2301 + "@types/react": { 2302 + "optional": true 2303 + }, 2304 + "@types/react-dom": { 2305 + "optional": true 2306 + } 2307 + } 2308 + }, 2309 + "node_modules/@radix-ui/react-dropdown-menu": { 2310 + "version": "2.1.16", 2311 + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.16.tgz", 2312 + "integrity": "sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==", 2313 + "dependencies": { 2314 + "@radix-ui/primitive": "1.1.3", 2315 + "@radix-ui/react-compose-refs": "1.1.2", 2316 + "@radix-ui/react-context": "1.1.2", 2317 + "@radix-ui/react-id": "1.1.1", 2318 + "@radix-ui/react-menu": "2.1.16", 2319 + "@radix-ui/react-primitive": "2.1.3", 2320 + "@radix-ui/react-use-controllable-state": "1.2.2" 2321 + }, 2322 + "peerDependencies": { 2323 + "@types/react": "*", 2324 + "@types/react-dom": "*", 2325 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2326 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2327 + }, 2328 + "peerDependenciesMeta": { 2329 + "@types/react": { 2330 + "optional": true 2331 + }, 2332 + "@types/react-dom": { 2333 + "optional": true 2334 + } 2335 + } 2336 + }, 2337 + "node_modules/@radix-ui/react-focus-guards": { 2338 + "version": "1.1.3", 2339 + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz", 2340 + "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==", 2341 + "peerDependencies": { 2342 + "@types/react": "*", 2343 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2344 + }, 2345 + "peerDependenciesMeta": { 2346 + "@types/react": { 2347 + "optional": true 2348 + } 2349 + } 2350 + }, 2351 + "node_modules/@radix-ui/react-focus-scope": { 2352 + "version": "1.1.7", 2353 + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", 2354 + "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", 2355 + "dependencies": { 2356 + "@radix-ui/react-compose-refs": "1.1.2", 2357 + "@radix-ui/react-primitive": "2.1.3", 2358 + "@radix-ui/react-use-callback-ref": "1.1.1" 2359 + }, 2360 + "peerDependencies": { 2361 + "@types/react": "*", 2362 + "@types/react-dom": "*", 2363 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2364 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2365 + }, 2366 + "peerDependenciesMeta": { 2367 + "@types/react": { 2368 + "optional": true 2369 + }, 2370 + "@types/react-dom": { 2371 + "optional": true 2372 + } 2373 + } 2374 + }, 2375 + "node_modules/@radix-ui/react-form": { 2376 + "version": "0.1.8", 2377 + "resolved": "https://registry.npmjs.org/@radix-ui/react-form/-/react-form-0.1.8.tgz", 2378 + "integrity": "sha512-QM70k4Zwjttifr5a4sZFts9fn8FzHYvQ5PiB19O2HsYibaHSVt9fH9rzB0XZo/YcM+b7t/p7lYCT/F5eOeF5yQ==", 2379 + "dependencies": { 2380 + "@radix-ui/primitive": "1.1.3", 2381 + "@radix-ui/react-compose-refs": "1.1.2", 2382 + "@radix-ui/react-context": "1.1.2", 2383 + "@radix-ui/react-id": "1.1.1", 2384 + "@radix-ui/react-label": "2.1.7", 2385 + "@radix-ui/react-primitive": "2.1.3" 2386 + }, 2387 + "peerDependencies": { 2388 + "@types/react": "*", 2389 + "@types/react-dom": "*", 2390 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2391 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2392 + }, 2393 + "peerDependenciesMeta": { 2394 + "@types/react": { 2395 + "optional": true 2396 + }, 2397 + "@types/react-dom": { 2398 + "optional": true 2399 + } 2400 + } 2401 + }, 2402 + "node_modules/@radix-ui/react-hover-card": { 2403 + "version": "1.1.15", 2404 + "resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.1.15.tgz", 2405 + "integrity": "sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg==", 2406 + "license": "MIT", 2407 + "dependencies": { 2408 + "@radix-ui/primitive": "1.1.3", 2409 + "@radix-ui/react-compose-refs": "1.1.2", 2410 + "@radix-ui/react-context": "1.1.2", 2411 + "@radix-ui/react-dismissable-layer": "1.1.11", 2412 + "@radix-ui/react-popper": "1.2.8", 2413 + "@radix-ui/react-portal": "1.1.9", 2414 + "@radix-ui/react-presence": "1.1.5", 2415 + "@radix-ui/react-primitive": "2.1.3", 2416 + "@radix-ui/react-use-controllable-state": "1.2.2" 2417 + }, 2418 + "peerDependencies": { 2419 + "@types/react": "*", 2420 + "@types/react-dom": "*", 2421 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2422 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2423 + }, 2424 + "peerDependenciesMeta": { 2425 + "@types/react": { 2426 + "optional": true 2427 + }, 2428 + "@types/react-dom": { 2429 + "optional": true 2430 + } 2431 + } 2432 + }, 2433 + "node_modules/@radix-ui/react-id": { 2434 + "version": "1.1.1", 2435 + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", 2436 + "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", 2437 + "dependencies": { 2438 + "@radix-ui/react-use-layout-effect": "1.1.1" 2439 + }, 2440 + "peerDependencies": { 2441 + "@types/react": "*", 2442 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2443 + }, 2444 + "peerDependenciesMeta": { 2445 + "@types/react": { 2446 + "optional": true 2447 + } 2448 + } 2449 + }, 2450 + "node_modules/@radix-ui/react-label": { 2451 + "version": "2.1.7", 2452 + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.7.tgz", 2453 + "integrity": "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==", 2454 + "dependencies": { 2455 + "@radix-ui/react-primitive": "2.1.3" 2456 + }, 2457 + "peerDependencies": { 2458 + "@types/react": "*", 2459 + "@types/react-dom": "*", 2460 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2461 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2462 + }, 2463 + "peerDependenciesMeta": { 2464 + "@types/react": { 2465 + "optional": true 2466 + }, 2467 + "@types/react-dom": { 2468 + "optional": true 2469 + } 2470 + } 2471 + }, 2472 + "node_modules/@radix-ui/react-menu": { 2473 + "version": "2.1.16", 2474 + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.16.tgz", 2475 + "integrity": "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==", 2476 + "dependencies": { 2477 + "@radix-ui/primitive": "1.1.3", 2478 + "@radix-ui/react-collection": "1.1.7", 2479 + "@radix-ui/react-compose-refs": "1.1.2", 2480 + "@radix-ui/react-context": "1.1.2", 2481 + "@radix-ui/react-direction": "1.1.1", 2482 + "@radix-ui/react-dismissable-layer": "1.1.11", 2483 + "@radix-ui/react-focus-guards": "1.1.3", 2484 + "@radix-ui/react-focus-scope": "1.1.7", 2485 + "@radix-ui/react-id": "1.1.1", 2486 + "@radix-ui/react-popper": "1.2.8", 2487 + "@radix-ui/react-portal": "1.1.9", 2488 + "@radix-ui/react-presence": "1.1.5", 2489 + "@radix-ui/react-primitive": "2.1.3", 2490 + "@radix-ui/react-roving-focus": "1.1.11", 2491 + "@radix-ui/react-slot": "1.2.3", 2492 + "@radix-ui/react-use-callback-ref": "1.1.1", 2493 + "aria-hidden": "^1.2.4", 2494 + "react-remove-scroll": "^2.6.3" 2495 + }, 2496 + "peerDependencies": { 2497 + "@types/react": "*", 2498 + "@types/react-dom": "*", 2499 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2500 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2501 + }, 2502 + "peerDependenciesMeta": { 2503 + "@types/react": { 2504 + "optional": true 2505 + }, 2506 + "@types/react-dom": { 2507 + "optional": true 2508 + } 2509 + } 2510 + }, 2511 + "node_modules/@radix-ui/react-menubar": { 2512 + "version": "1.1.16", 2513 + "resolved": "https://registry.npmjs.org/@radix-ui/react-menubar/-/react-menubar-1.1.16.tgz", 2514 + "integrity": "sha512-EB1FktTz5xRRi2Er974AUQZWg2yVBb1yjip38/lgwtCVRd3a+maUoGHN/xs9Yv8SY8QwbSEb+YrxGadVWbEutA==", 2515 + "dependencies": { 2516 + "@radix-ui/primitive": "1.1.3", 2517 + "@radix-ui/react-collection": "1.1.7", 2518 + "@radix-ui/react-compose-refs": "1.1.2", 2519 + "@radix-ui/react-context": "1.1.2", 2520 + "@radix-ui/react-direction": "1.1.1", 2521 + "@radix-ui/react-id": "1.1.1", 2522 + "@radix-ui/react-menu": "2.1.16", 2523 + "@radix-ui/react-primitive": "2.1.3", 2524 + "@radix-ui/react-roving-focus": "1.1.11", 2525 + "@radix-ui/react-use-controllable-state": "1.2.2" 2526 + }, 2527 + "peerDependencies": { 2528 + "@types/react": "*", 2529 + "@types/react-dom": "*", 2530 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2531 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2532 + }, 2533 + "peerDependenciesMeta": { 2534 + "@types/react": { 2535 + "optional": true 2536 + }, 2537 + "@types/react-dom": { 2538 + "optional": true 2539 + } 2540 + } 2541 + }, 2542 + "node_modules/@radix-ui/react-navigation-menu": { 2543 + "version": "1.2.14", 2544 + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.14.tgz", 2545 + "integrity": "sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w==", 2546 + "dependencies": { 2547 + "@radix-ui/primitive": "1.1.3", 2548 + "@radix-ui/react-collection": "1.1.7", 2549 + "@radix-ui/react-compose-refs": "1.1.2", 2550 + "@radix-ui/react-context": "1.1.2", 2551 + "@radix-ui/react-direction": "1.1.1", 2552 + "@radix-ui/react-dismissable-layer": "1.1.11", 2553 + "@radix-ui/react-id": "1.1.1", 2554 + "@radix-ui/react-presence": "1.1.5", 2555 + "@radix-ui/react-primitive": "2.1.3", 2556 + "@radix-ui/react-use-callback-ref": "1.1.1", 2557 + "@radix-ui/react-use-controllable-state": "1.2.2", 2558 + "@radix-ui/react-use-layout-effect": "1.1.1", 2559 + "@radix-ui/react-use-previous": "1.1.1", 2560 + "@radix-ui/react-visually-hidden": "1.2.3" 2561 + }, 2562 + "peerDependencies": { 2563 + "@types/react": "*", 2564 + "@types/react-dom": "*", 2565 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2566 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2567 + }, 2568 + "peerDependenciesMeta": { 2569 + "@types/react": { 2570 + "optional": true 2571 + }, 2572 + "@types/react-dom": { 2573 + "optional": true 2574 + } 2575 + } 2576 + }, 2577 + "node_modules/@radix-ui/react-one-time-password-field": { 2578 + "version": "0.1.8", 2579 + "resolved": "https://registry.npmjs.org/@radix-ui/react-one-time-password-field/-/react-one-time-password-field-0.1.8.tgz", 2580 + "integrity": "sha512-ycS4rbwURavDPVjCb5iS3aG4lURFDILi6sKI/WITUMZ13gMmn/xGjpLoqBAalhJaDk8I3UbCM5GzKHrnzwHbvg==", 2581 + "dependencies": { 2582 + "@radix-ui/number": "1.1.1", 2583 + "@radix-ui/primitive": "1.1.3", 2584 + "@radix-ui/react-collection": "1.1.7", 2585 + "@radix-ui/react-compose-refs": "1.1.2", 2586 + "@radix-ui/react-context": "1.1.2", 2587 + "@radix-ui/react-direction": "1.1.1", 2588 + "@radix-ui/react-primitive": "2.1.3", 2589 + "@radix-ui/react-roving-focus": "1.1.11", 2590 + "@radix-ui/react-use-controllable-state": "1.2.2", 2591 + "@radix-ui/react-use-effect-event": "0.0.2", 2592 + "@radix-ui/react-use-is-hydrated": "0.1.0", 2593 + "@radix-ui/react-use-layout-effect": "1.1.1" 2594 + }, 2595 + "peerDependencies": { 2596 + "@types/react": "*", 2597 + "@types/react-dom": "*", 2598 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2599 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2600 + }, 2601 + "peerDependenciesMeta": { 2602 + "@types/react": { 2603 + "optional": true 2604 + }, 2605 + "@types/react-dom": { 2606 + "optional": true 2607 + } 2608 + } 2609 + }, 2610 + "node_modules/@radix-ui/react-password-toggle-field": { 2611 + "version": "0.1.3", 2612 + "resolved": "https://registry.npmjs.org/@radix-ui/react-password-toggle-field/-/react-password-toggle-field-0.1.3.tgz", 2613 + "integrity": "sha512-/UuCrDBWravcaMix4TdT+qlNdVwOM1Nck9kWx/vafXsdfj1ChfhOdfi3cy9SGBpWgTXwYCuboT/oYpJy3clqfw==", 2614 + "dependencies": { 2615 + "@radix-ui/primitive": "1.1.3", 2616 + "@radix-ui/react-compose-refs": "1.1.2", 2617 + "@radix-ui/react-context": "1.1.2", 2618 + "@radix-ui/react-id": "1.1.1", 2619 + "@radix-ui/react-primitive": "2.1.3", 2620 + "@radix-ui/react-use-controllable-state": "1.2.2", 2621 + "@radix-ui/react-use-effect-event": "0.0.2", 2622 + "@radix-ui/react-use-is-hydrated": "0.1.0" 2623 + }, 2624 + "peerDependencies": { 2625 + "@types/react": "*", 2626 + "@types/react-dom": "*", 2627 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2628 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2629 + }, 2630 + "peerDependenciesMeta": { 2631 + "@types/react": { 2632 + "optional": true 2633 + }, 2634 + "@types/react-dom": { 2635 + "optional": true 2636 + } 2637 + } 2638 + }, 2639 + "node_modules/@radix-ui/react-popover": { 2640 + "version": "1.1.15", 2641 + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.15.tgz", 2642 + "integrity": "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==", 2643 + "dependencies": { 2644 + "@radix-ui/primitive": "1.1.3", 2645 + "@radix-ui/react-compose-refs": "1.1.2", 2646 + "@radix-ui/react-context": "1.1.2", 2647 + "@radix-ui/react-dismissable-layer": "1.1.11", 2648 + "@radix-ui/react-focus-guards": "1.1.3", 2649 + "@radix-ui/react-focus-scope": "1.1.7", 2650 + "@radix-ui/react-id": "1.1.1", 2651 + "@radix-ui/react-popper": "1.2.8", 2652 + "@radix-ui/react-portal": "1.1.9", 2653 + "@radix-ui/react-presence": "1.1.5", 2654 + "@radix-ui/react-primitive": "2.1.3", 2655 + "@radix-ui/react-slot": "1.2.3", 2656 + "@radix-ui/react-use-controllable-state": "1.2.2", 2657 + "aria-hidden": "^1.2.4", 2658 + "react-remove-scroll": "^2.6.3" 2659 + }, 2660 + "peerDependencies": { 2661 + "@types/react": "*", 2662 + "@types/react-dom": "*", 2663 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2664 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2665 + }, 2666 + "peerDependenciesMeta": { 2667 + "@types/react": { 2668 + "optional": true 2669 + }, 2670 + "@types/react-dom": { 2671 + "optional": true 2672 + } 2673 + } 2674 + }, 2675 + "node_modules/@radix-ui/react-popper": { 2676 + "version": "1.2.8", 2677 + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz", 2678 + "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==", 2679 + "dependencies": { 2680 + "@floating-ui/react-dom": "^2.0.0", 2681 + "@radix-ui/react-arrow": "1.1.7", 2682 + "@radix-ui/react-compose-refs": "1.1.2", 2683 + "@radix-ui/react-context": "1.1.2", 2684 + "@radix-ui/react-primitive": "2.1.3", 2685 + "@radix-ui/react-use-callback-ref": "1.1.1", 2686 + "@radix-ui/react-use-layout-effect": "1.1.1", 2687 + "@radix-ui/react-use-rect": "1.1.1", 2688 + "@radix-ui/react-use-size": "1.1.1", 2689 + "@radix-ui/rect": "1.1.1" 2690 + }, 2691 + "peerDependencies": { 2692 + "@types/react": "*", 2693 + "@types/react-dom": "*", 2694 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2695 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2696 + }, 2697 + "peerDependenciesMeta": { 2698 + "@types/react": { 2699 + "optional": true 2700 + }, 2701 + "@types/react-dom": { 2702 + "optional": true 2703 + } 2704 + } 2705 + }, 2706 + "node_modules/@radix-ui/react-portal": { 2707 + "version": "1.1.9", 2708 + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", 2709 + "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", 2710 + "dependencies": { 2711 + "@radix-ui/react-primitive": "2.1.3", 2712 + "@radix-ui/react-use-layout-effect": "1.1.1" 2713 + }, 2714 + "peerDependencies": { 2715 + "@types/react": "*", 2716 + "@types/react-dom": "*", 2717 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2718 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2719 + }, 2720 + "peerDependenciesMeta": { 2721 + "@types/react": { 2722 + "optional": true 2723 + }, 2724 + "@types/react-dom": { 2725 + "optional": true 2726 + } 2727 + } 2728 + }, 2729 + "node_modules/@radix-ui/react-presence": { 2730 + "version": "1.1.5", 2731 + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", 2732 + "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", 2733 + "dependencies": { 2734 + "@radix-ui/react-compose-refs": "1.1.2", 2735 + "@radix-ui/react-use-layout-effect": "1.1.1" 2736 + }, 2737 + "peerDependencies": { 2738 + "@types/react": "*", 2739 + "@types/react-dom": "*", 2740 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2741 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2742 + }, 2743 + "peerDependenciesMeta": { 2744 + "@types/react": { 2745 + "optional": true 2746 + }, 2747 + "@types/react-dom": { 2748 + "optional": true 2749 + } 2750 + } 2751 + }, 2752 + "node_modules/@radix-ui/react-primitive": { 2753 + "version": "2.1.3", 2754 + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", 2755 + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", 2756 + "dependencies": { 2757 + "@radix-ui/react-slot": "1.2.3" 2758 + }, 2759 + "peerDependencies": { 2760 + "@types/react": "*", 2761 + "@types/react-dom": "*", 2762 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2763 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2764 + }, 2765 + "peerDependenciesMeta": { 2766 + "@types/react": { 2767 + "optional": true 2768 + }, 2769 + "@types/react-dom": { 2770 + "optional": true 2771 + } 2772 + } 2773 + }, 2774 + "node_modules/@radix-ui/react-progress": { 2775 + "version": "1.1.7", 2776 + "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.7.tgz", 2777 + "integrity": "sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg==", 2778 + "dependencies": { 2779 + "@radix-ui/react-context": "1.1.2", 2780 + "@radix-ui/react-primitive": "2.1.3" 2781 + }, 2782 + "peerDependencies": { 2783 + "@types/react": "*", 2784 + "@types/react-dom": "*", 2785 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2786 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2787 + }, 2788 + "peerDependenciesMeta": { 2789 + "@types/react": { 2790 + "optional": true 2791 + }, 2792 + "@types/react-dom": { 2793 + "optional": true 2794 + } 2795 + } 2796 + }, 2797 + "node_modules/@radix-ui/react-radio-group": { 2798 + "version": "1.3.8", 2799 + "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.3.8.tgz", 2800 + "integrity": "sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ==", 2801 + "dependencies": { 2802 + "@radix-ui/primitive": "1.1.3", 2803 + "@radix-ui/react-compose-refs": "1.1.2", 2804 + "@radix-ui/react-context": "1.1.2", 2805 + "@radix-ui/react-direction": "1.1.1", 2806 + "@radix-ui/react-presence": "1.1.5", 2807 + "@radix-ui/react-primitive": "2.1.3", 2808 + "@radix-ui/react-roving-focus": "1.1.11", 2809 + "@radix-ui/react-use-controllable-state": "1.2.2", 2810 + "@radix-ui/react-use-previous": "1.1.1", 2811 + "@radix-ui/react-use-size": "1.1.1" 2812 + }, 2813 + "peerDependencies": { 2814 + "@types/react": "*", 2815 + "@types/react-dom": "*", 2816 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2817 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2818 + }, 2819 + "peerDependenciesMeta": { 2820 + "@types/react": { 2821 + "optional": true 2822 + }, 2823 + "@types/react-dom": { 2824 + "optional": true 2825 + } 2826 + } 2827 + }, 2828 + "node_modules/@radix-ui/react-roving-focus": { 2829 + "version": "1.1.11", 2830 + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz", 2831 + "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==", 2832 + "dependencies": { 2833 + "@radix-ui/primitive": "1.1.3", 2834 + "@radix-ui/react-collection": "1.1.7", 2835 + "@radix-ui/react-compose-refs": "1.1.2", 2836 + "@radix-ui/react-context": "1.1.2", 2837 + "@radix-ui/react-direction": "1.1.1", 2838 + "@radix-ui/react-id": "1.1.1", 2839 + "@radix-ui/react-primitive": "2.1.3", 2840 + "@radix-ui/react-use-callback-ref": "1.1.1", 2841 + "@radix-ui/react-use-controllable-state": "1.2.2" 2842 + }, 2843 + "peerDependencies": { 2844 + "@types/react": "*", 2845 + "@types/react-dom": "*", 2846 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2847 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2848 + }, 2849 + "peerDependenciesMeta": { 2850 + "@types/react": { 2851 + "optional": true 2852 + }, 2853 + "@types/react-dom": { 2854 + "optional": true 2855 + } 2856 + } 2857 + }, 2858 + "node_modules/@radix-ui/react-scroll-area": { 2859 + "version": "1.2.10", 2860 + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.10.tgz", 2861 + "integrity": "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==", 2862 + "dependencies": { 2863 + "@radix-ui/number": "1.1.1", 2864 + "@radix-ui/primitive": "1.1.3", 2865 + "@radix-ui/react-compose-refs": "1.1.2", 2866 + "@radix-ui/react-context": "1.1.2", 2867 + "@radix-ui/react-direction": "1.1.1", 2868 + "@radix-ui/react-presence": "1.1.5", 2869 + "@radix-ui/react-primitive": "2.1.3", 2870 + "@radix-ui/react-use-callback-ref": "1.1.1", 2871 + "@radix-ui/react-use-layout-effect": "1.1.1" 2872 + }, 2873 + "peerDependencies": { 2874 + "@types/react": "*", 2875 + "@types/react-dom": "*", 2876 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2877 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2878 + }, 2879 + "peerDependenciesMeta": { 2880 + "@types/react": { 2881 + "optional": true 2882 + }, 2883 + "@types/react-dom": { 2884 + "optional": true 2885 + } 2886 + } 2887 + }, 2888 + "node_modules/@radix-ui/react-select": { 2889 + "version": "2.2.6", 2890 + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz", 2891 + "integrity": "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==", 2892 + "dependencies": { 2893 + "@radix-ui/number": "1.1.1", 2894 + "@radix-ui/primitive": "1.1.3", 2895 + "@radix-ui/react-collection": "1.1.7", 2896 + "@radix-ui/react-compose-refs": "1.1.2", 2897 + "@radix-ui/react-context": "1.1.2", 2898 + "@radix-ui/react-direction": "1.1.1", 2899 + "@radix-ui/react-dismissable-layer": "1.1.11", 2900 + "@radix-ui/react-focus-guards": "1.1.3", 2901 + "@radix-ui/react-focus-scope": "1.1.7", 2902 + "@radix-ui/react-id": "1.1.1", 2903 + "@radix-ui/react-popper": "1.2.8", 2904 + "@radix-ui/react-portal": "1.1.9", 2905 + "@radix-ui/react-primitive": "2.1.3", 2906 + "@radix-ui/react-slot": "1.2.3", 2907 + "@radix-ui/react-use-callback-ref": "1.1.1", 2908 + "@radix-ui/react-use-controllable-state": "1.2.2", 2909 + "@radix-ui/react-use-layout-effect": "1.1.1", 2910 + "@radix-ui/react-use-previous": "1.1.1", 2911 + "@radix-ui/react-visually-hidden": "1.2.3", 2912 + "aria-hidden": "^1.2.4", 2913 + "react-remove-scroll": "^2.6.3" 2914 + }, 2915 + "peerDependencies": { 2916 + "@types/react": "*", 2917 + "@types/react-dom": "*", 2918 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2919 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2920 + }, 2921 + "peerDependenciesMeta": { 2922 + "@types/react": { 2923 + "optional": true 2924 + }, 2925 + "@types/react-dom": { 2926 + "optional": true 2927 + } 2928 + } 2929 + }, 2930 + "node_modules/@radix-ui/react-separator": { 2931 + "version": "1.1.7", 2932 + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.7.tgz", 2933 + "integrity": "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==", 2934 + "dependencies": { 2935 + "@radix-ui/react-primitive": "2.1.3" 2936 + }, 2937 + "peerDependencies": { 2938 + "@types/react": "*", 2939 + "@types/react-dom": "*", 2940 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2941 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2942 + }, 2943 + "peerDependenciesMeta": { 2944 + "@types/react": { 2945 + "optional": true 2946 + }, 2947 + "@types/react-dom": { 2948 + "optional": true 2949 + } 2950 + } 2951 + }, 2952 + "node_modules/@radix-ui/react-slider": { 2953 + "version": "1.3.6", 2954 + "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.3.6.tgz", 2955 + "integrity": "sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw==", 2956 + "dependencies": { 2957 + "@radix-ui/number": "1.1.1", 2958 + "@radix-ui/primitive": "1.1.3", 2959 + "@radix-ui/react-collection": "1.1.7", 2960 + "@radix-ui/react-compose-refs": "1.1.2", 2961 + "@radix-ui/react-context": "1.1.2", 2962 + "@radix-ui/react-direction": "1.1.1", 2963 + "@radix-ui/react-primitive": "2.1.3", 2964 + "@radix-ui/react-use-controllable-state": "1.2.2", 2965 + "@radix-ui/react-use-layout-effect": "1.1.1", 2966 + "@radix-ui/react-use-previous": "1.1.1", 2967 + "@radix-ui/react-use-size": "1.1.1" 2968 + }, 2969 + "peerDependencies": { 2970 + "@types/react": "*", 2971 + "@types/react-dom": "*", 2972 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 2973 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2974 + }, 2975 + "peerDependenciesMeta": { 2976 + "@types/react": { 2977 + "optional": true 2978 + }, 2979 + "@types/react-dom": { 2980 + "optional": true 2981 + } 2982 + } 2983 + }, 2984 + "node_modules/@radix-ui/react-slot": { 2985 + "version": "1.2.3", 2986 + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", 2987 + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", 2988 + "dependencies": { 2989 + "@radix-ui/react-compose-refs": "1.1.2" 2990 + }, 2991 + "peerDependencies": { 2992 + "@types/react": "*", 2993 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 2994 + }, 2995 + "peerDependenciesMeta": { 2996 + "@types/react": { 2997 + "optional": true 2998 + } 2999 + } 3000 + }, 3001 + "node_modules/@radix-ui/react-switch": { 3002 + "version": "1.2.6", 3003 + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.6.tgz", 3004 + "integrity": "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==", 3005 + "dependencies": { 3006 + "@radix-ui/primitive": "1.1.3", 3007 + "@radix-ui/react-compose-refs": "1.1.2", 3008 + "@radix-ui/react-context": "1.1.2", 3009 + "@radix-ui/react-primitive": "2.1.3", 3010 + "@radix-ui/react-use-controllable-state": "1.2.2", 3011 + "@radix-ui/react-use-previous": "1.1.1", 3012 + "@radix-ui/react-use-size": "1.1.1" 3013 + }, 3014 + "peerDependencies": { 3015 + "@types/react": "*", 3016 + "@types/react-dom": "*", 3017 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 3018 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3019 + }, 3020 + "peerDependenciesMeta": { 3021 + "@types/react": { 3022 + "optional": true 3023 + }, 3024 + "@types/react-dom": { 3025 + "optional": true 3026 + } 3027 + } 3028 + }, 3029 + "node_modules/@radix-ui/react-tabs": { 3030 + "version": "1.1.13", 3031 + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz", 3032 + "integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==", 3033 + "dependencies": { 3034 + "@radix-ui/primitive": "1.1.3", 3035 + "@radix-ui/react-context": "1.1.2", 3036 + "@radix-ui/react-direction": "1.1.1", 3037 + "@radix-ui/react-id": "1.1.1", 3038 + "@radix-ui/react-presence": "1.1.5", 3039 + "@radix-ui/react-primitive": "2.1.3", 3040 + "@radix-ui/react-roving-focus": "1.1.11", 3041 + "@radix-ui/react-use-controllable-state": "1.2.2" 3042 + }, 3043 + "peerDependencies": { 3044 + "@types/react": "*", 3045 + "@types/react-dom": "*", 3046 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 3047 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3048 + }, 3049 + "peerDependenciesMeta": { 3050 + "@types/react": { 3051 + "optional": true 3052 + }, 3053 + "@types/react-dom": { 3054 + "optional": true 3055 + } 3056 + } 3057 + }, 3058 + "node_modules/@radix-ui/react-toast": { 3059 + "version": "1.2.15", 3060 + "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.15.tgz", 3061 + "integrity": "sha512-3OSz3TacUWy4WtOXV38DggwxoqJK4+eDkNMl5Z/MJZaoUPaP4/9lf81xXMe1I2ReTAptverZUpbPY4wWwWyL5g==", 3062 + "dependencies": { 3063 + "@radix-ui/primitive": "1.1.3", 3064 + "@radix-ui/react-collection": "1.1.7", 3065 + "@radix-ui/react-compose-refs": "1.1.2", 3066 + "@radix-ui/react-context": "1.1.2", 3067 + "@radix-ui/react-dismissable-layer": "1.1.11", 3068 + "@radix-ui/react-portal": "1.1.9", 3069 + "@radix-ui/react-presence": "1.1.5", 3070 + "@radix-ui/react-primitive": "2.1.3", 3071 + "@radix-ui/react-use-callback-ref": "1.1.1", 3072 + "@radix-ui/react-use-controllable-state": "1.2.2", 3073 + "@radix-ui/react-use-layout-effect": "1.1.1", 3074 + "@radix-ui/react-visually-hidden": "1.2.3" 3075 + }, 3076 + "peerDependencies": { 3077 + "@types/react": "*", 3078 + "@types/react-dom": "*", 3079 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 3080 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3081 + }, 3082 + "peerDependenciesMeta": { 3083 + "@types/react": { 3084 + "optional": true 3085 + }, 3086 + "@types/react-dom": { 3087 + "optional": true 3088 + } 3089 + } 3090 + }, 3091 + "node_modules/@radix-ui/react-toggle": { 3092 + "version": "1.1.10", 3093 + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.10.tgz", 3094 + "integrity": "sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ==", 3095 + "dependencies": { 3096 + "@radix-ui/primitive": "1.1.3", 3097 + "@radix-ui/react-primitive": "2.1.3", 3098 + "@radix-ui/react-use-controllable-state": "1.2.2" 3099 + }, 3100 + "peerDependencies": { 3101 + "@types/react": "*", 3102 + "@types/react-dom": "*", 3103 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 3104 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3105 + }, 3106 + "peerDependenciesMeta": { 3107 + "@types/react": { 3108 + "optional": true 3109 + }, 3110 + "@types/react-dom": { 3111 + "optional": true 3112 + } 3113 + } 3114 + }, 3115 + "node_modules/@radix-ui/react-toggle-group": { 3116 + "version": "1.1.11", 3117 + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.11.tgz", 3118 + "integrity": "sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q==", 3119 + "dependencies": { 3120 + "@radix-ui/primitive": "1.1.3", 3121 + "@radix-ui/react-context": "1.1.2", 3122 + "@radix-ui/react-direction": "1.1.1", 3123 + "@radix-ui/react-primitive": "2.1.3", 3124 + "@radix-ui/react-roving-focus": "1.1.11", 3125 + "@radix-ui/react-toggle": "1.1.10", 3126 + "@radix-ui/react-use-controllable-state": "1.2.2" 3127 + }, 3128 + "peerDependencies": { 3129 + "@types/react": "*", 3130 + "@types/react-dom": "*", 3131 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 3132 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3133 + }, 3134 + "peerDependenciesMeta": { 3135 + "@types/react": { 3136 + "optional": true 3137 + }, 3138 + "@types/react-dom": { 3139 + "optional": true 3140 + } 3141 + } 3142 + }, 3143 + "node_modules/@radix-ui/react-toolbar": { 3144 + "version": "1.1.11", 3145 + "resolved": "https://registry.npmjs.org/@radix-ui/react-toolbar/-/react-toolbar-1.1.11.tgz", 3146 + "integrity": "sha512-4ol06/1bLoFu1nwUqzdD4Y5RZ9oDdKeiHIsntug54Hcr1pgaHiPqHFEaXI1IFP/EsOfROQZ8Mig9VTIRza6Tjg==", 3147 + "dependencies": { 3148 + "@radix-ui/primitive": "1.1.3", 3149 + "@radix-ui/react-context": "1.1.2", 3150 + "@radix-ui/react-direction": "1.1.1", 3151 + "@radix-ui/react-primitive": "2.1.3", 3152 + "@radix-ui/react-roving-focus": "1.1.11", 3153 + "@radix-ui/react-separator": "1.1.7", 3154 + "@radix-ui/react-toggle-group": "1.1.11" 3155 + }, 3156 + "peerDependencies": { 3157 + "@types/react": "*", 3158 + "@types/react-dom": "*", 3159 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 3160 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3161 + }, 3162 + "peerDependenciesMeta": { 3163 + "@types/react": { 3164 + "optional": true 3165 + }, 3166 + "@types/react-dom": { 3167 + "optional": true 3168 + } 3169 + } 3170 + }, 3171 + "node_modules/@radix-ui/react-tooltip": { 3172 + "version": "1.2.8", 3173 + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz", 3174 + "integrity": "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==", 3175 + "dependencies": { 3176 + "@radix-ui/primitive": "1.1.3", 3177 + "@radix-ui/react-compose-refs": "1.1.2", 3178 + "@radix-ui/react-context": "1.1.2", 3179 + "@radix-ui/react-dismissable-layer": "1.1.11", 3180 + "@radix-ui/react-id": "1.1.1", 3181 + "@radix-ui/react-popper": "1.2.8", 3182 + "@radix-ui/react-portal": "1.1.9", 3183 + "@radix-ui/react-presence": "1.1.5", 3184 + "@radix-ui/react-primitive": "2.1.3", 3185 + "@radix-ui/react-slot": "1.2.3", 3186 + "@radix-ui/react-use-controllable-state": "1.2.2", 3187 + "@radix-ui/react-visually-hidden": "1.2.3" 3188 + }, 3189 + "peerDependencies": { 3190 + "@types/react": "*", 3191 + "@types/react-dom": "*", 3192 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 3193 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3194 + }, 3195 + "peerDependenciesMeta": { 3196 + "@types/react": { 3197 + "optional": true 3198 + }, 3199 + "@types/react-dom": { 3200 + "optional": true 3201 + } 3202 + } 3203 + }, 3204 + "node_modules/@radix-ui/react-use-callback-ref": { 3205 + "version": "1.1.1", 3206 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", 3207 + "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", 3208 + "peerDependencies": { 3209 + "@types/react": "*", 3210 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3211 + }, 3212 + "peerDependenciesMeta": { 3213 + "@types/react": { 3214 + "optional": true 3215 + } 3216 + } 3217 + }, 3218 + "node_modules/@radix-ui/react-use-controllable-state": { 3219 + "version": "1.2.2", 3220 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", 3221 + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", 3222 + "dependencies": { 3223 + "@radix-ui/react-use-effect-event": "0.0.2", 3224 + "@radix-ui/react-use-layout-effect": "1.1.1" 3225 + }, 3226 + "peerDependencies": { 3227 + "@types/react": "*", 3228 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3229 + }, 3230 + "peerDependenciesMeta": { 3231 + "@types/react": { 3232 + "optional": true 3233 + } 3234 + } 3235 + }, 3236 + "node_modules/@radix-ui/react-use-effect-event": { 3237 + "version": "0.0.2", 3238 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", 3239 + "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", 3240 + "dependencies": { 3241 + "@radix-ui/react-use-layout-effect": "1.1.1" 3242 + }, 3243 + "peerDependencies": { 3244 + "@types/react": "*", 3245 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3246 + }, 3247 + "peerDependenciesMeta": { 3248 + "@types/react": { 3249 + "optional": true 3250 + } 3251 + } 3252 + }, 3253 + "node_modules/@radix-ui/react-use-escape-keydown": { 3254 + "version": "1.1.1", 3255 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", 3256 + "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", 3257 + "dependencies": { 3258 + "@radix-ui/react-use-callback-ref": "1.1.1" 3259 + }, 3260 + "peerDependencies": { 3261 + "@types/react": "*", 3262 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3263 + }, 3264 + "peerDependenciesMeta": { 3265 + "@types/react": { 3266 + "optional": true 3267 + } 3268 + } 3269 + }, 3270 + "node_modules/@radix-ui/react-use-is-hydrated": { 3271 + "version": "0.1.0", 3272 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.0.tgz", 3273 + "integrity": "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==", 3274 + "dependencies": { 3275 + "use-sync-external-store": "^1.5.0" 3276 + }, 3277 + "peerDependencies": { 3278 + "@types/react": "*", 3279 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3280 + }, 3281 + "peerDependenciesMeta": { 3282 + "@types/react": { 3283 + "optional": true 3284 + } 3285 + } 3286 + }, 3287 + "node_modules/@radix-ui/react-use-layout-effect": { 3288 + "version": "1.1.1", 3289 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", 3290 + "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", 3291 + "peerDependencies": { 3292 + "@types/react": "*", 3293 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3294 + }, 3295 + "peerDependenciesMeta": { 3296 + "@types/react": { 3297 + "optional": true 3298 + } 3299 + } 3300 + }, 3301 + "node_modules/@radix-ui/react-use-previous": { 3302 + "version": "1.1.1", 3303 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", 3304 + "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", 3305 + "peerDependencies": { 3306 + "@types/react": "*", 3307 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3308 + }, 3309 + "peerDependenciesMeta": { 3310 + "@types/react": { 3311 + "optional": true 3312 + } 3313 + } 3314 + }, 3315 + "node_modules/@radix-ui/react-use-rect": { 3316 + "version": "1.1.1", 3317 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", 3318 + "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", 3319 + "dependencies": { 3320 + "@radix-ui/rect": "1.1.1" 3321 + }, 3322 + "peerDependencies": { 3323 + "@types/react": "*", 3324 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3325 + }, 3326 + "peerDependenciesMeta": { 3327 + "@types/react": { 3328 + "optional": true 3329 + } 3330 + } 3331 + }, 3332 + "node_modules/@radix-ui/react-use-size": { 3333 + "version": "1.1.1", 3334 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", 3335 + "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", 3336 + "dependencies": { 3337 + "@radix-ui/react-use-layout-effect": "1.1.1" 3338 + }, 3339 + "peerDependencies": { 3340 + "@types/react": "*", 3341 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3342 + }, 3343 + "peerDependenciesMeta": { 3344 + "@types/react": { 3345 + "optional": true 3346 + } 3347 + } 3348 + }, 3349 + "node_modules/@radix-ui/react-visually-hidden": { 3350 + "version": "1.2.3", 3351 + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", 3352 + "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", 3353 + "dependencies": { 3354 + "@radix-ui/react-primitive": "2.1.3" 3355 + }, 3356 + "peerDependencies": { 3357 + "@types/react": "*", 3358 + "@types/react-dom": "*", 3359 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 3360 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 3361 + }, 3362 + "peerDependenciesMeta": { 3363 + "@types/react": { 3364 + "optional": true 3365 + }, 3366 + "@types/react-dom": { 3367 + "optional": true 3368 + } 3369 + } 3370 + }, 3371 + "node_modules/@radix-ui/rect": { 3372 + "version": "1.1.1", 3373 + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", 3374 + "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==" 3375 + }, 1397 3376 "node_modules/@rolldown/pluginutils": { 1398 3377 "version": "1.0.0-beta.27", 1399 3378 "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", ··· 1708 3687 "solid-js": "^1.6.12" 1709 3688 } 1710 3689 }, 3690 + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { 3691 + "version": "8.0.0", 3692 + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", 3693 + "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", 3694 + "dev": true, 3695 + "license": "MIT", 3696 + "engines": { 3697 + "node": ">=14" 3698 + }, 3699 + "funding": { 3700 + "type": "github", 3701 + "url": "https://github.com/sponsors/gregberge" 3702 + }, 3703 + "peerDependencies": { 3704 + "@babel/core": "^7.0.0-0" 3705 + } 3706 + }, 3707 + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { 3708 + "version": "8.0.0", 3709 + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", 3710 + "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", 3711 + "dev": true, 3712 + "license": "MIT", 3713 + "engines": { 3714 + "node": ">=14" 3715 + }, 3716 + "funding": { 3717 + "type": "github", 3718 + "url": "https://github.com/sponsors/gregberge" 3719 + }, 3720 + "peerDependencies": { 3721 + "@babel/core": "^7.0.0-0" 3722 + } 3723 + }, 3724 + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { 3725 + "version": "8.0.0", 3726 + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", 3727 + "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", 3728 + "dev": true, 3729 + "license": "MIT", 3730 + "engines": { 3731 + "node": ">=14" 3732 + }, 3733 + "funding": { 3734 + "type": "github", 3735 + "url": "https://github.com/sponsors/gregberge" 3736 + }, 3737 + "peerDependencies": { 3738 + "@babel/core": "^7.0.0-0" 3739 + } 3740 + }, 3741 + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { 3742 + "version": "8.0.0", 3743 + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", 3744 + "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", 3745 + "dev": true, 3746 + "license": "MIT", 3747 + "engines": { 3748 + "node": ">=14" 3749 + }, 3750 + "funding": { 3751 + "type": "github", 3752 + "url": "https://github.com/sponsors/gregberge" 3753 + }, 3754 + "peerDependencies": { 3755 + "@babel/core": "^7.0.0-0" 3756 + } 3757 + }, 3758 + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { 3759 + "version": "8.0.0", 3760 + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", 3761 + "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", 3762 + "dev": true, 3763 + "license": "MIT", 3764 + "engines": { 3765 + "node": ">=14" 3766 + }, 3767 + "funding": { 3768 + "type": "github", 3769 + "url": "https://github.com/sponsors/gregberge" 3770 + }, 3771 + "peerDependencies": { 3772 + "@babel/core": "^7.0.0-0" 3773 + } 3774 + }, 3775 + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { 3776 + "version": "8.0.0", 3777 + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", 3778 + "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", 3779 + "dev": true, 3780 + "license": "MIT", 3781 + "engines": { 3782 + "node": ">=14" 3783 + }, 3784 + "funding": { 3785 + "type": "github", 3786 + "url": "https://github.com/sponsors/gregberge" 3787 + }, 3788 + "peerDependencies": { 3789 + "@babel/core": "^7.0.0-0" 3790 + } 3791 + }, 3792 + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { 3793 + "version": "8.1.0", 3794 + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", 3795 + "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", 3796 + "dev": true, 3797 + "license": "MIT", 3798 + "engines": { 3799 + "node": ">=14" 3800 + }, 3801 + "funding": { 3802 + "type": "github", 3803 + "url": "https://github.com/sponsors/gregberge" 3804 + }, 3805 + "peerDependencies": { 3806 + "@babel/core": "^7.0.0-0" 3807 + } 3808 + }, 3809 + "node_modules/@svgr/babel-plugin-transform-svg-component": { 3810 + "version": "8.0.0", 3811 + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", 3812 + "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", 3813 + "dev": true, 3814 + "license": "MIT", 3815 + "engines": { 3816 + "node": ">=12" 3817 + }, 3818 + "funding": { 3819 + "type": "github", 3820 + "url": "https://github.com/sponsors/gregberge" 3821 + }, 3822 + "peerDependencies": { 3823 + "@babel/core": "^7.0.0-0" 3824 + } 3825 + }, 3826 + "node_modules/@svgr/babel-preset": { 3827 + "version": "8.1.0", 3828 + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", 3829 + "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", 3830 + "dev": true, 3831 + "license": "MIT", 3832 + "dependencies": { 3833 + "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", 3834 + "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", 3835 + "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", 3836 + "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", 3837 + "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", 3838 + "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", 3839 + "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", 3840 + "@svgr/babel-plugin-transform-svg-component": "8.0.0" 3841 + }, 3842 + "engines": { 3843 + "node": ">=14" 3844 + }, 3845 + "funding": { 3846 + "type": "github", 3847 + "url": "https://github.com/sponsors/gregberge" 3848 + }, 3849 + "peerDependencies": { 3850 + "@babel/core": "^7.0.0-0" 3851 + } 3852 + }, 3853 + "node_modules/@svgr/core": { 3854 + "version": "8.1.0", 3855 + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", 3856 + "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", 3857 + "dev": true, 3858 + "license": "MIT", 3859 + "dependencies": { 3860 + "@babel/core": "^7.21.3", 3861 + "@svgr/babel-preset": "8.1.0", 3862 + "camelcase": "^6.2.0", 3863 + "cosmiconfig": "^8.1.3", 3864 + "snake-case": "^3.0.4" 3865 + }, 3866 + "engines": { 3867 + "node": ">=14" 3868 + }, 3869 + "funding": { 3870 + "type": "github", 3871 + "url": "https://github.com/sponsors/gregberge" 3872 + } 3873 + }, 3874 + "node_modules/@svgr/hast-util-to-babel-ast": { 3875 + "version": "8.0.0", 3876 + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", 3877 + "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", 3878 + "dev": true, 3879 + "license": "MIT", 3880 + "dependencies": { 3881 + "@babel/types": "^7.21.3", 3882 + "entities": "^4.4.0" 3883 + }, 3884 + "engines": { 3885 + "node": ">=14" 3886 + }, 3887 + "funding": { 3888 + "type": "github", 3889 + "url": "https://github.com/sponsors/gregberge" 3890 + } 3891 + }, 3892 + "node_modules/@svgr/hast-util-to-babel-ast/node_modules/entities": { 3893 + "version": "4.5.0", 3894 + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", 3895 + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", 3896 + "dev": true, 3897 + "license": "BSD-2-Clause", 3898 + "engines": { 3899 + "node": ">=0.12" 3900 + }, 3901 + "funding": { 3902 + "url": "https://github.com/fb55/entities?sponsor=1" 3903 + } 3904 + }, 3905 + "node_modules/@svgr/plugin-jsx": { 3906 + "version": "8.1.0", 3907 + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", 3908 + "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", 3909 + "dev": true, 3910 + "license": "MIT", 3911 + "dependencies": { 3912 + "@babel/core": "^7.21.3", 3913 + "@svgr/babel-preset": "8.1.0", 3914 + "@svgr/hast-util-to-babel-ast": "8.0.0", 3915 + "svg-parser": "^2.0.4" 3916 + }, 3917 + "engines": { 3918 + "node": ">=14" 3919 + }, 3920 + "funding": { 3921 + "type": "github", 3922 + "url": "https://github.com/sponsors/gregberge" 3923 + }, 3924 + "peerDependencies": { 3925 + "@svgr/core": "*" 3926 + } 3927 + }, 1711 3928 "node_modules/@svta/common-media-library": { 1712 3929 "version": "0.12.4", 1713 3930 "resolved": "https://registry.npmjs.org/@svta/common-media-library/-/common-media-library-0.12.4.tgz", ··· 2499 4716 "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", 2500 4717 "license": "MIT" 2501 4718 }, 4719 + "node_modules/@types/json-schema": { 4720 + "version": "7.0.15", 4721 + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", 4722 + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", 4723 + "dev": true, 4724 + "license": "MIT", 4725 + "peer": true 4726 + }, 2502 4727 "node_modules/@types/node": { 2503 4728 "version": "24.3.0", 2504 4729 "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz", ··· 2527 4752 "@types/react": "^19.0.0" 2528 4753 } 2529 4754 }, 4755 + "node_modules/@types/trusted-types": { 4756 + "version": "2.0.7", 4757 + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", 4758 + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", 4759 + "license": "MIT", 4760 + "optional": true 4761 + }, 4762 + "node_modules/@typescript-eslint/eslint-plugin": { 4763 + "version": "8.46.1", 4764 + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.1.tgz", 4765 + "integrity": "sha512-rUsLh8PXmBjdiPY+Emjz9NX2yHvhS11v0SR6xNJkm5GM1MO9ea/1GoDKlHHZGrOJclL/cZ2i/vRUYVtjRhrHVQ==", 4766 + "dev": true, 4767 + "license": "MIT", 4768 + "dependencies": { 4769 + "@eslint-community/regexpp": "^4.10.0", 4770 + "@typescript-eslint/scope-manager": "8.46.1", 4771 + "@typescript-eslint/type-utils": "8.46.1", 4772 + "@typescript-eslint/utils": "8.46.1", 4773 + "@typescript-eslint/visitor-keys": "8.46.1", 4774 + "graphemer": "^1.4.0", 4775 + "ignore": "^7.0.0", 4776 + "natural-compare": "^1.4.0", 4777 + "ts-api-utils": "^2.1.0" 4778 + }, 4779 + "engines": { 4780 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 4781 + }, 4782 + "funding": { 4783 + "type": "opencollective", 4784 + "url": "https://opencollective.com/typescript-eslint" 4785 + }, 4786 + "peerDependencies": { 4787 + "@typescript-eslint/parser": "^8.46.1", 4788 + "eslint": "^8.57.0 || ^9.0.0", 4789 + "typescript": ">=4.8.4 <6.0.0" 4790 + } 4791 + }, 4792 + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { 4793 + "version": "7.0.5", 4794 + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", 4795 + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", 4796 + "dev": true, 4797 + "license": "MIT", 4798 + "engines": { 4799 + "node": ">= 4" 4800 + } 4801 + }, 4802 + "node_modules/@typescript-eslint/parser": { 4803 + "version": "8.46.1", 4804 + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.1.tgz", 4805 + "integrity": "sha512-6JSSaBZmsKvEkbRUkf7Zj7dru/8ZCrJxAqArcLaVMee5907JdtEbKGsZ7zNiIm/UAkpGUkaSMZEXShnN2D1HZA==", 4806 + "dev": true, 4807 + "license": "MIT", 4808 + "dependencies": { 4809 + "@typescript-eslint/scope-manager": "8.46.1", 4810 + "@typescript-eslint/types": "8.46.1", 4811 + "@typescript-eslint/typescript-estree": "8.46.1", 4812 + "@typescript-eslint/visitor-keys": "8.46.1", 4813 + "debug": "^4.3.4" 4814 + }, 4815 + "engines": { 4816 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 4817 + }, 4818 + "funding": { 4819 + "type": "opencollective", 4820 + "url": "https://opencollective.com/typescript-eslint" 4821 + }, 4822 + "peerDependencies": { 4823 + "eslint": "^8.57.0 || ^9.0.0", 4824 + "typescript": ">=4.8.4 <6.0.0" 4825 + } 4826 + }, 4827 + "node_modules/@typescript-eslint/project-service": { 4828 + "version": "8.46.1", 4829 + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.1.tgz", 4830 + "integrity": "sha512-FOIaFVMHzRskXr5J4Jp8lFVV0gz5ngv3RHmn+E4HYxSJ3DgDzU7fVI1/M7Ijh1zf6S7HIoaIOtln1H5y8V+9Zg==", 4831 + "dev": true, 4832 + "license": "MIT", 4833 + "dependencies": { 4834 + "@typescript-eslint/tsconfig-utils": "^8.46.1", 4835 + "@typescript-eslint/types": "^8.46.1", 4836 + "debug": "^4.3.4" 4837 + }, 4838 + "engines": { 4839 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 4840 + }, 4841 + "funding": { 4842 + "type": "opencollective", 4843 + "url": "https://opencollective.com/typescript-eslint" 4844 + }, 4845 + "peerDependencies": { 4846 + "typescript": ">=4.8.4 <6.0.0" 4847 + } 4848 + }, 4849 + "node_modules/@typescript-eslint/scope-manager": { 4850 + "version": "8.46.1", 4851 + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.1.tgz", 4852 + "integrity": "sha512-weL9Gg3/5F0pVQKiF8eOXFZp8emqWzZsOJuWRUNtHT+UNV2xSJegmpCNQHy37aEQIbToTq7RHKhWvOsmbM680A==", 4853 + "dev": true, 4854 + "license": "MIT", 4855 + "dependencies": { 4856 + "@typescript-eslint/types": "8.46.1", 4857 + "@typescript-eslint/visitor-keys": "8.46.1" 4858 + }, 4859 + "engines": { 4860 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 4861 + }, 4862 + "funding": { 4863 + "type": "opencollective", 4864 + "url": "https://opencollective.com/typescript-eslint" 4865 + } 4866 + }, 4867 + "node_modules/@typescript-eslint/tsconfig-utils": { 4868 + "version": "8.46.1", 4869 + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.1.tgz", 4870 + "integrity": "sha512-X88+J/CwFvlJB+mK09VFqx5FE4H5cXD+H/Bdza2aEWkSb8hnWIQorNcscRl4IEo1Cz9VI/+/r/jnGWkbWPx54g==", 4871 + "dev": true, 4872 + "license": "MIT", 4873 + "engines": { 4874 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 4875 + }, 4876 + "funding": { 4877 + "type": "opencollective", 4878 + "url": "https://opencollective.com/typescript-eslint" 4879 + }, 4880 + "peerDependencies": { 4881 + "typescript": ">=4.8.4 <6.0.0" 4882 + } 4883 + }, 4884 + "node_modules/@typescript-eslint/type-utils": { 4885 + "version": "8.46.1", 4886 + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.1.tgz", 4887 + "integrity": "sha512-+BlmiHIiqufBxkVnOtFwjah/vrkF4MtKKvpXrKSPLCkCtAp8H01/VV43sfqA98Od7nJpDcFnkwgyfQbOG0AMvw==", 4888 + "dev": true, 4889 + "license": "MIT", 4890 + "dependencies": { 4891 + "@typescript-eslint/types": "8.46.1", 4892 + "@typescript-eslint/typescript-estree": "8.46.1", 4893 + "@typescript-eslint/utils": "8.46.1", 4894 + "debug": "^4.3.4", 4895 + "ts-api-utils": "^2.1.0" 4896 + }, 4897 + "engines": { 4898 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 4899 + }, 4900 + "funding": { 4901 + "type": "opencollective", 4902 + "url": "https://opencollective.com/typescript-eslint" 4903 + }, 4904 + "peerDependencies": { 4905 + "eslint": "^8.57.0 || ^9.0.0", 4906 + "typescript": ">=4.8.4 <6.0.0" 4907 + } 4908 + }, 4909 + "node_modules/@typescript-eslint/types": { 4910 + "version": "8.46.1", 4911 + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.1.tgz", 4912 + "integrity": "sha512-C+soprGBHwWBdkDpbaRC4paGBrkIXxVlNohadL5o0kfhsXqOC6GYH2S/Obmig+I0HTDl8wMaRySwrfrXVP8/pQ==", 4913 + "dev": true, 4914 + "license": "MIT", 4915 + "engines": { 4916 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 4917 + }, 4918 + "funding": { 4919 + "type": "opencollective", 4920 + "url": "https://opencollective.com/typescript-eslint" 4921 + } 4922 + }, 4923 + "node_modules/@typescript-eslint/typescript-estree": { 4924 + "version": "8.46.1", 4925 + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.1.tgz", 4926 + "integrity": "sha512-uIifjT4s8cQKFQ8ZBXXyoUODtRoAd7F7+G8MKmtzj17+1UbdzFl52AzRyZRyKqPHhgzvXunnSckVu36flGy8cg==", 4927 + "dev": true, 4928 + "license": "MIT", 4929 + "dependencies": { 4930 + "@typescript-eslint/project-service": "8.46.1", 4931 + "@typescript-eslint/tsconfig-utils": "8.46.1", 4932 + "@typescript-eslint/types": "8.46.1", 4933 + "@typescript-eslint/visitor-keys": "8.46.1", 4934 + "debug": "^4.3.4", 4935 + "fast-glob": "^3.3.2", 4936 + "is-glob": "^4.0.3", 4937 + "minimatch": "^9.0.4", 4938 + "semver": "^7.6.0", 4939 + "ts-api-utils": "^2.1.0" 4940 + }, 4941 + "engines": { 4942 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 4943 + }, 4944 + "funding": { 4945 + "type": "opencollective", 4946 + "url": "https://opencollective.com/typescript-eslint" 4947 + }, 4948 + "peerDependencies": { 4949 + "typescript": ">=4.8.4 <6.0.0" 4950 + } 4951 + }, 4952 + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { 4953 + "version": "2.0.2", 4954 + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", 4955 + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", 4956 + "dev": true, 4957 + "license": "MIT", 4958 + "dependencies": { 4959 + "balanced-match": "^1.0.0" 4960 + } 4961 + }, 4962 + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { 4963 + "version": "9.0.5", 4964 + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", 4965 + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", 4966 + "dev": true, 4967 + "license": "ISC", 4968 + "dependencies": { 4969 + "brace-expansion": "^2.0.1" 4970 + }, 4971 + "engines": { 4972 + "node": ">=16 || 14 >=14.17" 4973 + }, 4974 + "funding": { 4975 + "url": "https://github.com/sponsors/isaacs" 4976 + } 4977 + }, 4978 + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { 4979 + "version": "7.7.3", 4980 + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", 4981 + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", 4982 + "dev": true, 4983 + "license": "ISC", 4984 + "bin": { 4985 + "semver": "bin/semver.js" 4986 + }, 4987 + "engines": { 4988 + "node": ">=10" 4989 + } 4990 + }, 4991 + "node_modules/@typescript-eslint/utils": { 4992 + "version": "8.46.1", 4993 + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.1.tgz", 4994 + "integrity": "sha512-vkYUy6LdZS7q1v/Gxb2Zs7zziuXN0wxqsetJdeZdRe/f5dwJFglmuvZBfTUivCtjH725C1jWCDfpadadD95EDQ==", 4995 + "dev": true, 4996 + "license": "MIT", 4997 + "dependencies": { 4998 + "@eslint-community/eslint-utils": "^4.7.0", 4999 + "@typescript-eslint/scope-manager": "8.46.1", 5000 + "@typescript-eslint/types": "8.46.1", 5001 + "@typescript-eslint/typescript-estree": "8.46.1" 5002 + }, 5003 + "engines": { 5004 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 5005 + }, 5006 + "funding": { 5007 + "type": "opencollective", 5008 + "url": "https://opencollective.com/typescript-eslint" 5009 + }, 5010 + "peerDependencies": { 5011 + "eslint": "^8.57.0 || ^9.0.0", 5012 + "typescript": ">=4.8.4 <6.0.0" 5013 + } 5014 + }, 5015 + "node_modules/@typescript-eslint/visitor-keys": { 5016 + "version": "8.46.1", 5017 + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.1.tgz", 5018 + "integrity": "sha512-ptkmIf2iDkNUjdeu2bQqhFPV1m6qTnFFjg7PPDjxKWaMaP0Z6I9l30Jr3g5QqbZGdw8YdYvLp+XnqnWWZOg/NA==", 5019 + "dev": true, 5020 + "license": "MIT", 5021 + "dependencies": { 5022 + "@typescript-eslint/types": "8.46.1", 5023 + "eslint-visitor-keys": "^4.2.1" 5024 + }, 5025 + "engines": { 5026 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 5027 + }, 5028 + "funding": { 5029 + "type": "opencollective", 5030 + "url": "https://opencollective.com/typescript-eslint" 5031 + } 5032 + }, 2530 5033 "node_modules/@vercel/edge": { 2531 5034 "version": "1.2.2", 2532 5035 "resolved": "https://registry.npmjs.org/@vercel/edge/-/edge-1.2.2.tgz", ··· 2691 5194 "node": ">=0.4.0" 2692 5195 } 2693 5196 }, 5197 + "node_modules/acorn-jsx": { 5198 + "version": "5.3.2", 5199 + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", 5200 + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", 5201 + "dev": true, 5202 + "license": "MIT", 5203 + "peer": true, 5204 + "peerDependencies": { 5205 + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" 5206 + } 5207 + }, 2694 5208 "node_modules/agent-base": { 2695 5209 "version": "7.1.4", 2696 5210 "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", ··· 2701 5215 "node": ">= 14" 2702 5216 } 2703 5217 }, 5218 + "node_modules/ajv": { 5219 + "version": "6.12.6", 5220 + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 5221 + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 5222 + "dev": true, 5223 + "license": "MIT", 5224 + "peer": true, 5225 + "dependencies": { 5226 + "fast-deep-equal": "^3.1.1", 5227 + "fast-json-stable-stringify": "^2.0.0", 5228 + "json-schema-traverse": "^0.4.1", 5229 + "uri-js": "^4.2.2" 5230 + }, 5231 + "funding": { 5232 + "type": "github", 5233 + "url": "https://github.com/sponsors/epoberezkin" 5234 + } 5235 + }, 2704 5236 "node_modules/ansi-regex": { 2705 5237 "version": "5.0.1", 2706 5238 "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", ··· 2746 5278 "node": ">= 8" 2747 5279 } 2748 5280 }, 5281 + "node_modules/argparse": { 5282 + "version": "2.0.1", 5283 + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 5284 + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 5285 + "dev": true, 5286 + "license": "Python-2.0" 5287 + }, 5288 + "node_modules/aria-hidden": { 5289 + "version": "1.2.6", 5290 + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", 5291 + "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", 5292 + "dependencies": { 5293 + "tslib": "^2.0.0" 5294 + }, 5295 + "engines": { 5296 + "node": ">=10" 5297 + } 5298 + }, 2749 5299 "node_modules/aria-query": { 2750 5300 "version": "5.3.0", 2751 5301 "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", ··· 2756 5306 "dequal": "^2.0.3" 2757 5307 } 2758 5308 }, 5309 + "node_modules/array-buffer-byte-length": { 5310 + "version": "1.0.2", 5311 + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", 5312 + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", 5313 + "dev": true, 5314 + "license": "MIT", 5315 + "dependencies": { 5316 + "call-bound": "^1.0.3", 5317 + "is-array-buffer": "^3.0.5" 5318 + }, 5319 + "engines": { 5320 + "node": ">= 0.4" 5321 + }, 5322 + "funding": { 5323 + "url": "https://github.com/sponsors/ljharb" 5324 + } 5325 + }, 5326 + "node_modules/array-includes": { 5327 + "version": "3.1.9", 5328 + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", 5329 + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", 5330 + "dev": true, 5331 + "license": "MIT", 5332 + "dependencies": { 5333 + "call-bind": "^1.0.8", 5334 + "call-bound": "^1.0.4", 5335 + "define-properties": "^1.2.1", 5336 + "es-abstract": "^1.24.0", 5337 + "es-object-atoms": "^1.1.1", 5338 + "get-intrinsic": "^1.3.0", 5339 + "is-string": "^1.1.1", 5340 + "math-intrinsics": "^1.1.0" 5341 + }, 5342 + "engines": { 5343 + "node": ">= 0.4" 5344 + }, 5345 + "funding": { 5346 + "url": "https://github.com/sponsors/ljharb" 5347 + } 5348 + }, 5349 + "node_modules/array.prototype.findlast": { 5350 + "version": "1.2.5", 5351 + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", 5352 + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", 5353 + "dev": true, 5354 + "license": "MIT", 5355 + "dependencies": { 5356 + "call-bind": "^1.0.7", 5357 + "define-properties": "^1.2.1", 5358 + "es-abstract": "^1.23.2", 5359 + "es-errors": "^1.3.0", 5360 + "es-object-atoms": "^1.0.0", 5361 + "es-shim-unscopables": "^1.0.2" 5362 + }, 5363 + "engines": { 5364 + "node": ">= 0.4" 5365 + }, 5366 + "funding": { 5367 + "url": "https://github.com/sponsors/ljharb" 5368 + } 5369 + }, 5370 + "node_modules/array.prototype.flat": { 5371 + "version": "1.3.3", 5372 + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", 5373 + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", 5374 + "dev": true, 5375 + "license": "MIT", 5376 + "dependencies": { 5377 + "call-bind": "^1.0.8", 5378 + "define-properties": "^1.2.1", 5379 + "es-abstract": "^1.23.5", 5380 + "es-shim-unscopables": "^1.0.2" 5381 + }, 5382 + "engines": { 5383 + "node": ">= 0.4" 5384 + }, 5385 + "funding": { 5386 + "url": "https://github.com/sponsors/ljharb" 5387 + } 5388 + }, 5389 + "node_modules/array.prototype.flatmap": { 5390 + "version": "1.3.3", 5391 + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", 5392 + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", 5393 + "dev": true, 5394 + "license": "MIT", 5395 + "dependencies": { 5396 + "call-bind": "^1.0.8", 5397 + "define-properties": "^1.2.1", 5398 + "es-abstract": "^1.23.5", 5399 + "es-shim-unscopables": "^1.0.2" 5400 + }, 5401 + "engines": { 5402 + "node": ">= 0.4" 5403 + }, 5404 + "funding": { 5405 + "url": "https://github.com/sponsors/ljharb" 5406 + } 5407 + }, 5408 + "node_modules/array.prototype.tosorted": { 5409 + "version": "1.1.4", 5410 + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", 5411 + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", 5412 + "dev": true, 5413 + "license": "MIT", 5414 + "dependencies": { 5415 + "call-bind": "^1.0.7", 5416 + "define-properties": "^1.2.1", 5417 + "es-abstract": "^1.23.3", 5418 + "es-errors": "^1.3.0", 5419 + "es-shim-unscopables": "^1.0.2" 5420 + }, 5421 + "engines": { 5422 + "node": ">= 0.4" 5423 + } 5424 + }, 5425 + "node_modules/arraybuffer.prototype.slice": { 5426 + "version": "1.0.4", 5427 + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", 5428 + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", 5429 + "dev": true, 5430 + "license": "MIT", 5431 + "dependencies": { 5432 + "array-buffer-byte-length": "^1.0.1", 5433 + "call-bind": "^1.0.8", 5434 + "define-properties": "^1.2.1", 5435 + "es-abstract": "^1.23.5", 5436 + "es-errors": "^1.3.0", 5437 + "get-intrinsic": "^1.2.6", 5438 + "is-array-buffer": "^3.0.4" 5439 + }, 5440 + "engines": { 5441 + "node": ">= 0.4" 5442 + }, 5443 + "funding": { 5444 + "url": "https://github.com/sponsors/ljharb" 5445 + } 5446 + }, 2759 5447 "node_modules/assertion-error": { 2760 5448 "version": "2.0.1", 2761 5449 "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", ··· 2778 5466 "node": ">=4" 2779 5467 } 2780 5468 }, 5469 + "node_modules/async-function": { 5470 + "version": "1.0.0", 5471 + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", 5472 + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", 5473 + "dev": true, 5474 + "license": "MIT", 5475 + "engines": { 5476 + "node": ">= 0.4" 5477 + } 5478 + }, 5479 + "node_modules/available-typed-arrays": { 5480 + "version": "1.0.7", 5481 + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", 5482 + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", 5483 + "dev": true, 5484 + "license": "MIT", 5485 + "dependencies": { 5486 + "possible-typed-array-names": "^1.0.0" 5487 + }, 5488 + "engines": { 5489 + "node": ">= 0.4" 5490 + }, 5491 + "funding": { 5492 + "url": "https://github.com/sponsors/ljharb" 5493 + } 5494 + }, 2781 5495 "node_modules/await-lock": { 2782 5496 "version": "2.2.2", 2783 5497 "resolved": "https://registry.npmjs.org/await-lock/-/await-lock-2.2.2.tgz", ··· 2796 5510 "@babel/types": "^7.23.6" 2797 5511 } 2798 5512 }, 5513 + "node_modules/babel-plugin-react-compiler": { 5514 + "version": "1.0.0", 5515 + "resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-1.0.0.tgz", 5516 + "integrity": "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==", 5517 + "dev": true, 5518 + "license": "MIT", 5519 + "dependencies": { 5520 + "@babel/types": "^7.26.0" 5521 + } 5522 + }, 5523 + "node_modules/balanced-match": { 5524 + "version": "1.0.2", 5525 + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 5526 + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 5527 + "dev": true, 5528 + "license": "MIT" 5529 + }, 2799 5530 "node_modules/bcp-47": { 2800 5531 "version": "2.1.0", 2801 5532 "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-2.1.0.tgz", ··· 2847 5578 "url": "https://github.com/sponsors/sindresorhus" 2848 5579 } 2849 5580 }, 5581 + "node_modules/birecord": { 5582 + "version": "0.1.1", 5583 + "resolved": "https://registry.npmjs.org/birecord/-/birecord-0.1.1.tgz", 5584 + "integrity": "sha512-VUpsf/qykW0heRlC8LooCq28Kxn3mAqKohhDG/49rrsQ1dT1CXyj/pgXS+5BSRzFTR/3DyIBOqQOrGyZOh71Aw==", 5585 + "dev": true, 5586 + "license": "(MIT OR Apache-2.0)" 5587 + }, 5588 + "node_modules/brace-expansion": { 5589 + "version": "1.1.12", 5590 + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", 5591 + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", 5592 + "dev": true, 5593 + "license": "MIT", 5594 + "dependencies": { 5595 + "balanced-match": "^1.0.0", 5596 + "concat-map": "0.0.1" 5597 + } 5598 + }, 2850 5599 "node_modules/braces": { 2851 5600 "version": "3.0.3", 2852 5601 "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", ··· 2901 5650 "node": ">=8" 2902 5651 } 2903 5652 }, 5653 + "node_modules/call-bind": { 5654 + "version": "1.0.8", 5655 + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", 5656 + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", 5657 + "dev": true, 5658 + "license": "MIT", 5659 + "dependencies": { 5660 + "call-bind-apply-helpers": "^1.0.0", 5661 + "es-define-property": "^1.0.0", 5662 + "get-intrinsic": "^1.2.4", 5663 + "set-function-length": "^1.2.2" 5664 + }, 5665 + "engines": { 5666 + "node": ">= 0.4" 5667 + }, 5668 + "funding": { 5669 + "url": "https://github.com/sponsors/ljharb" 5670 + } 5671 + }, 5672 + "node_modules/call-bind-apply-helpers": { 5673 + "version": "1.0.2", 5674 + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", 5675 + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", 5676 + "dev": true, 5677 + "license": "MIT", 5678 + "dependencies": { 5679 + "es-errors": "^1.3.0", 5680 + "function-bind": "^1.1.2" 5681 + }, 5682 + "engines": { 5683 + "node": ">= 0.4" 5684 + } 5685 + }, 5686 + "node_modules/call-bound": { 5687 + "version": "1.0.4", 5688 + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", 5689 + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", 5690 + "dev": true, 5691 + "license": "MIT", 5692 + "dependencies": { 5693 + "call-bind-apply-helpers": "^1.0.2", 5694 + "get-intrinsic": "^1.3.0" 5695 + }, 5696 + "engines": { 5697 + "node": ">= 0.4" 5698 + }, 5699 + "funding": { 5700 + "url": "https://github.com/sponsors/ljharb" 5701 + } 5702 + }, 5703 + "node_modules/callsites": { 5704 + "version": "3.1.0", 5705 + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 5706 + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 5707 + "dev": true, 5708 + "license": "MIT", 5709 + "engines": { 5710 + "node": ">=6" 5711 + } 5712 + }, 5713 + "node_modules/camelcase": { 5714 + "version": "6.3.0", 5715 + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", 5716 + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", 5717 + "dev": true, 5718 + "license": "MIT", 5719 + "engines": { 5720 + "node": ">=10" 5721 + }, 5722 + "funding": { 5723 + "url": "https://github.com/sponsors/sindresorhus" 5724 + } 5725 + }, 2904 5726 "node_modules/caniuse-lite": { 2905 5727 "version": "1.0.30001737", 2906 5728 "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001737.tgz", ··· 2956 5778 "node": ">=18" 2957 5779 } 2958 5780 }, 5781 + "node_modules/chalk": { 5782 + "version": "4.1.2", 5783 + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 5784 + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 5785 + "dev": true, 5786 + "license": "MIT", 5787 + "peer": true, 5788 + "dependencies": { 5789 + "ansi-styles": "^4.1.0", 5790 + "supports-color": "^7.1.0" 5791 + }, 5792 + "engines": { 5793 + "node": ">=10" 5794 + }, 5795 + "funding": { 5796 + "url": "https://github.com/chalk/chalk?sponsor=1" 5797 + } 5798 + }, 5799 + "node_modules/chalk/node_modules/ansi-styles": { 5800 + "version": "4.3.0", 5801 + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 5802 + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 5803 + "dev": true, 5804 + "license": "MIT", 5805 + "peer": true, 5806 + "dependencies": { 5807 + "color-convert": "^2.0.1" 5808 + }, 5809 + "engines": { 5810 + "node": ">=8" 5811 + }, 5812 + "funding": { 5813 + "url": "https://github.com/chalk/ansi-styles?sponsor=1" 5814 + } 5815 + }, 2959 5816 "node_modules/check-error": { 2960 5817 "version": "2.1.1", 2961 5818 "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", ··· 3020 5877 "integrity": "sha512-eNk3TRV+xQMJ1PEj0FQGY8KD4m0GPxT487XJ+Iftm7mVa9WpPFDMWqPt+46buiP5j5Wzqe5oMIhqBcAeKfygSA==", 3021 5878 "license": "MIT" 3022 5879 }, 5880 + "node_modules/color-convert": { 5881 + "version": "2.0.1", 5882 + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 5883 + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 5884 + "dev": true, 5885 + "license": "MIT", 5886 + "peer": true, 5887 + "dependencies": { 5888 + "color-name": "~1.1.4" 5889 + }, 5890 + "engines": { 5891 + "node": ">=7.0.0" 5892 + } 5893 + }, 5894 + "node_modules/color-name": { 5895 + "version": "1.1.4", 5896 + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 5897 + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 5898 + "dev": true, 5899 + "license": "MIT", 5900 + "peer": true 5901 + }, 5902 + "node_modules/compare-versions": { 5903 + "version": "6.1.1", 5904 + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", 5905 + "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==", 5906 + "dev": true, 5907 + "license": "MIT" 5908 + }, 5909 + "node_modules/concat-map": { 5910 + "version": "0.0.1", 5911 + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 5912 + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 5913 + "dev": true, 5914 + "license": "MIT" 5915 + }, 5916 + "node_modules/confbox": { 5917 + "version": "0.2.2", 5918 + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", 5919 + "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", 5920 + "dev": true, 5921 + "license": "MIT" 5922 + }, 3023 5923 "node_modules/convert-source-map": { 3024 5924 "version": "2.0.0", 3025 5925 "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", ··· 3043 5943 "url": "https://opencollective.com/core-js" 3044 5944 } 3045 5945 }, 5946 + "node_modules/cosmiconfig": { 5947 + "version": "8.3.6", 5948 + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", 5949 + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", 5950 + "dev": true, 5951 + "license": "MIT", 5952 + "dependencies": { 5953 + "import-fresh": "^3.3.0", 5954 + "js-yaml": "^4.1.0", 5955 + "parse-json": "^5.2.0", 5956 + "path-type": "^4.0.0" 5957 + }, 5958 + "engines": { 5959 + "node": ">=14" 5960 + }, 5961 + "funding": { 5962 + "url": "https://github.com/sponsors/d-fischer" 5963 + }, 5964 + "peerDependencies": { 5965 + "typescript": ">=4.9.5" 5966 + }, 5967 + "peerDependenciesMeta": { 5968 + "typescript": { 5969 + "optional": true 5970 + } 5971 + } 5972 + }, 5973 + "node_modules/cross-spawn": { 5974 + "version": "7.0.6", 5975 + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", 5976 + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", 5977 + "dev": true, 5978 + "license": "MIT", 5979 + "peer": true, 5980 + "dependencies": { 5981 + "path-key": "^3.1.0", 5982 + "shebang-command": "^2.0.0", 5983 + "which": "^2.0.1" 5984 + }, 5985 + "engines": { 5986 + "node": ">= 8" 5987 + } 5988 + }, 3046 5989 "node_modules/cssstyle": { 3047 5990 "version": "4.6.0", 3048 5991 "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", ··· 3111 6054 "node": ">=18" 3112 6055 } 3113 6056 }, 6057 + "node_modules/data-view-buffer": { 6058 + "version": "1.0.2", 6059 + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", 6060 + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", 6061 + "dev": true, 6062 + "license": "MIT", 6063 + "dependencies": { 6064 + "call-bound": "^1.0.3", 6065 + "es-errors": "^1.3.0", 6066 + "is-data-view": "^1.0.2" 6067 + }, 6068 + "engines": { 6069 + "node": ">= 0.4" 6070 + }, 6071 + "funding": { 6072 + "url": "https://github.com/sponsors/ljharb" 6073 + } 6074 + }, 6075 + "node_modules/data-view-byte-length": { 6076 + "version": "1.0.2", 6077 + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", 6078 + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", 6079 + "dev": true, 6080 + "license": "MIT", 6081 + "dependencies": { 6082 + "call-bound": "^1.0.3", 6083 + "es-errors": "^1.3.0", 6084 + "is-data-view": "^1.0.2" 6085 + }, 6086 + "engines": { 6087 + "node": ">= 0.4" 6088 + }, 6089 + "funding": { 6090 + "url": "https://github.com/sponsors/inspect-js" 6091 + } 6092 + }, 6093 + "node_modules/data-view-byte-offset": { 6094 + "version": "1.0.1", 6095 + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", 6096 + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", 6097 + "dev": true, 6098 + "license": "MIT", 6099 + "dependencies": { 6100 + "call-bound": "^1.0.2", 6101 + "es-errors": "^1.3.0", 6102 + "is-data-view": "^1.0.1" 6103 + }, 6104 + "engines": { 6105 + "node": ">= 0.4" 6106 + }, 6107 + "funding": { 6108 + "url": "https://github.com/sponsors/ljharb" 6109 + } 6110 + }, 3114 6111 "node_modules/debug": { 3115 - "version": "4.4.1", 3116 - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", 3117 - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", 6112 + "version": "4.4.3", 6113 + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", 6114 + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", 3118 6115 "license": "MIT", 3119 6116 "dependencies": { 3120 6117 "ms": "^2.1.3" ··· 3145 6142 "node": ">=6" 3146 6143 } 3147 6144 }, 6145 + "node_modules/deep-is": { 6146 + "version": "0.1.4", 6147 + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 6148 + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", 6149 + "dev": true, 6150 + "license": "MIT", 6151 + "peer": true 6152 + }, 6153 + "node_modules/define-data-property": { 6154 + "version": "1.1.4", 6155 + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", 6156 + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", 6157 + "dev": true, 6158 + "license": "MIT", 6159 + "dependencies": { 6160 + "es-define-property": "^1.0.0", 6161 + "es-errors": "^1.3.0", 6162 + "gopd": "^1.0.1" 6163 + }, 6164 + "engines": { 6165 + "node": ">= 0.4" 6166 + }, 6167 + "funding": { 6168 + "url": "https://github.com/sponsors/ljharb" 6169 + } 6170 + }, 6171 + "node_modules/define-properties": { 6172 + "version": "1.2.1", 6173 + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", 6174 + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", 6175 + "dev": true, 6176 + "license": "MIT", 6177 + "dependencies": { 6178 + "define-data-property": "^1.0.1", 6179 + "has-property-descriptors": "^1.0.0", 6180 + "object-keys": "^1.1.1" 6181 + }, 6182 + "engines": { 6183 + "node": ">= 0.4" 6184 + }, 6185 + "funding": { 6186 + "url": "https://github.com/sponsors/ljharb" 6187 + } 6188 + }, 3148 6189 "node_modules/dequal": { 3149 6190 "version": "2.0.3", 3150 6191 "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", ··· 3164 6205 "node": ">=8" 3165 6206 } 3166 6207 }, 6208 + "node_modules/detect-node-es": { 6209 + "version": "1.1.0", 6210 + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", 6211 + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" 6212 + }, 3167 6213 "node_modules/diff": { 3168 6214 "version": "8.0.2", 3169 6215 "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.2.tgz", ··· 3173 6219 "node": ">=0.3.1" 3174 6220 } 3175 6221 }, 6222 + "node_modules/doctrine": { 6223 + "version": "2.1.0", 6224 + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", 6225 + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", 6226 + "dev": true, 6227 + "license": "Apache-2.0", 6228 + "dependencies": { 6229 + "esutils": "^2.0.2" 6230 + }, 6231 + "engines": { 6232 + "node": ">=0.10.0" 6233 + } 6234 + }, 3176 6235 "node_modules/dom-accessibility-api": { 3177 6236 "version": "0.5.16", 3178 6237 "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", ··· 3180 6239 "dev": true, 3181 6240 "license": "MIT" 3182 6241 }, 6242 + "node_modules/dompurify": { 6243 + "version": "3.3.0", 6244 + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.0.tgz", 6245 + "integrity": "sha512-r+f6MYR1gGN1eJv0TVQbhA7if/U7P87cdPl3HN5rikqaBSBxLiCb/b9O+2eG0cxz0ghyU+mU1QkbsOwERMYlWQ==", 6246 + "license": "(MPL-2.0 OR Apache-2.0)", 6247 + "optionalDependencies": { 6248 + "@types/trusted-types": "^2.0.7" 6249 + } 6250 + }, 6251 + "node_modules/dot-case": { 6252 + "version": "3.0.4", 6253 + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", 6254 + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", 6255 + "dev": true, 6256 + "license": "MIT", 6257 + "dependencies": { 6258 + "no-case": "^3.0.4", 6259 + "tslib": "^2.0.3" 6260 + } 6261 + }, 6262 + "node_modules/dunder-proto": { 6263 + "version": "1.0.1", 6264 + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", 6265 + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", 6266 + "dev": true, 6267 + "license": "MIT", 6268 + "dependencies": { 6269 + "call-bind-apply-helpers": "^1.0.1", 6270 + "es-errors": "^1.3.0", 6271 + "gopd": "^1.2.0" 6272 + }, 6273 + "engines": { 6274 + "node": ">= 0.4" 6275 + } 6276 + }, 3183 6277 "node_modules/electron-to-chromium": { 3184 6278 "version": "1.5.211", 3185 6279 "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.211.tgz", ··· 3212 6306 "url": "https://github.com/fb55/entities?sponsor=1" 3213 6307 } 3214 6308 }, 6309 + "node_modules/error-ex": { 6310 + "version": "1.3.4", 6311 + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", 6312 + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", 6313 + "dev": true, 6314 + "license": "MIT", 6315 + "dependencies": { 6316 + "is-arrayish": "^0.2.1" 6317 + } 6318 + }, 6319 + "node_modules/es-abstract": { 6320 + "version": "1.24.0", 6321 + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", 6322 + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", 6323 + "dev": true, 6324 + "license": "MIT", 6325 + "dependencies": { 6326 + "array-buffer-byte-length": "^1.0.2", 6327 + "arraybuffer.prototype.slice": "^1.0.4", 6328 + "available-typed-arrays": "^1.0.7", 6329 + "call-bind": "^1.0.8", 6330 + "call-bound": "^1.0.4", 6331 + "data-view-buffer": "^1.0.2", 6332 + "data-view-byte-length": "^1.0.2", 6333 + "data-view-byte-offset": "^1.0.1", 6334 + "es-define-property": "^1.0.1", 6335 + "es-errors": "^1.3.0", 6336 + "es-object-atoms": "^1.1.1", 6337 + "es-set-tostringtag": "^2.1.0", 6338 + "es-to-primitive": "^1.3.0", 6339 + "function.prototype.name": "^1.1.8", 6340 + "get-intrinsic": "^1.3.0", 6341 + "get-proto": "^1.0.1", 6342 + "get-symbol-description": "^1.1.0", 6343 + "globalthis": "^1.0.4", 6344 + "gopd": "^1.2.0", 6345 + "has-property-descriptors": "^1.0.2", 6346 + "has-proto": "^1.2.0", 6347 + "has-symbols": "^1.1.0", 6348 + "hasown": "^2.0.2", 6349 + "internal-slot": "^1.1.0", 6350 + "is-array-buffer": "^3.0.5", 6351 + "is-callable": "^1.2.7", 6352 + "is-data-view": "^1.0.2", 6353 + "is-negative-zero": "^2.0.3", 6354 + "is-regex": "^1.2.1", 6355 + "is-set": "^2.0.3", 6356 + "is-shared-array-buffer": "^1.0.4", 6357 + "is-string": "^1.1.1", 6358 + "is-typed-array": "^1.1.15", 6359 + "is-weakref": "^1.1.1", 6360 + "math-intrinsics": "^1.1.0", 6361 + "object-inspect": "^1.13.4", 6362 + "object-keys": "^1.1.1", 6363 + "object.assign": "^4.1.7", 6364 + "own-keys": "^1.0.1", 6365 + "regexp.prototype.flags": "^1.5.4", 6366 + "safe-array-concat": "^1.1.3", 6367 + "safe-push-apply": "^1.0.0", 6368 + "safe-regex-test": "^1.1.0", 6369 + "set-proto": "^1.0.0", 6370 + "stop-iteration-iterator": "^1.1.0", 6371 + "string.prototype.trim": "^1.2.10", 6372 + "string.prototype.trimend": "^1.0.9", 6373 + "string.prototype.trimstart": "^1.0.8", 6374 + "typed-array-buffer": "^1.0.3", 6375 + "typed-array-byte-length": "^1.0.3", 6376 + "typed-array-byte-offset": "^1.0.4", 6377 + "typed-array-length": "^1.0.7", 6378 + "unbox-primitive": "^1.1.0", 6379 + "which-typed-array": "^1.1.19" 6380 + }, 6381 + "engines": { 6382 + "node": ">= 0.4" 6383 + }, 6384 + "funding": { 6385 + "url": "https://github.com/sponsors/ljharb" 6386 + } 6387 + }, 6388 + "node_modules/es-define-property": { 6389 + "version": "1.0.1", 6390 + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", 6391 + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", 6392 + "dev": true, 6393 + "license": "MIT", 6394 + "engines": { 6395 + "node": ">= 0.4" 6396 + } 6397 + }, 6398 + "node_modules/es-errors": { 6399 + "version": "1.3.0", 6400 + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", 6401 + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", 6402 + "dev": true, 6403 + "license": "MIT", 6404 + "engines": { 6405 + "node": ">= 0.4" 6406 + } 6407 + }, 6408 + "node_modules/es-iterator-helpers": { 6409 + "version": "1.2.1", 6410 + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", 6411 + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", 6412 + "dev": true, 6413 + "license": "MIT", 6414 + "dependencies": { 6415 + "call-bind": "^1.0.8", 6416 + "call-bound": "^1.0.3", 6417 + "define-properties": "^1.2.1", 6418 + "es-abstract": "^1.23.6", 6419 + "es-errors": "^1.3.0", 6420 + "es-set-tostringtag": "^2.0.3", 6421 + "function-bind": "^1.1.2", 6422 + "get-intrinsic": "^1.2.6", 6423 + "globalthis": "^1.0.4", 6424 + "gopd": "^1.2.0", 6425 + "has-property-descriptors": "^1.0.2", 6426 + "has-proto": "^1.2.0", 6427 + "has-symbols": "^1.1.0", 6428 + "internal-slot": "^1.1.0", 6429 + "iterator.prototype": "^1.1.4", 6430 + "safe-array-concat": "^1.1.3" 6431 + }, 6432 + "engines": { 6433 + "node": ">= 0.4" 6434 + } 6435 + }, 3215 6436 "node_modules/es-module-lexer": { 3216 6437 "version": "1.7.0", 3217 6438 "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", ··· 3219 6440 "dev": true, 3220 6441 "license": "MIT" 3221 6442 }, 6443 + "node_modules/es-object-atoms": { 6444 + "version": "1.1.1", 6445 + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", 6446 + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", 6447 + "dev": true, 6448 + "license": "MIT", 6449 + "dependencies": { 6450 + "es-errors": "^1.3.0" 6451 + }, 6452 + "engines": { 6453 + "node": ">= 0.4" 6454 + } 6455 + }, 6456 + "node_modules/es-set-tostringtag": { 6457 + "version": "2.1.0", 6458 + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", 6459 + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", 6460 + "dev": true, 6461 + "license": "MIT", 6462 + "dependencies": { 6463 + "es-errors": "^1.3.0", 6464 + "get-intrinsic": "^1.2.6", 6465 + "has-tostringtag": "^1.0.2", 6466 + "hasown": "^2.0.2" 6467 + }, 6468 + "engines": { 6469 + "node": ">= 0.4" 6470 + } 6471 + }, 6472 + "node_modules/es-shim-unscopables": { 6473 + "version": "1.1.0", 6474 + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", 6475 + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", 6476 + "dev": true, 6477 + "license": "MIT", 6478 + "dependencies": { 6479 + "hasown": "^2.0.2" 6480 + }, 6481 + "engines": { 6482 + "node": ">= 0.4" 6483 + } 6484 + }, 6485 + "node_modules/es-to-primitive": { 6486 + "version": "1.3.0", 6487 + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", 6488 + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", 6489 + "dev": true, 6490 + "license": "MIT", 6491 + "dependencies": { 6492 + "is-callable": "^1.2.7", 6493 + "is-date-object": "^1.0.5", 6494 + "is-symbol": "^1.0.4" 6495 + }, 6496 + "engines": { 6497 + "node": ">= 0.4" 6498 + }, 6499 + "funding": { 6500 + "url": "https://github.com/sponsors/ljharb" 6501 + } 6502 + }, 3222 6503 "node_modules/esbuild": { 3223 6504 "version": "0.25.9", 3224 6505 "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz", ··· 3269 6550 "node": ">=6" 3270 6551 } 3271 6552 }, 6553 + "node_modules/escape-string-regexp": { 6554 + "version": "4.0.0", 6555 + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 6556 + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 6557 + "dev": true, 6558 + "license": "MIT", 6559 + "peer": true, 6560 + "engines": { 6561 + "node": ">=10" 6562 + }, 6563 + "funding": { 6564 + "url": "https://github.com/sponsors/sindresorhus" 6565 + } 6566 + }, 6567 + "node_modules/eslint": { 6568 + "version": "9.37.0", 6569 + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.37.0.tgz", 6570 + "integrity": "sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig==", 6571 + "dev": true, 6572 + "license": "MIT", 6573 + "peer": true, 6574 + "dependencies": { 6575 + "@eslint-community/eslint-utils": "^4.8.0", 6576 + "@eslint-community/regexpp": "^4.12.1", 6577 + "@eslint/config-array": "^0.21.0", 6578 + "@eslint/config-helpers": "^0.4.0", 6579 + "@eslint/core": "^0.16.0", 6580 + "@eslint/eslintrc": "^3.3.1", 6581 + "@eslint/js": "9.37.0", 6582 + "@eslint/plugin-kit": "^0.4.0", 6583 + "@humanfs/node": "^0.16.6", 6584 + "@humanwhocodes/module-importer": "^1.0.1", 6585 + "@humanwhocodes/retry": "^0.4.2", 6586 + "@types/estree": "^1.0.6", 6587 + "@types/json-schema": "^7.0.15", 6588 + "ajv": "^6.12.4", 6589 + "chalk": "^4.0.0", 6590 + "cross-spawn": "^7.0.6", 6591 + "debug": "^4.3.2", 6592 + "escape-string-regexp": "^4.0.0", 6593 + "eslint-scope": "^8.4.0", 6594 + "eslint-visitor-keys": "^4.2.1", 6595 + "espree": "^10.4.0", 6596 + "esquery": "^1.5.0", 6597 + "esutils": "^2.0.2", 6598 + "fast-deep-equal": "^3.1.3", 6599 + "file-entry-cache": "^8.0.0", 6600 + "find-up": "^5.0.0", 6601 + "glob-parent": "^6.0.2", 6602 + "ignore": "^5.2.0", 6603 + "imurmurhash": "^0.1.4", 6604 + "is-glob": "^4.0.0", 6605 + "json-stable-stringify-without-jsonify": "^1.0.1", 6606 + "lodash.merge": "^4.6.2", 6607 + "minimatch": "^3.1.2", 6608 + "natural-compare": "^1.4.0", 6609 + "optionator": "^0.9.3" 6610 + }, 6611 + "bin": { 6612 + "eslint": "bin/eslint.js" 6613 + }, 6614 + "engines": { 6615 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 6616 + }, 6617 + "funding": { 6618 + "url": "https://eslint.org/donate" 6619 + }, 6620 + "peerDependencies": { 6621 + "jiti": "*" 6622 + }, 6623 + "peerDependenciesMeta": { 6624 + "jiti": { 6625 + "optional": true 6626 + } 6627 + } 6628 + }, 6629 + "node_modules/eslint-plugin-react": { 6630 + "version": "7.37.5", 6631 + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", 6632 + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", 6633 + "dev": true, 6634 + "license": "MIT", 6635 + "dependencies": { 6636 + "array-includes": "^3.1.8", 6637 + "array.prototype.findlast": "^1.2.5", 6638 + "array.prototype.flatmap": "^1.3.3", 6639 + "array.prototype.tosorted": "^1.1.4", 6640 + "doctrine": "^2.1.0", 6641 + "es-iterator-helpers": "^1.2.1", 6642 + "estraverse": "^5.3.0", 6643 + "hasown": "^2.0.2", 6644 + "jsx-ast-utils": "^2.4.1 || ^3.0.0", 6645 + "minimatch": "^3.1.2", 6646 + "object.entries": "^1.1.9", 6647 + "object.fromentries": "^2.0.8", 6648 + "object.values": "^1.2.1", 6649 + "prop-types": "^15.8.1", 6650 + "resolve": "^2.0.0-next.5", 6651 + "semver": "^6.3.1", 6652 + "string.prototype.matchall": "^4.0.12", 6653 + "string.prototype.repeat": "^1.0.0" 6654 + }, 6655 + "engines": { 6656 + "node": ">=4" 6657 + }, 6658 + "peerDependencies": { 6659 + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" 6660 + } 6661 + }, 6662 + "node_modules/eslint-plugin-react-dom": { 6663 + "version": "2.2.1", 6664 + "resolved": "https://registry.npmjs.org/eslint-plugin-react-dom/-/eslint-plugin-react-dom-2.2.1.tgz", 6665 + "integrity": "sha512-g6B4yTLHWhgqu3mN0kUJvrQp285uFMQYXzWVAIBqziV6n93sgPH8Eb8ht3gTzRUfA9Rt3JQr8QaxBxpfSkp67w==", 6666 + "dev": true, 6667 + "license": "MIT", 6668 + "dependencies": { 6669 + "@eslint-react/ast": "2.2.1", 6670 + "@eslint-react/core": "2.2.1", 6671 + "@eslint-react/eff": "2.2.1", 6672 + "@eslint-react/shared": "2.2.1", 6673 + "@eslint-react/var": "2.2.1", 6674 + "@typescript-eslint/scope-manager": "^8.46.0", 6675 + "@typescript-eslint/types": "^8.46.0", 6676 + "@typescript-eslint/utils": "^8.46.0", 6677 + "compare-versions": "^6.1.1", 6678 + "string-ts": "^2.2.1", 6679 + "ts-pattern": "^5.8.0" 6680 + }, 6681 + "engines": { 6682 + "node": ">=20.19.0" 6683 + }, 6684 + "peerDependencies": { 6685 + "eslint": "^9.37.0", 6686 + "typescript": "^5.9.3" 6687 + } 6688 + }, 6689 + "node_modules/eslint-plugin-react-hooks": { 6690 + "version": "7.0.0", 6691 + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.0.0.tgz", 6692 + "integrity": "sha512-fNXaOwvKwq2+pXiRpXc825Vd63+KM4DLL40Rtlycb8m7fYpp6efrTp1sa6ZbP/Ap58K2bEKFXRmhURE+CJAQWw==", 6693 + "dev": true, 6694 + "license": "MIT", 6695 + "dependencies": { 6696 + "@babel/core": "^7.24.4", 6697 + "@babel/parser": "^7.24.4", 6698 + "hermes-parser": "^0.25.1", 6699 + "zod": "^3.22.4 || ^4.0.0", 6700 + "zod-validation-error": "^3.0.3 || ^4.0.0" 6701 + }, 6702 + "engines": { 6703 + "node": ">=18" 6704 + }, 6705 + "peerDependencies": { 6706 + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" 6707 + } 6708 + }, 6709 + "node_modules/eslint-plugin-react-hooks-extra": { 6710 + "version": "2.2.1", 6711 + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks-extra/-/eslint-plugin-react-hooks-extra-2.2.1.tgz", 6712 + "integrity": "sha512-MfUbjKIEhF0qEpfXIPgcmmteCx5h9lMuuMGLaau4KmOKh3vewj6DW/JubVuhQ+7eaHqpuCz8/0uBH0k2lfavjg==", 6713 + "dev": true, 6714 + "license": "MIT", 6715 + "dependencies": { 6716 + "@eslint-react/ast": "2.2.1", 6717 + "@eslint-react/core": "2.2.1", 6718 + "@eslint-react/eff": "2.2.1", 6719 + "@eslint-react/shared": "2.2.1", 6720 + "@eslint-react/var": "2.2.1", 6721 + "@typescript-eslint/scope-manager": "^8.46.0", 6722 + "@typescript-eslint/type-utils": "^8.46.0", 6723 + "@typescript-eslint/types": "^8.46.0", 6724 + "@typescript-eslint/utils": "^8.46.0", 6725 + "string-ts": "^2.2.1", 6726 + "ts-pattern": "^5.8.0" 6727 + }, 6728 + "engines": { 6729 + "node": ">=20.0.0" 6730 + }, 6731 + "peerDependencies": { 6732 + "eslint": "^9.37.0", 6733 + "typescript": "^5.9.3" 6734 + } 6735 + }, 6736 + "node_modules/eslint-plugin-react-naming-convention": { 6737 + "version": "2.2.1", 6738 + "resolved": "https://registry.npmjs.org/eslint-plugin-react-naming-convention/-/eslint-plugin-react-naming-convention-2.2.1.tgz", 6739 + "integrity": "sha512-yjNfzPmYAJDFp7yZ4BkmwBRmK3mAGYGXFDyb5Ws2vZBj6R8BKbh5Ao/Chmemo/LmW7a2IoySICuBp6wxuBC9Yg==", 6740 + "dev": true, 6741 + "license": "MIT", 6742 + "dependencies": { 6743 + "@eslint-react/ast": "2.2.1", 6744 + "@eslint-react/core": "2.2.1", 6745 + "@eslint-react/eff": "2.2.1", 6746 + "@eslint-react/shared": "2.2.1", 6747 + "@eslint-react/var": "2.2.1", 6748 + "@typescript-eslint/scope-manager": "^8.46.0", 6749 + "@typescript-eslint/type-utils": "^8.46.0", 6750 + "@typescript-eslint/types": "^8.46.0", 6751 + "@typescript-eslint/utils": "^8.46.0", 6752 + "string-ts": "^2.2.1", 6753 + "ts-pattern": "^5.8.0" 6754 + }, 6755 + "engines": { 6756 + "node": ">=20.19.0" 6757 + }, 6758 + "peerDependencies": { 6759 + "eslint": "^9.37.0", 6760 + "typescript": "^5.9.3" 6761 + } 6762 + }, 6763 + "node_modules/eslint-plugin-react-web-api": { 6764 + "version": "2.2.1", 6765 + "resolved": "https://registry.npmjs.org/eslint-plugin-react-web-api/-/eslint-plugin-react-web-api-2.2.1.tgz", 6766 + "integrity": "sha512-JGRufRDJ8rmckQ82R+3kKhl9ybVeCjRt8fo8/IvxCQJukyyL4Y5b+mOwnPTRDJLQMeDzql4VDeeLegcjweTmAw==", 6767 + "dev": true, 6768 + "license": "MIT", 6769 + "dependencies": { 6770 + "@eslint-react/ast": "2.2.1", 6771 + "@eslint-react/core": "2.2.1", 6772 + "@eslint-react/eff": "2.2.1", 6773 + "@eslint-react/shared": "2.2.1", 6774 + "@eslint-react/var": "2.2.1", 6775 + "@typescript-eslint/scope-manager": "^8.46.0", 6776 + "@typescript-eslint/types": "^8.46.0", 6777 + "@typescript-eslint/utils": "^8.46.0", 6778 + "string-ts": "^2.2.1", 6779 + "ts-pattern": "^5.8.0" 6780 + }, 6781 + "engines": { 6782 + "node": ">=20.19.0" 6783 + }, 6784 + "peerDependencies": { 6785 + "eslint": "^9.37.0", 6786 + "typescript": "^5.9.3" 6787 + } 6788 + }, 6789 + "node_modules/eslint-plugin-react-x": { 6790 + "version": "2.2.1", 6791 + "resolved": "https://registry.npmjs.org/eslint-plugin-react-x/-/eslint-plugin-react-x-2.2.1.tgz", 6792 + "integrity": "sha512-Bz5MoLgimALqiJ5O7/KQ/JhZ7AC24qILvA7KHsjT5n0XEQKrktGKGZEm4AKiKsTmboAitpVbHDB9kGpwXIrFXw==", 6793 + "dev": true, 6794 + "license": "MIT", 6795 + "dependencies": { 6796 + "@eslint-react/ast": "2.2.1", 6797 + "@eslint-react/core": "2.2.1", 6798 + "@eslint-react/eff": "2.2.1", 6799 + "@eslint-react/shared": "2.2.1", 6800 + "@eslint-react/var": "2.2.1", 6801 + "@typescript-eslint/scope-manager": "^8.46.0", 6802 + "@typescript-eslint/type-utils": "^8.46.0", 6803 + "@typescript-eslint/types": "^8.46.0", 6804 + "@typescript-eslint/utils": "^8.46.0", 6805 + "compare-versions": "^6.1.1", 6806 + "is-immutable-type": "^5.0.1", 6807 + "string-ts": "^2.2.1", 6808 + "ts-api-utils": "^2.1.0", 6809 + "ts-pattern": "^5.8.0" 6810 + }, 6811 + "engines": { 6812 + "node": ">=20.19.0" 6813 + }, 6814 + "peerDependencies": { 6815 + "eslint": "^9.37.0", 6816 + "typescript": "^5.9.3" 6817 + } 6818 + }, 6819 + "node_modules/eslint-plugin-simple-import-sort": { 6820 + "version": "12.1.1", 6821 + "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.1.tgz", 6822 + "integrity": "sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==", 6823 + "dev": true, 6824 + "license": "MIT", 6825 + "peerDependencies": { 6826 + "eslint": ">=5.0.0" 6827 + } 6828 + }, 6829 + "node_modules/eslint-plugin-unused-imports": { 6830 + "version": "4.2.0", 6831 + "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.2.0.tgz", 6832 + "integrity": "sha512-hLbJ2/wnjKq4kGA9AUaExVFIbNzyxYdVo49QZmKCnhk5pc9wcYRbfgLHvWJ8tnsdcseGhoUAddm9gn/lt+d74w==", 6833 + "dev": true, 6834 + "license": "MIT", 6835 + "peerDependencies": { 6836 + "@typescript-eslint/eslint-plugin": "^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0", 6837 + "eslint": "^9.0.0 || ^8.0.0" 6838 + }, 6839 + "peerDependenciesMeta": { 6840 + "@typescript-eslint/eslint-plugin": { 6841 + "optional": true 6842 + } 6843 + } 6844 + }, 6845 + "node_modules/eslint-scope": { 6846 + "version": "8.4.0", 6847 + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", 6848 + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", 6849 + "dev": true, 6850 + "license": "BSD-2-Clause", 6851 + "peer": true, 6852 + "dependencies": { 6853 + "esrecurse": "^4.3.0", 6854 + "estraverse": "^5.2.0" 6855 + }, 6856 + "engines": { 6857 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 6858 + }, 6859 + "funding": { 6860 + "url": "https://opencollective.com/eslint" 6861 + } 6862 + }, 6863 + "node_modules/eslint-visitor-keys": { 6864 + "version": "4.2.1", 6865 + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", 6866 + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", 6867 + "dev": true, 6868 + "license": "Apache-2.0", 6869 + "engines": { 6870 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 6871 + }, 6872 + "funding": { 6873 + "url": "https://opencollective.com/eslint" 6874 + } 6875 + }, 6876 + "node_modules/eslint/node_modules/glob-parent": { 6877 + "version": "6.0.2", 6878 + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 6879 + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 6880 + "dev": true, 6881 + "license": "ISC", 6882 + "peer": true, 6883 + "dependencies": { 6884 + "is-glob": "^4.0.3" 6885 + }, 6886 + "engines": { 6887 + "node": ">=10.13.0" 6888 + } 6889 + }, 6890 + "node_modules/espree": { 6891 + "version": "10.4.0", 6892 + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", 6893 + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", 6894 + "dev": true, 6895 + "license": "BSD-2-Clause", 6896 + "peer": true, 6897 + "dependencies": { 6898 + "acorn": "^8.15.0", 6899 + "acorn-jsx": "^5.3.2", 6900 + "eslint-visitor-keys": "^4.2.1" 6901 + }, 6902 + "engines": { 6903 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 6904 + }, 6905 + "funding": { 6906 + "url": "https://opencollective.com/eslint" 6907 + } 6908 + }, 3272 6909 "node_modules/esprima": { 3273 6910 "version": "4.0.1", 3274 6911 "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", ··· 3282 6919 "node": ">=4" 3283 6920 } 3284 6921 }, 6922 + "node_modules/esquery": { 6923 + "version": "1.6.0", 6924 + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", 6925 + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", 6926 + "dev": true, 6927 + "license": "BSD-3-Clause", 6928 + "peer": true, 6929 + "dependencies": { 6930 + "estraverse": "^5.1.0" 6931 + }, 6932 + "engines": { 6933 + "node": ">=0.10" 6934 + } 6935 + }, 6936 + "node_modules/esrecurse": { 6937 + "version": "4.3.0", 6938 + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 6939 + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 6940 + "dev": true, 6941 + "license": "BSD-2-Clause", 6942 + "peer": true, 6943 + "dependencies": { 6944 + "estraverse": "^5.2.0" 6945 + }, 6946 + "engines": { 6947 + "node": ">=4.0" 6948 + } 6949 + }, 6950 + "node_modules/estraverse": { 6951 + "version": "5.3.0", 6952 + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 6953 + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 6954 + "dev": true, 6955 + "license": "BSD-2-Clause", 6956 + "engines": { 6957 + "node": ">=4.0" 6958 + } 6959 + }, 3285 6960 "node_modules/estree-walker": { 3286 6961 "version": "3.0.3", 3287 6962 "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", ··· 3292 6967 "@types/estree": "^1.0.0" 3293 6968 } 3294 6969 }, 6970 + "node_modules/esutils": { 6971 + "version": "2.0.3", 6972 + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 6973 + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 6974 + "dev": true, 6975 + "license": "BSD-2-Clause", 6976 + "engines": { 6977 + "node": ">=0.10.0" 6978 + } 6979 + }, 6980 + "node_modules/eventemitter3": { 6981 + "version": "5.0.1", 6982 + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", 6983 + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", 6984 + "license": "MIT" 6985 + }, 3295 6986 "node_modules/expect-type": { 3296 6987 "version": "1.2.2", 3297 6988 "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", ··· 3302 6993 "node": ">=12.0.0" 3303 6994 } 3304 6995 }, 6996 + "node_modules/exsolve": { 6997 + "version": "1.0.7", 6998 + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz", 6999 + "integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==", 7000 + "dev": true, 7001 + "license": "MIT" 7002 + }, 3305 7003 "node_modules/fast-deep-equal": { 3306 7004 "version": "3.1.3", 3307 7005 "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 3308 7006 "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 3309 7007 "license": "MIT" 3310 7008 }, 7009 + "node_modules/fast-glob": { 7010 + "version": "3.3.3", 7011 + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", 7012 + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", 7013 + "dev": true, 7014 + "license": "MIT", 7015 + "dependencies": { 7016 + "@nodelib/fs.stat": "^2.0.2", 7017 + "@nodelib/fs.walk": "^1.2.3", 7018 + "glob-parent": "^5.1.2", 7019 + "merge2": "^1.3.0", 7020 + "micromatch": "^4.0.8" 7021 + }, 7022 + "engines": { 7023 + "node": ">=8.6.0" 7024 + } 7025 + }, 7026 + "node_modules/fast-json-stable-stringify": { 7027 + "version": "2.1.0", 7028 + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 7029 + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 7030 + "dev": true, 7031 + "license": "MIT", 7032 + "peer": true 7033 + }, 7034 + "node_modules/fast-levenshtein": { 7035 + "version": "2.0.6", 7036 + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 7037 + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", 7038 + "dev": true, 7039 + "license": "MIT", 7040 + "peer": true 7041 + }, 7042 + "node_modules/fastq": { 7043 + "version": "1.19.1", 7044 + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", 7045 + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", 7046 + "dev": true, 7047 + "license": "ISC", 7048 + "dependencies": { 7049 + "reusify": "^1.0.4" 7050 + } 7051 + }, 7052 + "node_modules/file-entry-cache": { 7053 + "version": "8.0.0", 7054 + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", 7055 + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", 7056 + "dev": true, 7057 + "license": "MIT", 7058 + "peer": true, 7059 + "dependencies": { 7060 + "flat-cache": "^4.0.0" 7061 + }, 7062 + "engines": { 7063 + "node": ">=16.0.0" 7064 + } 7065 + }, 3311 7066 "node_modules/fill-range": { 3312 7067 "version": "7.1.1", 3313 7068 "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", ··· 3320 7075 "node": ">=8" 3321 7076 } 3322 7077 }, 7078 + "node_modules/find-up": { 7079 + "version": "5.0.0", 7080 + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 7081 + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 7082 + "dev": true, 7083 + "license": "MIT", 7084 + "peer": true, 7085 + "dependencies": { 7086 + "locate-path": "^6.0.0", 7087 + "path-exists": "^4.0.0" 7088 + }, 7089 + "engines": { 7090 + "node": ">=10" 7091 + }, 7092 + "funding": { 7093 + "url": "https://github.com/sponsors/sindresorhus" 7094 + } 7095 + }, 7096 + "node_modules/flat-cache": { 7097 + "version": "4.0.1", 7098 + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", 7099 + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", 7100 + "dev": true, 7101 + "license": "MIT", 7102 + "peer": true, 7103 + "dependencies": { 7104 + "flatted": "^3.2.9", 7105 + "keyv": "^4.5.4" 7106 + }, 7107 + "engines": { 7108 + "node": ">=16" 7109 + } 7110 + }, 7111 + "node_modules/flatted": { 7112 + "version": "3.3.3", 7113 + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", 7114 + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", 7115 + "dev": true, 7116 + "license": "ISC", 7117 + "peer": true 7118 + }, 7119 + "node_modules/for-each": { 7120 + "version": "0.3.5", 7121 + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", 7122 + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", 7123 + "dev": true, 7124 + "license": "MIT", 7125 + "dependencies": { 7126 + "is-callable": "^1.2.7" 7127 + }, 7128 + "engines": { 7129 + "node": ">= 0.4" 7130 + }, 7131 + "funding": { 7132 + "url": "https://github.com/sponsors/ljharb" 7133 + } 7134 + }, 3323 7135 "node_modules/fsevents": { 3324 7136 "version": "2.3.3", 3325 7137 "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", ··· 3334 7146 "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 3335 7147 } 3336 7148 }, 7149 + "node_modules/function-bind": { 7150 + "version": "1.1.2", 7151 + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 7152 + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 7153 + "dev": true, 7154 + "license": "MIT", 7155 + "funding": { 7156 + "url": "https://github.com/sponsors/ljharb" 7157 + } 7158 + }, 7159 + "node_modules/function.prototype.name": { 7160 + "version": "1.1.8", 7161 + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", 7162 + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", 7163 + "dev": true, 7164 + "license": "MIT", 7165 + "dependencies": { 7166 + "call-bind": "^1.0.8", 7167 + "call-bound": "^1.0.3", 7168 + "define-properties": "^1.2.1", 7169 + "functions-have-names": "^1.2.3", 7170 + "hasown": "^2.0.2", 7171 + "is-callable": "^1.2.7" 7172 + }, 7173 + "engines": { 7174 + "node": ">= 0.4" 7175 + }, 7176 + "funding": { 7177 + "url": "https://github.com/sponsors/ljharb" 7178 + } 7179 + }, 7180 + "node_modules/functions-have-names": { 7181 + "version": "1.2.3", 7182 + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", 7183 + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", 7184 + "dev": true, 7185 + "license": "MIT", 7186 + "funding": { 7187 + "url": "https://github.com/sponsors/ljharb" 7188 + } 7189 + }, 7190 + "node_modules/generator-function": { 7191 + "version": "2.0.1", 7192 + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", 7193 + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", 7194 + "dev": true, 7195 + "license": "MIT", 7196 + "engines": { 7197 + "node": ">= 0.4" 7198 + } 7199 + }, 3337 7200 "node_modules/gensync": { 3338 7201 "version": "1.0.0-beta.2", 3339 7202 "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", ··· 3343 7206 "node": ">=6.9.0" 3344 7207 } 3345 7208 }, 7209 + "node_modules/get-intrinsic": { 7210 + "version": "1.3.0", 7211 + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", 7212 + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", 7213 + "dev": true, 7214 + "license": "MIT", 7215 + "dependencies": { 7216 + "call-bind-apply-helpers": "^1.0.2", 7217 + "es-define-property": "^1.0.1", 7218 + "es-errors": "^1.3.0", 7219 + "es-object-atoms": "^1.1.1", 7220 + "function-bind": "^1.1.2", 7221 + "get-proto": "^1.0.1", 7222 + "gopd": "^1.2.0", 7223 + "has-symbols": "^1.1.0", 7224 + "hasown": "^2.0.2", 7225 + "math-intrinsics": "^1.1.0" 7226 + }, 7227 + "engines": { 7228 + "node": ">= 0.4" 7229 + }, 7230 + "funding": { 7231 + "url": "https://github.com/sponsors/ljharb" 7232 + } 7233 + }, 7234 + "node_modules/get-nonce": { 7235 + "version": "1.0.1", 7236 + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", 7237 + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", 7238 + "engines": { 7239 + "node": ">=6" 7240 + } 7241 + }, 7242 + "node_modules/get-proto": { 7243 + "version": "1.0.1", 7244 + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", 7245 + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", 7246 + "dev": true, 7247 + "license": "MIT", 7248 + "dependencies": { 7249 + "dunder-proto": "^1.0.1", 7250 + "es-object-atoms": "^1.0.0" 7251 + }, 7252 + "engines": { 7253 + "node": ">= 0.4" 7254 + } 7255 + }, 7256 + "node_modules/get-symbol-description": { 7257 + "version": "1.1.0", 7258 + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", 7259 + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", 7260 + "dev": true, 7261 + "license": "MIT", 7262 + "dependencies": { 7263 + "call-bound": "^1.0.3", 7264 + "es-errors": "^1.3.0", 7265 + "get-intrinsic": "^1.2.6" 7266 + }, 7267 + "engines": { 7268 + "node": ">= 0.4" 7269 + }, 7270 + "funding": { 7271 + "url": "https://github.com/sponsors/ljharb" 7272 + } 7273 + }, 3346 7274 "node_modules/get-tsconfig": { 3347 7275 "version": "4.10.1", 3348 7276 "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", ··· 3367 7295 "node": ">= 6" 3368 7296 } 3369 7297 }, 7298 + "node_modules/globals": { 7299 + "version": "14.0.0", 7300 + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", 7301 + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", 7302 + "dev": true, 7303 + "license": "MIT", 7304 + "peer": true, 7305 + "engines": { 7306 + "node": ">=18" 7307 + }, 7308 + "funding": { 7309 + "url": "https://github.com/sponsors/sindresorhus" 7310 + } 7311 + }, 7312 + "node_modules/globalthis": { 7313 + "version": "1.0.4", 7314 + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", 7315 + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", 7316 + "dev": true, 7317 + "license": "MIT", 7318 + "dependencies": { 7319 + "define-properties": "^1.2.1", 7320 + "gopd": "^1.0.1" 7321 + }, 7322 + "engines": { 7323 + "node": ">= 0.4" 7324 + }, 7325 + "funding": { 7326 + "url": "https://github.com/sponsors/ljharb" 7327 + } 7328 + }, 3370 7329 "node_modules/goober": { 3371 7330 "version": "2.1.16", 3372 7331 "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.16.tgz", ··· 3376 7335 "csstype": "^3.0.10" 3377 7336 } 3378 7337 }, 7338 + "node_modules/gopd": { 7339 + "version": "1.2.0", 7340 + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", 7341 + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", 7342 + "dev": true, 7343 + "license": "MIT", 7344 + "engines": { 7345 + "node": ">= 0.4" 7346 + }, 7347 + "funding": { 7348 + "url": "https://github.com/sponsors/ljharb" 7349 + } 7350 + }, 3379 7351 "node_modules/graceful-fs": { 3380 7352 "version": "4.2.11", 3381 7353 "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", ··· 3388 7360 "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", 3389 7361 "license": "MIT" 3390 7362 }, 7363 + "node_modules/has-bigints": { 7364 + "version": "1.1.0", 7365 + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", 7366 + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", 7367 + "dev": true, 7368 + "license": "MIT", 7369 + "engines": { 7370 + "node": ">= 0.4" 7371 + }, 7372 + "funding": { 7373 + "url": "https://github.com/sponsors/ljharb" 7374 + } 7375 + }, 7376 + "node_modules/has-flag": { 7377 + "version": "4.0.0", 7378 + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 7379 + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 7380 + "dev": true, 7381 + "license": "MIT", 7382 + "peer": true, 7383 + "engines": { 7384 + "node": ">=8" 7385 + } 7386 + }, 7387 + "node_modules/has-property-descriptors": { 7388 + "version": "1.0.2", 7389 + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", 7390 + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", 7391 + "dev": true, 7392 + "license": "MIT", 7393 + "dependencies": { 7394 + "es-define-property": "^1.0.0" 7395 + }, 7396 + "funding": { 7397 + "url": "https://github.com/sponsors/ljharb" 7398 + } 7399 + }, 7400 + "node_modules/has-proto": { 7401 + "version": "1.2.0", 7402 + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", 7403 + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", 7404 + "dev": true, 7405 + "license": "MIT", 7406 + "dependencies": { 7407 + "dunder-proto": "^1.0.0" 7408 + }, 7409 + "engines": { 7410 + "node": ">= 0.4" 7411 + }, 7412 + "funding": { 7413 + "url": "https://github.com/sponsors/ljharb" 7414 + } 7415 + }, 7416 + "node_modules/has-symbols": { 7417 + "version": "1.1.0", 7418 + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", 7419 + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", 7420 + "dev": true, 7421 + "license": "MIT", 7422 + "engines": { 7423 + "node": ">= 0.4" 7424 + }, 7425 + "funding": { 7426 + "url": "https://github.com/sponsors/ljharb" 7427 + } 7428 + }, 7429 + "node_modules/has-tostringtag": { 7430 + "version": "1.0.2", 7431 + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", 7432 + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", 7433 + "dev": true, 7434 + "license": "MIT", 7435 + "dependencies": { 7436 + "has-symbols": "^1.0.3" 7437 + }, 7438 + "engines": { 7439 + "node": ">= 0.4" 7440 + }, 7441 + "funding": { 7442 + "url": "https://github.com/sponsors/ljharb" 7443 + } 7444 + }, 7445 + "node_modules/hasown": { 7446 + "version": "2.0.2", 7447 + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 7448 + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 7449 + "dev": true, 7450 + "license": "MIT", 7451 + "dependencies": { 7452 + "function-bind": "^1.1.2" 7453 + }, 7454 + "engines": { 7455 + "node": ">= 0.4" 7456 + } 7457 + }, 7458 + "node_modules/hermes-estree": { 7459 + "version": "0.25.1", 7460 + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", 7461 + "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==", 7462 + "dev": true, 7463 + "license": "MIT" 7464 + }, 7465 + "node_modules/hermes-parser": { 7466 + "version": "0.25.1", 7467 + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", 7468 + "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", 7469 + "dev": true, 7470 + "license": "MIT", 7471 + "dependencies": { 7472 + "hermes-estree": "0.25.1" 7473 + } 7474 + }, 3391 7475 "node_modules/hls-video-element": { 3392 7476 "version": "1.5.7", 3393 7477 "resolved": "https://registry.npmjs.org/hls-video-element/-/hls-video-element-1.5.7.tgz", ··· 3462 7546 "node": ">= 14" 3463 7547 } 3464 7548 }, 7549 + "node_modules/i": { 7550 + "version": "0.3.7", 7551 + "resolved": "https://registry.npmjs.org/i/-/i-0.3.7.tgz", 7552 + "integrity": "sha512-FYz4wlXgkQwIPqhzC5TdNMLSE5+GS1IIDJZY/1ZiEPCT2S3COUVZeT5OW4BmW4r5LHLQuOosSwsvnroG9GR59Q==", 7553 + "engines": { 7554 + "node": ">=0.4" 7555 + } 7556 + }, 7557 + "node_modules/iconify-icon": { 7558 + "version": "3.0.1", 7559 + "resolved": "https://registry.npmjs.org/iconify-icon/-/iconify-icon-3.0.1.tgz", 7560 + "integrity": "sha512-M3/kH3C+e/ufhmQuOSYSb1Ri1ImJ+ZEQYcVRMKnlSc8Nrdoy+iY9YvFnplX8t/3aCRuo5wN4RVPtCSHGnbt8dg==", 7561 + "dev": true, 7562 + "license": "MIT", 7563 + "dependencies": { 7564 + "@iconify/types": "^2.0.0" 7565 + }, 7566 + "funding": { 7567 + "url": "https://github.com/sponsors/cyberalien" 7568 + } 7569 + }, 3465 7570 "node_modules/iconv-lite": { 3466 7571 "version": "0.6.3", 3467 7572 "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", ··· 3481 7586 "integrity": "sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==", 3482 7587 "license": "Apache-2.0" 3483 7588 }, 7589 + "node_modules/ignore": { 7590 + "version": "5.3.2", 7591 + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", 7592 + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", 7593 + "dev": true, 7594 + "license": "MIT", 7595 + "peer": true, 7596 + "engines": { 7597 + "node": ">= 4" 7598 + } 7599 + }, 3484 7600 "node_modules/immediate": { 3485 7601 "version": "3.0.6", 3486 7602 "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", 3487 7603 "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", 3488 7604 "license": "MIT" 3489 7605 }, 7606 + "node_modules/import-fresh": { 7607 + "version": "3.3.1", 7608 + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", 7609 + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", 7610 + "dev": true, 7611 + "license": "MIT", 7612 + "dependencies": { 7613 + "parent-module": "^1.0.0", 7614 + "resolve-from": "^4.0.0" 7615 + }, 7616 + "engines": { 7617 + "node": ">=6" 7618 + }, 7619 + "funding": { 7620 + "url": "https://github.com/sponsors/sindresorhus" 7621 + } 7622 + }, 3490 7623 "node_modules/imsc": { 3491 7624 "version": "1.1.5", 3492 7625 "resolved": "https://registry.npmjs.org/imsc/-/imsc-1.1.5.tgz", ··· 3494 7627 "license": "BSD-2-Clause", 3495 7628 "dependencies": { 3496 7629 "sax": "1.2.1" 7630 + } 7631 + }, 7632 + "node_modules/imurmurhash": { 7633 + "version": "0.1.4", 7634 + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 7635 + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", 7636 + "dev": true, 7637 + "license": "MIT", 7638 + "peer": true, 7639 + "engines": { 7640 + "node": ">=0.8.19" 7641 + } 7642 + }, 7643 + "node_modules/internal-slot": { 7644 + "version": "1.1.0", 7645 + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", 7646 + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", 7647 + "dev": true, 7648 + "license": "MIT", 7649 + "dependencies": { 7650 + "es-errors": "^1.3.0", 7651 + "hasown": "^2.0.2", 7652 + "side-channel": "^1.1.0" 7653 + }, 7654 + "engines": { 7655 + "node": ">= 0.4" 3497 7656 } 3498 7657 }, 3499 7658 "node_modules/is-alphabetical": { ··· 3520 7679 "url": "https://github.com/sponsors/wooorm" 3521 7680 } 3522 7681 }, 7682 + "node_modules/is-array-buffer": { 7683 + "version": "3.0.5", 7684 + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", 7685 + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", 7686 + "dev": true, 7687 + "license": "MIT", 7688 + "dependencies": { 7689 + "call-bind": "^1.0.8", 7690 + "call-bound": "^1.0.3", 7691 + "get-intrinsic": "^1.2.6" 7692 + }, 7693 + "engines": { 7694 + "node": ">= 0.4" 7695 + }, 7696 + "funding": { 7697 + "url": "https://github.com/sponsors/ljharb" 7698 + } 7699 + }, 7700 + "node_modules/is-arrayish": { 7701 + "version": "0.2.1", 7702 + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", 7703 + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", 7704 + "dev": true, 7705 + "license": "MIT" 7706 + }, 7707 + "node_modules/is-async-function": { 7708 + "version": "2.1.1", 7709 + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", 7710 + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", 7711 + "dev": true, 7712 + "license": "MIT", 7713 + "dependencies": { 7714 + "async-function": "^1.0.0", 7715 + "call-bound": "^1.0.3", 7716 + "get-proto": "^1.0.1", 7717 + "has-tostringtag": "^1.0.2", 7718 + "safe-regex-test": "^1.1.0" 7719 + }, 7720 + "engines": { 7721 + "node": ">= 0.4" 7722 + }, 7723 + "funding": { 7724 + "url": "https://github.com/sponsors/ljharb" 7725 + } 7726 + }, 7727 + "node_modules/is-bigint": { 7728 + "version": "1.1.0", 7729 + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", 7730 + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", 7731 + "dev": true, 7732 + "license": "MIT", 7733 + "dependencies": { 7734 + "has-bigints": "^1.0.2" 7735 + }, 7736 + "engines": { 7737 + "node": ">= 0.4" 7738 + }, 7739 + "funding": { 7740 + "url": "https://github.com/sponsors/ljharb" 7741 + } 7742 + }, 3523 7743 "node_modules/is-binary-path": { 3524 7744 "version": "2.1.0", 3525 7745 "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", ··· 3532 7752 "node": ">=8" 3533 7753 } 3534 7754 }, 7755 + "node_modules/is-boolean-object": { 7756 + "version": "1.2.2", 7757 + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", 7758 + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", 7759 + "dev": true, 7760 + "license": "MIT", 7761 + "dependencies": { 7762 + "call-bound": "^1.0.3", 7763 + "has-tostringtag": "^1.0.2" 7764 + }, 7765 + "engines": { 7766 + "node": ">= 0.4" 7767 + }, 7768 + "funding": { 7769 + "url": "https://github.com/sponsors/ljharb" 7770 + } 7771 + }, 7772 + "node_modules/is-callable": { 7773 + "version": "1.2.7", 7774 + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", 7775 + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", 7776 + "dev": true, 7777 + "license": "MIT", 7778 + "engines": { 7779 + "node": ">= 0.4" 7780 + }, 7781 + "funding": { 7782 + "url": "https://github.com/sponsors/ljharb" 7783 + } 7784 + }, 7785 + "node_modules/is-core-module": { 7786 + "version": "2.16.1", 7787 + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", 7788 + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", 7789 + "dev": true, 7790 + "license": "MIT", 7791 + "dependencies": { 7792 + "hasown": "^2.0.2" 7793 + }, 7794 + "engines": { 7795 + "node": ">= 0.4" 7796 + }, 7797 + "funding": { 7798 + "url": "https://github.com/sponsors/ljharb" 7799 + } 7800 + }, 7801 + "node_modules/is-data-view": { 7802 + "version": "1.0.2", 7803 + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", 7804 + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", 7805 + "dev": true, 7806 + "license": "MIT", 7807 + "dependencies": { 7808 + "call-bound": "^1.0.2", 7809 + "get-intrinsic": "^1.2.6", 7810 + "is-typed-array": "^1.1.13" 7811 + }, 7812 + "engines": { 7813 + "node": ">= 0.4" 7814 + }, 7815 + "funding": { 7816 + "url": "https://github.com/sponsors/ljharb" 7817 + } 7818 + }, 7819 + "node_modules/is-date-object": { 7820 + "version": "1.1.0", 7821 + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", 7822 + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", 7823 + "dev": true, 7824 + "license": "MIT", 7825 + "dependencies": { 7826 + "call-bound": "^1.0.2", 7827 + "has-tostringtag": "^1.0.2" 7828 + }, 7829 + "engines": { 7830 + "node": ">= 0.4" 7831 + }, 7832 + "funding": { 7833 + "url": "https://github.com/sponsors/ljharb" 7834 + } 7835 + }, 3535 7836 "node_modules/is-decimal": { 3536 7837 "version": "2.0.1", 3537 7838 "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", ··· 3551 7852 "node": ">=0.10.0" 3552 7853 } 3553 7854 }, 7855 + "node_modules/is-finalizationregistry": { 7856 + "version": "1.1.1", 7857 + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", 7858 + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", 7859 + "dev": true, 7860 + "license": "MIT", 7861 + "dependencies": { 7862 + "call-bound": "^1.0.3" 7863 + }, 7864 + "engines": { 7865 + "node": ">= 0.4" 7866 + }, 7867 + "funding": { 7868 + "url": "https://github.com/sponsors/ljharb" 7869 + } 7870 + }, 7871 + "node_modules/is-generator-function": { 7872 + "version": "1.1.2", 7873 + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", 7874 + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", 7875 + "dev": true, 7876 + "license": "MIT", 7877 + "dependencies": { 7878 + "call-bound": "^1.0.4", 7879 + "generator-function": "^2.0.0", 7880 + "get-proto": "^1.0.1", 7881 + "has-tostringtag": "^1.0.2", 7882 + "safe-regex-test": "^1.1.0" 7883 + }, 7884 + "engines": { 7885 + "node": ">= 0.4" 7886 + }, 7887 + "funding": { 7888 + "url": "https://github.com/sponsors/ljharb" 7889 + } 7890 + }, 3554 7891 "node_modules/is-glob": { 3555 7892 "version": "4.0.3", 3556 7893 "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", ··· 3563 7900 "node": ">=0.10.0" 3564 7901 } 3565 7902 }, 7903 + "node_modules/is-immutable-type": { 7904 + "version": "5.0.1", 7905 + "resolved": "https://registry.npmjs.org/is-immutable-type/-/is-immutable-type-5.0.1.tgz", 7906 + "integrity": "sha512-LkHEOGVZZXxGl8vDs+10k3DvP++SEoYEAJLRk6buTFi6kD7QekThV7xHS0j6gpnUCQ0zpud/gMDGiV4dQneLTg==", 7907 + "dev": true, 7908 + "license": "BSD-3-Clause", 7909 + "dependencies": { 7910 + "@typescript-eslint/type-utils": "^8.0.0", 7911 + "ts-api-utils": "^2.0.0", 7912 + "ts-declaration-location": "^1.0.4" 7913 + }, 7914 + "peerDependencies": { 7915 + "eslint": "*", 7916 + "typescript": ">=4.7.4" 7917 + } 7918 + }, 7919 + "node_modules/is-map": { 7920 + "version": "2.0.3", 7921 + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", 7922 + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", 7923 + "dev": true, 7924 + "license": "MIT", 7925 + "engines": { 7926 + "node": ">= 0.4" 7927 + }, 7928 + "funding": { 7929 + "url": "https://github.com/sponsors/ljharb" 7930 + } 7931 + }, 7932 + "node_modules/is-negative-zero": { 7933 + "version": "2.0.3", 7934 + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", 7935 + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", 7936 + "dev": true, 7937 + "license": "MIT", 7938 + "engines": { 7939 + "node": ">= 0.4" 7940 + }, 7941 + "funding": { 7942 + "url": "https://github.com/sponsors/ljharb" 7943 + } 7944 + }, 3566 7945 "node_modules/is-number": { 3567 7946 "version": "7.0.0", 3568 7947 "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", ··· 3572 7951 "node": ">=0.12.0" 3573 7952 } 3574 7953 }, 7954 + "node_modules/is-number-object": { 7955 + "version": "1.1.1", 7956 + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", 7957 + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", 7958 + "dev": true, 7959 + "license": "MIT", 7960 + "dependencies": { 7961 + "call-bound": "^1.0.3", 7962 + "has-tostringtag": "^1.0.2" 7963 + }, 7964 + "engines": { 7965 + "node": ">= 0.4" 7966 + }, 7967 + "funding": { 7968 + "url": "https://github.com/sponsors/ljharb" 7969 + } 7970 + }, 3575 7971 "node_modules/is-potential-custom-element-name": { 3576 7972 "version": "1.0.1", 3577 7973 "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", ··· 3579 7975 "dev": true, 3580 7976 "license": "MIT" 3581 7977 }, 7978 + "node_modules/is-regex": { 7979 + "version": "1.2.1", 7980 + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", 7981 + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", 7982 + "dev": true, 7983 + "license": "MIT", 7984 + "dependencies": { 7985 + "call-bound": "^1.0.2", 7986 + "gopd": "^1.2.0", 7987 + "has-tostringtag": "^1.0.2", 7988 + "hasown": "^2.0.2" 7989 + }, 7990 + "engines": { 7991 + "node": ">= 0.4" 7992 + }, 7993 + "funding": { 7994 + "url": "https://github.com/sponsors/ljharb" 7995 + } 7996 + }, 7997 + "node_modules/is-set": { 7998 + "version": "2.0.3", 7999 + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", 8000 + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", 8001 + "dev": true, 8002 + "license": "MIT", 8003 + "engines": { 8004 + "node": ">= 0.4" 8005 + }, 8006 + "funding": { 8007 + "url": "https://github.com/sponsors/ljharb" 8008 + } 8009 + }, 8010 + "node_modules/is-shared-array-buffer": { 8011 + "version": "1.0.4", 8012 + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", 8013 + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", 8014 + "dev": true, 8015 + "license": "MIT", 8016 + "dependencies": { 8017 + "call-bound": "^1.0.3" 8018 + }, 8019 + "engines": { 8020 + "node": ">= 0.4" 8021 + }, 8022 + "funding": { 8023 + "url": "https://github.com/sponsors/ljharb" 8024 + } 8025 + }, 8026 + "node_modules/is-string": { 8027 + "version": "1.1.1", 8028 + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", 8029 + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", 8030 + "dev": true, 8031 + "license": "MIT", 8032 + "dependencies": { 8033 + "call-bound": "^1.0.3", 8034 + "has-tostringtag": "^1.0.2" 8035 + }, 8036 + "engines": { 8037 + "node": ">= 0.4" 8038 + }, 8039 + "funding": { 8040 + "url": "https://github.com/sponsors/ljharb" 8041 + } 8042 + }, 8043 + "node_modules/is-symbol": { 8044 + "version": "1.1.1", 8045 + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", 8046 + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", 8047 + "dev": true, 8048 + "license": "MIT", 8049 + "dependencies": { 8050 + "call-bound": "^1.0.2", 8051 + "has-symbols": "^1.1.0", 8052 + "safe-regex-test": "^1.1.0" 8053 + }, 8054 + "engines": { 8055 + "node": ">= 0.4" 8056 + }, 8057 + "funding": { 8058 + "url": "https://github.com/sponsors/ljharb" 8059 + } 8060 + }, 8061 + "node_modules/is-typed-array": { 8062 + "version": "1.1.15", 8063 + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", 8064 + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", 8065 + "dev": true, 8066 + "license": "MIT", 8067 + "dependencies": { 8068 + "which-typed-array": "^1.1.16" 8069 + }, 8070 + "engines": { 8071 + "node": ">= 0.4" 8072 + }, 8073 + "funding": { 8074 + "url": "https://github.com/sponsors/ljharb" 8075 + } 8076 + }, 8077 + "node_modules/is-weakmap": { 8078 + "version": "2.0.2", 8079 + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", 8080 + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", 8081 + "dev": true, 8082 + "license": "MIT", 8083 + "engines": { 8084 + "node": ">= 0.4" 8085 + }, 8086 + "funding": { 8087 + "url": "https://github.com/sponsors/ljharb" 8088 + } 8089 + }, 8090 + "node_modules/is-weakref": { 8091 + "version": "1.1.1", 8092 + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", 8093 + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", 8094 + "dev": true, 8095 + "license": "MIT", 8096 + "dependencies": { 8097 + "call-bound": "^1.0.3" 8098 + }, 8099 + "engines": { 8100 + "node": ">= 0.4" 8101 + }, 8102 + "funding": { 8103 + "url": "https://github.com/sponsors/ljharb" 8104 + } 8105 + }, 8106 + "node_modules/is-weakset": { 8107 + "version": "2.0.4", 8108 + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", 8109 + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", 8110 + "dev": true, 8111 + "license": "MIT", 8112 + "dependencies": { 8113 + "call-bound": "^1.0.3", 8114 + "get-intrinsic": "^1.2.6" 8115 + }, 8116 + "engines": { 8117 + "node": ">= 0.4" 8118 + }, 8119 + "funding": { 8120 + "url": "https://github.com/sponsors/ljharb" 8121 + } 8122 + }, 8123 + "node_modules/isarray": { 8124 + "version": "2.0.5", 8125 + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", 8126 + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", 8127 + "dev": true, 8128 + "license": "MIT" 8129 + }, 3582 8130 "node_modules/isbot": { 3583 8131 "version": "5.1.30", 3584 8132 "resolved": "https://registry.npmjs.org/isbot/-/isbot-5.1.30.tgz", ··· 3588 8136 "node": ">=18" 3589 8137 } 3590 8138 }, 8139 + "node_modules/isexe": { 8140 + "version": "2.0.0", 8141 + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 8142 + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 8143 + "dev": true, 8144 + "license": "ISC", 8145 + "peer": true 8146 + }, 3591 8147 "node_modules/iso-datestring-validator": { 3592 8148 "version": "2.2.2", 3593 8149 "resolved": "https://registry.npmjs.org/iso-datestring-validator/-/iso-datestring-validator-2.2.2.tgz", 3594 8150 "integrity": "sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==", 3595 8151 "license": "MIT" 3596 8152 }, 8153 + "node_modules/iterator.prototype": { 8154 + "version": "1.1.5", 8155 + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", 8156 + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", 8157 + "dev": true, 8158 + "license": "MIT", 8159 + "dependencies": { 8160 + "define-data-property": "^1.1.4", 8161 + "es-object-atoms": "^1.0.0", 8162 + "get-intrinsic": "^1.2.6", 8163 + "get-proto": "^1.0.0", 8164 + "has-symbols": "^1.1.0", 8165 + "set-function-name": "^2.0.2" 8166 + }, 8167 + "engines": { 8168 + "node": ">= 0.4" 8169 + } 8170 + }, 3597 8171 "node_modules/jiti": { 3598 8172 "version": "2.5.1", 3599 8173 "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz", ··· 3647 8221 "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 3648 8222 "license": "MIT" 3649 8223 }, 8224 + "node_modules/js-yaml": { 8225 + "version": "4.1.0", 8226 + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 8227 + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 8228 + "dev": true, 8229 + "license": "MIT", 8230 + "dependencies": { 8231 + "argparse": "^2.0.1" 8232 + }, 8233 + "bin": { 8234 + "js-yaml": "bin/js-yaml.js" 8235 + } 8236 + }, 3650 8237 "node_modules/jsdom": { 3651 8238 "version": "26.1.0", 3652 8239 "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz", ··· 3699 8286 "node": ">=6" 3700 8287 } 3701 8288 }, 8289 + "node_modules/json-buffer": { 8290 + "version": "3.0.1", 8291 + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 8292 + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", 8293 + "dev": true, 8294 + "license": "MIT", 8295 + "peer": true 8296 + }, 8297 + "node_modules/json-parse-even-better-errors": { 8298 + "version": "2.3.1", 8299 + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", 8300 + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", 8301 + "dev": true, 8302 + "license": "MIT" 8303 + }, 8304 + "node_modules/json-schema-traverse": { 8305 + "version": "0.4.1", 8306 + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 8307 + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 8308 + "dev": true, 8309 + "license": "MIT", 8310 + "peer": true 8311 + }, 8312 + "node_modules/json-stable-stringify-without-jsonify": { 8313 + "version": "1.0.1", 8314 + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 8315 + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", 8316 + "dev": true, 8317 + "license": "MIT", 8318 + "peer": true 8319 + }, 3702 8320 "node_modules/json5": { 3703 8321 "version": "2.2.3", 3704 8322 "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", ··· 3709 8327 }, 3710 8328 "engines": { 3711 8329 "node": ">=6" 8330 + } 8331 + }, 8332 + "node_modules/jsx-ast-utils": { 8333 + "version": "3.3.5", 8334 + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", 8335 + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", 8336 + "dev": true, 8337 + "license": "MIT", 8338 + "dependencies": { 8339 + "array-includes": "^3.1.6", 8340 + "array.prototype.flat": "^1.3.1", 8341 + "object.assign": "^4.1.4", 8342 + "object.values": "^1.1.6" 8343 + }, 8344 + "engines": { 8345 + "node": ">=4.0" 8346 + } 8347 + }, 8348 + "node_modules/keyv": { 8349 + "version": "4.5.4", 8350 + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", 8351 + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", 8352 + "dev": true, 8353 + "license": "MIT", 8354 + "peer": true, 8355 + "dependencies": { 8356 + "json-buffer": "3.0.1" 8357 + } 8358 + }, 8359 + "node_modules/kolorist": { 8360 + "version": "1.8.0", 8361 + "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", 8362 + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", 8363 + "dev": true, 8364 + "license": "MIT" 8365 + }, 8366 + "node_modules/levn": { 8367 + "version": "0.4.1", 8368 + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 8369 + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 8370 + "dev": true, 8371 + "license": "MIT", 8372 + "peer": true, 8373 + "dependencies": { 8374 + "prelude-ls": "^1.2.1", 8375 + "type-check": "~0.4.0" 8376 + }, 8377 + "engines": { 8378 + "node": ">= 0.8.0" 3712 8379 } 3713 8380 }, 3714 8381 "node_modules/lie": { ··· 3948 8615 "url": "https://opencollective.com/parcel" 3949 8616 } 3950 8617 }, 8618 + "node_modules/lines-and-columns": { 8619 + "version": "1.2.4", 8620 + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", 8621 + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", 8622 + "dev": true, 8623 + "license": "MIT" 8624 + }, 8625 + "node_modules/local-pkg": { 8626 + "version": "1.1.2", 8627 + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.2.tgz", 8628 + "integrity": "sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==", 8629 + "dev": true, 8630 + "license": "MIT", 8631 + "dependencies": { 8632 + "mlly": "^1.7.4", 8633 + "pkg-types": "^2.3.0", 8634 + "quansync": "^0.2.11" 8635 + }, 8636 + "engines": { 8637 + "node": ">=14" 8638 + }, 8639 + "funding": { 8640 + "url": "https://github.com/sponsors/antfu" 8641 + } 8642 + }, 3951 8643 "node_modules/localforage": { 3952 8644 "version": "1.10.0", 3953 8645 "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz", ··· 3957 8649 "lie": "3.1.1" 3958 8650 } 3959 8651 }, 8652 + "node_modules/locate-path": { 8653 + "version": "6.0.0", 8654 + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 8655 + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 8656 + "dev": true, 8657 + "license": "MIT", 8658 + "peer": true, 8659 + "dependencies": { 8660 + "p-locate": "^5.0.0" 8661 + }, 8662 + "engines": { 8663 + "node": ">=10" 8664 + }, 8665 + "funding": { 8666 + "url": "https://github.com/sponsors/sindresorhus" 8667 + } 8668 + }, 8669 + "node_modules/lodash.clonedeep": { 8670 + "version": "4.5.0", 8671 + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", 8672 + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", 8673 + "license": "MIT" 8674 + }, 8675 + "node_modules/lodash.merge": { 8676 + "version": "4.6.2", 8677 + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 8678 + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", 8679 + "dev": true, 8680 + "license": "MIT", 8681 + "peer": true 8682 + }, 3960 8683 "node_modules/loose-envify": { 3961 8684 "version": "1.4.0", 3962 8685 "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", ··· 3976 8699 "dev": true, 3977 8700 "license": "MIT" 3978 8701 }, 8702 + "node_modules/lower-case": { 8703 + "version": "2.0.2", 8704 + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", 8705 + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", 8706 + "dev": true, 8707 + "license": "MIT", 8708 + "dependencies": { 8709 + "tslib": "^2.0.3" 8710 + } 8711 + }, 3979 8712 "node_modules/lru-cache": { 3980 8713 "version": "5.1.1", 3981 8714 "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", ··· 3996 8729 } 3997 8730 }, 3998 8731 "node_modules/magic-string": { 3999 - "version": "0.30.18", 4000 - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.18.tgz", 4001 - "integrity": "sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==", 8732 + "version": "0.30.19", 8733 + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz", 8734 + "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", 4002 8735 "license": "MIT", 4003 8736 "dependencies": { 4004 8737 "@jridgewell/sourcemap-codec": "^1.5.5" 4005 8738 } 4006 8739 }, 8740 + "node_modules/math-intrinsics": { 8741 + "version": "1.1.0", 8742 + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", 8743 + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", 8744 + "dev": true, 8745 + "license": "MIT", 8746 + "engines": { 8747 + "node": ">= 0.4" 8748 + } 8749 + }, 4007 8750 "node_modules/media-chrome": { 4008 8751 "version": "4.11.1", 4009 8752 "resolved": "https://registry.npmjs.org/media-chrome/-/media-chrome-4.11.1.tgz", ··· 4020 8763 "integrity": "sha512-9P2FuUHnZZ3iji+2RQk7Zkh5AmZTnOG5fODACnjhCVveX1McY3jmCRHofIEI+yTBqplz7LXy48c7fQ3Uigp88w==", 4021 8764 "license": "MIT" 4022 8765 }, 8766 + "node_modules/merge2": { 8767 + "version": "1.4.1", 8768 + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 8769 + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 8770 + "dev": true, 8771 + "license": "MIT", 8772 + "engines": { 8773 + "node": ">= 8" 8774 + } 8775 + }, 8776 + "node_modules/micromatch": { 8777 + "version": "4.0.8", 8778 + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", 8779 + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", 8780 + "dev": true, 8781 + "license": "MIT", 8782 + "dependencies": { 8783 + "braces": "^3.0.3", 8784 + "picomatch": "^2.3.1" 8785 + }, 8786 + "engines": { 8787 + "node": ">=8.6" 8788 + } 8789 + }, 8790 + "node_modules/minimatch": { 8791 + "version": "3.1.2", 8792 + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 8793 + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 8794 + "dev": true, 8795 + "license": "ISC", 8796 + "dependencies": { 8797 + "brace-expansion": "^1.1.7" 8798 + }, 8799 + "engines": { 8800 + "node": "*" 8801 + } 8802 + }, 4023 8803 "node_modules/minipass": { 4024 8804 "version": "7.1.2", 4025 8805 "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", ··· 4056 8836 "url": "https://github.com/sponsors/isaacs" 4057 8837 } 4058 8838 }, 8839 + "node_modules/mlly": { 8840 + "version": "1.8.0", 8841 + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz", 8842 + "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==", 8843 + "dev": true, 8844 + "license": "MIT", 8845 + "dependencies": { 8846 + "acorn": "^8.15.0", 8847 + "pathe": "^2.0.3", 8848 + "pkg-types": "^1.3.1", 8849 + "ufo": "^1.6.1" 8850 + } 8851 + }, 8852 + "node_modules/mlly/node_modules/confbox": { 8853 + "version": "0.1.8", 8854 + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", 8855 + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", 8856 + "dev": true, 8857 + "license": "MIT" 8858 + }, 8859 + "node_modules/mlly/node_modules/pkg-types": { 8860 + "version": "1.3.1", 8861 + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", 8862 + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", 8863 + "dev": true, 8864 + "license": "MIT", 8865 + "dependencies": { 8866 + "confbox": "^0.1.8", 8867 + "mlly": "^1.7.4", 8868 + "pathe": "^2.0.1" 8869 + } 8870 + }, 4059 8871 "node_modules/ms": { 4060 8872 "version": "2.1.3", 4061 8873 "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", ··· 4098 8910 "integrity": "sha512-zkVhZUA3y8mbz652WrL5x0fB0ehrBkulWT3TomAQ9iDtyXZvzKeEA6GPxAItBYeNYl5yngKRX612qHOhvMkDeg==", 4099 8911 "license": "MIT" 4100 8912 }, 8913 + "node_modules/natural-compare": { 8914 + "version": "1.4.0", 8915 + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 8916 + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", 8917 + "dev": true, 8918 + "license": "MIT" 8919 + }, 8920 + "node_modules/no-case": { 8921 + "version": "3.0.4", 8922 + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", 8923 + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", 8924 + "dev": true, 8925 + "license": "MIT", 8926 + "dependencies": { 8927 + "lower-case": "^2.0.2", 8928 + "tslib": "^2.0.3" 8929 + } 8930 + }, 4101 8931 "node_modules/node-releases": { 4102 8932 "version": "2.0.19", 4103 8933 "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", ··· 4113 8943 "node": ">=0.10.0" 4114 8944 } 4115 8945 }, 8946 + "node_modules/npm": { 8947 + "version": "11.6.2", 8948 + "resolved": "https://registry.npmjs.org/npm/-/npm-11.6.2.tgz", 8949 + "integrity": "sha512-7iKzNfy8lWYs3zq4oFPa8EXZz5xt9gQNKJZau3B1ErLBb6bF7sBJ00x09485DOvRT2l5Gerbl3VlZNT57MxJVA==", 8950 + "bundleDependencies": [ 8951 + "@isaacs/string-locale-compare", 8952 + "@npmcli/arborist", 8953 + "@npmcli/config", 8954 + "@npmcli/fs", 8955 + "@npmcli/map-workspaces", 8956 + "@npmcli/package-json", 8957 + "@npmcli/promise-spawn", 8958 + "@npmcli/redact", 8959 + "@npmcli/run-script", 8960 + "@sigstore/tuf", 8961 + "abbrev", 8962 + "archy", 8963 + "cacache", 8964 + "chalk", 8965 + "ci-info", 8966 + "cli-columns", 8967 + "fastest-levenshtein", 8968 + "fs-minipass", 8969 + "glob", 8970 + "graceful-fs", 8971 + "hosted-git-info", 8972 + "ini", 8973 + "init-package-json", 8974 + "is-cidr", 8975 + "json-parse-even-better-errors", 8976 + "libnpmaccess", 8977 + "libnpmdiff", 8978 + "libnpmexec", 8979 + "libnpmfund", 8980 + "libnpmorg", 8981 + "libnpmpack", 8982 + "libnpmpublish", 8983 + "libnpmsearch", 8984 + "libnpmteam", 8985 + "libnpmversion", 8986 + "make-fetch-happen", 8987 + "minimatch", 8988 + "minipass", 8989 + "minipass-pipeline", 8990 + "ms", 8991 + "node-gyp", 8992 + "nopt", 8993 + "npm-audit-report", 8994 + "npm-install-checks", 8995 + "npm-package-arg", 8996 + "npm-pick-manifest", 8997 + "npm-profile", 8998 + "npm-registry-fetch", 8999 + "npm-user-validate", 9000 + "p-map", 9001 + "pacote", 9002 + "parse-conflict-json", 9003 + "proc-log", 9004 + "qrcode-terminal", 9005 + "read", 9006 + "semver", 9007 + "spdx-expression-parse", 9008 + "ssri", 9009 + "supports-color", 9010 + "tar", 9011 + "text-table", 9012 + "tiny-relative-date", 9013 + "treeverse", 9014 + "validate-npm-package-name", 9015 + "which" 9016 + ], 9017 + "license": "Artistic-2.0", 9018 + "workspaces": [ 9019 + "docs", 9020 + "smoke-tests", 9021 + "mock-globals", 9022 + "mock-registry", 9023 + "workspaces/*" 9024 + ], 9025 + "dependencies": { 9026 + "@isaacs/string-locale-compare": "^1.1.0", 9027 + "@npmcli/arborist": "^9.1.6", 9028 + "@npmcli/config": "^10.4.2", 9029 + "@npmcli/fs": "^4.0.0", 9030 + "@npmcli/map-workspaces": "^5.0.0", 9031 + "@npmcli/package-json": "^7.0.1", 9032 + "@npmcli/promise-spawn": "^8.0.3", 9033 + "@npmcli/redact": "^3.2.2", 9034 + "@npmcli/run-script": "^10.0.0", 9035 + "@sigstore/tuf": "^4.0.0", 9036 + "abbrev": "^3.0.1", 9037 + "archy": "~1.0.0", 9038 + "cacache": "^20.0.1", 9039 + "chalk": "^5.6.2", 9040 + "ci-info": "^4.3.1", 9041 + "cli-columns": "^4.0.0", 9042 + "fastest-levenshtein": "^1.0.16", 9043 + "fs-minipass": "^3.0.3", 9044 + "glob": "^11.0.3", 9045 + "graceful-fs": "^4.2.11", 9046 + "hosted-git-info": "^9.0.2", 9047 + "ini": "^5.0.0", 9048 + "init-package-json": "^8.2.2", 9049 + "is-cidr": "^6.0.1", 9050 + "json-parse-even-better-errors": "^4.0.0", 9051 + "libnpmaccess": "^10.0.3", 9052 + "libnpmdiff": "^8.0.9", 9053 + "libnpmexec": "^10.1.8", 9054 + "libnpmfund": "^7.0.9", 9055 + "libnpmorg": "^8.0.1", 9056 + "libnpmpack": "^9.0.9", 9057 + "libnpmpublish": "^11.1.2", 9058 + "libnpmsearch": "^9.0.1", 9059 + "libnpmteam": "^8.0.2", 9060 + "libnpmversion": "^8.0.2", 9061 + "make-fetch-happen": "^15.0.2", 9062 + "minimatch": "^10.0.3", 9063 + "minipass": "^7.1.1", 9064 + "minipass-pipeline": "^1.2.4", 9065 + "ms": "^2.1.2", 9066 + "node-gyp": "^11.4.2", 9067 + "nopt": "^8.1.0", 9068 + "npm-audit-report": "^6.0.0", 9069 + "npm-install-checks": "^7.1.2", 9070 + "npm-package-arg": "^13.0.1", 9071 + "npm-pick-manifest": "^11.0.1", 9072 + "npm-profile": "^12.0.0", 9073 + "npm-registry-fetch": "^19.0.0", 9074 + "npm-user-validate": "^3.0.0", 9075 + "p-map": "^7.0.3", 9076 + "pacote": "^21.0.3", 9077 + "parse-conflict-json": "^4.0.0", 9078 + "proc-log": "^5.0.0", 9079 + "qrcode-terminal": "^0.12.0", 9080 + "read": "^4.1.0", 9081 + "semver": "^7.7.3", 9082 + "spdx-expression-parse": "^4.0.0", 9083 + "ssri": "^12.0.0", 9084 + "supports-color": "^10.2.2", 9085 + "tar": "^7.5.1", 9086 + "text-table": "~0.2.0", 9087 + "tiny-relative-date": "^2.0.2", 9088 + "treeverse": "^3.0.0", 9089 + "validate-npm-package-name": "^6.0.2", 9090 + "which": "^5.0.0" 9091 + }, 9092 + "bin": { 9093 + "npm": "bin/npm-cli.js", 9094 + "npx": "bin/npx-cli.js" 9095 + }, 9096 + "engines": { 9097 + "node": "^20.17.0 || >=22.9.0" 9098 + } 9099 + }, 9100 + "node_modules/npm/node_modules/@isaacs/balanced-match": { 9101 + "version": "4.0.1", 9102 + "inBundle": true, 9103 + "license": "MIT", 9104 + "engines": { 9105 + "node": "20 || >=22" 9106 + } 9107 + }, 9108 + "node_modules/npm/node_modules/@isaacs/brace-expansion": { 9109 + "version": "5.0.0", 9110 + "inBundle": true, 9111 + "license": "MIT", 9112 + "dependencies": { 9113 + "@isaacs/balanced-match": "^4.0.1" 9114 + }, 9115 + "engines": { 9116 + "node": "20 || >=22" 9117 + } 9118 + }, 9119 + "node_modules/npm/node_modules/@isaacs/cliui": { 9120 + "version": "8.0.2", 9121 + "inBundle": true, 9122 + "license": "ISC", 9123 + "dependencies": { 9124 + "string-width": "^5.1.2", 9125 + "string-width-cjs": "npm:string-width@^4.2.0", 9126 + "strip-ansi": "^7.0.1", 9127 + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", 9128 + "wrap-ansi": "^8.1.0", 9129 + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" 9130 + }, 9131 + "engines": { 9132 + "node": ">=12" 9133 + } 9134 + }, 9135 + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": { 9136 + "version": "6.2.2", 9137 + "inBundle": true, 9138 + "license": "MIT", 9139 + "engines": { 9140 + "node": ">=12" 9141 + }, 9142 + "funding": { 9143 + "url": "https://github.com/chalk/ansi-regex?sponsor=1" 9144 + } 9145 + }, 9146 + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": { 9147 + "version": "9.2.2", 9148 + "inBundle": true, 9149 + "license": "MIT" 9150 + }, 9151 + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": { 9152 + "version": "5.1.2", 9153 + "inBundle": true, 9154 + "license": "MIT", 9155 + "dependencies": { 9156 + "eastasianwidth": "^0.2.0", 9157 + "emoji-regex": "^9.2.2", 9158 + "strip-ansi": "^7.0.1" 9159 + }, 9160 + "engines": { 9161 + "node": ">=12" 9162 + }, 9163 + "funding": { 9164 + "url": "https://github.com/sponsors/sindresorhus" 9165 + } 9166 + }, 9167 + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi": { 9168 + "version": "7.1.2", 9169 + "inBundle": true, 9170 + "license": "MIT", 9171 + "dependencies": { 9172 + "ansi-regex": "^6.0.1" 9173 + }, 9174 + "engines": { 9175 + "node": ">=12" 9176 + }, 9177 + "funding": { 9178 + "url": "https://github.com/chalk/strip-ansi?sponsor=1" 9179 + } 9180 + }, 9181 + "node_modules/npm/node_modules/@isaacs/fs-minipass": { 9182 + "version": "4.0.1", 9183 + "inBundle": true, 9184 + "license": "ISC", 9185 + "dependencies": { 9186 + "minipass": "^7.0.4" 9187 + }, 9188 + "engines": { 9189 + "node": ">=18.0.0" 9190 + } 9191 + }, 9192 + "node_modules/npm/node_modules/@isaacs/string-locale-compare": { 9193 + "version": "1.1.0", 9194 + "inBundle": true, 9195 + "license": "ISC" 9196 + }, 9197 + "node_modules/npm/node_modules/@npmcli/agent": { 9198 + "version": "4.0.0", 9199 + "inBundle": true, 9200 + "license": "ISC", 9201 + "dependencies": { 9202 + "agent-base": "^7.1.0", 9203 + "http-proxy-agent": "^7.0.0", 9204 + "https-proxy-agent": "^7.0.1", 9205 + "lru-cache": "^11.2.1", 9206 + "socks-proxy-agent": "^8.0.3" 9207 + }, 9208 + "engines": { 9209 + "node": "^20.17.0 || >=22.9.0" 9210 + } 9211 + }, 9212 + "node_modules/npm/node_modules/@npmcli/arborist": { 9213 + "version": "9.1.6", 9214 + "inBundle": true, 9215 + "license": "ISC", 9216 + "dependencies": { 9217 + "@isaacs/string-locale-compare": "^1.1.0", 9218 + "@npmcli/fs": "^4.0.0", 9219 + "@npmcli/installed-package-contents": "^3.0.0", 9220 + "@npmcli/map-workspaces": "^5.0.0", 9221 + "@npmcli/metavuln-calculator": "^9.0.2", 9222 + "@npmcli/name-from-folder": "^3.0.0", 9223 + "@npmcli/node-gyp": "^4.0.0", 9224 + "@npmcli/package-json": "^7.0.0", 9225 + "@npmcli/query": "^4.0.0", 9226 + "@npmcli/redact": "^3.0.0", 9227 + "@npmcli/run-script": "^10.0.0", 9228 + "bin-links": "^5.0.0", 9229 + "cacache": "^20.0.1", 9230 + "common-ancestor-path": "^1.0.1", 9231 + "hosted-git-info": "^9.0.0", 9232 + "json-stringify-nice": "^1.1.4", 9233 + "lru-cache": "^11.2.1", 9234 + "minimatch": "^10.0.3", 9235 + "nopt": "^8.0.0", 9236 + "npm-install-checks": "^7.1.0", 9237 + "npm-package-arg": "^13.0.0", 9238 + "npm-pick-manifest": "^11.0.1", 9239 + "npm-registry-fetch": "^19.0.0", 9240 + "pacote": "^21.0.2", 9241 + "parse-conflict-json": "^4.0.0", 9242 + "proc-log": "^5.0.0", 9243 + "proggy": "^3.0.0", 9244 + "promise-all-reject-late": "^1.0.0", 9245 + "promise-call-limit": "^3.0.1", 9246 + "semver": "^7.3.7", 9247 + "ssri": "^12.0.0", 9248 + "treeverse": "^3.0.0", 9249 + "walk-up-path": "^4.0.0" 9250 + }, 9251 + "bin": { 9252 + "arborist": "bin/index.js" 9253 + }, 9254 + "engines": { 9255 + "node": "^20.17.0 || >=22.9.0" 9256 + } 9257 + }, 9258 + "node_modules/npm/node_modules/@npmcli/config": { 9259 + "version": "10.4.2", 9260 + "inBundle": true, 9261 + "license": "ISC", 9262 + "dependencies": { 9263 + "@npmcli/map-workspaces": "^5.0.0", 9264 + "@npmcli/package-json": "^7.0.0", 9265 + "ci-info": "^4.0.0", 9266 + "ini": "^5.0.0", 9267 + "nopt": "^8.1.0", 9268 + "proc-log": "^5.0.0", 9269 + "semver": "^7.3.5", 9270 + "walk-up-path": "^4.0.0" 9271 + }, 9272 + "engines": { 9273 + "node": "^20.17.0 || >=22.9.0" 9274 + } 9275 + }, 9276 + "node_modules/npm/node_modules/@npmcli/fs": { 9277 + "version": "4.0.0", 9278 + "inBundle": true, 9279 + "license": "ISC", 9280 + "dependencies": { 9281 + "semver": "^7.3.5" 9282 + }, 9283 + "engines": { 9284 + "node": "^18.17.0 || >=20.5.0" 9285 + } 9286 + }, 9287 + "node_modules/npm/node_modules/@npmcli/git": { 9288 + "version": "7.0.0", 9289 + "inBundle": true, 9290 + "license": "ISC", 9291 + "dependencies": { 9292 + "@npmcli/promise-spawn": "^8.0.0", 9293 + "ini": "^5.0.0", 9294 + "lru-cache": "^11.2.1", 9295 + "npm-pick-manifest": "^11.0.1", 9296 + "proc-log": "^5.0.0", 9297 + "promise-retry": "^2.0.1", 9298 + "semver": "^7.3.5", 9299 + "which": "^5.0.0" 9300 + }, 9301 + "engines": { 9302 + "node": "^20.17.0 || >=22.9.0" 9303 + } 9304 + }, 9305 + "node_modules/npm/node_modules/@npmcli/installed-package-contents": { 9306 + "version": "3.0.0", 9307 + "inBundle": true, 9308 + "license": "ISC", 9309 + "dependencies": { 9310 + "npm-bundled": "^4.0.0", 9311 + "npm-normalize-package-bin": "^4.0.0" 9312 + }, 9313 + "bin": { 9314 + "installed-package-contents": "bin/index.js" 9315 + }, 9316 + "engines": { 9317 + "node": "^18.17.0 || >=20.5.0" 9318 + } 9319 + }, 9320 + "node_modules/npm/node_modules/@npmcli/map-workspaces": { 9321 + "version": "5.0.0", 9322 + "inBundle": true, 9323 + "license": "ISC", 9324 + "dependencies": { 9325 + "@npmcli/name-from-folder": "^3.0.0", 9326 + "@npmcli/package-json": "^7.0.0", 9327 + "glob": "^11.0.3", 9328 + "minimatch": "^10.0.3" 9329 + }, 9330 + "engines": { 9331 + "node": "^20.17.0 || >=22.9.0" 9332 + } 9333 + }, 9334 + "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { 9335 + "version": "9.0.2", 9336 + "inBundle": true, 9337 + "license": "ISC", 9338 + "dependencies": { 9339 + "cacache": "^20.0.0", 9340 + "json-parse-even-better-errors": "^4.0.0", 9341 + "pacote": "^21.0.0", 9342 + "proc-log": "^5.0.0", 9343 + "semver": "^7.3.5" 9344 + }, 9345 + "engines": { 9346 + "node": "^20.17.0 || >=22.9.0" 9347 + } 9348 + }, 9349 + "node_modules/npm/node_modules/@npmcli/name-from-folder": { 9350 + "version": "3.0.0", 9351 + "inBundle": true, 9352 + "license": "ISC", 9353 + "engines": { 9354 + "node": "^18.17.0 || >=20.5.0" 9355 + } 9356 + }, 9357 + "node_modules/npm/node_modules/@npmcli/node-gyp": { 9358 + "version": "4.0.0", 9359 + "inBundle": true, 9360 + "license": "ISC", 9361 + "engines": { 9362 + "node": "^18.17.0 || >=20.5.0" 9363 + } 9364 + }, 9365 + "node_modules/npm/node_modules/@npmcli/package-json": { 9366 + "version": "7.0.1", 9367 + "inBundle": true, 9368 + "license": "ISC", 9369 + "dependencies": { 9370 + "@npmcli/git": "^7.0.0", 9371 + "glob": "^11.0.3", 9372 + "hosted-git-info": "^9.0.0", 9373 + "json-parse-even-better-errors": "^4.0.0", 9374 + "proc-log": "^5.0.0", 9375 + "semver": "^7.5.3", 9376 + "validate-npm-package-license": "^3.0.4" 9377 + }, 9378 + "engines": { 9379 + "node": "^20.17.0 || >=22.9.0" 9380 + } 9381 + }, 9382 + "node_modules/npm/node_modules/@npmcli/promise-spawn": { 9383 + "version": "8.0.3", 9384 + "inBundle": true, 9385 + "license": "ISC", 9386 + "dependencies": { 9387 + "which": "^5.0.0" 9388 + }, 9389 + "engines": { 9390 + "node": "^18.17.0 || >=20.5.0" 9391 + } 9392 + }, 9393 + "node_modules/npm/node_modules/@npmcli/query": { 9394 + "version": "4.0.1", 9395 + "inBundle": true, 9396 + "license": "ISC", 9397 + "dependencies": { 9398 + "postcss-selector-parser": "^7.0.0" 9399 + }, 9400 + "engines": { 9401 + "node": "^18.17.0 || >=20.5.0" 9402 + } 9403 + }, 9404 + "node_modules/npm/node_modules/@npmcli/redact": { 9405 + "version": "3.2.2", 9406 + "inBundle": true, 9407 + "license": "ISC", 9408 + "engines": { 9409 + "node": "^18.17.0 || >=20.5.0" 9410 + } 9411 + }, 9412 + "node_modules/npm/node_modules/@npmcli/run-script": { 9413 + "version": "10.0.0", 9414 + "inBundle": true, 9415 + "license": "ISC", 9416 + "dependencies": { 9417 + "@npmcli/node-gyp": "^4.0.0", 9418 + "@npmcli/package-json": "^7.0.0", 9419 + "@npmcli/promise-spawn": "^8.0.0", 9420 + "node-gyp": "^11.0.0", 9421 + "proc-log": "^5.0.0", 9422 + "which": "^5.0.0" 9423 + }, 9424 + "engines": { 9425 + "node": "^20.17.0 || >=22.9.0" 9426 + } 9427 + }, 9428 + "node_modules/npm/node_modules/@pkgjs/parseargs": { 9429 + "version": "0.11.0", 9430 + "inBundle": true, 9431 + "license": "MIT", 9432 + "optional": true, 9433 + "engines": { 9434 + "node": ">=14" 9435 + } 9436 + }, 9437 + "node_modules/npm/node_modules/@sigstore/bundle": { 9438 + "version": "4.0.0", 9439 + "inBundle": true, 9440 + "license": "Apache-2.0", 9441 + "dependencies": { 9442 + "@sigstore/protobuf-specs": "^0.5.0" 9443 + }, 9444 + "engines": { 9445 + "node": "^20.17.0 || >=22.9.0" 9446 + } 9447 + }, 9448 + "node_modules/npm/node_modules/@sigstore/core": { 9449 + "version": "3.0.0", 9450 + "inBundle": true, 9451 + "license": "Apache-2.0", 9452 + "engines": { 9453 + "node": "^20.17.0 || >=22.9.0" 9454 + } 9455 + }, 9456 + "node_modules/npm/node_modules/@sigstore/protobuf-specs": { 9457 + "version": "0.5.0", 9458 + "inBundle": true, 9459 + "license": "Apache-2.0", 9460 + "engines": { 9461 + "node": "^18.17.0 || >=20.5.0" 9462 + } 9463 + }, 9464 + "node_modules/npm/node_modules/@sigstore/sign": { 9465 + "version": "4.0.1", 9466 + "inBundle": true, 9467 + "license": "Apache-2.0", 9468 + "dependencies": { 9469 + "@sigstore/bundle": "^4.0.0", 9470 + "@sigstore/core": "^3.0.0", 9471 + "@sigstore/protobuf-specs": "^0.5.0", 9472 + "make-fetch-happen": "^15.0.2", 9473 + "proc-log": "^5.0.0", 9474 + "promise-retry": "^2.0.1" 9475 + }, 9476 + "engines": { 9477 + "node": "^20.17.0 || >=22.9.0" 9478 + } 9479 + }, 9480 + "node_modules/npm/node_modules/@sigstore/tuf": { 9481 + "version": "4.0.0", 9482 + "inBundle": true, 9483 + "license": "Apache-2.0", 9484 + "dependencies": { 9485 + "@sigstore/protobuf-specs": "^0.5.0", 9486 + "tuf-js": "^4.0.0" 9487 + }, 9488 + "engines": { 9489 + "node": "^20.17.0 || >=22.9.0" 9490 + } 9491 + }, 9492 + "node_modules/npm/node_modules/@sigstore/verify": { 9493 + "version": "3.0.0", 9494 + "inBundle": true, 9495 + "license": "Apache-2.0", 9496 + "dependencies": { 9497 + "@sigstore/bundle": "^4.0.0", 9498 + "@sigstore/core": "^3.0.0", 9499 + "@sigstore/protobuf-specs": "^0.5.0" 9500 + }, 9501 + "engines": { 9502 + "node": "^20.17.0 || >=22.9.0" 9503 + } 9504 + }, 9505 + "node_modules/npm/node_modules/@tufjs/canonical-json": { 9506 + "version": "2.0.0", 9507 + "inBundle": true, 9508 + "license": "MIT", 9509 + "engines": { 9510 + "node": "^16.14.0 || >=18.0.0" 9511 + } 9512 + }, 9513 + "node_modules/npm/node_modules/@tufjs/models": { 9514 + "version": "4.0.0", 9515 + "inBundle": true, 9516 + "license": "MIT", 9517 + "dependencies": { 9518 + "@tufjs/canonical-json": "2.0.0", 9519 + "minimatch": "^9.0.5" 9520 + }, 9521 + "engines": { 9522 + "node": "^20.17.0 || >=22.9.0" 9523 + } 9524 + }, 9525 + "node_modules/npm/node_modules/@tufjs/models/node_modules/minimatch": { 9526 + "version": "9.0.5", 9527 + "inBundle": true, 9528 + "license": "ISC", 9529 + "dependencies": { 9530 + "brace-expansion": "^2.0.1" 9531 + }, 9532 + "engines": { 9533 + "node": ">=16 || 14 >=14.17" 9534 + }, 9535 + "funding": { 9536 + "url": "https://github.com/sponsors/isaacs" 9537 + } 9538 + }, 9539 + "node_modules/npm/node_modules/abbrev": { 9540 + "version": "3.0.1", 9541 + "inBundle": true, 9542 + "license": "ISC", 9543 + "engines": { 9544 + "node": "^18.17.0 || >=20.5.0" 9545 + } 9546 + }, 9547 + "node_modules/npm/node_modules/agent-base": { 9548 + "version": "7.1.4", 9549 + "inBundle": true, 9550 + "license": "MIT", 9551 + "engines": { 9552 + "node": ">= 14" 9553 + } 9554 + }, 9555 + "node_modules/npm/node_modules/ansi-regex": { 9556 + "version": "5.0.1", 9557 + "inBundle": true, 9558 + "license": "MIT", 9559 + "engines": { 9560 + "node": ">=8" 9561 + } 9562 + }, 9563 + "node_modules/npm/node_modules/ansi-styles": { 9564 + "version": "6.2.3", 9565 + "inBundle": true, 9566 + "license": "MIT", 9567 + "engines": { 9568 + "node": ">=12" 9569 + }, 9570 + "funding": { 9571 + "url": "https://github.com/chalk/ansi-styles?sponsor=1" 9572 + } 9573 + }, 9574 + "node_modules/npm/node_modules/aproba": { 9575 + "version": "2.1.0", 9576 + "inBundle": true, 9577 + "license": "ISC" 9578 + }, 9579 + "node_modules/npm/node_modules/archy": { 9580 + "version": "1.0.0", 9581 + "inBundle": true, 9582 + "license": "MIT" 9583 + }, 9584 + "node_modules/npm/node_modules/balanced-match": { 9585 + "version": "1.0.2", 9586 + "inBundle": true, 9587 + "license": "MIT" 9588 + }, 9589 + "node_modules/npm/node_modules/bin-links": { 9590 + "version": "5.0.0", 9591 + "inBundle": true, 9592 + "license": "ISC", 9593 + "dependencies": { 9594 + "cmd-shim": "^7.0.0", 9595 + "npm-normalize-package-bin": "^4.0.0", 9596 + "proc-log": "^5.0.0", 9597 + "read-cmd-shim": "^5.0.0", 9598 + "write-file-atomic": "^6.0.0" 9599 + }, 9600 + "engines": { 9601 + "node": "^18.17.0 || >=20.5.0" 9602 + } 9603 + }, 9604 + "node_modules/npm/node_modules/binary-extensions": { 9605 + "version": "3.1.0", 9606 + "inBundle": true, 9607 + "license": "MIT", 9608 + "engines": { 9609 + "node": ">=18.20" 9610 + }, 9611 + "funding": { 9612 + "url": "https://github.com/sponsors/sindresorhus" 9613 + } 9614 + }, 9615 + "node_modules/npm/node_modules/brace-expansion": { 9616 + "version": "2.0.2", 9617 + "inBundle": true, 9618 + "license": "MIT", 9619 + "dependencies": { 9620 + "balanced-match": "^1.0.0" 9621 + } 9622 + }, 9623 + "node_modules/npm/node_modules/cacache": { 9624 + "version": "20.0.1", 9625 + "inBundle": true, 9626 + "license": "ISC", 9627 + "dependencies": { 9628 + "@npmcli/fs": "^4.0.0", 9629 + "fs-minipass": "^3.0.0", 9630 + "glob": "^11.0.3", 9631 + "lru-cache": "^11.1.0", 9632 + "minipass": "^7.0.3", 9633 + "minipass-collect": "^2.0.1", 9634 + "minipass-flush": "^1.0.5", 9635 + "minipass-pipeline": "^1.2.4", 9636 + "p-map": "^7.0.2", 9637 + "ssri": "^12.0.0", 9638 + "unique-filename": "^4.0.0" 9639 + }, 9640 + "engines": { 9641 + "node": "^20.17.0 || >=22.9.0" 9642 + } 9643 + }, 9644 + "node_modules/npm/node_modules/chalk": { 9645 + "version": "5.6.2", 9646 + "inBundle": true, 9647 + "license": "MIT", 9648 + "engines": { 9649 + "node": "^12.17.0 || ^14.13 || >=16.0.0" 9650 + }, 9651 + "funding": { 9652 + "url": "https://github.com/chalk/chalk?sponsor=1" 9653 + } 9654 + }, 9655 + "node_modules/npm/node_modules/chownr": { 9656 + "version": "3.0.0", 9657 + "inBundle": true, 9658 + "license": "BlueOak-1.0.0", 9659 + "engines": { 9660 + "node": ">=18" 9661 + } 9662 + }, 9663 + "node_modules/npm/node_modules/ci-info": { 9664 + "version": "4.3.1", 9665 + "funding": [ 9666 + { 9667 + "type": "github", 9668 + "url": "https://github.com/sponsors/sibiraj-s" 9669 + } 9670 + ], 9671 + "inBundle": true, 9672 + "license": "MIT", 9673 + "engines": { 9674 + "node": ">=8" 9675 + } 9676 + }, 9677 + "node_modules/npm/node_modules/cidr-regex": { 9678 + "version": "5.0.1", 9679 + "inBundle": true, 9680 + "license": "BSD-2-Clause", 9681 + "dependencies": { 9682 + "ip-regex": "5.0.0" 9683 + }, 9684 + "engines": { 9685 + "node": ">=20" 9686 + } 9687 + }, 9688 + "node_modules/npm/node_modules/cli-columns": { 9689 + "version": "4.0.0", 9690 + "inBundle": true, 9691 + "license": "MIT", 9692 + "dependencies": { 9693 + "string-width": "^4.2.3", 9694 + "strip-ansi": "^6.0.1" 9695 + }, 9696 + "engines": { 9697 + "node": ">= 10" 9698 + } 9699 + }, 9700 + "node_modules/npm/node_modules/cmd-shim": { 9701 + "version": "7.0.0", 9702 + "inBundle": true, 9703 + "license": "ISC", 9704 + "engines": { 9705 + "node": "^18.17.0 || >=20.5.0" 9706 + } 9707 + }, 9708 + "node_modules/npm/node_modules/color-convert": { 9709 + "version": "2.0.1", 9710 + "inBundle": true, 9711 + "license": "MIT", 9712 + "dependencies": { 9713 + "color-name": "~1.1.4" 9714 + }, 9715 + "engines": { 9716 + "node": ">=7.0.0" 9717 + } 9718 + }, 9719 + "node_modules/npm/node_modules/color-name": { 9720 + "version": "1.1.4", 9721 + "inBundle": true, 9722 + "license": "MIT" 9723 + }, 9724 + "node_modules/npm/node_modules/common-ancestor-path": { 9725 + "version": "1.0.1", 9726 + "inBundle": true, 9727 + "license": "ISC" 9728 + }, 9729 + "node_modules/npm/node_modules/cross-spawn": { 9730 + "version": "7.0.6", 9731 + "inBundle": true, 9732 + "license": "MIT", 9733 + "dependencies": { 9734 + "path-key": "^3.1.0", 9735 + "shebang-command": "^2.0.0", 9736 + "which": "^2.0.1" 9737 + }, 9738 + "engines": { 9739 + "node": ">= 8" 9740 + } 9741 + }, 9742 + "node_modules/npm/node_modules/cross-spawn/node_modules/isexe": { 9743 + "version": "2.0.0", 9744 + "inBundle": true, 9745 + "license": "ISC" 9746 + }, 9747 + "node_modules/npm/node_modules/cross-spawn/node_modules/which": { 9748 + "version": "2.0.2", 9749 + "inBundle": true, 9750 + "license": "ISC", 9751 + "dependencies": { 9752 + "isexe": "^2.0.0" 9753 + }, 9754 + "bin": { 9755 + "node-which": "bin/node-which" 9756 + }, 9757 + "engines": { 9758 + "node": ">= 8" 9759 + } 9760 + }, 9761 + "node_modules/npm/node_modules/cssesc": { 9762 + "version": "3.0.0", 9763 + "inBundle": true, 9764 + "license": "MIT", 9765 + "bin": { 9766 + "cssesc": "bin/cssesc" 9767 + }, 9768 + "engines": { 9769 + "node": ">=4" 9770 + } 9771 + }, 9772 + "node_modules/npm/node_modules/debug": { 9773 + "version": "4.4.3", 9774 + "inBundle": true, 9775 + "license": "MIT", 9776 + "dependencies": { 9777 + "ms": "^2.1.3" 9778 + }, 9779 + "engines": { 9780 + "node": ">=6.0" 9781 + }, 9782 + "peerDependenciesMeta": { 9783 + "supports-color": { 9784 + "optional": true 9785 + } 9786 + } 9787 + }, 9788 + "node_modules/npm/node_modules/diff": { 9789 + "version": "8.0.2", 9790 + "inBundle": true, 9791 + "license": "BSD-3-Clause", 9792 + "engines": { 9793 + "node": ">=0.3.1" 9794 + } 9795 + }, 9796 + "node_modules/npm/node_modules/eastasianwidth": { 9797 + "version": "0.2.0", 9798 + "inBundle": true, 9799 + "license": "MIT" 9800 + }, 9801 + "node_modules/npm/node_modules/emoji-regex": { 9802 + "version": "8.0.0", 9803 + "inBundle": true, 9804 + "license": "MIT" 9805 + }, 9806 + "node_modules/npm/node_modules/encoding": { 9807 + "version": "0.1.13", 9808 + "inBundle": true, 9809 + "license": "MIT", 9810 + "optional": true, 9811 + "dependencies": { 9812 + "iconv-lite": "^0.6.2" 9813 + } 9814 + }, 9815 + "node_modules/npm/node_modules/env-paths": { 9816 + "version": "2.2.1", 9817 + "inBundle": true, 9818 + "license": "MIT", 9819 + "engines": { 9820 + "node": ">=6" 9821 + } 9822 + }, 9823 + "node_modules/npm/node_modules/err-code": { 9824 + "version": "2.0.3", 9825 + "inBundle": true, 9826 + "license": "MIT" 9827 + }, 9828 + "node_modules/npm/node_modules/exponential-backoff": { 9829 + "version": "3.1.2", 9830 + "inBundle": true, 9831 + "license": "Apache-2.0" 9832 + }, 9833 + "node_modules/npm/node_modules/fastest-levenshtein": { 9834 + "version": "1.0.16", 9835 + "inBundle": true, 9836 + "license": "MIT", 9837 + "engines": { 9838 + "node": ">= 4.9.1" 9839 + } 9840 + }, 9841 + "node_modules/npm/node_modules/foreground-child": { 9842 + "version": "3.3.1", 9843 + "inBundle": true, 9844 + "license": "ISC", 9845 + "dependencies": { 9846 + "cross-spawn": "^7.0.6", 9847 + "signal-exit": "^4.0.1" 9848 + }, 9849 + "engines": { 9850 + "node": ">=14" 9851 + }, 9852 + "funding": { 9853 + "url": "https://github.com/sponsors/isaacs" 9854 + } 9855 + }, 9856 + "node_modules/npm/node_modules/fs-minipass": { 9857 + "version": "3.0.3", 9858 + "inBundle": true, 9859 + "license": "ISC", 9860 + "dependencies": { 9861 + "minipass": "^7.0.3" 9862 + }, 9863 + "engines": { 9864 + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" 9865 + } 9866 + }, 9867 + "node_modules/npm/node_modules/glob": { 9868 + "version": "11.0.3", 9869 + "inBundle": true, 9870 + "license": "ISC", 9871 + "dependencies": { 9872 + "foreground-child": "^3.3.1", 9873 + "jackspeak": "^4.1.1", 9874 + "minimatch": "^10.0.3", 9875 + "minipass": "^7.1.2", 9876 + "package-json-from-dist": "^1.0.0", 9877 + "path-scurry": "^2.0.0" 9878 + }, 9879 + "bin": { 9880 + "glob": "dist/esm/bin.mjs" 9881 + }, 9882 + "engines": { 9883 + "node": "20 || >=22" 9884 + }, 9885 + "funding": { 9886 + "url": "https://github.com/sponsors/isaacs" 9887 + } 9888 + }, 9889 + "node_modules/npm/node_modules/graceful-fs": { 9890 + "version": "4.2.11", 9891 + "inBundle": true, 9892 + "license": "ISC" 9893 + }, 9894 + "node_modules/npm/node_modules/hosted-git-info": { 9895 + "version": "9.0.2", 9896 + "inBundle": true, 9897 + "license": "ISC", 9898 + "dependencies": { 9899 + "lru-cache": "^11.1.0" 9900 + }, 9901 + "engines": { 9902 + "node": "^20.17.0 || >=22.9.0" 9903 + } 9904 + }, 9905 + "node_modules/npm/node_modules/http-cache-semantics": { 9906 + "version": "4.2.0", 9907 + "inBundle": true, 9908 + "license": "BSD-2-Clause" 9909 + }, 9910 + "node_modules/npm/node_modules/http-proxy-agent": { 9911 + "version": "7.0.2", 9912 + "inBundle": true, 9913 + "license": "MIT", 9914 + "dependencies": { 9915 + "agent-base": "^7.1.0", 9916 + "debug": "^4.3.4" 9917 + }, 9918 + "engines": { 9919 + "node": ">= 14" 9920 + } 9921 + }, 9922 + "node_modules/npm/node_modules/https-proxy-agent": { 9923 + "version": "7.0.6", 9924 + "inBundle": true, 9925 + "license": "MIT", 9926 + "dependencies": { 9927 + "agent-base": "^7.1.2", 9928 + "debug": "4" 9929 + }, 9930 + "engines": { 9931 + "node": ">= 14" 9932 + } 9933 + }, 9934 + "node_modules/npm/node_modules/iconv-lite": { 9935 + "version": "0.6.3", 9936 + "inBundle": true, 9937 + "license": "MIT", 9938 + "optional": true, 9939 + "dependencies": { 9940 + "safer-buffer": ">= 2.1.2 < 3.0.0" 9941 + }, 9942 + "engines": { 9943 + "node": ">=0.10.0" 9944 + } 9945 + }, 9946 + "node_modules/npm/node_modules/ignore-walk": { 9947 + "version": "8.0.0", 9948 + "inBundle": true, 9949 + "license": "ISC", 9950 + "dependencies": { 9951 + "minimatch": "^10.0.3" 9952 + }, 9953 + "engines": { 9954 + "node": "^20.17.0 || >=22.9.0" 9955 + } 9956 + }, 9957 + "node_modules/npm/node_modules/imurmurhash": { 9958 + "version": "0.1.4", 9959 + "inBundle": true, 9960 + "license": "MIT", 9961 + "engines": { 9962 + "node": ">=0.8.19" 9963 + } 9964 + }, 9965 + "node_modules/npm/node_modules/ini": { 9966 + "version": "5.0.0", 9967 + "inBundle": true, 9968 + "license": "ISC", 9969 + "engines": { 9970 + "node": "^18.17.0 || >=20.5.0" 9971 + } 9972 + }, 9973 + "node_modules/npm/node_modules/init-package-json": { 9974 + "version": "8.2.2", 9975 + "inBundle": true, 9976 + "license": "ISC", 9977 + "dependencies": { 9978 + "@npmcli/package-json": "^7.0.0", 9979 + "npm-package-arg": "^13.0.0", 9980 + "promzard": "^2.0.0", 9981 + "read": "^4.0.0", 9982 + "semver": "^7.7.2", 9983 + "validate-npm-package-license": "^3.0.4", 9984 + "validate-npm-package-name": "^6.0.2" 9985 + }, 9986 + "engines": { 9987 + "node": "^20.17.0 || >=22.9.0" 9988 + } 9989 + }, 9990 + "node_modules/npm/node_modules/ip-address": { 9991 + "version": "10.0.1", 9992 + "inBundle": true, 9993 + "license": "MIT", 9994 + "engines": { 9995 + "node": ">= 12" 9996 + } 9997 + }, 9998 + "node_modules/npm/node_modules/ip-regex": { 9999 + "version": "5.0.0", 10000 + "inBundle": true, 10001 + "license": "MIT", 10002 + "engines": { 10003 + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" 10004 + }, 10005 + "funding": { 10006 + "url": "https://github.com/sponsors/sindresorhus" 10007 + } 10008 + }, 10009 + "node_modules/npm/node_modules/is-cidr": { 10010 + "version": "6.0.1", 10011 + "inBundle": true, 10012 + "license": "BSD-2-Clause", 10013 + "dependencies": { 10014 + "cidr-regex": "5.0.1" 10015 + }, 10016 + "engines": { 10017 + "node": ">=20" 10018 + } 10019 + }, 10020 + "node_modules/npm/node_modules/is-fullwidth-code-point": { 10021 + "version": "3.0.0", 10022 + "inBundle": true, 10023 + "license": "MIT", 10024 + "engines": { 10025 + "node": ">=8" 10026 + } 10027 + }, 10028 + "node_modules/npm/node_modules/isexe": { 10029 + "version": "3.1.1", 10030 + "inBundle": true, 10031 + "license": "ISC", 10032 + "engines": { 10033 + "node": ">=16" 10034 + } 10035 + }, 10036 + "node_modules/npm/node_modules/jackspeak": { 10037 + "version": "4.1.1", 10038 + "inBundle": true, 10039 + "license": "BlueOak-1.0.0", 10040 + "dependencies": { 10041 + "@isaacs/cliui": "^8.0.2" 10042 + }, 10043 + "engines": { 10044 + "node": "20 || >=22" 10045 + }, 10046 + "funding": { 10047 + "url": "https://github.com/sponsors/isaacs" 10048 + } 10049 + }, 10050 + "node_modules/npm/node_modules/json-parse-even-better-errors": { 10051 + "version": "4.0.0", 10052 + "inBundle": true, 10053 + "license": "MIT", 10054 + "engines": { 10055 + "node": "^18.17.0 || >=20.5.0" 10056 + } 10057 + }, 10058 + "node_modules/npm/node_modules/json-stringify-nice": { 10059 + "version": "1.1.4", 10060 + "inBundle": true, 10061 + "license": "ISC", 10062 + "funding": { 10063 + "url": "https://github.com/sponsors/isaacs" 10064 + } 10065 + }, 10066 + "node_modules/npm/node_modules/jsonparse": { 10067 + "version": "1.3.1", 10068 + "engines": [ 10069 + "node >= 0.2.0" 10070 + ], 10071 + "inBundle": true, 10072 + "license": "MIT" 10073 + }, 10074 + "node_modules/npm/node_modules/just-diff": { 10075 + "version": "6.0.2", 10076 + "inBundle": true, 10077 + "license": "MIT" 10078 + }, 10079 + "node_modules/npm/node_modules/just-diff-apply": { 10080 + "version": "5.5.0", 10081 + "inBundle": true, 10082 + "license": "MIT" 10083 + }, 10084 + "node_modules/npm/node_modules/libnpmaccess": { 10085 + "version": "10.0.3", 10086 + "inBundle": true, 10087 + "license": "ISC", 10088 + "dependencies": { 10089 + "npm-package-arg": "^13.0.0", 10090 + "npm-registry-fetch": "^19.0.0" 10091 + }, 10092 + "engines": { 10093 + "node": "^20.17.0 || >=22.9.0" 10094 + } 10095 + }, 10096 + "node_modules/npm/node_modules/libnpmdiff": { 10097 + "version": "8.0.9", 10098 + "inBundle": true, 10099 + "license": "ISC", 10100 + "dependencies": { 10101 + "@npmcli/arborist": "^9.1.6", 10102 + "@npmcli/installed-package-contents": "^3.0.0", 10103 + "binary-extensions": "^3.0.0", 10104 + "diff": "^8.0.2", 10105 + "minimatch": "^10.0.3", 10106 + "npm-package-arg": "^13.0.0", 10107 + "pacote": "^21.0.2", 10108 + "tar": "^7.5.1" 10109 + }, 10110 + "engines": { 10111 + "node": "^20.17.0 || >=22.9.0" 10112 + } 10113 + }, 10114 + "node_modules/npm/node_modules/libnpmexec": { 10115 + "version": "10.1.8", 10116 + "inBundle": true, 10117 + "license": "ISC", 10118 + "dependencies": { 10119 + "@npmcli/arborist": "^9.1.6", 10120 + "@npmcli/package-json": "^7.0.0", 10121 + "@npmcli/run-script": "^10.0.0", 10122 + "ci-info": "^4.0.0", 10123 + "npm-package-arg": "^13.0.0", 10124 + "pacote": "^21.0.2", 10125 + "proc-log": "^5.0.0", 10126 + "promise-retry": "^2.0.1", 10127 + "read": "^4.0.0", 10128 + "semver": "^7.3.7", 10129 + "signal-exit": "^4.1.0", 10130 + "walk-up-path": "^4.0.0" 10131 + }, 10132 + "engines": { 10133 + "node": "^20.17.0 || >=22.9.0" 10134 + } 10135 + }, 10136 + "node_modules/npm/node_modules/libnpmfund": { 10137 + "version": "7.0.9", 10138 + "inBundle": true, 10139 + "license": "ISC", 10140 + "dependencies": { 10141 + "@npmcli/arborist": "^9.1.6" 10142 + }, 10143 + "engines": { 10144 + "node": "^20.17.0 || >=22.9.0" 10145 + } 10146 + }, 10147 + "node_modules/npm/node_modules/libnpmorg": { 10148 + "version": "8.0.1", 10149 + "inBundle": true, 10150 + "license": "ISC", 10151 + "dependencies": { 10152 + "aproba": "^2.0.0", 10153 + "npm-registry-fetch": "^19.0.0" 10154 + }, 10155 + "engines": { 10156 + "node": "^20.17.0 || >=22.9.0" 10157 + } 10158 + }, 10159 + "node_modules/npm/node_modules/libnpmpack": { 10160 + "version": "9.0.9", 10161 + "inBundle": true, 10162 + "license": "ISC", 10163 + "dependencies": { 10164 + "@npmcli/arborist": "^9.1.6", 10165 + "@npmcli/run-script": "^10.0.0", 10166 + "npm-package-arg": "^13.0.0", 10167 + "pacote": "^21.0.2" 10168 + }, 10169 + "engines": { 10170 + "node": "^20.17.0 || >=22.9.0" 10171 + } 10172 + }, 10173 + "node_modules/npm/node_modules/libnpmpublish": { 10174 + "version": "11.1.2", 10175 + "inBundle": true, 10176 + "license": "ISC", 10177 + "dependencies": { 10178 + "@npmcli/package-json": "^7.0.0", 10179 + "ci-info": "^4.0.0", 10180 + "npm-package-arg": "^13.0.0", 10181 + "npm-registry-fetch": "^19.0.0", 10182 + "proc-log": "^5.0.0", 10183 + "semver": "^7.3.7", 10184 + "sigstore": "^4.0.0", 10185 + "ssri": "^12.0.0" 10186 + }, 10187 + "engines": { 10188 + "node": "^20.17.0 || >=22.9.0" 10189 + } 10190 + }, 10191 + "node_modules/npm/node_modules/libnpmsearch": { 10192 + "version": "9.0.1", 10193 + "inBundle": true, 10194 + "license": "ISC", 10195 + "dependencies": { 10196 + "npm-registry-fetch": "^19.0.0" 10197 + }, 10198 + "engines": { 10199 + "node": "^20.17.0 || >=22.9.0" 10200 + } 10201 + }, 10202 + "node_modules/npm/node_modules/libnpmteam": { 10203 + "version": "8.0.2", 10204 + "inBundle": true, 10205 + "license": "ISC", 10206 + "dependencies": { 10207 + "aproba": "^2.0.0", 10208 + "npm-registry-fetch": "^19.0.0" 10209 + }, 10210 + "engines": { 10211 + "node": "^20.17.0 || >=22.9.0" 10212 + } 10213 + }, 10214 + "node_modules/npm/node_modules/libnpmversion": { 10215 + "version": "8.0.2", 10216 + "inBundle": true, 10217 + "license": "ISC", 10218 + "dependencies": { 10219 + "@npmcli/git": "^7.0.0", 10220 + "@npmcli/run-script": "^10.0.0", 10221 + "json-parse-even-better-errors": "^4.0.0", 10222 + "proc-log": "^5.0.0", 10223 + "semver": "^7.3.7" 10224 + }, 10225 + "engines": { 10226 + "node": "^20.17.0 || >=22.9.0" 10227 + } 10228 + }, 10229 + "node_modules/npm/node_modules/lru-cache": { 10230 + "version": "11.2.2", 10231 + "inBundle": true, 10232 + "license": "ISC", 10233 + "engines": { 10234 + "node": "20 || >=22" 10235 + } 10236 + }, 10237 + "node_modules/npm/node_modules/make-fetch-happen": { 10238 + "version": "15.0.2", 10239 + "inBundle": true, 10240 + "license": "ISC", 10241 + "dependencies": { 10242 + "@npmcli/agent": "^4.0.0", 10243 + "cacache": "^20.0.1", 10244 + "http-cache-semantics": "^4.1.1", 10245 + "minipass": "^7.0.2", 10246 + "minipass-fetch": "^4.0.0", 10247 + "minipass-flush": "^1.0.5", 10248 + "minipass-pipeline": "^1.2.4", 10249 + "negotiator": "^1.0.0", 10250 + "proc-log": "^5.0.0", 10251 + "promise-retry": "^2.0.1", 10252 + "ssri": "^12.0.0" 10253 + }, 10254 + "engines": { 10255 + "node": "^20.17.0 || >=22.9.0" 10256 + } 10257 + }, 10258 + "node_modules/npm/node_modules/minimatch": { 10259 + "version": "10.0.3", 10260 + "inBundle": true, 10261 + "license": "ISC", 10262 + "dependencies": { 10263 + "@isaacs/brace-expansion": "^5.0.0" 10264 + }, 10265 + "engines": { 10266 + "node": "20 || >=22" 10267 + }, 10268 + "funding": { 10269 + "url": "https://github.com/sponsors/isaacs" 10270 + } 10271 + }, 10272 + "node_modules/npm/node_modules/minipass": { 10273 + "version": "7.1.2", 10274 + "inBundle": true, 10275 + "license": "ISC", 10276 + "engines": { 10277 + "node": ">=16 || 14 >=14.17" 10278 + } 10279 + }, 10280 + "node_modules/npm/node_modules/minipass-collect": { 10281 + "version": "2.0.1", 10282 + "inBundle": true, 10283 + "license": "ISC", 10284 + "dependencies": { 10285 + "minipass": "^7.0.3" 10286 + }, 10287 + "engines": { 10288 + "node": ">=16 || 14 >=14.17" 10289 + } 10290 + }, 10291 + "node_modules/npm/node_modules/minipass-fetch": { 10292 + "version": "4.0.1", 10293 + "inBundle": true, 10294 + "license": "MIT", 10295 + "dependencies": { 10296 + "minipass": "^7.0.3", 10297 + "minipass-sized": "^1.0.3", 10298 + "minizlib": "^3.0.1" 10299 + }, 10300 + "engines": { 10301 + "node": "^18.17.0 || >=20.5.0" 10302 + }, 10303 + "optionalDependencies": { 10304 + "encoding": "^0.1.13" 10305 + } 10306 + }, 10307 + "node_modules/npm/node_modules/minipass-flush": { 10308 + "version": "1.0.5", 10309 + "inBundle": true, 10310 + "license": "ISC", 10311 + "dependencies": { 10312 + "minipass": "^3.0.0" 10313 + }, 10314 + "engines": { 10315 + "node": ">= 8" 10316 + } 10317 + }, 10318 + "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { 10319 + "version": "3.3.6", 10320 + "inBundle": true, 10321 + "license": "ISC", 10322 + "dependencies": { 10323 + "yallist": "^4.0.0" 10324 + }, 10325 + "engines": { 10326 + "node": ">=8" 10327 + } 10328 + }, 10329 + "node_modules/npm/node_modules/minipass-pipeline": { 10330 + "version": "1.2.4", 10331 + "inBundle": true, 10332 + "license": "ISC", 10333 + "dependencies": { 10334 + "minipass": "^3.0.0" 10335 + }, 10336 + "engines": { 10337 + "node": ">=8" 10338 + } 10339 + }, 10340 + "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": { 10341 + "version": "3.3.6", 10342 + "inBundle": true, 10343 + "license": "ISC", 10344 + "dependencies": { 10345 + "yallist": "^4.0.0" 10346 + }, 10347 + "engines": { 10348 + "node": ">=8" 10349 + } 10350 + }, 10351 + "node_modules/npm/node_modules/minipass-sized": { 10352 + "version": "1.0.3", 10353 + "inBundle": true, 10354 + "license": "ISC", 10355 + "dependencies": { 10356 + "minipass": "^3.0.0" 10357 + }, 10358 + "engines": { 10359 + "node": ">=8" 10360 + } 10361 + }, 10362 + "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": { 10363 + "version": "3.3.6", 10364 + "inBundle": true, 10365 + "license": "ISC", 10366 + "dependencies": { 10367 + "yallist": "^4.0.0" 10368 + }, 10369 + "engines": { 10370 + "node": ">=8" 10371 + } 10372 + }, 10373 + "node_modules/npm/node_modules/minizlib": { 10374 + "version": "3.1.0", 10375 + "inBundle": true, 10376 + "license": "MIT", 10377 + "dependencies": { 10378 + "minipass": "^7.1.2" 10379 + }, 10380 + "engines": { 10381 + "node": ">= 18" 10382 + } 10383 + }, 10384 + "node_modules/npm/node_modules/ms": { 10385 + "version": "2.1.3", 10386 + "inBundle": true, 10387 + "license": "MIT" 10388 + }, 10389 + "node_modules/npm/node_modules/mute-stream": { 10390 + "version": "2.0.0", 10391 + "inBundle": true, 10392 + "license": "ISC", 10393 + "engines": { 10394 + "node": "^18.17.0 || >=20.5.0" 10395 + } 10396 + }, 10397 + "node_modules/npm/node_modules/negotiator": { 10398 + "version": "1.0.0", 10399 + "inBundle": true, 10400 + "license": "MIT", 10401 + "engines": { 10402 + "node": ">= 0.6" 10403 + } 10404 + }, 10405 + "node_modules/npm/node_modules/node-gyp": { 10406 + "version": "11.4.2", 10407 + "inBundle": true, 10408 + "license": "MIT", 10409 + "dependencies": { 10410 + "env-paths": "^2.2.0", 10411 + "exponential-backoff": "^3.1.1", 10412 + "graceful-fs": "^4.2.6", 10413 + "make-fetch-happen": "^14.0.3", 10414 + "nopt": "^8.0.0", 10415 + "proc-log": "^5.0.0", 10416 + "semver": "^7.3.5", 10417 + "tar": "^7.4.3", 10418 + "tinyglobby": "^0.2.12", 10419 + "which": "^5.0.0" 10420 + }, 10421 + "bin": { 10422 + "node-gyp": "bin/node-gyp.js" 10423 + }, 10424 + "engines": { 10425 + "node": "^18.17.0 || >=20.5.0" 10426 + } 10427 + }, 10428 + "node_modules/npm/node_modules/node-gyp/node_modules/@npmcli/agent": { 10429 + "version": "3.0.0", 10430 + "inBundle": true, 10431 + "license": "ISC", 10432 + "dependencies": { 10433 + "agent-base": "^7.1.0", 10434 + "http-proxy-agent": "^7.0.0", 10435 + "https-proxy-agent": "^7.0.1", 10436 + "lru-cache": "^10.0.1", 10437 + "socks-proxy-agent": "^8.0.3" 10438 + }, 10439 + "engines": { 10440 + "node": "^18.17.0 || >=20.5.0" 10441 + } 10442 + }, 10443 + "node_modules/npm/node_modules/node-gyp/node_modules/cacache": { 10444 + "version": "19.0.1", 10445 + "inBundle": true, 10446 + "license": "ISC", 10447 + "dependencies": { 10448 + "@npmcli/fs": "^4.0.0", 10449 + "fs-minipass": "^3.0.0", 10450 + "glob": "^10.2.2", 10451 + "lru-cache": "^10.0.1", 10452 + "minipass": "^7.0.3", 10453 + "minipass-collect": "^2.0.1", 10454 + "minipass-flush": "^1.0.5", 10455 + "minipass-pipeline": "^1.2.4", 10456 + "p-map": "^7.0.2", 10457 + "ssri": "^12.0.0", 10458 + "tar": "^7.4.3", 10459 + "unique-filename": "^4.0.0" 10460 + }, 10461 + "engines": { 10462 + "node": "^18.17.0 || >=20.5.0" 10463 + } 10464 + }, 10465 + "node_modules/npm/node_modules/node-gyp/node_modules/glob": { 10466 + "version": "10.4.5", 10467 + "inBundle": true, 10468 + "license": "ISC", 10469 + "dependencies": { 10470 + "foreground-child": "^3.1.0", 10471 + "jackspeak": "^3.1.2", 10472 + "minimatch": "^9.0.4", 10473 + "minipass": "^7.1.2", 10474 + "package-json-from-dist": "^1.0.0", 10475 + "path-scurry": "^1.11.1" 10476 + }, 10477 + "bin": { 10478 + "glob": "dist/esm/bin.mjs" 10479 + }, 10480 + "funding": { 10481 + "url": "https://github.com/sponsors/isaacs" 10482 + } 10483 + }, 10484 + "node_modules/npm/node_modules/node-gyp/node_modules/jackspeak": { 10485 + "version": "3.4.3", 10486 + "inBundle": true, 10487 + "license": "BlueOak-1.0.0", 10488 + "dependencies": { 10489 + "@isaacs/cliui": "^8.0.2" 10490 + }, 10491 + "funding": { 10492 + "url": "https://github.com/sponsors/isaacs" 10493 + }, 10494 + "optionalDependencies": { 10495 + "@pkgjs/parseargs": "^0.11.0" 10496 + } 10497 + }, 10498 + "node_modules/npm/node_modules/node-gyp/node_modules/lru-cache": { 10499 + "version": "10.4.3", 10500 + "inBundle": true, 10501 + "license": "ISC" 10502 + }, 10503 + "node_modules/npm/node_modules/node-gyp/node_modules/make-fetch-happen": { 10504 + "version": "14.0.3", 10505 + "inBundle": true, 10506 + "license": "ISC", 10507 + "dependencies": { 10508 + "@npmcli/agent": "^3.0.0", 10509 + "cacache": "^19.0.1", 10510 + "http-cache-semantics": "^4.1.1", 10511 + "minipass": "^7.0.2", 10512 + "minipass-fetch": "^4.0.0", 10513 + "minipass-flush": "^1.0.5", 10514 + "minipass-pipeline": "^1.2.4", 10515 + "negotiator": "^1.0.0", 10516 + "proc-log": "^5.0.0", 10517 + "promise-retry": "^2.0.1", 10518 + "ssri": "^12.0.0" 10519 + }, 10520 + "engines": { 10521 + "node": "^18.17.0 || >=20.5.0" 10522 + } 10523 + }, 10524 + "node_modules/npm/node_modules/node-gyp/node_modules/minimatch": { 10525 + "version": "9.0.5", 10526 + "inBundle": true, 10527 + "license": "ISC", 10528 + "dependencies": { 10529 + "brace-expansion": "^2.0.1" 10530 + }, 10531 + "engines": { 10532 + "node": ">=16 || 14 >=14.17" 10533 + }, 10534 + "funding": { 10535 + "url": "https://github.com/sponsors/isaacs" 10536 + } 10537 + }, 10538 + "node_modules/npm/node_modules/node-gyp/node_modules/path-scurry": { 10539 + "version": "1.11.1", 10540 + "inBundle": true, 10541 + "license": "BlueOak-1.0.0", 10542 + "dependencies": { 10543 + "lru-cache": "^10.2.0", 10544 + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" 10545 + }, 10546 + "engines": { 10547 + "node": ">=16 || 14 >=14.18" 10548 + }, 10549 + "funding": { 10550 + "url": "https://github.com/sponsors/isaacs" 10551 + } 10552 + }, 10553 + "node_modules/npm/node_modules/nopt": { 10554 + "version": "8.1.0", 10555 + "inBundle": true, 10556 + "license": "ISC", 10557 + "dependencies": { 10558 + "abbrev": "^3.0.0" 10559 + }, 10560 + "bin": { 10561 + "nopt": "bin/nopt.js" 10562 + }, 10563 + "engines": { 10564 + "node": "^18.17.0 || >=20.5.0" 10565 + } 10566 + }, 10567 + "node_modules/npm/node_modules/npm-audit-report": { 10568 + "version": "6.0.0", 10569 + "inBundle": true, 10570 + "license": "ISC", 10571 + "engines": { 10572 + "node": "^18.17.0 || >=20.5.0" 10573 + } 10574 + }, 10575 + "node_modules/npm/node_modules/npm-bundled": { 10576 + "version": "4.0.0", 10577 + "inBundle": true, 10578 + "license": "ISC", 10579 + "dependencies": { 10580 + "npm-normalize-package-bin": "^4.0.0" 10581 + }, 10582 + "engines": { 10583 + "node": "^18.17.0 || >=20.5.0" 10584 + } 10585 + }, 10586 + "node_modules/npm/node_modules/npm-install-checks": { 10587 + "version": "7.1.2", 10588 + "inBundle": true, 10589 + "license": "BSD-2-Clause", 10590 + "dependencies": { 10591 + "semver": "^7.1.1" 10592 + }, 10593 + "engines": { 10594 + "node": "^18.17.0 || >=20.5.0" 10595 + } 10596 + }, 10597 + "node_modules/npm/node_modules/npm-normalize-package-bin": { 10598 + "version": "4.0.0", 10599 + "inBundle": true, 10600 + "license": "ISC", 10601 + "engines": { 10602 + "node": "^18.17.0 || >=20.5.0" 10603 + } 10604 + }, 10605 + "node_modules/npm/node_modules/npm-package-arg": { 10606 + "version": "13.0.1", 10607 + "inBundle": true, 10608 + "license": "ISC", 10609 + "dependencies": { 10610 + "hosted-git-info": "^9.0.0", 10611 + "proc-log": "^5.0.0", 10612 + "semver": "^7.3.5", 10613 + "validate-npm-package-name": "^6.0.0" 10614 + }, 10615 + "engines": { 10616 + "node": "^20.17.0 || >=22.9.0" 10617 + } 10618 + }, 10619 + "node_modules/npm/node_modules/npm-packlist": { 10620 + "version": "10.0.2", 10621 + "inBundle": true, 10622 + "license": "ISC", 10623 + "dependencies": { 10624 + "ignore-walk": "^8.0.0", 10625 + "proc-log": "^5.0.0" 10626 + }, 10627 + "engines": { 10628 + "node": "^20.17.0 || >=22.9.0" 10629 + } 10630 + }, 10631 + "node_modules/npm/node_modules/npm-pick-manifest": { 10632 + "version": "11.0.1", 10633 + "inBundle": true, 10634 + "license": "ISC", 10635 + "dependencies": { 10636 + "npm-install-checks": "^7.1.0", 10637 + "npm-normalize-package-bin": "^4.0.0", 10638 + "npm-package-arg": "^13.0.0", 10639 + "semver": "^7.3.5" 10640 + }, 10641 + "engines": { 10642 + "node": "^20.17.0 || >=22.9.0" 10643 + } 10644 + }, 10645 + "node_modules/npm/node_modules/npm-profile": { 10646 + "version": "12.0.0", 10647 + "inBundle": true, 10648 + "license": "ISC", 10649 + "dependencies": { 10650 + "npm-registry-fetch": "^19.0.0", 10651 + "proc-log": "^5.0.0" 10652 + }, 10653 + "engines": { 10654 + "node": "^20.17.0 || >=22.9.0" 10655 + } 10656 + }, 10657 + "node_modules/npm/node_modules/npm-registry-fetch": { 10658 + "version": "19.0.0", 10659 + "inBundle": true, 10660 + "license": "ISC", 10661 + "dependencies": { 10662 + "@npmcli/redact": "^3.0.0", 10663 + "jsonparse": "^1.3.1", 10664 + "make-fetch-happen": "^15.0.0", 10665 + "minipass": "^7.0.2", 10666 + "minipass-fetch": "^4.0.0", 10667 + "minizlib": "^3.0.1", 10668 + "npm-package-arg": "^13.0.0", 10669 + "proc-log": "^5.0.0" 10670 + }, 10671 + "engines": { 10672 + "node": "^20.17.0 || >=22.9.0" 10673 + } 10674 + }, 10675 + "node_modules/npm/node_modules/npm-user-validate": { 10676 + "version": "3.0.0", 10677 + "inBundle": true, 10678 + "license": "BSD-2-Clause", 10679 + "engines": { 10680 + "node": "^18.17.0 || >=20.5.0" 10681 + } 10682 + }, 10683 + "node_modules/npm/node_modules/p-map": { 10684 + "version": "7.0.3", 10685 + "inBundle": true, 10686 + "license": "MIT", 10687 + "engines": { 10688 + "node": ">=18" 10689 + }, 10690 + "funding": { 10691 + "url": "https://github.com/sponsors/sindresorhus" 10692 + } 10693 + }, 10694 + "node_modules/npm/node_modules/package-json-from-dist": { 10695 + "version": "1.0.1", 10696 + "inBundle": true, 10697 + "license": "BlueOak-1.0.0" 10698 + }, 10699 + "node_modules/npm/node_modules/pacote": { 10700 + "version": "21.0.3", 10701 + "inBundle": true, 10702 + "license": "ISC", 10703 + "dependencies": { 10704 + "@npmcli/git": "^7.0.0", 10705 + "@npmcli/installed-package-contents": "^3.0.0", 10706 + "@npmcli/package-json": "^7.0.0", 10707 + "@npmcli/promise-spawn": "^8.0.0", 10708 + "@npmcli/run-script": "^10.0.0", 10709 + "cacache": "^20.0.0", 10710 + "fs-minipass": "^3.0.0", 10711 + "minipass": "^7.0.2", 10712 + "npm-package-arg": "^13.0.0", 10713 + "npm-packlist": "^10.0.1", 10714 + "npm-pick-manifest": "^11.0.1", 10715 + "npm-registry-fetch": "^19.0.0", 10716 + "proc-log": "^5.0.0", 10717 + "promise-retry": "^2.0.1", 10718 + "sigstore": "^4.0.0", 10719 + "ssri": "^12.0.0", 10720 + "tar": "^7.4.3" 10721 + }, 10722 + "bin": { 10723 + "pacote": "bin/index.js" 10724 + }, 10725 + "engines": { 10726 + "node": "^20.17.0 || >=22.9.0" 10727 + } 10728 + }, 10729 + "node_modules/npm/node_modules/parse-conflict-json": { 10730 + "version": "4.0.0", 10731 + "inBundle": true, 10732 + "license": "ISC", 10733 + "dependencies": { 10734 + "json-parse-even-better-errors": "^4.0.0", 10735 + "just-diff": "^6.0.0", 10736 + "just-diff-apply": "^5.2.0" 10737 + }, 10738 + "engines": { 10739 + "node": "^18.17.0 || >=20.5.0" 10740 + } 10741 + }, 10742 + "node_modules/npm/node_modules/path-key": { 10743 + "version": "3.1.1", 10744 + "inBundle": true, 10745 + "license": "MIT", 10746 + "engines": { 10747 + "node": ">=8" 10748 + } 10749 + }, 10750 + "node_modules/npm/node_modules/path-scurry": { 10751 + "version": "2.0.0", 10752 + "inBundle": true, 10753 + "license": "BlueOak-1.0.0", 10754 + "dependencies": { 10755 + "lru-cache": "^11.0.0", 10756 + "minipass": "^7.1.2" 10757 + }, 10758 + "engines": { 10759 + "node": "20 || >=22" 10760 + }, 10761 + "funding": { 10762 + "url": "https://github.com/sponsors/isaacs" 10763 + } 10764 + }, 10765 + "node_modules/npm/node_modules/postcss-selector-parser": { 10766 + "version": "7.1.0", 10767 + "inBundle": true, 10768 + "license": "MIT", 10769 + "dependencies": { 10770 + "cssesc": "^3.0.0", 10771 + "util-deprecate": "^1.0.2" 10772 + }, 10773 + "engines": { 10774 + "node": ">=4" 10775 + } 10776 + }, 10777 + "node_modules/npm/node_modules/proc-log": { 10778 + "version": "5.0.0", 10779 + "inBundle": true, 10780 + "license": "ISC", 10781 + "engines": { 10782 + "node": "^18.17.0 || >=20.5.0" 10783 + } 10784 + }, 10785 + "node_modules/npm/node_modules/proggy": { 10786 + "version": "3.0.0", 10787 + "inBundle": true, 10788 + "license": "ISC", 10789 + "engines": { 10790 + "node": "^18.17.0 || >=20.5.0" 10791 + } 10792 + }, 10793 + "node_modules/npm/node_modules/promise-all-reject-late": { 10794 + "version": "1.0.1", 10795 + "inBundle": true, 10796 + "license": "ISC", 10797 + "funding": { 10798 + "url": "https://github.com/sponsors/isaacs" 10799 + } 10800 + }, 10801 + "node_modules/npm/node_modules/promise-call-limit": { 10802 + "version": "3.0.2", 10803 + "inBundle": true, 10804 + "license": "ISC", 10805 + "funding": { 10806 + "url": "https://github.com/sponsors/isaacs" 10807 + } 10808 + }, 10809 + "node_modules/npm/node_modules/promise-retry": { 10810 + "version": "2.0.1", 10811 + "inBundle": true, 10812 + "license": "MIT", 10813 + "dependencies": { 10814 + "err-code": "^2.0.2", 10815 + "retry": "^0.12.0" 10816 + }, 10817 + "engines": { 10818 + "node": ">=10" 10819 + } 10820 + }, 10821 + "node_modules/npm/node_modules/promzard": { 10822 + "version": "2.0.0", 10823 + "inBundle": true, 10824 + "license": "ISC", 10825 + "dependencies": { 10826 + "read": "^4.0.0" 10827 + }, 10828 + "engines": { 10829 + "node": "^18.17.0 || >=20.5.0" 10830 + } 10831 + }, 10832 + "node_modules/npm/node_modules/qrcode-terminal": { 10833 + "version": "0.12.0", 10834 + "inBundle": true, 10835 + "bin": { 10836 + "qrcode-terminal": "bin/qrcode-terminal.js" 10837 + } 10838 + }, 10839 + "node_modules/npm/node_modules/read": { 10840 + "version": "4.1.0", 10841 + "inBundle": true, 10842 + "license": "ISC", 10843 + "dependencies": { 10844 + "mute-stream": "^2.0.0" 10845 + }, 10846 + "engines": { 10847 + "node": "^18.17.0 || >=20.5.0" 10848 + } 10849 + }, 10850 + "node_modules/npm/node_modules/read-cmd-shim": { 10851 + "version": "5.0.0", 10852 + "inBundle": true, 10853 + "license": "ISC", 10854 + "engines": { 10855 + "node": "^18.17.0 || >=20.5.0" 10856 + } 10857 + }, 10858 + "node_modules/npm/node_modules/retry": { 10859 + "version": "0.12.0", 10860 + "inBundle": true, 10861 + "license": "MIT", 10862 + "engines": { 10863 + "node": ">= 4" 10864 + } 10865 + }, 10866 + "node_modules/npm/node_modules/safer-buffer": { 10867 + "version": "2.1.2", 10868 + "inBundle": true, 10869 + "license": "MIT", 10870 + "optional": true 10871 + }, 10872 + "node_modules/npm/node_modules/semver": { 10873 + "version": "7.7.3", 10874 + "inBundle": true, 10875 + "license": "ISC", 10876 + "bin": { 10877 + "semver": "bin/semver.js" 10878 + }, 10879 + "engines": { 10880 + "node": ">=10" 10881 + } 10882 + }, 10883 + "node_modules/npm/node_modules/shebang-command": { 10884 + "version": "2.0.0", 10885 + "inBundle": true, 10886 + "license": "MIT", 10887 + "dependencies": { 10888 + "shebang-regex": "^3.0.0" 10889 + }, 10890 + "engines": { 10891 + "node": ">=8" 10892 + } 10893 + }, 10894 + "node_modules/npm/node_modules/shebang-regex": { 10895 + "version": "3.0.0", 10896 + "inBundle": true, 10897 + "license": "MIT", 10898 + "engines": { 10899 + "node": ">=8" 10900 + } 10901 + }, 10902 + "node_modules/npm/node_modules/signal-exit": { 10903 + "version": "4.1.0", 10904 + "inBundle": true, 10905 + "license": "ISC", 10906 + "engines": { 10907 + "node": ">=14" 10908 + }, 10909 + "funding": { 10910 + "url": "https://github.com/sponsors/isaacs" 10911 + } 10912 + }, 10913 + "node_modules/npm/node_modules/sigstore": { 10914 + "version": "4.0.0", 10915 + "inBundle": true, 10916 + "license": "Apache-2.0", 10917 + "dependencies": { 10918 + "@sigstore/bundle": "^4.0.0", 10919 + "@sigstore/core": "^3.0.0", 10920 + "@sigstore/protobuf-specs": "^0.5.0", 10921 + "@sigstore/sign": "^4.0.0", 10922 + "@sigstore/tuf": "^4.0.0", 10923 + "@sigstore/verify": "^3.0.0" 10924 + }, 10925 + "engines": { 10926 + "node": "^20.17.0 || >=22.9.0" 10927 + } 10928 + }, 10929 + "node_modules/npm/node_modules/smart-buffer": { 10930 + "version": "4.2.0", 10931 + "inBundle": true, 10932 + "license": "MIT", 10933 + "engines": { 10934 + "node": ">= 6.0.0", 10935 + "npm": ">= 3.0.0" 10936 + } 10937 + }, 10938 + "node_modules/npm/node_modules/socks": { 10939 + "version": "2.8.7", 10940 + "inBundle": true, 10941 + "license": "MIT", 10942 + "dependencies": { 10943 + "ip-address": "^10.0.1", 10944 + "smart-buffer": "^4.2.0" 10945 + }, 10946 + "engines": { 10947 + "node": ">= 10.0.0", 10948 + "npm": ">= 3.0.0" 10949 + } 10950 + }, 10951 + "node_modules/npm/node_modules/socks-proxy-agent": { 10952 + "version": "8.0.5", 10953 + "inBundle": true, 10954 + "license": "MIT", 10955 + "dependencies": { 10956 + "agent-base": "^7.1.2", 10957 + "debug": "^4.3.4", 10958 + "socks": "^2.8.3" 10959 + }, 10960 + "engines": { 10961 + "node": ">= 14" 10962 + } 10963 + }, 10964 + "node_modules/npm/node_modules/spdx-correct": { 10965 + "version": "3.2.0", 10966 + "inBundle": true, 10967 + "license": "Apache-2.0", 10968 + "dependencies": { 10969 + "spdx-expression-parse": "^3.0.0", 10970 + "spdx-license-ids": "^3.0.0" 10971 + } 10972 + }, 10973 + "node_modules/npm/node_modules/spdx-correct/node_modules/spdx-expression-parse": { 10974 + "version": "3.0.1", 10975 + "inBundle": true, 10976 + "license": "MIT", 10977 + "dependencies": { 10978 + "spdx-exceptions": "^2.1.0", 10979 + "spdx-license-ids": "^3.0.0" 10980 + } 10981 + }, 10982 + "node_modules/npm/node_modules/spdx-exceptions": { 10983 + "version": "2.5.0", 10984 + "inBundle": true, 10985 + "license": "CC-BY-3.0" 10986 + }, 10987 + "node_modules/npm/node_modules/spdx-expression-parse": { 10988 + "version": "4.0.0", 10989 + "inBundle": true, 10990 + "license": "MIT", 10991 + "dependencies": { 10992 + "spdx-exceptions": "^2.1.0", 10993 + "spdx-license-ids": "^3.0.0" 10994 + } 10995 + }, 10996 + "node_modules/npm/node_modules/spdx-license-ids": { 10997 + "version": "3.0.22", 10998 + "inBundle": true, 10999 + "license": "CC0-1.0" 11000 + }, 11001 + "node_modules/npm/node_modules/ssri": { 11002 + "version": "12.0.0", 11003 + "inBundle": true, 11004 + "license": "ISC", 11005 + "dependencies": { 11006 + "minipass": "^7.0.3" 11007 + }, 11008 + "engines": { 11009 + "node": "^18.17.0 || >=20.5.0" 11010 + } 11011 + }, 11012 + "node_modules/npm/node_modules/string-width": { 11013 + "version": "4.2.3", 11014 + "inBundle": true, 11015 + "license": "MIT", 11016 + "dependencies": { 11017 + "emoji-regex": "^8.0.0", 11018 + "is-fullwidth-code-point": "^3.0.0", 11019 + "strip-ansi": "^6.0.1" 11020 + }, 11021 + "engines": { 11022 + "node": ">=8" 11023 + } 11024 + }, 11025 + "node_modules/npm/node_modules/string-width-cjs": { 11026 + "name": "string-width", 11027 + "version": "4.2.3", 11028 + "inBundle": true, 11029 + "license": "MIT", 11030 + "dependencies": { 11031 + "emoji-regex": "^8.0.0", 11032 + "is-fullwidth-code-point": "^3.0.0", 11033 + "strip-ansi": "^6.0.1" 11034 + }, 11035 + "engines": { 11036 + "node": ">=8" 11037 + } 11038 + }, 11039 + "node_modules/npm/node_modules/strip-ansi": { 11040 + "version": "6.0.1", 11041 + "inBundle": true, 11042 + "license": "MIT", 11043 + "dependencies": { 11044 + "ansi-regex": "^5.0.1" 11045 + }, 11046 + "engines": { 11047 + "node": ">=8" 11048 + } 11049 + }, 11050 + "node_modules/npm/node_modules/strip-ansi-cjs": { 11051 + "name": "strip-ansi", 11052 + "version": "6.0.1", 11053 + "inBundle": true, 11054 + "license": "MIT", 11055 + "dependencies": { 11056 + "ansi-regex": "^5.0.1" 11057 + }, 11058 + "engines": { 11059 + "node": ">=8" 11060 + } 11061 + }, 11062 + "node_modules/npm/node_modules/supports-color": { 11063 + "version": "10.2.2", 11064 + "inBundle": true, 11065 + "license": "MIT", 11066 + "engines": { 11067 + "node": ">=18" 11068 + }, 11069 + "funding": { 11070 + "url": "https://github.com/chalk/supports-color?sponsor=1" 11071 + } 11072 + }, 11073 + "node_modules/npm/node_modules/tar": { 11074 + "version": "7.5.1", 11075 + "inBundle": true, 11076 + "license": "ISC", 11077 + "dependencies": { 11078 + "@isaacs/fs-minipass": "^4.0.0", 11079 + "chownr": "^3.0.0", 11080 + "minipass": "^7.1.2", 11081 + "minizlib": "^3.1.0", 11082 + "yallist": "^5.0.0" 11083 + }, 11084 + "engines": { 11085 + "node": ">=18" 11086 + } 11087 + }, 11088 + "node_modules/npm/node_modules/tar/node_modules/yallist": { 11089 + "version": "5.0.0", 11090 + "inBundle": true, 11091 + "license": "BlueOak-1.0.0", 11092 + "engines": { 11093 + "node": ">=18" 11094 + } 11095 + }, 11096 + "node_modules/npm/node_modules/text-table": { 11097 + "version": "0.2.0", 11098 + "inBundle": true, 11099 + "license": "MIT" 11100 + }, 11101 + "node_modules/npm/node_modules/tiny-relative-date": { 11102 + "version": "2.0.2", 11103 + "inBundle": true, 11104 + "license": "MIT" 11105 + }, 11106 + "node_modules/npm/node_modules/tinyglobby": { 11107 + "version": "0.2.15", 11108 + "inBundle": true, 11109 + "license": "MIT", 11110 + "dependencies": { 11111 + "fdir": "^6.5.0", 11112 + "picomatch": "^4.0.3" 11113 + }, 11114 + "engines": { 11115 + "node": ">=12.0.0" 11116 + }, 11117 + "funding": { 11118 + "url": "https://github.com/sponsors/SuperchupuDev" 11119 + } 11120 + }, 11121 + "node_modules/npm/node_modules/tinyglobby/node_modules/fdir": { 11122 + "version": "6.5.0", 11123 + "inBundle": true, 11124 + "license": "MIT", 11125 + "engines": { 11126 + "node": ">=12.0.0" 11127 + }, 11128 + "peerDependencies": { 11129 + "picomatch": "^3 || ^4" 11130 + }, 11131 + "peerDependenciesMeta": { 11132 + "picomatch": { 11133 + "optional": true 11134 + } 11135 + } 11136 + }, 11137 + "node_modules/npm/node_modules/tinyglobby/node_modules/picomatch": { 11138 + "version": "4.0.3", 11139 + "inBundle": true, 11140 + "license": "MIT", 11141 + "engines": { 11142 + "node": ">=12" 11143 + }, 11144 + "funding": { 11145 + "url": "https://github.com/sponsors/jonschlinkert" 11146 + } 11147 + }, 11148 + "node_modules/npm/node_modules/treeverse": { 11149 + "version": "3.0.0", 11150 + "inBundle": true, 11151 + "license": "ISC", 11152 + "engines": { 11153 + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" 11154 + } 11155 + }, 11156 + "node_modules/npm/node_modules/tuf-js": { 11157 + "version": "4.0.0", 11158 + "inBundle": true, 11159 + "license": "MIT", 11160 + "dependencies": { 11161 + "@tufjs/models": "4.0.0", 11162 + "debug": "^4.4.1", 11163 + "make-fetch-happen": "^15.0.0" 11164 + }, 11165 + "engines": { 11166 + "node": "^20.17.0 || >=22.9.0" 11167 + } 11168 + }, 11169 + "node_modules/npm/node_modules/unique-filename": { 11170 + "version": "4.0.0", 11171 + "inBundle": true, 11172 + "license": "ISC", 11173 + "dependencies": { 11174 + "unique-slug": "^5.0.0" 11175 + }, 11176 + "engines": { 11177 + "node": "^18.17.0 || >=20.5.0" 11178 + } 11179 + }, 11180 + "node_modules/npm/node_modules/unique-slug": { 11181 + "version": "5.0.0", 11182 + "inBundle": true, 11183 + "license": "ISC", 11184 + "dependencies": { 11185 + "imurmurhash": "^0.1.4" 11186 + }, 11187 + "engines": { 11188 + "node": "^18.17.0 || >=20.5.0" 11189 + } 11190 + }, 11191 + "node_modules/npm/node_modules/util-deprecate": { 11192 + "version": "1.0.2", 11193 + "inBundle": true, 11194 + "license": "MIT" 11195 + }, 11196 + "node_modules/npm/node_modules/validate-npm-package-license": { 11197 + "version": "3.0.4", 11198 + "inBundle": true, 11199 + "license": "Apache-2.0", 11200 + "dependencies": { 11201 + "spdx-correct": "^3.0.0", 11202 + "spdx-expression-parse": "^3.0.0" 11203 + } 11204 + }, 11205 + "node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": { 11206 + "version": "3.0.1", 11207 + "inBundle": true, 11208 + "license": "MIT", 11209 + "dependencies": { 11210 + "spdx-exceptions": "^2.1.0", 11211 + "spdx-license-ids": "^3.0.0" 11212 + } 11213 + }, 11214 + "node_modules/npm/node_modules/validate-npm-package-name": { 11215 + "version": "6.0.2", 11216 + "inBundle": true, 11217 + "license": "ISC", 11218 + "engines": { 11219 + "node": "^18.17.0 || >=20.5.0" 11220 + } 11221 + }, 11222 + "node_modules/npm/node_modules/walk-up-path": { 11223 + "version": "4.0.0", 11224 + "inBundle": true, 11225 + "license": "ISC", 11226 + "engines": { 11227 + "node": "20 || >=22" 11228 + } 11229 + }, 11230 + "node_modules/npm/node_modules/which": { 11231 + "version": "5.0.0", 11232 + "inBundle": true, 11233 + "license": "ISC", 11234 + "dependencies": { 11235 + "isexe": "^3.1.1" 11236 + }, 11237 + "bin": { 11238 + "node-which": "bin/which.js" 11239 + }, 11240 + "engines": { 11241 + "node": "^18.17.0 || >=20.5.0" 11242 + } 11243 + }, 11244 + "node_modules/npm/node_modules/wrap-ansi": { 11245 + "version": "8.1.0", 11246 + "inBundle": true, 11247 + "license": "MIT", 11248 + "dependencies": { 11249 + "ansi-styles": "^6.1.0", 11250 + "string-width": "^5.0.1", 11251 + "strip-ansi": "^7.0.1" 11252 + }, 11253 + "engines": { 11254 + "node": ">=12" 11255 + }, 11256 + "funding": { 11257 + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 11258 + } 11259 + }, 11260 + "node_modules/npm/node_modules/wrap-ansi-cjs": { 11261 + "name": "wrap-ansi", 11262 + "version": "7.0.0", 11263 + "inBundle": true, 11264 + "license": "MIT", 11265 + "dependencies": { 11266 + "ansi-styles": "^4.0.0", 11267 + "string-width": "^4.1.0", 11268 + "strip-ansi": "^6.0.0" 11269 + }, 11270 + "engines": { 11271 + "node": ">=10" 11272 + }, 11273 + "funding": { 11274 + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 11275 + } 11276 + }, 11277 + "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { 11278 + "version": "4.3.0", 11279 + "inBundle": true, 11280 + "license": "MIT", 11281 + "dependencies": { 11282 + "color-convert": "^2.0.1" 11283 + }, 11284 + "engines": { 11285 + "node": ">=8" 11286 + }, 11287 + "funding": { 11288 + "url": "https://github.com/chalk/ansi-styles?sponsor=1" 11289 + } 11290 + }, 11291 + "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": { 11292 + "version": "6.2.2", 11293 + "inBundle": true, 11294 + "license": "MIT", 11295 + "engines": { 11296 + "node": ">=12" 11297 + }, 11298 + "funding": { 11299 + "url": "https://github.com/chalk/ansi-regex?sponsor=1" 11300 + } 11301 + }, 11302 + "node_modules/npm/node_modules/wrap-ansi/node_modules/emoji-regex": { 11303 + "version": "9.2.2", 11304 + "inBundle": true, 11305 + "license": "MIT" 11306 + }, 11307 + "node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": { 11308 + "version": "5.1.2", 11309 + "inBundle": true, 11310 + "license": "MIT", 11311 + "dependencies": { 11312 + "eastasianwidth": "^0.2.0", 11313 + "emoji-regex": "^9.2.2", 11314 + "strip-ansi": "^7.0.1" 11315 + }, 11316 + "engines": { 11317 + "node": ">=12" 11318 + }, 11319 + "funding": { 11320 + "url": "https://github.com/sponsors/sindresorhus" 11321 + } 11322 + }, 11323 + "node_modules/npm/node_modules/wrap-ansi/node_modules/strip-ansi": { 11324 + "version": "7.1.2", 11325 + "inBundle": true, 11326 + "license": "MIT", 11327 + "dependencies": { 11328 + "ansi-regex": "^6.0.1" 11329 + }, 11330 + "engines": { 11331 + "node": ">=12" 11332 + }, 11333 + "funding": { 11334 + "url": "https://github.com/chalk/strip-ansi?sponsor=1" 11335 + } 11336 + }, 11337 + "node_modules/npm/node_modules/write-file-atomic": { 11338 + "version": "6.0.0", 11339 + "inBundle": true, 11340 + "license": "ISC", 11341 + "dependencies": { 11342 + "imurmurhash": "^0.1.4", 11343 + "signal-exit": "^4.0.1" 11344 + }, 11345 + "engines": { 11346 + "node": "^18.17.0 || >=20.5.0" 11347 + } 11348 + }, 11349 + "node_modules/npm/node_modules/yallist": { 11350 + "version": "4.0.0", 11351 + "inBundle": true, 11352 + "license": "ISC" 11353 + }, 4116 11354 "node_modules/nwsapi": { 4117 11355 "version": "2.2.21", 4118 11356 "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.21.tgz", ··· 4129 11367 "node": ">=0.10.0" 4130 11368 } 4131 11369 }, 11370 + "node_modules/object-inspect": { 11371 + "version": "1.13.4", 11372 + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", 11373 + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", 11374 + "dev": true, 11375 + "license": "MIT", 11376 + "engines": { 11377 + "node": ">= 0.4" 11378 + }, 11379 + "funding": { 11380 + "url": "https://github.com/sponsors/ljharb" 11381 + } 11382 + }, 11383 + "node_modules/object-keys": { 11384 + "version": "1.1.1", 11385 + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", 11386 + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", 11387 + "dev": true, 11388 + "license": "MIT", 11389 + "engines": { 11390 + "node": ">= 0.4" 11391 + } 11392 + }, 11393 + "node_modules/object.assign": { 11394 + "version": "4.1.7", 11395 + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", 11396 + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", 11397 + "dev": true, 11398 + "license": "MIT", 11399 + "dependencies": { 11400 + "call-bind": "^1.0.8", 11401 + "call-bound": "^1.0.3", 11402 + "define-properties": "^1.2.1", 11403 + "es-object-atoms": "^1.0.0", 11404 + "has-symbols": "^1.1.0", 11405 + "object-keys": "^1.1.1" 11406 + }, 11407 + "engines": { 11408 + "node": ">= 0.4" 11409 + }, 11410 + "funding": { 11411 + "url": "https://github.com/sponsors/ljharb" 11412 + } 11413 + }, 11414 + "node_modules/object.entries": { 11415 + "version": "1.1.9", 11416 + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", 11417 + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", 11418 + "dev": true, 11419 + "license": "MIT", 11420 + "dependencies": { 11421 + "call-bind": "^1.0.8", 11422 + "call-bound": "^1.0.4", 11423 + "define-properties": "^1.2.1", 11424 + "es-object-atoms": "^1.1.1" 11425 + }, 11426 + "engines": { 11427 + "node": ">= 0.4" 11428 + } 11429 + }, 11430 + "node_modules/object.fromentries": { 11431 + "version": "2.0.8", 11432 + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", 11433 + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", 11434 + "dev": true, 11435 + "license": "MIT", 11436 + "dependencies": { 11437 + "call-bind": "^1.0.7", 11438 + "define-properties": "^1.2.1", 11439 + "es-abstract": "^1.23.2", 11440 + "es-object-atoms": "^1.0.0" 11441 + }, 11442 + "engines": { 11443 + "node": ">= 0.4" 11444 + }, 11445 + "funding": { 11446 + "url": "https://github.com/sponsors/ljharb" 11447 + } 11448 + }, 11449 + "node_modules/object.values": { 11450 + "version": "1.2.1", 11451 + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", 11452 + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", 11453 + "dev": true, 11454 + "license": "MIT", 11455 + "dependencies": { 11456 + "call-bind": "^1.0.8", 11457 + "call-bound": "^1.0.3", 11458 + "define-properties": "^1.2.1", 11459 + "es-object-atoms": "^1.0.0" 11460 + }, 11461 + "engines": { 11462 + "node": ">= 0.4" 11463 + }, 11464 + "funding": { 11465 + "url": "https://github.com/sponsors/ljharb" 11466 + } 11467 + }, 11468 + "node_modules/optionator": { 11469 + "version": "0.9.4", 11470 + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", 11471 + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", 11472 + "dev": true, 11473 + "license": "MIT", 11474 + "peer": true, 11475 + "dependencies": { 11476 + "deep-is": "^0.1.3", 11477 + "fast-levenshtein": "^2.0.6", 11478 + "levn": "^0.4.1", 11479 + "prelude-ls": "^1.2.1", 11480 + "type-check": "^0.4.0", 11481 + "word-wrap": "^1.2.5" 11482 + }, 11483 + "engines": { 11484 + "node": ">= 0.8.0" 11485 + } 11486 + }, 11487 + "node_modules/own-keys": { 11488 + "version": "1.0.1", 11489 + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", 11490 + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", 11491 + "dev": true, 11492 + "license": "MIT", 11493 + "dependencies": { 11494 + "get-intrinsic": "^1.2.6", 11495 + "object-keys": "^1.1.1", 11496 + "safe-push-apply": "^1.0.0" 11497 + }, 11498 + "engines": { 11499 + "node": ">= 0.4" 11500 + }, 11501 + "funding": { 11502 + "url": "https://github.com/sponsors/ljharb" 11503 + } 11504 + }, 11505 + "node_modules/p-limit": { 11506 + "version": "3.1.0", 11507 + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 11508 + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 11509 + "dev": true, 11510 + "license": "MIT", 11511 + "peer": true, 11512 + "dependencies": { 11513 + "yocto-queue": "^0.1.0" 11514 + }, 11515 + "engines": { 11516 + "node": ">=10" 11517 + }, 11518 + "funding": { 11519 + "url": "https://github.com/sponsors/sindresorhus" 11520 + } 11521 + }, 11522 + "node_modules/p-locate": { 11523 + "version": "5.0.0", 11524 + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 11525 + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 11526 + "dev": true, 11527 + "license": "MIT", 11528 + "peer": true, 11529 + "dependencies": { 11530 + "p-limit": "^3.0.2" 11531 + }, 11532 + "engines": { 11533 + "node": ">=10" 11534 + }, 11535 + "funding": { 11536 + "url": "https://github.com/sponsors/sindresorhus" 11537 + } 11538 + }, 11539 + "node_modules/package-manager-detector": { 11540 + "version": "1.4.1", 11541 + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.4.1.tgz", 11542 + "integrity": "sha512-dSMiVLBEA4XaNJ0PRb4N5cV/SEP4BWrWZKBmfF+OUm2pQTiZ6DDkKeWaltwu3JRhLoy59ayIkJ00cx9K9CaYTg==", 11543 + "dev": true, 11544 + "license": "MIT" 11545 + }, 11546 + "node_modules/parent-module": { 11547 + "version": "1.0.1", 11548 + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 11549 + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 11550 + "dev": true, 11551 + "license": "MIT", 11552 + "dependencies": { 11553 + "callsites": "^3.0.0" 11554 + }, 11555 + "engines": { 11556 + "node": ">=6" 11557 + } 11558 + }, 11559 + "node_modules/parse-json": { 11560 + "version": "5.2.0", 11561 + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", 11562 + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", 11563 + "dev": true, 11564 + "license": "MIT", 11565 + "dependencies": { 11566 + "@babel/code-frame": "^7.0.0", 11567 + "error-ex": "^1.3.1", 11568 + "json-parse-even-better-errors": "^2.3.0", 11569 + "lines-and-columns": "^1.1.6" 11570 + }, 11571 + "engines": { 11572 + "node": ">=8" 11573 + }, 11574 + "funding": { 11575 + "url": "https://github.com/sponsors/sindresorhus" 11576 + } 11577 + }, 4132 11578 "node_modules/parse5": { 4133 11579 "version": "7.3.0", 4134 11580 "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", ··· 4148 11594 "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", 4149 11595 "license": "MIT" 4150 11596 }, 11597 + "node_modules/path-exists": { 11598 + "version": "4.0.0", 11599 + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 11600 + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 11601 + "dev": true, 11602 + "license": "MIT", 11603 + "peer": true, 11604 + "engines": { 11605 + "node": ">=8" 11606 + } 11607 + }, 11608 + "node_modules/path-key": { 11609 + "version": "3.1.1", 11610 + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 11611 + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 11612 + "dev": true, 11613 + "license": "MIT", 11614 + "peer": true, 11615 + "engines": { 11616 + "node": ">=8" 11617 + } 11618 + }, 11619 + "node_modules/path-parse": { 11620 + "version": "1.0.7", 11621 + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 11622 + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 11623 + "dev": true, 11624 + "license": "MIT" 11625 + }, 11626 + "node_modules/path-type": { 11627 + "version": "4.0.0", 11628 + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", 11629 + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", 11630 + "dev": true, 11631 + "license": "MIT", 11632 + "engines": { 11633 + "node": ">=8" 11634 + } 11635 + }, 4151 11636 "node_modules/pathe": { 4152 11637 "version": "2.0.3", 4153 11638 "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", ··· 4183 11668 "url": "https://github.com/sponsors/jonschlinkert" 4184 11669 } 4185 11670 }, 11671 + "node_modules/pkg-types": { 11672 + "version": "2.3.0", 11673 + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz", 11674 + "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==", 11675 + "dev": true, 11676 + "license": "MIT", 11677 + "dependencies": { 11678 + "confbox": "^0.2.2", 11679 + "exsolve": "^1.0.7", 11680 + "pathe": "^2.0.3" 11681 + } 11682 + }, 4186 11683 "node_modules/player.style": { 4187 11684 "version": "0.1.10", 4188 11685 "resolved": "https://registry.npmjs.org/player.style/-/player.style-0.1.10.tgz", ··· 4199 11696 "media-chrome": "~4.11.0" 4200 11697 } 4201 11698 }, 11699 + "node_modules/possible-typed-array-names": { 11700 + "version": "1.1.0", 11701 + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", 11702 + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", 11703 + "dev": true, 11704 + "license": "MIT", 11705 + "engines": { 11706 + "node": ">= 0.4" 11707 + } 11708 + }, 4202 11709 "node_modules/postcss": { 4203 11710 "version": "8.5.6", 4204 11711 "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", ··· 4227 11734 "node": "^10 || ^12 || >=14" 4228 11735 } 4229 11736 }, 11737 + "node_modules/prelude-ls": { 11738 + "version": "1.2.1", 11739 + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 11740 + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 11741 + "dev": true, 11742 + "license": "MIT", 11743 + "peer": true, 11744 + "engines": { 11745 + "node": ">= 0.8.0" 11746 + } 11747 + }, 4230 11748 "node_modules/prettier": { 4231 11749 "version": "3.6.2", 4232 11750 "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", ··· 4284 11802 "node": ">=6" 4285 11803 } 4286 11804 }, 11805 + "node_modules/quansync": { 11806 + "version": "0.2.11", 11807 + "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz", 11808 + "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==", 11809 + "dev": true, 11810 + "funding": [ 11811 + { 11812 + "type": "individual", 11813 + "url": "https://github.com/sponsors/antfu" 11814 + }, 11815 + { 11816 + "type": "individual", 11817 + "url": "https://github.com/sponsors/sxzz" 11818 + } 11819 + ], 11820 + "license": "MIT" 11821 + }, 11822 + "node_modules/queue-microtask": { 11823 + "version": "1.2.3", 11824 + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 11825 + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 11826 + "dev": true, 11827 + "funding": [ 11828 + { 11829 + "type": "github", 11830 + "url": "https://github.com/sponsors/feross" 11831 + }, 11832 + { 11833 + "type": "patreon", 11834 + "url": "https://www.patreon.com/feross" 11835 + }, 11836 + { 11837 + "type": "consulting", 11838 + "url": "https://feross.org/support" 11839 + } 11840 + ], 11841 + "license": "MIT" 11842 + }, 11843 + "node_modules/radix-ui": { 11844 + "version": "1.4.3", 11845 + "resolved": "https://registry.npmjs.org/radix-ui/-/radix-ui-1.4.3.tgz", 11846 + "integrity": "sha512-aWizCQiyeAenIdUbqEpXgRA1ya65P13NKn/W8rWkcN0OPkRDxdBVLWnIEDsS2RpwCK2nobI7oMUSmexzTDyAmA==", 11847 + "dependencies": { 11848 + "@radix-ui/primitive": "1.1.3", 11849 + "@radix-ui/react-accessible-icon": "1.1.7", 11850 + "@radix-ui/react-accordion": "1.2.12", 11851 + "@radix-ui/react-alert-dialog": "1.1.15", 11852 + "@radix-ui/react-arrow": "1.1.7", 11853 + "@radix-ui/react-aspect-ratio": "1.1.7", 11854 + "@radix-ui/react-avatar": "1.1.10", 11855 + "@radix-ui/react-checkbox": "1.3.3", 11856 + "@radix-ui/react-collapsible": "1.1.12", 11857 + "@radix-ui/react-collection": "1.1.7", 11858 + "@radix-ui/react-compose-refs": "1.1.2", 11859 + "@radix-ui/react-context": "1.1.2", 11860 + "@radix-ui/react-context-menu": "2.2.16", 11861 + "@radix-ui/react-dialog": "1.1.15", 11862 + "@radix-ui/react-direction": "1.1.1", 11863 + "@radix-ui/react-dismissable-layer": "1.1.11", 11864 + "@radix-ui/react-dropdown-menu": "2.1.16", 11865 + "@radix-ui/react-focus-guards": "1.1.3", 11866 + "@radix-ui/react-focus-scope": "1.1.7", 11867 + "@radix-ui/react-form": "0.1.8", 11868 + "@radix-ui/react-hover-card": "1.1.15", 11869 + "@radix-ui/react-label": "2.1.7", 11870 + "@radix-ui/react-menu": "2.1.16", 11871 + "@radix-ui/react-menubar": "1.1.16", 11872 + "@radix-ui/react-navigation-menu": "1.2.14", 11873 + "@radix-ui/react-one-time-password-field": "0.1.8", 11874 + "@radix-ui/react-password-toggle-field": "0.1.3", 11875 + "@radix-ui/react-popover": "1.1.15", 11876 + "@radix-ui/react-popper": "1.2.8", 11877 + "@radix-ui/react-portal": "1.1.9", 11878 + "@radix-ui/react-presence": "1.1.5", 11879 + "@radix-ui/react-primitive": "2.1.3", 11880 + "@radix-ui/react-progress": "1.1.7", 11881 + "@radix-ui/react-radio-group": "1.3.8", 11882 + "@radix-ui/react-roving-focus": "1.1.11", 11883 + "@radix-ui/react-scroll-area": "1.2.10", 11884 + "@radix-ui/react-select": "2.2.6", 11885 + "@radix-ui/react-separator": "1.1.7", 11886 + "@radix-ui/react-slider": "1.3.6", 11887 + "@radix-ui/react-slot": "1.2.3", 11888 + "@radix-ui/react-switch": "1.2.6", 11889 + "@radix-ui/react-tabs": "1.1.13", 11890 + "@radix-ui/react-toast": "1.2.15", 11891 + "@radix-ui/react-toggle": "1.1.10", 11892 + "@radix-ui/react-toggle-group": "1.1.11", 11893 + "@radix-ui/react-toolbar": "1.1.11", 11894 + "@radix-ui/react-tooltip": "1.2.8", 11895 + "@radix-ui/react-use-callback-ref": "1.1.1", 11896 + "@radix-ui/react-use-controllable-state": "1.2.2", 11897 + "@radix-ui/react-use-effect-event": "0.0.2", 11898 + "@radix-ui/react-use-escape-keydown": "1.1.1", 11899 + "@radix-ui/react-use-is-hydrated": "0.1.0", 11900 + "@radix-ui/react-use-layout-effect": "1.1.1", 11901 + "@radix-ui/react-use-size": "1.1.1", 11902 + "@radix-ui/react-visually-hidden": "1.2.3" 11903 + }, 11904 + "peerDependencies": { 11905 + "@types/react": "*", 11906 + "@types/react-dom": "*", 11907 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", 11908 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" 11909 + }, 11910 + "peerDependenciesMeta": { 11911 + "@types/react": { 11912 + "optional": true 11913 + }, 11914 + "@types/react-dom": { 11915 + "optional": true 11916 + } 11917 + } 11918 + }, 4287 11919 "node_modules/react": { 4288 11920 "version": "19.1.1", 4289 11921 "resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz", ··· 4345 11977 "node": ">=0.10.0" 4346 11978 } 4347 11979 }, 11980 + "node_modules/react-remove-scroll": { 11981 + "version": "2.7.1", 11982 + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz", 11983 + "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==", 11984 + "dependencies": { 11985 + "react-remove-scroll-bar": "^2.3.7", 11986 + "react-style-singleton": "^2.2.3", 11987 + "tslib": "^2.1.0", 11988 + "use-callback-ref": "^1.3.3", 11989 + "use-sidecar": "^1.1.3" 11990 + }, 11991 + "engines": { 11992 + "node": ">=10" 11993 + }, 11994 + "peerDependencies": { 11995 + "@types/react": "*", 11996 + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" 11997 + }, 11998 + "peerDependenciesMeta": { 11999 + "@types/react": { 12000 + "optional": true 12001 + } 12002 + } 12003 + }, 12004 + "node_modules/react-remove-scroll-bar": { 12005 + "version": "2.3.8", 12006 + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", 12007 + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", 12008 + "dependencies": { 12009 + "react-style-singleton": "^2.2.2", 12010 + "tslib": "^2.0.0" 12011 + }, 12012 + "engines": { 12013 + "node": ">=10" 12014 + }, 12015 + "peerDependencies": { 12016 + "@types/react": "*", 12017 + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" 12018 + }, 12019 + "peerDependenciesMeta": { 12020 + "@types/react": { 12021 + "optional": true 12022 + } 12023 + } 12024 + }, 12025 + "node_modules/react-style-singleton": { 12026 + "version": "2.2.3", 12027 + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", 12028 + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", 12029 + "dependencies": { 12030 + "get-nonce": "^1.0.0", 12031 + "tslib": "^2.0.0" 12032 + }, 12033 + "engines": { 12034 + "node": ">=10" 12035 + }, 12036 + "peerDependencies": { 12037 + "@types/react": "*", 12038 + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" 12039 + }, 12040 + "peerDependenciesMeta": { 12041 + "@types/react": { 12042 + "optional": true 12043 + } 12044 + } 12045 + }, 4348 12046 "node_modules/readdirp": { 4349 12047 "version": "3.6.0", 4350 12048 "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", ··· 4382 12080 "node": ">=0.10.0" 4383 12081 } 4384 12082 }, 12083 + "node_modules/reflect.getprototypeof": { 12084 + "version": "1.0.10", 12085 + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", 12086 + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", 12087 + "dev": true, 12088 + "license": "MIT", 12089 + "dependencies": { 12090 + "call-bind": "^1.0.8", 12091 + "define-properties": "^1.2.1", 12092 + "es-abstract": "^1.23.9", 12093 + "es-errors": "^1.3.0", 12094 + "es-object-atoms": "^1.0.0", 12095 + "get-intrinsic": "^1.2.7", 12096 + "get-proto": "^1.0.1", 12097 + "which-builtin-type": "^1.2.1" 12098 + }, 12099 + "engines": { 12100 + "node": ">= 0.4" 12101 + }, 12102 + "funding": { 12103 + "url": "https://github.com/sponsors/ljharb" 12104 + } 12105 + }, 12106 + "node_modules/regexp.prototype.flags": { 12107 + "version": "1.5.4", 12108 + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", 12109 + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", 12110 + "dev": true, 12111 + "license": "MIT", 12112 + "dependencies": { 12113 + "call-bind": "^1.0.8", 12114 + "define-properties": "^1.2.1", 12115 + "es-errors": "^1.3.0", 12116 + "get-proto": "^1.0.1", 12117 + "gopd": "^1.2.0", 12118 + "set-function-name": "^2.0.2" 12119 + }, 12120 + "engines": { 12121 + "node": ">= 0.4" 12122 + }, 12123 + "funding": { 12124 + "url": "https://github.com/sponsors/ljharb" 12125 + } 12126 + }, 12127 + "node_modules/resolve": { 12128 + "version": "2.0.0-next.5", 12129 + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", 12130 + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", 12131 + "dev": true, 12132 + "license": "MIT", 12133 + "dependencies": { 12134 + "is-core-module": "^2.13.0", 12135 + "path-parse": "^1.0.7", 12136 + "supports-preserve-symlinks-flag": "^1.0.0" 12137 + }, 12138 + "bin": { 12139 + "resolve": "bin/resolve" 12140 + }, 12141 + "funding": { 12142 + "url": "https://github.com/sponsors/ljharb" 12143 + } 12144 + }, 12145 + "node_modules/resolve-from": { 12146 + "version": "4.0.0", 12147 + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 12148 + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 12149 + "dev": true, 12150 + "license": "MIT", 12151 + "engines": { 12152 + "node": ">=4" 12153 + } 12154 + }, 4385 12155 "node_modules/resolve-pkg-maps": { 4386 12156 "version": "1.0.0", 4387 12157 "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", ··· 4389 12159 "license": "MIT", 4390 12160 "funding": { 4391 12161 "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" 12162 + } 12163 + }, 12164 + "node_modules/reusify": { 12165 + "version": "1.1.0", 12166 + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", 12167 + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", 12168 + "dev": true, 12169 + "license": "MIT", 12170 + "engines": { 12171 + "iojs": ">=1.0.0", 12172 + "node": ">=0.10.0" 4392 12173 } 4393 12174 }, 4394 12175 "node_modules/rollup": { ··· 4437 12218 "dev": true, 4438 12219 "license": "MIT" 4439 12220 }, 12221 + "node_modules/run-parallel": { 12222 + "version": "1.2.0", 12223 + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 12224 + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 12225 + "dev": true, 12226 + "funding": [ 12227 + { 12228 + "type": "github", 12229 + "url": "https://github.com/sponsors/feross" 12230 + }, 12231 + { 12232 + "type": "patreon", 12233 + "url": "https://www.patreon.com/feross" 12234 + }, 12235 + { 12236 + "type": "consulting", 12237 + "url": "https://feross.org/support" 12238 + } 12239 + ], 12240 + "license": "MIT", 12241 + "dependencies": { 12242 + "queue-microtask": "^1.2.2" 12243 + } 12244 + }, 12245 + "node_modules/safe-array-concat": { 12246 + "version": "1.1.3", 12247 + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", 12248 + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", 12249 + "dev": true, 12250 + "license": "MIT", 12251 + "dependencies": { 12252 + "call-bind": "^1.0.8", 12253 + "call-bound": "^1.0.2", 12254 + "get-intrinsic": "^1.2.6", 12255 + "has-symbols": "^1.1.0", 12256 + "isarray": "^2.0.5" 12257 + }, 12258 + "engines": { 12259 + "node": ">=0.4" 12260 + }, 12261 + "funding": { 12262 + "url": "https://github.com/sponsors/ljharb" 12263 + } 12264 + }, 12265 + "node_modules/safe-push-apply": { 12266 + "version": "1.0.0", 12267 + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", 12268 + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", 12269 + "dev": true, 12270 + "license": "MIT", 12271 + "dependencies": { 12272 + "es-errors": "^1.3.0", 12273 + "isarray": "^2.0.5" 12274 + }, 12275 + "engines": { 12276 + "node": ">= 0.4" 12277 + }, 12278 + "funding": { 12279 + "url": "https://github.com/sponsors/ljharb" 12280 + } 12281 + }, 12282 + "node_modules/safe-regex-test": { 12283 + "version": "1.1.0", 12284 + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", 12285 + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", 12286 + "dev": true, 12287 + "license": "MIT", 12288 + "dependencies": { 12289 + "call-bound": "^1.0.2", 12290 + "es-errors": "^1.3.0", 12291 + "is-regex": "^1.2.1" 12292 + }, 12293 + "engines": { 12294 + "node": ">= 0.4" 12295 + }, 12296 + "funding": { 12297 + "url": "https://github.com/sponsors/ljharb" 12298 + } 12299 + }, 4440 12300 "node_modules/safer-buffer": { 4441 12301 "version": "2.1.2", 4442 12302 "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", ··· 4469 12329 "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", 4470 12330 "license": "MIT" 4471 12331 }, 12332 + "node_modules/scule": { 12333 + "version": "1.3.0", 12334 + "resolved": "https://registry.npmjs.org/scule/-/scule-1.3.0.tgz", 12335 + "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==", 12336 + "dev": true, 12337 + "license": "MIT" 12338 + }, 4472 12339 "node_modules/semver": { 4473 12340 "version": "6.3.1", 4474 12341 "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", ··· 4499 12366 "seroval": "^1.0" 4500 12367 } 4501 12368 }, 12369 + "node_modules/set-function-length": { 12370 + "version": "1.2.2", 12371 + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", 12372 + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", 12373 + "dev": true, 12374 + "license": "MIT", 12375 + "dependencies": { 12376 + "define-data-property": "^1.1.4", 12377 + "es-errors": "^1.3.0", 12378 + "function-bind": "^1.1.2", 12379 + "get-intrinsic": "^1.2.4", 12380 + "gopd": "^1.0.1", 12381 + "has-property-descriptors": "^1.0.2" 12382 + }, 12383 + "engines": { 12384 + "node": ">= 0.4" 12385 + } 12386 + }, 12387 + "node_modules/set-function-name": { 12388 + "version": "2.0.2", 12389 + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", 12390 + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", 12391 + "dev": true, 12392 + "license": "MIT", 12393 + "dependencies": { 12394 + "define-data-property": "^1.1.4", 12395 + "es-errors": "^1.3.0", 12396 + "functions-have-names": "^1.2.3", 12397 + "has-property-descriptors": "^1.0.2" 12398 + }, 12399 + "engines": { 12400 + "node": ">= 0.4" 12401 + } 12402 + }, 12403 + "node_modules/set-proto": { 12404 + "version": "1.0.0", 12405 + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", 12406 + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", 12407 + "dev": true, 12408 + "license": "MIT", 12409 + "dependencies": { 12410 + "dunder-proto": "^1.0.1", 12411 + "es-errors": "^1.3.0", 12412 + "es-object-atoms": "^1.0.0" 12413 + }, 12414 + "engines": { 12415 + "node": ">= 0.4" 12416 + } 12417 + }, 12418 + "node_modules/shebang-command": { 12419 + "version": "2.0.0", 12420 + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 12421 + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 12422 + "dev": true, 12423 + "license": "MIT", 12424 + "peer": true, 12425 + "dependencies": { 12426 + "shebang-regex": "^3.0.0" 12427 + }, 12428 + "engines": { 12429 + "node": ">=8" 12430 + } 12431 + }, 12432 + "node_modules/shebang-regex": { 12433 + "version": "3.0.0", 12434 + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 12435 + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 12436 + "dev": true, 12437 + "license": "MIT", 12438 + "peer": true, 12439 + "engines": { 12440 + "node": ">=8" 12441 + } 12442 + }, 12443 + "node_modules/side-channel": { 12444 + "version": "1.1.0", 12445 + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", 12446 + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", 12447 + "dev": true, 12448 + "license": "MIT", 12449 + "dependencies": { 12450 + "es-errors": "^1.3.0", 12451 + "object-inspect": "^1.13.3", 12452 + "side-channel-list": "^1.0.0", 12453 + "side-channel-map": "^1.0.1", 12454 + "side-channel-weakmap": "^1.0.2" 12455 + }, 12456 + "engines": { 12457 + "node": ">= 0.4" 12458 + }, 12459 + "funding": { 12460 + "url": "https://github.com/sponsors/ljharb" 12461 + } 12462 + }, 12463 + "node_modules/side-channel-list": { 12464 + "version": "1.0.0", 12465 + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", 12466 + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", 12467 + "dev": true, 12468 + "license": "MIT", 12469 + "dependencies": { 12470 + "es-errors": "^1.3.0", 12471 + "object-inspect": "^1.13.3" 12472 + }, 12473 + "engines": { 12474 + "node": ">= 0.4" 12475 + }, 12476 + "funding": { 12477 + "url": "https://github.com/sponsors/ljharb" 12478 + } 12479 + }, 12480 + "node_modules/side-channel-map": { 12481 + "version": "1.0.1", 12482 + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", 12483 + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", 12484 + "dev": true, 12485 + "license": "MIT", 12486 + "dependencies": { 12487 + "call-bound": "^1.0.2", 12488 + "es-errors": "^1.3.0", 12489 + "get-intrinsic": "^1.2.5", 12490 + "object-inspect": "^1.13.3" 12491 + }, 12492 + "engines": { 12493 + "node": ">= 0.4" 12494 + }, 12495 + "funding": { 12496 + "url": "https://github.com/sponsors/ljharb" 12497 + } 12498 + }, 12499 + "node_modules/side-channel-weakmap": { 12500 + "version": "1.0.2", 12501 + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", 12502 + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", 12503 + "dev": true, 12504 + "license": "MIT", 12505 + "dependencies": { 12506 + "call-bound": "^1.0.2", 12507 + "es-errors": "^1.3.0", 12508 + "get-intrinsic": "^1.2.5", 12509 + "object-inspect": "^1.13.3", 12510 + "side-channel-map": "^1.0.1" 12511 + }, 12512 + "engines": { 12513 + "node": ">= 0.4" 12514 + }, 12515 + "funding": { 12516 + "url": "https://github.com/sponsors/ljharb" 12517 + } 12518 + }, 4502 12519 "node_modules/siginfo": { 4503 12520 "version": "2.0.0", 4504 12521 "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", 4505 12522 "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", 4506 12523 "dev": true, 4507 12524 "license": "ISC" 12525 + }, 12526 + "node_modules/snake-case": { 12527 + "version": "3.0.4", 12528 + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", 12529 + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", 12530 + "dev": true, 12531 + "license": "MIT", 12532 + "dependencies": { 12533 + "dot-case": "^3.0.4", 12534 + "tslib": "^2.0.3" 12535 + } 4508 12536 }, 4509 12537 "node_modules/solid-js": { 4510 12538 "version": "1.9.9", ··· 4555 12583 "dev": true, 4556 12584 "license": "MIT" 4557 12585 }, 12586 + "node_modules/stop-iteration-iterator": { 12587 + "version": "1.1.0", 12588 + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", 12589 + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", 12590 + "dev": true, 12591 + "license": "MIT", 12592 + "dependencies": { 12593 + "es-errors": "^1.3.0", 12594 + "internal-slot": "^1.1.0" 12595 + }, 12596 + "engines": { 12597 + "node": ">= 0.4" 12598 + } 12599 + }, 12600 + "node_modules/string-ts": { 12601 + "version": "2.2.1", 12602 + "resolved": "https://registry.npmjs.org/string-ts/-/string-ts-2.2.1.tgz", 12603 + "integrity": "sha512-Q2u0gko67PLLhbte5HmPfdOjNvUKbKQM+mCNQae6jE91DmoFHY6HH9GcdqCeNx87DZ2KKjiFxmA0R/42OneGWw==", 12604 + "dev": true, 12605 + "license": "MIT" 12606 + }, 12607 + "node_modules/string.prototype.matchall": { 12608 + "version": "4.0.12", 12609 + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", 12610 + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", 12611 + "dev": true, 12612 + "license": "MIT", 12613 + "dependencies": { 12614 + "call-bind": "^1.0.8", 12615 + "call-bound": "^1.0.3", 12616 + "define-properties": "^1.2.1", 12617 + "es-abstract": "^1.23.6", 12618 + "es-errors": "^1.3.0", 12619 + "es-object-atoms": "^1.0.0", 12620 + "get-intrinsic": "^1.2.6", 12621 + "gopd": "^1.2.0", 12622 + "has-symbols": "^1.1.0", 12623 + "internal-slot": "^1.1.0", 12624 + "regexp.prototype.flags": "^1.5.3", 12625 + "set-function-name": "^2.0.2", 12626 + "side-channel": "^1.1.0" 12627 + }, 12628 + "engines": { 12629 + "node": ">= 0.4" 12630 + }, 12631 + "funding": { 12632 + "url": "https://github.com/sponsors/ljharb" 12633 + } 12634 + }, 12635 + "node_modules/string.prototype.repeat": { 12636 + "version": "1.0.0", 12637 + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", 12638 + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", 12639 + "dev": true, 12640 + "license": "MIT", 12641 + "dependencies": { 12642 + "define-properties": "^1.1.3", 12643 + "es-abstract": "^1.17.5" 12644 + } 12645 + }, 12646 + "node_modules/string.prototype.trim": { 12647 + "version": "1.2.10", 12648 + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", 12649 + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", 12650 + "dev": true, 12651 + "license": "MIT", 12652 + "dependencies": { 12653 + "call-bind": "^1.0.8", 12654 + "call-bound": "^1.0.2", 12655 + "define-data-property": "^1.1.4", 12656 + "define-properties": "^1.2.1", 12657 + "es-abstract": "^1.23.5", 12658 + "es-object-atoms": "^1.0.0", 12659 + "has-property-descriptors": "^1.0.2" 12660 + }, 12661 + "engines": { 12662 + "node": ">= 0.4" 12663 + }, 12664 + "funding": { 12665 + "url": "https://github.com/sponsors/ljharb" 12666 + } 12667 + }, 12668 + "node_modules/string.prototype.trimend": { 12669 + "version": "1.0.9", 12670 + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", 12671 + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", 12672 + "dev": true, 12673 + "license": "MIT", 12674 + "dependencies": { 12675 + "call-bind": "^1.0.8", 12676 + "call-bound": "^1.0.2", 12677 + "define-properties": "^1.2.1", 12678 + "es-object-atoms": "^1.0.0" 12679 + }, 12680 + "engines": { 12681 + "node": ">= 0.4" 12682 + }, 12683 + "funding": { 12684 + "url": "https://github.com/sponsors/ljharb" 12685 + } 12686 + }, 12687 + "node_modules/string.prototype.trimstart": { 12688 + "version": "1.0.8", 12689 + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", 12690 + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", 12691 + "dev": true, 12692 + "license": "MIT", 12693 + "dependencies": { 12694 + "call-bind": "^1.0.7", 12695 + "define-properties": "^1.2.1", 12696 + "es-object-atoms": "^1.0.0" 12697 + }, 12698 + "engines": { 12699 + "node": ">= 0.4" 12700 + }, 12701 + "funding": { 12702 + "url": "https://github.com/sponsors/ljharb" 12703 + } 12704 + }, 12705 + "node_modules/strip-json-comments": { 12706 + "version": "3.1.1", 12707 + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 12708 + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 12709 + "dev": true, 12710 + "license": "MIT", 12711 + "peer": true, 12712 + "engines": { 12713 + "node": ">=8" 12714 + }, 12715 + "funding": { 12716 + "url": "https://github.com/sponsors/sindresorhus" 12717 + } 12718 + }, 4558 12719 "node_modules/strip-literal": { 4559 - "version": "3.0.0", 4560 - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.0.0.tgz", 4561 - "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==", 12720 + "version": "3.1.0", 12721 + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", 12722 + "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", 4562 12723 "dev": true, 4563 12724 "license": "MIT", 4564 12725 "dependencies": { ··· 4581 12742 "integrity": "sha512-9pP/CVNp4NF2MNlRzLwQkjiTgKKe9WYXrLh9+8QokWmMxz+zt2mf1utkWLco26IuA3AfVcTb//qtlTIjY3VHxA==", 4582 12743 "license": "MIT" 4583 12744 }, 12745 + "node_modules/supports-color": { 12746 + "version": "7.2.0", 12747 + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 12748 + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 12749 + "dev": true, 12750 + "license": "MIT", 12751 + "peer": true, 12752 + "dependencies": { 12753 + "has-flag": "^4.0.0" 12754 + }, 12755 + "engines": { 12756 + "node": ">=8" 12757 + } 12758 + }, 12759 + "node_modules/supports-preserve-symlinks-flag": { 12760 + "version": "1.0.0", 12761 + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 12762 + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 12763 + "dev": true, 12764 + "license": "MIT", 12765 + "engines": { 12766 + "node": ">= 0.4" 12767 + }, 12768 + "funding": { 12769 + "url": "https://github.com/sponsors/ljharb" 12770 + } 12771 + }, 12772 + "node_modules/svg-parser": { 12773 + "version": "2.0.4", 12774 + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", 12775 + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", 12776 + "dev": true, 12777 + "license": "MIT" 12778 + }, 4584 12779 "node_modules/symbol-tree": { 4585 12780 "version": "3.2.4", 4586 12781 "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", ··· 4593 12788 "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.12.tgz", 4594 12789 "integrity": "sha512-DzFtxOi+7NsFf7DBtI3BJsynR+0Yp6etH+nRPTbpWnS2pZBaSksv/JGctNwSWzbFjp0vxSqknaUylseZqMDGrA==", 4595 12790 "license": "MIT" 12791 + }, 12792 + "node_modules/tanstack-router-keepalive": { 12793 + "version": "1.0.0", 12794 + "resolved": "https://registry.npmjs.org/tanstack-router-keepalive/-/tanstack-router-keepalive-1.0.0.tgz", 12795 + "integrity": "sha512-SxMl9sgIZGjB4OZvGXufTz14ygmZi+eAbrhz3sjmXYZzhSQOekx5LYi9TvKcMXVu8fQR6W/itF5hdglqD6WB/w==", 12796 + "license": "MIT", 12797 + "dependencies": { 12798 + "eventemitter3": "^5.0.1", 12799 + "lodash.clonedeep": "^4.5.0" 12800 + } 4596 12801 }, 4597 12802 "node_modules/tapable": { 4598 12803 "version": "2.2.3", ··· 4666 12871 "license": "MIT" 4667 12872 }, 4668 12873 "node_modules/tinyglobby": { 4669 - "version": "0.2.14", 4670 - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", 4671 - "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", 12874 + "version": "0.2.15", 12875 + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", 12876 + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", 4672 12877 "license": "MIT", 4673 12878 "dependencies": { 4674 - "fdir": "^6.4.4", 4675 - "picomatch": "^4.0.2" 12879 + "fdir": "^6.5.0", 12880 + "picomatch": "^4.0.3" 4676 12881 }, 4677 12882 "engines": { 4678 12883 "node": ">=12.0.0" ··· 4807 13012 "node": ">=18" 4808 13013 } 4809 13014 }, 13015 + "node_modules/ts-api-utils": { 13016 + "version": "2.1.0", 13017 + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", 13018 + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", 13019 + "dev": true, 13020 + "license": "MIT", 13021 + "engines": { 13022 + "node": ">=18.12" 13023 + }, 13024 + "peerDependencies": { 13025 + "typescript": ">=4.8.4" 13026 + } 13027 + }, 13028 + "node_modules/ts-declaration-location": { 13029 + "version": "1.0.7", 13030 + "resolved": "https://registry.npmjs.org/ts-declaration-location/-/ts-declaration-location-1.0.7.tgz", 13031 + "integrity": "sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA==", 13032 + "dev": true, 13033 + "funding": [ 13034 + { 13035 + "type": "ko-fi", 13036 + "url": "https://ko-fi.com/rebeccastevens" 13037 + }, 13038 + { 13039 + "type": "tidelift", 13040 + "url": "https://tidelift.com/funding/github/npm/ts-declaration-location" 13041 + } 13042 + ], 13043 + "license": "BSD-3-Clause", 13044 + "dependencies": { 13045 + "picomatch": "^4.0.2" 13046 + }, 13047 + "peerDependencies": { 13048 + "typescript": ">=4.0.0" 13049 + } 13050 + }, 13051 + "node_modules/ts-declaration-location/node_modules/picomatch": { 13052 + "version": "4.0.3", 13053 + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", 13054 + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", 13055 + "dev": true, 13056 + "license": "MIT", 13057 + "engines": { 13058 + "node": ">=12" 13059 + }, 13060 + "funding": { 13061 + "url": "https://github.com/sponsors/jonschlinkert" 13062 + } 13063 + }, 13064 + "node_modules/ts-pattern": { 13065 + "version": "5.8.0", 13066 + "resolved": "https://registry.npmjs.org/ts-pattern/-/ts-pattern-5.8.0.tgz", 13067 + "integrity": "sha512-kIjN2qmWiHnhgr5DAkAafF9fwb0T5OhMVSWrm8XEdTFnX6+wfXwYOFjeF86UZ54vduqiR7BfqScFmXSzSaH8oA==", 13068 + "dev": true, 13069 + "license": "MIT" 13070 + }, 4810 13071 "node_modules/tslib": { 4811 13072 "version": "2.8.1", 4812 13073 "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", ··· 4838 13099 "integrity": "sha512-SDpZ4f7sZmwHF6XG5PF0KWuP18pH/kNG04MhTcpqJby7Lk/D3TS/lCYd+RSg0rIAAVi1LDgSIo1yJs9kmHlhgw==", 4839 13100 "license": "MIT" 4840 13101 }, 13102 + "node_modules/type-check": { 13103 + "version": "0.4.0", 13104 + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 13105 + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 13106 + "dev": true, 13107 + "license": "MIT", 13108 + "peer": true, 13109 + "dependencies": { 13110 + "prelude-ls": "^1.2.1" 13111 + }, 13112 + "engines": { 13113 + "node": ">= 0.8.0" 13114 + } 13115 + }, 13116 + "node_modules/typed-array-buffer": { 13117 + "version": "1.0.3", 13118 + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", 13119 + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", 13120 + "dev": true, 13121 + "license": "MIT", 13122 + "dependencies": { 13123 + "call-bound": "^1.0.3", 13124 + "es-errors": "^1.3.0", 13125 + "is-typed-array": "^1.1.14" 13126 + }, 13127 + "engines": { 13128 + "node": ">= 0.4" 13129 + } 13130 + }, 13131 + "node_modules/typed-array-byte-length": { 13132 + "version": "1.0.3", 13133 + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", 13134 + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", 13135 + "dev": true, 13136 + "license": "MIT", 13137 + "dependencies": { 13138 + "call-bind": "^1.0.8", 13139 + "for-each": "^0.3.3", 13140 + "gopd": "^1.2.0", 13141 + "has-proto": "^1.2.0", 13142 + "is-typed-array": "^1.1.14" 13143 + }, 13144 + "engines": { 13145 + "node": ">= 0.4" 13146 + }, 13147 + "funding": { 13148 + "url": "https://github.com/sponsors/ljharb" 13149 + } 13150 + }, 13151 + "node_modules/typed-array-byte-offset": { 13152 + "version": "1.0.4", 13153 + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", 13154 + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", 13155 + "dev": true, 13156 + "license": "MIT", 13157 + "dependencies": { 13158 + "available-typed-arrays": "^1.0.7", 13159 + "call-bind": "^1.0.8", 13160 + "for-each": "^0.3.3", 13161 + "gopd": "^1.2.0", 13162 + "has-proto": "^1.2.0", 13163 + "is-typed-array": "^1.1.15", 13164 + "reflect.getprototypeof": "^1.0.9" 13165 + }, 13166 + "engines": { 13167 + "node": ">= 0.4" 13168 + }, 13169 + "funding": { 13170 + "url": "https://github.com/sponsors/ljharb" 13171 + } 13172 + }, 13173 + "node_modules/typed-array-length": { 13174 + "version": "1.0.7", 13175 + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", 13176 + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", 13177 + "dev": true, 13178 + "license": "MIT", 13179 + "dependencies": { 13180 + "call-bind": "^1.0.7", 13181 + "for-each": "^0.3.3", 13182 + "gopd": "^1.0.1", 13183 + "is-typed-array": "^1.1.13", 13184 + "possible-typed-array-names": "^1.0.0", 13185 + "reflect.getprototypeof": "^1.0.6" 13186 + }, 13187 + "engines": { 13188 + "node": ">= 0.4" 13189 + }, 13190 + "funding": { 13191 + "url": "https://github.com/sponsors/ljharb" 13192 + } 13193 + }, 4841 13194 "node_modules/typescript": { 4842 - "version": "5.9.2", 4843 - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", 4844 - "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", 13195 + "version": "5.9.3", 13196 + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", 13197 + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", 4845 13198 "dev": true, 4846 13199 "license": "Apache-2.0", 4847 13200 "bin": { ··· 4852 13205 "node": ">=14.17" 4853 13206 } 4854 13207 }, 13208 + "node_modules/typescript-eslint": { 13209 + "version": "8.46.1", 13210 + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.46.1.tgz", 13211 + "integrity": "sha512-VHgijW803JafdSsDO8I761r3SHrgk4T00IdyQ+/UsthtgPRsBWQLqoSxOolxTpxRKi1kGXK0bSz4CoAc9ObqJA==", 13212 + "dev": true, 13213 + "license": "MIT", 13214 + "dependencies": { 13215 + "@typescript-eslint/eslint-plugin": "8.46.1", 13216 + "@typescript-eslint/parser": "8.46.1", 13217 + "@typescript-eslint/typescript-estree": "8.46.1", 13218 + "@typescript-eslint/utils": "8.46.1" 13219 + }, 13220 + "engines": { 13221 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 13222 + }, 13223 + "funding": { 13224 + "type": "opencollective", 13225 + "url": "https://opencollective.com/typescript-eslint" 13226 + }, 13227 + "peerDependencies": { 13228 + "eslint": "^8.57.0 || ^9.0.0", 13229 + "typescript": ">=4.8.4 <6.0.0" 13230 + } 13231 + }, 4855 13232 "node_modules/ua-parser-js": { 4856 13233 "version": "1.0.41", 4857 13234 "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.41.tgz", ··· 4877 13254 "engines": { 4878 13255 "node": "*" 4879 13256 } 13257 + }, 13258 + "node_modules/ufo": { 13259 + "version": "1.6.1", 13260 + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", 13261 + "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", 13262 + "dev": true, 13263 + "license": "MIT" 4880 13264 }, 4881 13265 "node_modules/uint8arrays": { 4882 13266 "version": "3.0.0", ··· 4887 13271 "multiformats": "^9.4.2" 4888 13272 } 4889 13273 }, 13274 + "node_modules/unbox-primitive": { 13275 + "version": "1.1.0", 13276 + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", 13277 + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", 13278 + "dev": true, 13279 + "license": "MIT", 13280 + "dependencies": { 13281 + "call-bound": "^1.0.3", 13282 + "has-bigints": "^1.0.2", 13283 + "has-symbols": "^1.1.0", 13284 + "which-boxed-primitive": "^1.1.1" 13285 + }, 13286 + "engines": { 13287 + "node": ">= 0.4" 13288 + }, 13289 + "funding": { 13290 + "url": "https://github.com/sponsors/ljharb" 13291 + } 13292 + }, 4890 13293 "node_modules/undici-types": { 4891 13294 "version": "7.10.0", 4892 13295 "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", ··· 4894 13297 "devOptional": true, 4895 13298 "license": "MIT" 4896 13299 }, 13300 + "node_modules/unimport": { 13301 + "version": "5.5.0", 13302 + "resolved": "https://registry.npmjs.org/unimport/-/unimport-5.5.0.tgz", 13303 + "integrity": "sha512-/JpWMG9s1nBSlXJAQ8EREFTFy3oy6USFd8T6AoBaw1q2GGcF4R9yp3ofg32UODZlYEO5VD0EWE1RpI9XDWyPYg==", 13304 + "dev": true, 13305 + "license": "MIT", 13306 + "dependencies": { 13307 + "acorn": "^8.15.0", 13308 + "escape-string-regexp": "^5.0.0", 13309 + "estree-walker": "^3.0.3", 13310 + "local-pkg": "^1.1.2", 13311 + "magic-string": "^0.30.19", 13312 + "mlly": "^1.8.0", 13313 + "pathe": "^2.0.3", 13314 + "picomatch": "^4.0.3", 13315 + "pkg-types": "^2.3.0", 13316 + "scule": "^1.3.0", 13317 + "strip-literal": "^3.1.0", 13318 + "tinyglobby": "^0.2.15", 13319 + "unplugin": "^2.3.10", 13320 + "unplugin-utils": "^0.3.0" 13321 + }, 13322 + "engines": { 13323 + "node": ">=18.12.0" 13324 + } 13325 + }, 13326 + "node_modules/unimport/node_modules/escape-string-regexp": { 13327 + "version": "5.0.0", 13328 + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", 13329 + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", 13330 + "dev": true, 13331 + "license": "MIT", 13332 + "engines": { 13333 + "node": ">=12" 13334 + }, 13335 + "funding": { 13336 + "url": "https://github.com/sponsors/sindresorhus" 13337 + } 13338 + }, 13339 + "node_modules/unimport/node_modules/picomatch": { 13340 + "version": "4.0.3", 13341 + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", 13342 + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", 13343 + "dev": true, 13344 + "license": "MIT", 13345 + "engines": { 13346 + "node": ">=12" 13347 + }, 13348 + "funding": { 13349 + "url": "https://github.com/sponsors/jonschlinkert" 13350 + } 13351 + }, 4897 13352 "node_modules/unplugin": { 4898 - "version": "2.3.9", 4899 - "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.9.tgz", 4900 - "integrity": "sha512-2dcbZq6aprwXTkzptq3k5qm5B8cvpjG9ynPd5fyM2wDJuuF7PeUK64Sxf0d+X1ZyDOeGydbNzMqBSIVlH8GIfA==", 13353 + "version": "2.3.10", 13354 + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.10.tgz", 13355 + "integrity": "sha512-6NCPkv1ClwH+/BGE9QeoTIl09nuiAt0gS28nn1PvYXsGKRwM2TCbFA2QiilmehPDTXIe684k4rZI1yl3A1PCUw==", 4901 13356 "license": "MIT", 4902 13357 "dependencies": { 4903 13358 "@jridgewell/remapping": "^2.3.5", ··· 4909 13364 "node": ">=18.12.0" 4910 13365 } 4911 13366 }, 13367 + "node_modules/unplugin-auto-import": { 13368 + "version": "20.2.0", 13369 + "resolved": "https://registry.npmjs.org/unplugin-auto-import/-/unplugin-auto-import-20.2.0.tgz", 13370 + "integrity": "sha512-vfBI/SvD9hJqYNinipVOAj5n8dS8DJXFlCKFR5iLDp2SaQwsfdnfLXgZ+34Kd3YY3YEY9omk8XQg0bwos3Q8ug==", 13371 + "dev": true, 13372 + "license": "MIT", 13373 + "dependencies": { 13374 + "local-pkg": "^1.1.2", 13375 + "magic-string": "^0.30.19", 13376 + "picomatch": "^4.0.3", 13377 + "unimport": "^5.4.0", 13378 + "unplugin": "^2.3.10", 13379 + "unplugin-utils": "^0.3.0" 13380 + }, 13381 + "engines": { 13382 + "node": ">=14" 13383 + }, 13384 + "funding": { 13385 + "url": "https://github.com/sponsors/antfu" 13386 + }, 13387 + "peerDependencies": { 13388 + "@nuxt/kit": "^4.0.0", 13389 + "@vueuse/core": "*" 13390 + }, 13391 + "peerDependenciesMeta": { 13392 + "@nuxt/kit": { 13393 + "optional": true 13394 + }, 13395 + "@vueuse/core": { 13396 + "optional": true 13397 + } 13398 + } 13399 + }, 13400 + "node_modules/unplugin-auto-import/node_modules/picomatch": { 13401 + "version": "4.0.3", 13402 + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", 13403 + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", 13404 + "dev": true, 13405 + "license": "MIT", 13406 + "engines": { 13407 + "node": ">=12" 13408 + }, 13409 + "funding": { 13410 + "url": "https://github.com/sponsors/jonschlinkert" 13411 + } 13412 + }, 13413 + "node_modules/unplugin-icons": { 13414 + "version": "22.4.2", 13415 + "resolved": "https://registry.npmjs.org/unplugin-icons/-/unplugin-icons-22.4.2.tgz", 13416 + "integrity": "sha512-Yv15405unO67Chme0Slk0JRA/H2AiAZLK5t7ebt8/ZpTDlBfM4d4En2qD3MX2rzOSkIteQ0syIm3q8MSofeoBA==", 13417 + "dev": true, 13418 + "license": "MIT", 13419 + "dependencies": { 13420 + "@antfu/install-pkg": "^1.1.0", 13421 + "@iconify/utils": "^3.0.2", 13422 + "debug": "^4.4.3", 13423 + "local-pkg": "^1.1.2", 13424 + "unplugin": "^2.3.10" 13425 + }, 13426 + "funding": { 13427 + "url": "https://github.com/sponsors/antfu" 13428 + }, 13429 + "peerDependencies": { 13430 + "@svgr/core": ">=7.0.0", 13431 + "@svgx/core": "^1.0.1", 13432 + "@vue/compiler-sfc": "^3.0.2 || ^2.7.0", 13433 + "svelte": "^3.0.0 || ^4.0.0 || ^5.0.0", 13434 + "vue-template-compiler": "^2.6.12", 13435 + "vue-template-es2015-compiler": "^1.9.0" 13436 + }, 13437 + "peerDependenciesMeta": { 13438 + "@svgr/core": { 13439 + "optional": true 13440 + }, 13441 + "@svgx/core": { 13442 + "optional": true 13443 + }, 13444 + "@vue/compiler-sfc": { 13445 + "optional": true 13446 + }, 13447 + "svelte": { 13448 + "optional": true 13449 + }, 13450 + "vue-template-compiler": { 13451 + "optional": true 13452 + }, 13453 + "vue-template-es2015-compiler": { 13454 + "optional": true 13455 + } 13456 + } 13457 + }, 13458 + "node_modules/unplugin-utils": { 13459 + "version": "0.3.1", 13460 + "resolved": "https://registry.npmjs.org/unplugin-utils/-/unplugin-utils-0.3.1.tgz", 13461 + "integrity": "sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog==", 13462 + "dev": true, 13463 + "license": "MIT", 13464 + "dependencies": { 13465 + "pathe": "^2.0.3", 13466 + "picomatch": "^4.0.3" 13467 + }, 13468 + "engines": { 13469 + "node": ">=20.19.0" 13470 + }, 13471 + "funding": { 13472 + "url": "https://github.com/sponsors/sxzz" 13473 + } 13474 + }, 13475 + "node_modules/unplugin-utils/node_modules/picomatch": { 13476 + "version": "4.0.3", 13477 + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", 13478 + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", 13479 + "dev": true, 13480 + "license": "MIT", 13481 + "engines": { 13482 + "node": ">=12" 13483 + }, 13484 + "funding": { 13485 + "url": "https://github.com/sponsors/jonschlinkert" 13486 + } 13487 + }, 4912 13488 "node_modules/unplugin/node_modules/picomatch": { 4913 13489 "version": "4.0.3", 4914 13490 "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", ··· 4949 13525 }, 4950 13526 "peerDependencies": { 4951 13527 "browserslist": ">= 4.21.0" 13528 + } 13529 + }, 13530 + "node_modules/uri-js": { 13531 + "version": "4.4.1", 13532 + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 13533 + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 13534 + "dev": true, 13535 + "license": "BSD-2-Clause", 13536 + "peer": true, 13537 + "dependencies": { 13538 + "punycode": "^2.1.0" 13539 + } 13540 + }, 13541 + "node_modules/use-callback-ref": { 13542 + "version": "1.3.3", 13543 + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", 13544 + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", 13545 + "dependencies": { 13546 + "tslib": "^2.0.0" 13547 + }, 13548 + "engines": { 13549 + "node": ">=10" 13550 + }, 13551 + "peerDependencies": { 13552 + "@types/react": "*", 13553 + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" 13554 + }, 13555 + "peerDependenciesMeta": { 13556 + "@types/react": { 13557 + "optional": true 13558 + } 13559 + } 13560 + }, 13561 + "node_modules/use-sidecar": { 13562 + "version": "1.1.3", 13563 + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", 13564 + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", 13565 + "dependencies": { 13566 + "detect-node-es": "^1.1.0", 13567 + "tslib": "^2.0.0" 13568 + }, 13569 + "engines": { 13570 + "node": ">=10" 13571 + }, 13572 + "peerDependencies": { 13573 + "@types/react": "*", 13574 + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" 13575 + }, 13576 + "peerDependenciesMeta": { 13577 + "@types/react": { 13578 + "optional": true 13579 + } 4952 13580 } 4953 13581 }, 4954 13582 "node_modules/use-sync-external-store": { ··· 5263 13891 "node": ">=18" 5264 13892 } 5265 13893 }, 13894 + "node_modules/which": { 13895 + "version": "2.0.2", 13896 + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 13897 + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 13898 + "dev": true, 13899 + "license": "ISC", 13900 + "peer": true, 13901 + "dependencies": { 13902 + "isexe": "^2.0.0" 13903 + }, 13904 + "bin": { 13905 + "node-which": "bin/node-which" 13906 + }, 13907 + "engines": { 13908 + "node": ">= 8" 13909 + } 13910 + }, 13911 + "node_modules/which-boxed-primitive": { 13912 + "version": "1.1.1", 13913 + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", 13914 + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", 13915 + "dev": true, 13916 + "license": "MIT", 13917 + "dependencies": { 13918 + "is-bigint": "^1.1.0", 13919 + "is-boolean-object": "^1.2.1", 13920 + "is-number-object": "^1.1.1", 13921 + "is-string": "^1.1.1", 13922 + "is-symbol": "^1.1.1" 13923 + }, 13924 + "engines": { 13925 + "node": ">= 0.4" 13926 + }, 13927 + "funding": { 13928 + "url": "https://github.com/sponsors/ljharb" 13929 + } 13930 + }, 13931 + "node_modules/which-builtin-type": { 13932 + "version": "1.2.1", 13933 + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", 13934 + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", 13935 + "dev": true, 13936 + "license": "MIT", 13937 + "dependencies": { 13938 + "call-bound": "^1.0.2", 13939 + "function.prototype.name": "^1.1.6", 13940 + "has-tostringtag": "^1.0.2", 13941 + "is-async-function": "^2.0.0", 13942 + "is-date-object": "^1.1.0", 13943 + "is-finalizationregistry": "^1.1.0", 13944 + "is-generator-function": "^1.0.10", 13945 + "is-regex": "^1.2.1", 13946 + "is-weakref": "^1.0.2", 13947 + "isarray": "^2.0.5", 13948 + "which-boxed-primitive": "^1.1.0", 13949 + "which-collection": "^1.0.2", 13950 + "which-typed-array": "^1.1.16" 13951 + }, 13952 + "engines": { 13953 + "node": ">= 0.4" 13954 + }, 13955 + "funding": { 13956 + "url": "https://github.com/sponsors/ljharb" 13957 + } 13958 + }, 13959 + "node_modules/which-collection": { 13960 + "version": "1.0.2", 13961 + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", 13962 + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", 13963 + "dev": true, 13964 + "license": "MIT", 13965 + "dependencies": { 13966 + "is-map": "^2.0.3", 13967 + "is-set": "^2.0.3", 13968 + "is-weakmap": "^2.0.2", 13969 + "is-weakset": "^2.0.3" 13970 + }, 13971 + "engines": { 13972 + "node": ">= 0.4" 13973 + }, 13974 + "funding": { 13975 + "url": "https://github.com/sponsors/ljharb" 13976 + } 13977 + }, 13978 + "node_modules/which-typed-array": { 13979 + "version": "1.1.19", 13980 + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", 13981 + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", 13982 + "dev": true, 13983 + "license": "MIT", 13984 + "dependencies": { 13985 + "available-typed-arrays": "^1.0.7", 13986 + "call-bind": "^1.0.8", 13987 + "call-bound": "^1.0.4", 13988 + "for-each": "^0.3.5", 13989 + "get-proto": "^1.0.1", 13990 + "gopd": "^1.2.0", 13991 + "has-tostringtag": "^1.0.2" 13992 + }, 13993 + "engines": { 13994 + "node": ">= 0.4" 13995 + }, 13996 + "funding": { 13997 + "url": "https://github.com/sponsors/ljharb" 13998 + } 13999 + }, 5266 14000 "node_modules/why-is-node-running": { 5267 14001 "version": "2.3.0", 5268 14002 "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", ··· 5289 14023 "super-media-element": "~1.4.2" 5290 14024 } 5291 14025 }, 14026 + "node_modules/word-wrap": { 14027 + "version": "1.2.5", 14028 + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", 14029 + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", 14030 + "dev": true, 14031 + "license": "MIT", 14032 + "peer": true, 14033 + "engines": { 14034 + "node": ">=0.10.0" 14035 + } 14036 + }, 5292 14037 "node_modules/ws": { 5293 14038 "version": "8.18.3", 5294 14039 "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", ··· 5333 14078 "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", 5334 14079 "license": "ISC" 5335 14080 }, 14081 + "node_modules/yocto-queue": { 14082 + "version": "0.1.0", 14083 + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 14084 + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 14085 + "dev": true, 14086 + "license": "MIT", 14087 + "peer": true, 14088 + "engines": { 14089 + "node": ">=10" 14090 + }, 14091 + "funding": { 14092 + "url": "https://github.com/sponsors/sindresorhus" 14093 + } 14094 + }, 5336 14095 "node_modules/youtube-video-element": { 5337 14096 "version": "1.6.2", 5338 14097 "resolved": "https://registry.npmjs.org/youtube-video-element/-/youtube-video-element-1.6.2.tgz", ··· 5346 14105 "license": "MIT", 5347 14106 "funding": { 5348 14107 "url": "https://github.com/sponsors/colinhacks" 14108 + } 14109 + }, 14110 + "node_modules/zod-validation-error": { 14111 + "version": "4.0.2", 14112 + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz", 14113 + "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==", 14114 + "dev": true, 14115 + "license": "MIT", 14116 + "engines": { 14117 + "node": ">=18.0.0" 14118 + }, 14119 + "peerDependencies": { 14120 + "zod": "^3.25.0 || ^4.0.0" 5349 14121 } 5350 14122 } 5351 14123 }
+27 -1
package.json
··· 12 12 "dependencies": { 13 13 "@atproto/api": "^0.16.6", 14 14 "@atproto/oauth-client-browser": "^0.3.33", 15 + "@radix-ui/react-dialog": "^1.1.15", 16 + "@radix-ui/react-dropdown-menu": "^2.1.16", 17 + "@radix-ui/react-hover-card": "^1.1.15", 18 + "@radix-ui/react-slider": "^1.3.6", 15 19 "@tailwindcss/vite": "^4.0.6", 16 20 "@tanstack/query-sync-storage-persister": "^5.85.6", 17 21 "@tanstack/react-devtools": "^0.2.2", ··· 20 24 "@tanstack/react-router": "^1.130.2", 21 25 "@tanstack/react-router-devtools": "^1.131.5", 22 26 "@tanstack/router-plugin": "^1.121.2", 27 + "dompurify": "^3.3.0", 28 + "i": "^0.3.7", 23 29 "idb-keyval": "^6.2.2", 24 30 "jotai": "^2.13.1", 31 + "npm": "^11.6.2", 32 + "radix-ui": "^1.4.3", 25 33 "react": "^19.0.0", 26 34 "react-dom": "^19.0.0", 27 35 "react-player": "^3.3.2", 28 - "tailwindcss": "^4.0.6" 36 + "tailwindcss": "^4.0.6", 37 + "tanstack-router-keepalive": "^1.0.0" 29 38 }, 30 39 "devDependencies": { 40 + "@eslint-react/eslint-plugin": "^2.2.1", 41 + "@iconify-icon/react": "^3.0.1", 42 + "@iconify-json/material-symbols": "^1.2.42", 43 + "@iconify-json/mdi": "^1.2.3", 44 + "@iconify/json": "^2.2.396", 45 + "@svgr/core": "^8.1.0", 46 + "@svgr/plugin-jsx": "^8.1.0", 31 47 "@testing-library/dom": "^10.4.0", 32 48 "@testing-library/react": "^16.2.0", 33 49 "@types/node": "^24.3.0", 34 50 "@types/react": "^19.0.8", 35 51 "@types/react-dom": "^19.0.3", 52 + "@typescript-eslint/eslint-plugin": "^8.46.1", 53 + "@typescript-eslint/parser": "^8.46.1", 36 54 "@vitejs/plugin-react": "^4.3.4", 55 + "babel-plugin-react-compiler": "^1.0.0", 56 + "eslint-plugin-react": "^7.37.5", 57 + "eslint-plugin-react-hooks": "^7.0.0", 58 + "eslint-plugin-simple-import-sort": "^12.1.1", 59 + "eslint-plugin-unused-imports": "^4.2.0", 37 60 "jsdom": "^26.0.0", 38 61 "prettier": "^3.6.2", 39 62 "typescript": "^5.7.2", 63 + "typescript-eslint": "^8.46.1", 64 + "unplugin-auto-import": "^20.2.0", 65 + "unplugin-icons": "^22.4.2", 40 66 "vite": "^6.3.5", 41 67 "vitest": "^3.0.5", 42 68 "web-vitals": "^4.2.4"
+2 -2
public/manifest.json
··· 20 20 ], 21 21 "start_url": ".", 22 22 "display": "standalone", 23 - "theme_color": "#000000", 24 - "background_color": "#ffffff" 23 + "theme_color": "#180001", 24 + "background_color": "#180001" 25 25 }
public/screenshot.jpg

This is a binary file and will not be displayed.

public/screenshot.png

This is a binary file and will not be displayed.

+22
src/auto-imports.d.ts
··· 1 + /* eslint-disable */ 2 + /* prettier-ignore */ 3 + // @ts-nocheck 4 + // noinspection JSUnusedGlobalSymbols 5 + // Generated by unplugin-auto-import 6 + // biome-ignore lint: disable 7 + export {} 8 + declare global { 9 + const IconMaterialSymbolsAccountCircle: typeof import('~icons/material-symbols/account-circle.jsx').default 10 + const IconMaterialSymbolsAccountCircleOutline: typeof import('~icons/material-symbols/account-circle-outline.jsx').default 11 + const IconMaterialSymbolsArrowBack: typeof import('~icons/material-symbols/arrow-back.jsx').default 12 + const IconMaterialSymbolsHome: typeof import('~icons/material-symbols/home.jsx').default 13 + const IconMaterialSymbolsHomeOutline: typeof import('~icons/material-symbols/home-outline.jsx').default 14 + const IconMaterialSymbolsNotifications: typeof import('~icons/material-symbols/notifications.jsx').default 15 + const IconMaterialSymbolsNotificationsOutline: typeof import('~icons/material-symbols/notifications-outline.jsx').default 16 + const IconMaterialSymbolsSearch: typeof import('~icons/material-symbols/search.jsx').default 17 + const IconMaterialSymbolsSettings: typeof import('~icons/material-symbols/settings.jsx').default 18 + const IconMaterialSymbolsSettingsOutline: typeof import('~icons/material-symbols/settings-outline.jsx').default 19 + const IconMaterialSymbolsTag: typeof import('~icons/material-symbols/tag.jsx').default 20 + const IconMdiAccountCircle: typeof import('~icons/mdi/account-circle.jsx').default 21 + const IconMdiPencilOutline: typeof import('~icons/mdi/pencil-outline.jsx').default 22 + }
+292
src/components/Composer.tsx
··· 1 + import { AppBskyRichtextFacet, RichText } from "@atproto/api"; 2 + import { useAtom } from "jotai"; 3 + import { Dialog } from "radix-ui"; 4 + import { useEffect, useRef, useState } from "react"; 5 + 6 + import { useAuth } from "~/providers/UnifiedAuthProvider"; 7 + import { composerAtom } from "~/utils/atoms"; 8 + import { useQueryPost } from "~/utils/useQuery"; 9 + 10 + import { ProfileThing } from "./Login"; 11 + import { UniversalPostRendererATURILoader } from "./UniversalPostRenderer"; 12 + 13 + const MAX_POST_LENGTH = 300; 14 + 15 + export function Composer() { 16 + const [composerState, setComposerState] = useAtom(composerAtom); 17 + const { agent } = useAuth(); 18 + 19 + const [postText, setPostText] = useState(""); 20 + const [posting, setPosting] = useState(false); 21 + const [postSuccess, setPostSuccess] = useState(false); 22 + const [postError, setPostError] = useState<string | null>(null); 23 + 24 + useEffect(() => { 25 + setPostText(""); 26 + setPosting(false); 27 + setPostSuccess(false); 28 + setPostError(null); 29 + }, [composerState.kind]); 30 + 31 + const parentUri = 32 + composerState.kind === "reply" 33 + ? composerState.parent 34 + : composerState.kind === "quote" 35 + ? composerState.subject 36 + : undefined; 37 + 38 + const { data: parentPost, isLoading: isParentLoading } = 39 + useQueryPost(parentUri); 40 + 41 + async function handlePost() { 42 + if (!agent || !postText.trim() || postText.length > MAX_POST_LENGTH) return; 43 + 44 + setPosting(true); 45 + setPostError(null); 46 + 47 + try { 48 + const rt = new RichText({ text: postText }); 49 + await rt.detectFacets(agent); 50 + 51 + if (rt.facets?.length) { 52 + rt.facets = rt.facets.filter((item) => { 53 + if (item.$type !== "app.bsky.richtext.facet") return true; 54 + if (!item.features?.length) return true; 55 + 56 + item.features = item.features.filter((feature) => { 57 + if (feature.$type !== "app.bsky.richtext.facet#mention") return true; 58 + const did = feature.$type === "app.bsky.richtext.facet#mention" ? (feature as AppBskyRichtextFacet.Mention)?.did : undefined; 59 + return typeof did === "string" && did.startsWith("did:"); 60 + }); 61 + 62 + return item.features.length > 0; 63 + }); 64 + } 65 + 66 + const record: Record<string, unknown> = { 67 + $type: "app.bsky.feed.post", 68 + text: rt.text, 69 + facets: rt.facets, 70 + createdAt: new Date().toISOString(), 71 + }; 72 + 73 + if (composerState.kind === "reply" && parentPost) { 74 + record.reply = { 75 + root: parentPost.value?.reply?.root ?? { 76 + uri: parentPost.uri, 77 + cid: parentPost.cid, 78 + }, 79 + parent: { 80 + uri: parentPost.uri, 81 + cid: parentPost.cid, 82 + }, 83 + }; 84 + } 85 + 86 + if (composerState.kind === "quote" && parentPost) { 87 + record.embed = { 88 + $type: "app.bsky.embed.record", 89 + record: { 90 + uri: parentPost.uri, 91 + cid: parentPost.cid, 92 + }, 93 + }; 94 + } 95 + 96 + await agent.com.atproto.repo.createRecord({ 97 + collection: "app.bsky.feed.post", 98 + repo: agent.assertDid, 99 + record, 100 + }); 101 + 102 + setPostSuccess(true); 103 + setPostText(""); 104 + 105 + setTimeout(() => { 106 + setPostSuccess(false); 107 + setComposerState({ kind: "closed" }); 108 + }, 1500); 109 + } catch (e: any) { 110 + setPostError(e?.message || "Failed to post"); 111 + } finally { 112 + setPosting(false); 113 + } 114 + } 115 + // if (composerState.kind === "closed") { 116 + // return null; 117 + // } 118 + 119 + const getPlaceholder = () => { 120 + switch (composerState.kind) { 121 + case "reply": 122 + return "Post your reply"; 123 + case "quote": 124 + return "Add a comment..."; 125 + case "root": 126 + default: 127 + return "What's happening?!"; 128 + } 129 + }; 130 + 131 + const charsLeft = MAX_POST_LENGTH - postText.length; 132 + const isPostButtonDisabled = 133 + posting || !postText.trim() || isParentLoading || charsLeft < 0; 134 + 135 + return ( 136 + <Dialog.Root 137 + open={composerState.kind !== "closed"} 138 + onOpenChange={(open) => { 139 + if (!open) setComposerState({ kind: "closed" }); 140 + }} 141 + > 142 + <Dialog.Portal> 143 + <Dialog.Overlay className="fixed inset-0 z-50 bg-black/40 dark:bg-black/50 data-[state=open]:animate-fadeIn" /> 144 + 145 + <Dialog.Content className="fixed overflow-y-scroll inset-0 z-50 flex items-start justify-center py-10 sm:py-20"> 146 + <div className="bg-gray-50 dark:bg-gray-950 border border-gray-200 dark:border-gray-700 rounded-2xl shadow-xl w-full max-w-xl relative mx-4"> 147 + <div className="flex flex-row justify-between p-2"> 148 + <Dialog.Close asChild> 149 + <button 150 + className="h-8 w-8 flex items-center justify-center rounded-full text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800" 151 + disabled={posting} 152 + aria-label="Close" 153 + > 154 + <svg 155 + xmlns="http://www.w3.org/2000/svg" 156 + width="20" 157 + height="20" 158 + viewBox="0 0 24 24" 159 + fill="none" 160 + stroke="currentColor" 161 + strokeWidth="2.5" 162 + strokeLinecap="round" 163 + strokeLinejoin="round" 164 + > 165 + <line x1="18" y1="6" x2="6" y2="18"></line> 166 + <line x1="6" y1="6" x2="18" y2="18"></line> 167 + </svg> 168 + </button> 169 + </Dialog.Close> 170 + 171 + <div className="flex-1" /> 172 + <div className="flex items-center gap-4"> 173 + <span 174 + className={`text-sm ${charsLeft < 0 ? "text-red-500" : "text-gray-500"}`} 175 + > 176 + {charsLeft} 177 + </span> 178 + <button 179 + className="bg-gray-600 hover:bg-gray-700 text-white font-bold py-1 px-4 rounded-full disabled:opacity-50 disabled:cursor-not-allowed transition-colors" 180 + onClick={handlePost} 181 + disabled={isPostButtonDisabled} 182 + > 183 + {posting ? "Posting..." : "Post"} 184 + </button> 185 + </div> 186 + </div> 187 + 188 + {postSuccess ? ( 189 + <div className="flex flex-col items-center justify-center py-16"> 190 + <span className="text-gray-500 text-6xl mb-4">โœ“</span> 191 + <span className="text-xl font-bold text-black dark:text-white"> 192 + Posted! 193 + </span> 194 + </div> 195 + ) : ( 196 + <div className="px-4"> 197 + {composerState.kind === "reply" && ( 198 + <div className="mb-1 -mx-4"> 199 + {isParentLoading ? ( 200 + <div className="text-sm text-gray-500 animate-pulse"> 201 + Loading parent post... 202 + </div> 203 + ) : parentUri ? ( 204 + <UniversalPostRendererATURILoader 205 + atUri={parentUri} 206 + bottomReplyLine 207 + bottomBorder={false} 208 + /> 209 + ) : ( 210 + <div className="text-sm text-red-500 rounded-lg border border-red-500/50 p-3"> 211 + Could not load parent post. 212 + </div> 213 + )} 214 + </div> 215 + )} 216 + 217 + <div className="flex w-full gap-1 flex-col"> 218 + <ProfileThing agent={agent} large /> 219 + <div className="flex pl-[50px]"> 220 + <AutoGrowTextarea 221 + className="w-full text-lg bg-transparent focus:outline-none resize-none placeholder:text-gray-500 text-black dark:text-white pb-2" 222 + rows={5} 223 + placeholder={getPlaceholder()} 224 + value={postText} 225 + onChange={(e) => setPostText(e.target.value)} 226 + disabled={posting} 227 + autoFocus 228 + /> 229 + </div> 230 + </div> 231 + 232 + {composerState.kind === "quote" && ( 233 + <div className="mb-4 ml-[50px] rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden"> 234 + {isParentLoading ? ( 235 + <div className="text-sm text-gray-500 animate-pulse"> 236 + Loading parent post... 237 + </div> 238 + ) : parentUri ? ( 239 + <UniversalPostRendererATURILoader 240 + atUri={parentUri} 241 + isQuote 242 + /> 243 + ) : ( 244 + <div className="text-sm text-red-500 rounded-lg border border-red-500/50 p-3"> 245 + Could not load parent post. 246 + </div> 247 + )} 248 + </div> 249 + )} 250 + 251 + {postError && ( 252 + <div className="text-red-500 text-sm my-2 text-center"> 253 + {postError} 254 + </div> 255 + )} 256 + </div> 257 + )} 258 + </div> 259 + </Dialog.Content> 260 + </Dialog.Portal> 261 + </Dialog.Root> 262 + ); 263 + } 264 + 265 + function AutoGrowTextarea({ 266 + value, 267 + className, 268 + onChange, 269 + ...props 270 + }: React.DetailedHTMLProps< 271 + React.TextareaHTMLAttributes<HTMLTextAreaElement>, 272 + HTMLTextAreaElement 273 + >) { 274 + const ref = useRef<HTMLTextAreaElement>(null); 275 + 276 + useEffect(() => { 277 + const el = ref.current; 278 + if (!el) return; 279 + el.style.height = "auto"; 280 + el.style.height = el.scrollHeight + "px"; 281 + }, [value]); 282 + 283 + return ( 284 + <textarea 285 + ref={ref} 286 + className={className} 287 + value={value} 288 + onChange={onChange} 289 + {...props} 290 + /> 291 + ); 292 + }
+33
src/components/Header.tsx
··· 1 + import { Link, useRouter } from "@tanstack/react-router"; 2 + import { useAtom } from "jotai"; 3 + 4 + import { isAtTopAtom } from "~/utils/atoms"; 5 + 6 + export function Header({ 7 + backButtonCallback, 8 + title 9 + }: { 10 + backButtonCallback?: () => void; 11 + title?: string; 12 + }) { 13 + const router = useRouter(); 14 + const [isAtTop] = useAtom(isAtTopAtom); 15 + //const what = router.history. 16 + return ( 17 + <div className={`flex items-center gap-3 px-3 py-3 h-[52px] sticky top-0 bg-[var(--header-bg-light)] dark:bg-[var(--header-bg-dark)] z-10 border-0 sm:border-b ${!isAtTop && "shadow-sm"} sm:shadow-none sm:dark:bg-gray-950 sm:bg-white border-gray-200 dark:border-gray-700`}> 18 + {backButtonCallback ? (<Link 19 + to=".." 20 + //className="px-3 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-900 font-bold text-lg" 21 + className="p-2 rounded-full hover:bg-gray-100 dark:hover:bg-gray-900 font-bold text-lg" 22 + onClick={(e) => { 23 + e.preventDefault(); 24 + backButtonCallback(); 25 + }} 26 + aria-label="Go back" 27 + > 28 + <IconMaterialSymbolsArrowBack className="w-6 h-6" /> 29 + </Link>) : (<div className="w-[0px]" />)} 30 + <span className="text-[21px] sm:text-[19px] sm:font-semibold font-roboto">{title}</span> 31 + </div> 32 + ); 33 + }
+150
src/components/Import.tsx
··· 1 + import { AtUri } from "@atproto/api"; 2 + import { useNavigate, type UseNavigateResult } from "@tanstack/react-router"; 3 + import { useState } from "react"; 4 + 5 + /** 6 + * Basically the best equivalent to Search that i can do 7 + */ 8 + export function Import() { 9 + const [textInput, setTextInput] = useState<string | undefined>(); 10 + const navigate = useNavigate(); 11 + 12 + const handleEnter = () => { 13 + if (!textInput) return; 14 + handleImport({ 15 + text: textInput, 16 + navigate, 17 + }); 18 + }; 19 + 20 + return ( 21 + <div className="w-full relative"> 22 + <IconMaterialSymbolsSearch className="w-5 h-5 absolute left-4 top-1/2 -translate-y-1/2 text-gray-400 dark:text-gray-500" /> 23 + 24 + <input 25 + type="text" 26 + placeholder="Import..." 27 + value={textInput} 28 + onChange={(e) => setTextInput(e.target.value)} 29 + onKeyDown={(e) => { 30 + if (e.key === "Enter") handleEnter(); 31 + }} 32 + className="w-full h-12 pl-12 pr-4 rounded-full bg-gray-100 dark:bg-gray-800 text-gray-800 dark:text-gray-200 placeholder-gray-400 dark:placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-gray-400 dark:focus:ring-gray-500 box-border transition" 33 + /> 34 + </div> 35 + ); 36 + } 37 + 38 + function handleImport({ 39 + text, 40 + navigate, 41 + }: { 42 + text: string; 43 + navigate: UseNavigateResult<string>; 44 + }) { 45 + const trimmed = text.trim(); 46 + // parse text 47 + /** 48 + * text might be 49 + * 1. bsky dot app url (reddwarf link segments might be uri encoded,) 50 + * 2. aturi 51 + * 3. plain handle 52 + * 4. plain did 53 + */ 54 + 55 + // 1. Check if itโ€™s a URL 56 + try { 57 + const url = new URL(text); 58 + const knownHosts = [ 59 + "bsky.app", 60 + "social.daniela.lol", 61 + "deer.social", 62 + "reddwarf.whey.party", 63 + "reddwarf.app", 64 + "main.bsky.dev", 65 + "catsky.social", 66 + "blacksky.community", 67 + "red-dwarf-social-app.whey.party", 68 + "zeppelin.social", 69 + ]; 70 + if (knownHosts.includes(url.hostname)) { 71 + // parse path to get URI or handle 72 + const path = decodeURIComponent(url.pathname.slice(1)); // remove leading / 73 + console.log("BSky URL path:", path); 74 + navigate({ 75 + to: `/${path}`, 76 + }); 77 + return; 78 + } 79 + } catch { 80 + // not a URL, continue 81 + } 82 + 83 + // 2. Check if text looks like an at-uri 84 + try { 85 + if (text.startsWith("at://")) { 86 + console.log("AT URI detected:", text); 87 + const aturi = new AtUri(text); 88 + switch (aturi.collection) { 89 + case "app.bsky.feed.post": { 90 + navigate({ 91 + to: "/profile/$did/post/$rkey", 92 + params: { 93 + did: aturi.host, 94 + rkey: aturi.rkey, 95 + }, 96 + }); 97 + return; 98 + } 99 + case "app.bsky.actor.profile": { 100 + navigate({ 101 + to: "/profile/$did", 102 + params: { 103 + did: aturi.host, 104 + }, 105 + }); 106 + return; 107 + } 108 + // todo add more handlers as more routes are added. like feeds, lists, etc etc thanks! 109 + default: { 110 + // continue 111 + } 112 + } 113 + } 114 + } catch { 115 + // continue 116 + } 117 + 118 + // 3. Plain handle (starts with @) 119 + try { 120 + if (text.startsWith("@")) { 121 + const handle = text.slice(1); 122 + console.log("Handle detected:", handle); 123 + navigate({ to: "/profile/$did", params: { did: handle } }); 124 + return; 125 + } 126 + } catch { 127 + // continue 128 + } 129 + 130 + // 4. Plain DID (starts with did:) 131 + try { 132 + if (text.startsWith("did:")) { 133 + console.log("did detected:", text); 134 + navigate({ to: "/profile/$did", params: { did: text } }); 135 + return; 136 + } 137 + } catch { 138 + // continue 139 + } 140 + 141 + // if all else fails 142 + 143 + // try { 144 + // // probably a user? 145 + // navigate({ to: "/profile/$did", params: { did: text } }); 146 + // return; 147 + // } catch { 148 + // // continue 149 + // } 150 + }
+36 -9
src/components/InfiniteCustomFeed.tsx
··· 1 + import { useQueryClient } from "@tanstack/react-query"; 1 2 import * as React from "react"; 3 + 2 4 //import { useInView } from "react-intersection-observer"; 3 5 import { UniversalPostRendererATURILoader } from "~/components/UniversalPostRenderer"; 4 6 import { useAuth } from "~/providers/UnifiedAuthProvider"; 5 7 import { 6 - useQueryArbitrary, 7 - useQueryIdentity, 8 8 useInfiniteQueryFeedSkeleton, 9 + // useQueryArbitrary, 10 + // useQueryIdentity, 9 11 } from "~/utils/useQuery"; 10 12 11 13 interface InfiniteCustomFeedProps { ··· 36 38 isFetchingNextPage, 37 39 refetch, 38 40 isRefetching, 41 + queryKey, 39 42 } = useInfiniteQueryFeedSkeleton({ 40 43 feedUri: feedUri, 41 44 agent: agent ?? undefined, ··· 43 46 pdsUrl: pdsUrl, 44 47 feedServiceDid: feedServiceDid, 45 48 }); 49 + const queryClient = useQueryClient(); 50 + 46 51 47 52 const handleRefresh = () => { 53 + queryClient.removeQueries({queryKey: queryKey}); 54 + //queryClient.invalidateQueries(["infinite-feed", feedUri] as const); 48 55 refetch(); 49 56 }; 50 57 58 + const allPosts = React.useMemo(() => { 59 + const flattenedPosts = data?.pages.flatMap((page) => page?.feed) ?? []; 60 + 61 + const seenUris = new Set<string>(); 62 + 63 + return flattenedPosts.filter((item) => { 64 + if (!item?.post) return false; 65 + 66 + if (seenUris.has(item.post)) { 67 + return false; 68 + } 69 + 70 + seenUris.add(item.post); 71 + 72 + return true; 73 + }); 74 + }, [data]); 75 + 51 76 //const { ref, inView } = useInView(); 52 77 53 78 // React.useEffect(() => { ··· 66 91 ); 67 92 } 68 93 69 - const allPosts = 70 - data?.pages.flatMap((page) => { 71 - if (page) return page.feed; 72 - }) ?? []; 94 + // const allPosts = 95 + // data?.pages.flatMap((page) => { 96 + // if (page) return page.feed; 97 + // }) ?? []; 73 98 74 99 if (!allPosts || typeof allPosts !== "object" || allPosts.length === 0) { 75 100 return ( ··· 112 137 <button 113 138 onClick={handleRefresh} 114 139 disabled={isRefetching} 115 - className="sticky lg:bottom-6 bottom-24 ml-4 w-[42px] h-[42px] z-10 bg-gray-500 hover:bg-gray-600 text-gray-50 p-[9px] rounded-full shadow-lg transition-transform duration-200 ease-in-out hover:scale-110 disabled:bg-gray-400 disabled:cursor-not-allowed" 140 + className="sticky lg:bottom-4 bottom-22 ml-4 w-[42px] h-[42px] z-10 bg-gray-200 dark:bg-gray-800 hover:bg-gray-300 dark:hover:bg-gray-700 text-gray-50 p-[9px] rounded-full shadow-lg transition-transform duration-200 ease-in-out hover:scale-110 disabled:dark:bg-gray-900 disabled:bg-gray-100 disabled:cursor-not-allowed" 116 141 aria-label="Refresh feed" 117 142 > 118 - {isRefetching ? <RefreshIcon className="h-6 w-6 animate-spin" /> : <RefreshIcon className="h-6 w-6" />} 143 + <RefreshIcon 144 + className={`h-6 w-6 text-gray-600 dark:text-gray-400 ${isRefetching && "animate-spin"}`} 145 + /> 119 146 </button> 120 147 </> 121 148 ); ··· 138 165 d="M20 11A8.1 8.1 0 0 0 4.5 9M4 5v4h4m-4 4a8.1 8.1 0 0 0 15.5 2m.5 4v-4h-4" 139 166 ></path> 140 167 </svg> 141 - ); 168 + );
+207 -59
src/components/Login.tsx
··· 1 1 // src/components/Login.tsx 2 - import React, { useEffect, useState, useRef } from "react"; 2 + import AtpAgent, { Agent } from "@atproto/api"; 3 + import { useAtom } from "jotai"; 4 + import React, { useEffect, useRef, useState } from "react"; 5 + 3 6 import { useAuth } from "~/providers/UnifiedAuthProvider"; 4 - import { Agent } from "@atproto/api"; 7 + import { imgCDNAtom } from "~/utils/atoms"; 8 + import { useQueryIdentity, useQueryProfile } from "~/utils/useQuery"; 5 9 6 10 // --- 1. The Main Component (Orchestrator with `compact` prop) --- 7 - export default function Login({ compact = false }: { compact?: boolean }) { 11 + export default function Login({ 12 + compact = false, 13 + popup = false, 14 + }: { 15 + compact?: boolean; 16 + popup?: boolean; 17 + }) { 8 18 const { status, agent, logout } = useAuth(); 9 19 10 20 // Loading state can be styled differently based on the prop ··· 14 24 className={ 15 25 compact 16 26 ? "flex items-center justify-center p-1" 17 - : "p-6 bg-gray-100 dark:bg-gray-900 rounded-xl shadow border border-gray-200 dark:border-gray-800 mt-6 mx-4 flex justify-center items-center h-[280px]" 27 + : "p-6 bg-gray-100 dark:bg-gray-900 rounded-xl shadow border border-gray-200 dark:border-gray-800 mt-4 mx-4 flex justify-center items-center h-[280px]" 18 28 } 19 29 > 20 30 <span ··· 33 43 // Large view 34 44 if (!compact) { 35 45 return ( 36 - <div className="p-6 bg-gray-100 dark:bg-gray-900 rounded-xl shadow border border-gray-200 dark:border-gray-800 mt-6 mx-4"> 46 + <div className="p-4 bg-gray-100 dark:bg-gray-900 rounded-xl border-gray-200 dark:border-gray-800 mt-4 mx-4"> 37 47 <div className="flex flex-col items-center justify-center text-center"> 38 48 <p className="text-lg font-semibold mb-4 text-gray-800 dark:text-gray-100"> 39 49 You are logged in! ··· 41 51 <ProfileThing agent={agent} large /> 42 52 <button 43 53 onClick={logout} 44 - className="bg-gray-600 mt-4 hover:bg-gray-700 text-white rounded px-6 py-2 font-semibold text-base transition-colors" 54 + className="bg-gray-600 mt-4 hover:bg-gray-700 text-white rounded-full px-6 py-2 font-semibold text-base transition-colors" 45 55 > 46 56 Log out 47 57 </button> ··· 67 77 if (!compact) { 68 78 // Large view renders the form directly in the card 69 79 return ( 70 - <div className="p-6 bg-gray-100 dark:bg-gray-900 rounded-xl shadow border border-gray-200 dark:border-gray-800 mt-6 mx-4"> 80 + <div className="p-4 bg-gray-100 dark:bg-gray-900 rounded-xl border-gray-200 dark:border-gray-800 mt-4 mx-4"> 71 81 <UnifiedLoginForm /> 72 82 </div> 73 83 ); 74 84 } 75 85 76 86 // Compact view renders a button that toggles the form in a dropdown 77 - return <CompactLoginButton />; 87 + return <CompactLoginButton popup={popup} />; 78 88 } 79 89 80 90 // --- 2. The Reusable, Self-Contained Login Form Component --- ··· 83 93 84 94 return ( 85 95 <div> 86 - <div className="flex border-b border-gray-200 dark:border-gray-700 mb-4"> 96 + <div className="flex bg-gray-300 rounded-full dark:bg-gray-700 mb-4"> 87 97 <TabButton 88 98 label="OAuth" 89 99 active={mode === "oauth"} ··· 103 113 // --- 3. Helper components for layouts, forms, and UI --- 104 114 105 115 // A new component to contain the logic for the compact dropdown 106 - const CompactLoginButton = () => { 116 + const CompactLoginButton = ({ popup }: { popup?: boolean }) => { 107 117 const [showForm, setShowForm] = useState(false); 108 118 const formRef = useRef<HTMLDivElement>(null); 109 119 ··· 125 135 <div className="relative" ref={formRef}> 126 136 <button 127 137 onClick={() => setShowForm(!showForm)} 128 - className="text-sm bg-gray-600 hover:bg-gray-700 text-white rounded px-3 py-1 font-medium transition-colors" 138 + className="text-sm bg-gray-600 hover:bg-gray-700 text-white rounded-full px-3 py-1 font-medium transition-colors" 129 139 > 130 140 Log in 131 141 </button> 132 142 {showForm && ( 133 - <div className="absolute top-full right-0 mt-2 w-80 bg-white dark:bg-gray-900 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700 p-4 z-50"> 143 + <div 144 + className={`absolute ${popup ? `bottom-[calc(100%)]` : `top-full`} right-0 mt-2 w-80 bg-white dark:bg-gray-900 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700 p-4 z-50`} 145 + > 134 146 <UnifiedLoginForm /> 135 147 </div> 136 148 )} ··· 138 150 ); 139 151 }; 140 152 141 - const TabButton = ({ label, active, onClick }: { label: string; active: boolean; onClick: () => void; }) => ( 153 + const TabButton = ({ 154 + label, 155 + active, 156 + onClick, 157 + }: { 158 + label: string; 159 + active: boolean; 160 + onClick: () => void; 161 + }) => ( 142 162 <button 143 163 onClick={onClick} 144 - className={`px-4 py-2 text-sm font-medium transition-colors ${ 164 + className={`px-4 py-2 text-sm font-medium transition-colors rounded-full flex-1 ${ 145 165 active 146 - ? "text-gray-600 dark:text-gray-200 border-b-2 border-gray-500" 147 - : "text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200" 166 + ? "text-gray-50 dark:text-gray-200 border-gray-500 bg-gray-400 dark:bg-gray-500" 167 + : "text-gray-600 dark:text-gray-300 hover:text-gray-700 dark:hover:text-gray-200" 148 168 }`} 149 169 > 150 170 {label} ··· 154 174 const OAuthForm = () => { 155 175 const { loginWithOAuth } = useAuth(); 156 176 const [handle, setHandle] = useState(""); 157 - const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (handle.trim()) loginWithOAuth(handle); }; 177 + 178 + useEffect(() => { 179 + const lastHandle = localStorage.getItem("lastHandle"); 180 + if (lastHandle) setHandle(lastHandle); 181 + }, []); 182 + 183 + const handleSubmit = (e: React.FormEvent) => { 184 + e.preventDefault(); 185 + if (handle.trim()) { 186 + localStorage.setItem("lastHandle", handle); 187 + loginWithOAuth(handle); 188 + } 189 + }; 158 190 return ( 159 191 <form onSubmit={handleSubmit} className="flex flex-col gap-3"> 160 - <p className="text-xs text-gray-500 dark:text-gray-400">Sign in with AT. Your password is never shared.</p> 161 - <input type="text" placeholder="handle.bsky.social" value={handle} onChange={(e) => setHandle(e.target.value)} className="px-3 py-2 rounded border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 text-sm focus:outline-none focus:ring-2 focus:ring-gray-500" /> 162 - <button type="submit" className="bg-gray-600 hover:bg-gray-700 text-white rounded px-4 py-2 font-medium text-sm transition-colors">Log in</button> 192 + <p className="text-xs text-gray-500 dark:text-gray-400"> 193 + Sign in with AT. Your password is never shared. 194 + </p> 195 + {/* <input 196 + type="text" 197 + placeholder="handle.bsky.social" 198 + value={handle} 199 + onChange={(e) => setHandle(e.target.value)} 200 + className="px-3 py-2 rounded border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 text-sm focus:outline-none focus:ring-2 focus:ring-gray-500" 201 + /> */} 202 + <div className="flex flex-col gap-3"> 203 + <div className="m3input-field m3input-label m3input-border size-md flex-1"> 204 + <input 205 + type="text" 206 + placeholder=" " 207 + value={handle} 208 + onChange={(e) => setHandle(e.target.value)} 209 + /> 210 + <label>AT Handle</label> 211 + </div> 212 + <button 213 + type="submit" 214 + className="bg-gray-600 hover:bg-gray-700 text-white rounded-full px-4 py-2 font-medium text-sm transition-colors" 215 + > 216 + Log in 217 + </button> 218 + </div> 163 219 </form> 164 220 ); 165 221 }; ··· 171 227 const [serviceURL, setServiceURL] = useState("bsky.social"); 172 228 const [error, setError] = useState<string | null>(null); 173 229 230 + useEffect(() => { 231 + const lastHandle = localStorage.getItem("lastHandle"); 232 + if (lastHandle) setUser(lastHandle); 233 + }, []); 234 + 174 235 const handleSubmit = async (e: React.FormEvent) => { 175 236 e.preventDefault(); 176 237 setError(null); 177 238 try { 239 + localStorage.setItem("lastHandle", user); 178 240 await loginWithPassword(user, password, `https://${serviceURL}`); 179 241 } catch (err) { 180 242 setError("Login failed. Check your handle and App Password."); ··· 183 245 184 246 return ( 185 247 <form onSubmit={handleSubmit} className="flex flex-col gap-3"> 186 - <p className="text-xs text-red-500 dark:text-red-400">Warning: Less secure. Use an App Password.</p> 187 - <input type="text" placeholder="handle.bsky.social" value={user} onChange={(e) => setUser(e.target.value)} className="px-3 py-2 rounded border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 text-sm focus:outline-none focus:ring-2 focus:ring-gray-500" autoComplete="username" /> 188 - <input type="password" placeholder="App Password" value={password} onChange={(e) => setPassword(e.target.value)} className="px-3 py-2 rounded border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 text-sm focus:outline-none focus:ring-2 focus:ring-gray-500" autoComplete="current-password" /> 189 - <input type="text" placeholder="PDS (e.g., bsky.social)" value={serviceURL} onChange={(e) => setServiceURL(e.target.value)} className="px-3 py-2 rounded border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 text-sm focus:outline-none focus:ring-2 focus:ring-gray-500" /> 248 + <p className="text-xs text-red-500 dark:text-red-400"> 249 + Warning: Less secure. Use an App Password. 250 + </p> 251 + {/* <input 252 + type="text" 253 + placeholder="handle.bsky.social" 254 + value={user} 255 + onChange={(e) => setUser(e.target.value)} 256 + className="px-3 py-2 rounded border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 text-sm focus:outline-none focus:ring-2 focus:ring-gray-500" 257 + autoComplete="username" 258 + /> 259 + <input 260 + type="password" 261 + placeholder="App Password" 262 + value={password} 263 + onChange={(e) => setPassword(e.target.value)} 264 + className="px-3 py-2 rounded border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 text-sm focus:outline-none focus:ring-2 focus:ring-gray-500" 265 + autoComplete="current-password" 266 + /> 267 + <input 268 + type="text" 269 + placeholder="PDS (e.g., bsky.social)" 270 + value={serviceURL} 271 + onChange={(e) => setServiceURL(e.target.value)} 272 + className="px-3 py-2 rounded border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 text-sm focus:outline-none focus:ring-2 focus:ring-gray-500" 273 + /> */} 274 + <div className="m3input-field m3input-label m3input-border size-md flex-1"> 275 + <input 276 + type="text" 277 + placeholder=" " 278 + value={user} 279 + onChange={(e) => setUser(e.target.value)} 280 + /> 281 + <label>AT Handle</label> 282 + </div> 283 + <div className="m3input-field m3input-label m3input-border size-md flex-1"> 284 + <input 285 + type="text" 286 + placeholder=" " 287 + value={password} 288 + onChange={(e) => setPassword(e.target.value)} 289 + /> 290 + <label>App Password</label> 291 + </div> 292 + <div className="m3input-field m3input-label m3input-border size-md flex-1"> 293 + <input 294 + type="text" 295 + placeholder=" " 296 + value={serviceURL} 297 + onChange={(e) => setServiceURL(e.target.value)} 298 + /> 299 + <label>PDS</label> 300 + </div> 190 301 {error && <p className="text-xs text-red-500">{error}</p>} 191 - <button type="submit" className="bg-gray-600 hover:bg-gray-700 text-white rounded px-4 py-2 font-medium text-sm transition-colors">Log in</button> 302 + <button 303 + type="submit" 304 + className="bg-gray-600 hover:bg-gray-700 text-white rounded-full px-4 py-2 font-medium text-sm transition-colors" 305 + > 306 + Log in 307 + </button> 192 308 </form> 193 309 ); 194 310 }; 195 311 196 312 // --- Profile Component (now supports a `large` prop for styling) --- 197 - export const ProfileThing = ({ agent, large = false }: { agent: Agent | null; large?: boolean }) => { 198 - const [profile, setProfile] = useState<any>(null); 313 + export const ProfileThing = ({ 314 + agent, 315 + large = false, 316 + }: { 317 + agent: Agent | null; 318 + large?: boolean; 319 + }) => { 320 + const did = ((agent as AtpAgent)?.session?.did ?? 321 + (agent as AtpAgent)?.assertDid ?? 322 + agent?.did) as string | undefined; 323 + const { data: identity } = useQueryIdentity(did); 324 + const { data: profiledata } = useQueryProfile( 325 + `at://${did}/app.bsky.actor.profile/self` 326 + ); 327 + const profile = profiledata?.value; 328 + 329 + const [imgcdn] = useAtom(imgCDNAtom) 330 + 331 + function getAvatarUrl(p: typeof profile) { 332 + const link = p?.avatar?.ref?.["$link"]; 333 + if (!link || !did) return null; 334 + return `https://${imgcdn}/img/avatar/plain/${did}/${link}@jpeg`; 335 + } 199 336 200 - useEffect(() => { 201 - const fetchUser = async () => { 202 - const did = (agent as any)?.session?.did ?? (agent as any)?.assertDid; 203 - if (!did) return; 204 - try { 205 - const res = await agent!.getProfile({ actor: did }); 206 - setProfile(res.data); 207 - } catch (e) { console.error("Failed to fetch profile", e); } 208 - }; 209 - if (agent) fetchUser(); 210 - }, [agent]); 337 + if (!profiledata) { 338 + return ( 339 + // Skeleton loader 340 + <div 341 + className={`flex items-center gap-2.5 animate-pulse ${large ? "mb-1" : ""}`} 342 + > 343 + <div 344 + className={`rounded-full bg-gray-300 dark:bg-gray-700 ${large ? "w-10 h-10" : "w-[30px] h-[30px]"}`} 345 + /> 346 + <div className="flex flex-col gap-2"> 347 + <div 348 + className={`bg-gray-300 dark:bg-gray-700 rounded ${large ? "h-4 w-28" : "h-3 w-20"}`} 349 + /> 350 + <div 351 + className={`bg-gray-300 dark:bg-gray-700 rounded ${large ? "h-4 w-20" : "h-3 w-16"}`} 352 + /> 353 + </div> 354 + </div> 355 + ); 356 + } 211 357 212 - if (!profile) { 213 - return ( // Skeleton loader 214 - <div className={`flex items-center gap-2.5 animate-pulse ${large ? 'mb-1' : ''}`}> 215 - <div className={`rounded-full bg-gray-300 dark:bg-gray-700 ${large ? 'w-10 h-10' : 'w-[30px] h-[30px]'}`} /> 216 - <div className="flex flex-col gap-2"> 217 - <div className={`bg-gray-300 dark:bg-gray-700 rounded ${large ? 'h-4 w-28' : 'h-3 w-20'}`} /> 218 - <div className={`bg-gray-300 dark:bg-gray-700 rounded ${large ? 'h-4 w-20' : 'h-3 w-16'}`} /> 219 - </div> 220 - </div> 221 - ); 222 - } 223 - 224 - return ( 225 - <div className={`flex flex-row items-center gap-2.5 ${large ? 'mb-1' : ''}`}> 226 - <img src={profile?.avatar} alt="avatar" className={`object-cover rounded-full ${large ? 'w-10 h-10' : 'w-[30px] h-[30px]'}`} /> 227 - <div className="flex flex-col items-start text-left"> 228 - <div className={`font-medium ${large ? 'text-gray-800 dark:text-gray-100 text-md' : 'text-gray-800 dark:text-gray-100 text-sm'}`}>{profile?.displayName}</div> 229 - <div className={` ${large ? 'text-gray-500 dark:text-gray-400 text-sm' : 'text-gray-500 dark:text-gray-400 text-xs'}`}>@{profile?.handle}</div> 230 - </div> 358 + return ( 359 + <div 360 + className={`flex flex-row items-center gap-2.5 ${large ? "mb-1" : ""}`} 361 + > 362 + <img 363 + src={getAvatarUrl(profile) ?? undefined} 364 + alt="avatar" 365 + className={`object-cover rounded-full ${large ? "w-10 h-10" : "w-[30px] h-[30px]"}`} 366 + /> 367 + <div className="flex flex-col items-start text-left"> 368 + <div 369 + className={`font-medium ${large ? "text-gray-800 dark:text-gray-100 text-md" : "text-gray-800 dark:text-gray-100 text-sm"}`} 370 + > 371 + {profile?.displayName} 372 + </div> 373 + <div 374 + className={` ${large ? "text-gray-500 dark:text-gray-400 text-sm" : "text-gray-500 dark:text-gray-400 text-xs"}`} 375 + > 376 + @{identity?.handle} 231 377 </div> 232 - ); 233 - }; 378 + </div> 379 + </div> 380 + ); 381 + };
+6
src/components/Star.tsx
··· 1 + import type { SVGProps } from 'react'; 2 + import React from 'react'; 3 + 4 + export function FluentEmojiHighContrastGlowingStar(props: SVGProps<SVGSVGElement>) { 5 + return (<svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}><g fill="currentColor"><path d="m28.979 17.003l-3.108.214c-.834.06-1.178 1.079-.542 1.608l2.388 1.955c.521.428 1.314.204 1.523-.428l.709-2.127c.219-.632-.292-1.273-.97-1.222M21.75 2.691l-.72 2.9c-.2.78.66 1.41 1.34.98l2.54-1.58c.55-.34.58-1.14.05-1.52l-1.78-1.29a.912.912 0 0 0-1.43.51M6.43 4.995l2.53 1.58c.68.43 1.54-.19 1.35-.98l-.72-2.9a.92.92 0 0 0-1.43-.52l-1.78 1.29c-.53.4-.5 1.19.05 1.53M4.185 20.713l2.29-1.92c.62-.52.29-1.53-.51-1.58l-2.98-.21a.92.92 0 0 0-.94 1.2l.68 2.09c.2.62.97.84 1.46.42m13.61 7.292l-1.12-2.77c-.3-.75-1.36-.75-1.66 0l-1.12 2.77c-.24.6.2 1.26.85 1.26h2.2a.92.92 0 0 0 .85-1.26"></path><path d="m17.565 3.324l1.726 3.72c.326.694.967 1.18 1.717 1.29l4.056.624c1.835.278 2.575 2.53 1.293 3.859L23.268 16a2.28 2.28 0 0 0-.612 1.964l.71 4.374c.307 1.885-1.687 3.293-3.354 2.37l-3.405-1.894a2.25 2.25 0 0 0-2.21 0l-3.404 1.895c-1.668.922-3.661-.486-3.355-2.37l.71-4.375A2.28 2.28 0 0 0 7.736 16l-3.088-3.184c-1.293-1.34-.543-3.581 1.293-3.859l4.055-.625a2.3 2.3 0 0 0 1.717-1.29l1.727-3.719c.819-1.765 3.306-1.765 4.124 0"></path></g></svg>); 6 + }
+885 -563
src/components/UniversalPostRenderer.tsx
··· 1 + import { useNavigate } from "@tanstack/react-router"; 2 + import DOMPurify from "dompurify"; 3 + import { useAtom } from "jotai"; 4 + import { DropdownMenu } from "radix-ui"; 5 + import { HoverCard } from "radix-ui"; 1 6 import * as React from "react"; 2 - import { usePersistentStore } from "~/providers/PersistentStoreProvider"; 3 - import { useNavigate } from "@tanstack/react-router"; 4 7 import { type SVGProps } from "react"; 8 + 9 + import { 10 + composerAtom, 11 + constellationURLAtom, 12 + imgCDNAtom, 13 + likedPostsAtom, 14 + } from "~/utils/atoms"; 5 15 import { useHydratedEmbed } from "~/utils/useHydrated"; 6 - import { useAtom } from 'jotai'; 7 - import { likedPostsAtom } from "~/utils/atoms"; 8 16 import { 17 + useQueryConstellation, 18 + useQueryIdentity, 9 19 useQueryPost, 10 - useQueryIdentity, 11 20 useQueryProfile, 12 - useQueryConstellation, 21 + yknowIReallyHateThisButWhateverGuardedConstructConstellationInfiniteQueryLinks, 13 22 } from "~/utils/useQuery"; 14 23 15 24 function asTyped<T extends { $type: string }>(obj: T): $Typed<T> { ··· 28 37 bottomBorder?: boolean; 29 38 feedviewpost?: boolean; 30 39 repostedby?: string; 40 + style?: React.CSSProperties; 41 + ref?: React.Ref<HTMLDivElement>; 42 + dataIndexPropPass?: number; 43 + nopics?: boolean; 44 + lightboxCallback?: (d: LightboxProps) => void; 45 + maxReplies?: number; 46 + isQuote?: boolean; 31 47 } 32 48 33 49 // export async function cachedGetRecord({ ··· 132 148 bottomBorder = true, 133 149 feedviewpost = false, 134 150 repostedby, 151 + style, 152 + ref, 153 + dataIndexPropPass, 154 + nopics, 155 + lightboxCallback, 156 + maxReplies, 157 + isQuote, 135 158 }: UniversalPostRendererATURILoaderProps) { 136 - console.log("atUri", atUri); 159 + // todo remove this once tree rendering is implemented, use a prop like isTree 160 + const TEMPLINEAR = true; 161 + // /*mass comment*/ console.log("atUri", atUri); 137 162 //const { get, set } = usePersistentStore(); 138 163 //const [record, setRecord] = React.useState<any>(null); 139 164 //const [links, setLinks] = React.useState<any>(null); ··· 146 171 // >(null); 147 172 //const router = useRouter(); 148 173 149 - const parsed = React.useMemo(() => parseAtUri(atUri), [atUri]); 150 - const did = parsed?.did; 174 + //const parsed = React.useMemo(() => parseAtUri(atUri), [atUri]); 175 + const parsed = new AtUri(atUri); 176 + const did = parsed?.host; 151 177 const rkey = parsed?.rkey; 152 - console.log("did", did); 153 - console.log("rkey", rkey); 178 + // /*mass comment*/ console.log("did", did); 179 + // /*mass comment*/ console.log("rkey", rkey); 154 180 155 181 // React.useEffect(() => { 156 182 // const checkCache = async () => { ··· 158 184 // const cacheKey = `record:${postUri}`; 159 185 // const cached = await get(cacheKey); 160 186 // const now = Date.now(); 161 - // console.log( 187 + // // /*mass comment*/ console.log( 162 188 // "UniversalPostRenderer checking cache for", 163 189 // cacheKey, 164 190 // "cached:", ··· 171 197 // now - cached.time < CACHE_TIMEOUT 172 198 // ) { 173 199 // try { 174 - // console.log("UniversalPostRenderer found cached data for", cacheKey); 200 + // // /*mass comment*/ console.log("UniversalPostRenderer found cached data for", cacheKey); 175 201 // setRecord(JSON.parse(cached.value)); 176 202 // } catch { 177 203 // setRecord(null); ··· 357 383 const [replies, setReplies] = React.useState<number | null>(null); 358 384 359 385 React.useEffect(() => { 360 - console.log(JSON.stringify(links, null, 2)); 386 + // /*mass comment*/ console.log(JSON.stringify(links, null, 2)); 361 387 setLikes( 362 388 links 363 389 ? links?.links?.["app.bsky.feed.like"]?.[".subject.uri"]?.records || 0 ··· 376 402 ); 377 403 }, [links]); 378 404 405 + // const { data: repliesData } = useQueryConstellation({ 406 + // method: "/links", 407 + // target: atUri, 408 + // collection: "app.bsky.feed.post", 409 + // path: ".reply.parent.uri", 410 + // }); 411 + 412 + const [constellationurl] = useAtom(constellationURLAtom); 413 + 414 + const infinitequeryresults = useInfiniteQuery({ 415 + ...yknowIReallyHateThisButWhateverGuardedConstructConstellationInfiniteQueryLinks( 416 + { 417 + constellation: constellationurl, 418 + method: "/links", 419 + target: atUri, 420 + collection: "app.bsky.feed.post", 421 + path: ".reply.parent.uri", 422 + } 423 + ), 424 + enabled: !!atUri && !!maxReplies && !isQuote, 425 + }); 426 + 427 + const { 428 + data: repliesData, 429 + // fetchNextPage, 430 + // hasNextPage, 431 + // isFetchingNextPage, 432 + } = infinitequeryresults; 433 + 434 + // auto-fetch all pages 435 + useEffect(() => { 436 + if (!maxReplies || isQuote || TEMPLINEAR) return; 437 + if ( 438 + infinitequeryresults.hasNextPage && 439 + !infinitequeryresults.isFetchingNextPage 440 + ) { 441 + console.log("Fetching the next page..."); 442 + infinitequeryresults.fetchNextPage(); 443 + } 444 + }, [TEMPLINEAR, infinitequeryresults, isQuote, maxReplies]); 445 + 446 + const replyAturis = repliesData 447 + ? repliesData.pages.flatMap((page) => 448 + page 449 + ? page.linking_records.map((record) => { 450 + const aturi = `at://${record.did}/${record.collection}/${record.rkey}`; 451 + return aturi; 452 + }) 453 + : [] 454 + ) 455 + : []; 456 + 457 + //const [oldestOpsReply, setOldestOpsReply] = useState<string | undefined>(undefined); 458 + 459 + const { oldestOpsReply, oldestOpsReplyElseNewestNonOpsReply } = (() => { 460 + if (isQuote || !replyAturis || replyAturis.length === 0 || !maxReplies) 461 + return { 462 + oldestOpsReply: undefined, 463 + oldestOpsReplyElseNewestNonOpsReply: undefined, 464 + }; 465 + 466 + const opdid = new AtUri( 467 + //postQuery?.value.reply?.root.uri ?? postQuery?.uri ?? atUri 468 + atUri 469 + ).host; 470 + 471 + const opReplies = replyAturis.filter( 472 + (aturi) => new AtUri(aturi).host === opdid 473 + ); 474 + 475 + if (opReplies.length > 0) { 476 + const opreply = opReplies[opReplies.length - 1]; 477 + //setOldestOpsReply(opreply); 478 + return { 479 + oldestOpsReply: opreply, 480 + oldestOpsReplyElseNewestNonOpsReply: opreply, 481 + }; 482 + } else { 483 + return { 484 + oldestOpsReply: undefined, 485 + oldestOpsReplyElseNewestNonOpsReply: replyAturis[0], 486 + }; 487 + } 488 + })(); 489 + 379 490 // const navigateToProfile = (e: React.MouseEvent) => { 380 491 // e.stopPropagation(); 381 492 // if (resolved?.did) { ··· 387 498 // }; 388 499 if (!postQuery?.value) { 389 500 // deleted post more often than a non-resolvable post 390 - return (<></>) 501 + return <></>; 391 502 } 392 503 393 504 return ( 394 - <UniversalPostRendererRawRecordShim 395 - detailed={detailed} 396 - postRecord={postQuery} 397 - profileRecord={opProfile} 398 - aturi={atUri} 399 - resolved={resolved} 400 - likesCount={likes} 401 - repostsCount={reposts} 402 - repliesCount={replies} 403 - bottomReplyLine={bottomReplyLine} 404 - topReplyLine={topReplyLine} 405 - bottomBorder={bottomBorder} 406 - feedviewpost={feedviewpost} 407 - repostedby={repostedby} 408 - /> 505 + <> 506 + {/* <span>uprrs {maxReplies} {!!maxReplies&&!!oldestOpsReplyElseNewestNonOpsReply ? "true" : "false"}</span> */} 507 + <UniversalPostRendererRawRecordShim 508 + detailed={detailed} 509 + postRecord={postQuery} 510 + profileRecord={opProfile} 511 + aturi={atUri} 512 + resolved={resolved} 513 + likesCount={likes} 514 + repostsCount={reposts} 515 + repliesCount={replies} 516 + bottomReplyLine={ 517 + maxReplies && oldestOpsReplyElseNewestNonOpsReply 518 + ? true 519 + : maxReplies && !oldestOpsReplyElseNewestNonOpsReply 520 + ? false 521 + : (maxReplies === 0 && (!replies || (!!replies && replies === 0))) ? false : bottomReplyLine 522 + } 523 + topReplyLine={topReplyLine} 524 + //bottomBorder={maxReplies&&oldestOpsReplyElseNewestNonOpsReply ? false : bottomBorder} 525 + bottomBorder={ 526 + maxReplies && oldestOpsReplyElseNewestNonOpsReply 527 + ? false 528 + : maxReplies === 0 529 + ? false 530 + : bottomBorder 531 + } 532 + feedviewpost={feedviewpost} 533 + repostedby={repostedby} 534 + //style={{...style, background: oldestOpsReply === atUri ? "Red" : undefined}} 535 + style={style} 536 + ref={ref} 537 + dataIndexPropPass={dataIndexPropPass} 538 + nopics={nopics} 539 + lightboxCallback={lightboxCallback} 540 + maxReplies={maxReplies} 541 + isQuote={isQuote} 542 + /> 543 + <> 544 + {(maxReplies && maxReplies === 0 && replies && replies > 0) ? ( 545 + <> 546 + {/* <div>hello</div> */} 547 + <MoreReplies atUri={atUri} /> 548 + </> 549 + ) : (<></>)} 550 + </> 551 + {!isQuote && oldestOpsReplyElseNewestNonOpsReply && ( 552 + <> 553 + {/* <span>hello {maxReplies}</span> */} 554 + <UniversalPostRendererATURILoader 555 + //detailed={detailed} 556 + atUri={oldestOpsReplyElseNewestNonOpsReply} 557 + bottomReplyLine={(maxReplies ?? 0) > 0} 558 + topReplyLine={ 559 + (!!(maxReplies && maxReplies - 1 === 0) && 560 + !!(replies && replies > 0)) || 561 + !!((maxReplies ?? 0) > 1) 562 + } 563 + bottomBorder={bottomBorder} 564 + feedviewpost={feedviewpost} 565 + repostedby={repostedby} 566 + style={style} 567 + ref={ref} 568 + dataIndexPropPass={dataIndexPropPass} 569 + nopics={nopics} 570 + lightboxCallback={lightboxCallback} 571 + maxReplies={ 572 + maxReplies && maxReplies > 0 ? maxReplies - 1 : undefined 573 + } 574 + /> 575 + </> 576 + )} 577 + </> 409 578 ); 410 579 } 411 580 581 + function MoreReplies({ atUri }: { atUri: string }) { 582 + const navigate = useNavigate(); 583 + const aturio = new AtUri(atUri); 584 + return ( 585 + <div 586 + onClick={() => 587 + navigate({ 588 + to: "/profile/$did/post/$rkey", 589 + params: { did: aturio.host, rkey: aturio.rkey }, 590 + }) 591 + } 592 + className="border-b border-gray-300 dark:border-gray-800 flex flex-row px-4 cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-900 transition-colors" 593 + > 594 + <div className="w-[42px] h-12 flex flex-col items-center justify-center"> 595 + <div 596 + style={{ 597 + width: 2, 598 + height: "100%", 599 + backgroundImage: 600 + "repeating-linear-gradient(to bottom, var(--color-gray-500) 0, var(--color-gray-500) 4px, transparent 4px, transparent 8px)", 601 + opacity: 0.5, 602 + }} 603 + className="dark:bg-[repeating-linear-gradient(to_bottom,var(--color-gray-500)_0,var(--color-gray-400)_4px,transparent_4px,transparent_8px)]" 604 + //className="border-gray-400 dark:border-gray-500" 605 + /> 606 + </div> 607 + 608 + <div className="flex items-center pl-3 text-sm text-gray-500 dark:text-gray-400 select-none"> 609 + More Replies 610 + </div> 611 + </div> 612 + ); 613 + } 614 + 615 + function getAvatarUrl(opProfile: any, did: string, cdn: string) { 616 + const link = opProfile?.value?.avatar?.ref?.["$link"]; 617 + if (!link) return null; 618 + return `https://${cdn}/img/avatar/plain/${did}/${link}@jpeg`; 619 + } 620 + 412 621 export function UniversalPostRendererRawRecordShim({ 413 622 postRecord, 414 623 profileRecord, ··· 423 632 bottomBorder = true, 424 633 feedviewpost = false, 425 634 repostedby, 635 + style, 636 + ref, 637 + dataIndexPropPass, 638 + nopics, 639 + lightboxCallback, 640 + maxReplies, 641 + isQuote, 426 642 }: { 427 643 postRecord: any; 428 644 profileRecord: any; ··· 437 653 bottomBorder?: boolean; 438 654 feedviewpost?: boolean; 439 655 repostedby?: string; 656 + style?: React.CSSProperties; 657 + ref?: React.Ref<HTMLDivElement>; 658 + dataIndexPropPass?: number; 659 + nopics?: boolean; 660 + lightboxCallback?: (d: LightboxProps) => void; 661 + maxReplies?: number; 662 + isQuote?: boolean; 440 663 }) { 441 - console.log(`received aturi: ${aturi} of post content: ${postRecord}`); 664 + // /*mass comment*/ console.log(`received aturi: ${aturi} of post content: ${postRecord}`); 442 665 const navigate = useNavigate(); 443 666 444 667 //const { get, set } = usePersistentStore(); 445 - function getAvatarUrl(opProfile: any) { 446 - const link = opProfile?.value?.avatar?.ref?.["$link"]; 447 - if (!link) return null; 448 - return `https://cdn.bsky.app/img/avatar/plain/${resolved?.did}/${link}@jpeg`; 449 - } 450 - 451 668 // const [hydratedEmbed, setHydratedEmbed] = useState<any>(undefined); 452 669 453 670 // useEffect(() => { ··· 500 717 // result = hydrated instanceof Promise ? await hydrated : hydrated; 501 718 // } 502 719 503 - // console.log( 720 + // // /*mass comment*/ console.log( 504 721 // String(result) + " hydrateEmbedRecordWithMedia hey hyeh ye", 505 722 // ); 506 723 // setHydratedEmbed(result); ··· 519 736 error: embedError, 520 737 } = useHydratedEmbed(postRecord?.value?.embed, resolved?.did); 521 738 522 - const parsedaturi = parseAtUri(aturi); 739 + const [imgcdn] = useAtom(imgCDNAtom); 740 + 741 + const parsedaturi = new AtUri(aturi); //parseAtUri(aturi); 742 + 743 + const fakeprofileviewbasic = React.useMemo<AppBskyActorDefs.ProfileViewBasic>( 744 + () => ({ 745 + did: resolved?.did || "", 746 + handle: resolved?.handle || "", 747 + displayName: profileRecord?.value?.displayName || "", 748 + avatar: getAvatarUrl(profileRecord, resolved?.did, imgcdn) || "", 749 + viewer: undefined, 750 + labels: profileRecord?.labels || undefined, 751 + verification: undefined, 752 + }), 753 + [imgcdn, profileRecord, resolved?.did, resolved?.handle] 754 + ); 755 + 756 + const fakeprofileviewdetailed = 757 + React.useMemo<AppBskyActorDefs.ProfileViewDetailed>( 758 + () => ({ 759 + ...fakeprofileviewbasic, 760 + $type: "app.bsky.actor.defs#profileViewDetailed", 761 + description: profileRecord?.value?.description || undefined, 762 + }), 763 + [fakeprofileviewbasic, profileRecord?.value?.description] 764 + ); 523 765 524 766 const fakepost = React.useMemo<AppBskyFeedDefs.PostView>( 525 767 () => ({ 526 768 $type: "app.bsky.feed.defs#postView", 527 769 uri: aturi, 528 770 cid: postRecord?.cid || "", 529 - author: { 530 - did: resolved?.did || "", 531 - handle: resolved?.handle || "", 532 - displayName: profileRecord?.value?.displayName || "", 533 - avatar: getAvatarUrl(profileRecord) || "", 534 - viewer: undefined, 535 - labels: profileRecord?.labels || undefined, 536 - verification: undefined, 537 - }, 771 + author: fakeprofileviewbasic, 538 772 record: postRecord?.value || {}, 539 773 embed: hydratedEmbed ?? undefined, 540 774 replyCount: repliesCount ?? 0, ··· 548 782 }), 549 783 [ 550 784 aturi, 551 - postRecord, 552 - profileRecord, 785 + postRecord?.cid, 786 + postRecord?.value, 787 + postRecord?.labels, 788 + fakeprofileviewbasic, 553 789 hydratedEmbed, 554 790 repliesCount, 555 791 repostsCount, 556 792 likesCount, 557 - resolved, 558 793 ] 559 794 ); 560 795 ··· 595 830 ); 596 831 const feedviewpostreplyhandle = replyhookvalue?.data?.handle; 597 832 598 - 599 - const aturirepostbydid = repostedby ? new AtUri(repostedby).host : undefined 833 + const aturirepostbydid = repostedby ? new AtUri(repostedby).host : undefined; 600 834 const repostedbyhookvalue = useQueryIdentity( 601 835 repostedby ? aturirepostbydid : undefined 602 836 ); ··· 612 846 parsedaturi && 613 847 navigate({ 614 848 to: "/profile/$did/post/$rkey", 615 - params: { did: parsedaturi.did, rkey: parsedaturi.rkey }, 849 + params: { did: parsedaturi.host, rkey: parsedaturi.rkey }, 616 850 }) 617 851 } 618 852 // onProfileClick={() => parsedaturi && navigate({to: "/profile/$did", ··· 623 857 if (parsedaturi) { 624 858 navigate({ 625 859 to: "/profile/$did", 626 - params: { did: parsedaturi.did }, 860 + params: { did: parsedaturi.host }, 627 861 }); 628 862 } 629 863 }} 630 864 post={fakepost} 865 + uprrrsauthor={fakeprofileviewdetailed} 631 866 salt={aturi} 632 867 bottomReplyLine={bottomReplyLine} 633 868 topReplyLine={topReplyLine} ··· 635 870 //extraOptionalItemInfo={{reply: postRecord?.value?.reply as AppBskyFeedDefs.ReplyRef, post: fakepost}} 636 871 feedviewpostreplyhandle={feedviewpostreplyhandle} 637 872 repostedby={feedviewpostrepostedbyhandle} 873 + style={style} 874 + ref={ref} 875 + dataIndexPropPass={dataIndexPropPass} 876 + nopics={nopics} 877 + lightboxCallback={lightboxCallback} 878 + maxReplies={maxReplies} 879 + isQuote={isQuote} 638 880 /> 639 881 </> 640 882 ); 641 883 } 642 884 643 - export function parseAtUri( 644 - atUri: string 645 - ): { did: string; collection: string; rkey: string } | null { 646 - const PREFIX = "at://"; 647 - if (!atUri.startsWith(PREFIX)) { 648 - return null; 649 - } 885 + // export function parseAtUri( 886 + // atUri: string 887 + // ): { did: string; collection: string; rkey: string } | null { 888 + // const PREFIX = "at://"; 889 + // if (!atUri.startsWith(PREFIX)) { 890 + // return null; 891 + // } 650 892 651 - const parts = atUri.slice(PREFIX.length).split("/"); 893 + // const parts = atUri.slice(PREFIX.length).split("/"); 652 894 653 - if (parts.length !== 3) { 654 - return null; 655 - } 895 + // if (parts.length !== 3) { 896 + // return null; 897 + // } 656 898 657 - const [did, collection, rkey] = parts; 899 + // const [did, collection, rkey] = parts; 658 900 659 - if (!did || !collection || !rkey) { 660 - return null; 661 - } 901 + // if (!did || !collection || !rkey) { 902 + // return null; 903 + // } 662 904 663 - return { did, collection, rkey }; 664 - } 905 + // return { did, collection, rkey }; 906 + // } 665 907 666 908 export function MdiCommentOutline(props: SVGProps<SVGSVGElement>) { 667 909 return ( ··· 673 915 {...props} 674 916 > 675 917 <path 676 - fill="oklch(0.704 0.05 28)" 918 + fill="var(--color-gray-400)" 677 919 d="M9 22a1 1 0 0 1-1-1v-3H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-6.1l-3.7 3.71c-.2.19-.45.29-.7.29zm1-6v3.08L13.08 16H20V4H4v12z" 678 920 ></path> 679 921 </svg> ··· 690 932 {...props} 691 933 > 692 934 <path 693 - fill="oklch(0.704 0.05 28)" 935 + fill="var(--color-gray-400)" 694 936 d="M17 17H7v-3l-4 4l4 4v-3h12v-6h-2M7 7h10v3l4-4l-4-4v3H5v6h2z" 695 937 ></path> 696 938 </svg> ··· 741 983 {...props} 742 984 > 743 985 <path 744 - fill="oklch(0.704 0.05 28)" 986 + fill="var(--color-gray-400)" 745 987 d="m12.1 18.55l-.1.1l-.11-.1C7.14 14.24 4 11.39 4 8.5C4 6.5 5.5 5 7.5 5c1.54 0 3.04 1 3.57 2.36h1.86C13.46 6 14.96 5 16.5 5c2 0 3.5 1.5 3.5 3.5c0 2.89-3.14 5.74-7.9 10.05M16.5 3c-1.74 0-3.41.81-4.5 2.08C10.91 3.81 9.24 3 7.5 3C4.42 3 2 5.41 2 8.5c0 3.77 3.4 6.86 8.55 11.53L12 21.35l1.45-1.32C18.6 15.36 22 12.27 22 8.5C22 5.41 19.58 3 16.5 3" 746 988 ></path> 747 989 </svg> ··· 758 1000 {...props} 759 1001 > 760 1002 <path 761 - fill="oklch(0.704 0.05 28)" 1003 + fill="var(--color-gray-400)" 762 1004 d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3a3 3 0 0 0-3-3a3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3a3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66c0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08" 763 1005 ></path> 764 1006 </svg> ··· 775 1017 {...props} 776 1018 > 777 1019 <path 778 - fill="oklch(0.704 0.05 28)" 1020 + fill="var(--color-gray-400)" 779 1021 d="M16 12a2 2 0 0 1 2-2a2 2 0 0 1 2 2a2 2 0 0 1-2 2a2 2 0 0 1-2-2m-6 0a2 2 0 0 1 2-2a2 2 0 0 1 2 2a2 2 0 0 1-2 2a2 2 0 0 1-2-2m-6 0a2 2 0 0 1 2-2a2 2 0 0 1 2 2a2 2 0 0 1-2 2a2 2 0 0 1-2-2" 780 1022 ></path> 781 1023 </svg> ··· 792 1034 {...props} 793 1035 > 794 1036 <path 795 - fill="oklch(0.704 0.05 28)" 1037 + fill="var(--color-gray-400)" 796 1038 d="M17.9 17.39c-.26-.8-1.01-1.39-1.9-1.39h-1v-3a1 1 0 0 0-1-1H8v-2h2a1 1 0 0 0 1-1V7h2a2 2 0 0 0 2-2v-.41a7.984 7.984 0 0 1 2.9 12.8M11 19.93c-3.95-.49-7-3.85-7-7.93c0-.62.08-1.22.21-1.79L9 15v1a2 2 0 0 0 2 2m1-16A10 10 0 0 0 2 12a10 10 0 0 0 10 10a10 10 0 0 0 10-10A10 10 0 0 0 12 2" 797 1039 ></path> 798 1040 </svg> ··· 826 1068 {...props} 827 1069 > 828 1070 <path 829 - fill="oklch(0.704 0.05 28)" 1071 + fill="var(--color-gray-400)" 830 1072 d="M10 9V5l-7 7l7 7v-4.1c5 0 8.5 1.6 11 5.1c-1-5-4-10-11-11" 831 1073 ></path> 832 1074 </svg> ··· 880 1122 {...props} 881 1123 > 882 1124 <path 883 - fill="oklch(0.704 0.05 28)" 1125 + fill="var(--color-gray-400)" 884 1126 d="M17 17H7v-3l-4 4l4 4v-3h12v-6h-2M7 7h10v3l4-4l-4-4v3H5v6h2z" 885 1127 ></path> 886 1128 </svg> ··· 897 1139 {...props} 898 1140 > 899 1141 <path 900 - fill="oklch(0.704 0.05 28)" 1142 + fill="var(--color-gray-400)" 901 1143 d="M6 5.75L10.25 10H7v6h6.5l2 2H7a2 2 0 0 1-2-2v-6H1.75zm12 12.5L13.75 14H17V8h-6.5l-2-2H17a2 2 0 0 1 2 2v6h3.25z" 902 1144 ></path> 903 1145 </svg> ··· 922 1164 } 923 1165 924 1166 /* what imported from testfront */ 925 - import defaultpfp from "~/../public/favicon.png"; 926 - 927 1167 //import Masonry from "@mui/lab/Masonry"; 928 1168 import { 1169 + type $Typed, 929 1170 AppBskyActorDefs, 930 - AppBskyActorProfile, 931 1171 AppBskyEmbedDefs, 932 1172 AppBskyEmbedExternal, 933 1173 AppBskyEmbedImages, ··· 938 1178 AppBskyFeedPost, 939 1179 AppBskyGraphDefs, 940 1180 AtUri, 1181 + type Facet, 941 1182 //AppBskyLabelerDefs, 942 1183 //AtUri, 943 1184 //ComAtprotoRepoStrongRef, 944 1185 ModerationDecision, 945 - type $Typed, 946 - type Facet, 947 1186 } from "@atproto/api"; 948 1187 import type { 949 1188 //BlockedPost, ··· 952 1191 PostView, 953 1192 //ThreadViewPost, 954 1193 } from "@atproto/api/dist/client/types/app/bsky/feed/defs"; 1194 + import { useInfiniteQuery } from "@tanstack/react-query"; 955 1195 import { useEffect, useRef, useState } from "react"; 956 1196 import ReactPlayer from "react-player"; 1197 + 1198 + import defaultpfp from "~/../public/favicon.png"; 957 1199 import { useAuth } from "~/providers/UnifiedAuthProvider"; 1200 + import { FollowButton, Mutual } from "~/routes/profile.$did"; 1201 + import type { LightboxProps } from "~/routes/profile.$did/post.$rkey.image.$i"; 958 1202 // import type { OutputSchema } from "@atproto/api/dist/client/types/app/bsky/feed/getFeed"; 959 1203 // import type { 960 1204 // ViewRecord, ··· 1062 1306 1063 1307 function UniversalPostRenderer({ 1064 1308 post, 1309 + uprrrsauthor, 1065 1310 //setMainItem, 1066 1311 //isMainItem, 1067 1312 onPostClick, ··· 1078 1323 feedviewpostreplyhandle, 1079 1324 depth = 0, 1080 1325 repostedby, 1326 + style, 1327 + ref, 1328 + dataIndexPropPass, 1329 + nopics, 1330 + lightboxCallback, 1331 + maxReplies, 1081 1332 }: { 1082 1333 post: PostView; 1334 + uprrrsauthor?: AppBskyActorDefs.ProfileViewDetailed; 1083 1335 // optional for now because i havent ported every use to this yet 1084 1336 // setMainItem?: React.Dispatch< 1085 1337 // React.SetStateAction<AppBskyFeedDefs.FeedViewPost> ··· 1097 1349 feedviewpostreplyhandle?: string; 1098 1350 depth?: number; 1099 1351 repostedby?: string; 1352 + style?: React.CSSProperties; 1353 + ref?: React.Ref<HTMLDivElement>; 1354 + dataIndexPropPass?: number; 1355 + nopics?: boolean; 1356 + lightboxCallback?: (d: LightboxProps) => void; 1357 + maxReplies?: number; 1100 1358 }) { 1359 + const parsed = new AtUri(post.uri); 1101 1360 const navigate = useNavigate(); 1102 1361 const [likedPosts, setLikedPosts] = useAtom(likedPostsAtom); 1103 - const [hasRetweeted, setHasRetweeted] = useState<Boolean>( 1362 + const [hasRetweeted, setHasRetweeted] = useState<boolean>( 1104 1363 post.viewer?.repost ? true : false 1105 1364 ); 1106 - const [hasLiked, setHasLiked] = useState<Boolean>( 1107 - (post.uri in likedPosts) || post.viewer?.like ? true : false 1365 + const [hasLiked, setHasLiked] = useState<boolean>( 1366 + post.uri in likedPosts || post.viewer?.like ? true : false 1108 1367 ); 1368 + const [, setComposerPost] = useAtom(composerAtom); 1109 1369 const { agent } = useAuth(); 1110 1370 const [likeUri, setLikeUri] = useState<string | undefined>(post.viewer?.like); 1111 1371 const [retweetUri, setRetweetUri] = useState<string | undefined>( ··· 1134 1394 setHasLiked(true); 1135 1395 newLikedPosts[post.uri] = uri; 1136 1396 } 1137 - setLikedPosts(newLikedPosts) 1397 + setLikedPosts(newLikedPosts); 1138 1398 }; 1139 1399 1140 1400 const repostOrUnrepostPost = async () => { ··· 1154 1414 } 1155 1415 }; 1156 1416 1157 - const isRepost = repostedby ? repostedby : extraOptionalItemInfo 1158 - ? AppBskyFeedDefs.isReasonRepost(extraOptionalItemInfo.reason) 1159 - ? extraOptionalItemInfo.reason?.by.displayName 1160 - : undefined 1161 - : undefined; 1417 + const isRepost = repostedby 1418 + ? repostedby 1419 + : extraOptionalItemInfo 1420 + ? AppBskyFeedDefs.isReasonRepost(extraOptionalItemInfo.reason) 1421 + ? extraOptionalItemInfo.reason?.by.displayName 1422 + : undefined 1423 + : undefined; 1162 1424 const isReply = extraOptionalItemInfo 1163 1425 ? extraOptionalItemInfo.reply 1164 1426 : undefined; 1165 1427 1166 1428 const emergencySalt = randomString(); 1429 + const fedi = (post.record as { bridgyOriginalText?: string }) 1430 + .bridgyOriginalText; 1167 1431 1168 1432 /* fuck you */ 1169 1433 const isMainItem = false; 1170 1434 const setMainItem = (any: any) => {}; 1435 + // eslint-disable-next-line react-hooks/refs 1436 + console.log("Received ref in UniversalPostRenderer:", ref); 1171 1437 return ( 1172 - <div 1173 - key={salt + "-" + (post.uri || emergencySalt)} 1174 - onClick={ 1175 - isMainItem 1176 - ? onPostClick 1177 - : setMainItem 1178 - ? onPostClick 1179 - ? (e) => { 1180 - setMainItem({ post: post }); 1181 - onPostClick(e); 1182 - } 1183 - : () => { 1184 - setMainItem({ post: post }); 1185 - } 1186 - : undefined 1187 - } 1188 - style={{ 1189 - //border: "1px solid #e1e8ed", 1190 - //borderRadius: 12, 1191 - opacity: "1 !important", 1192 - background: "transparent", 1193 - paddingLeft: isQuote ? 12 : 16, 1194 - paddingRight: isQuote ? 12 : 16, 1195 - //paddingTop: 16, 1196 - paddingTop: isRepost ? 10 : isQuote ? 12 : 16, 1197 - //paddingBottom: bottomReplyLine ? 0 : 16, 1198 - paddingBottom: 0, 1199 - fontFamily: "system-ui, sans-serif", 1200 - //boxShadow: "0 2px 8px rgba(0,0,0,0.04)", 1201 - position: "relative", 1202 - // dont cursor: "pointer", 1203 - borderBottomWidth: bottomBorder ? (isQuote ? 0 : 1) : 0, 1204 - }} 1205 - className="border-gray-300 dark:border-gray-600" 1206 - > 1207 - {isRepost && ( 1208 - <div 1209 - style={{ 1210 - marginLeft: 36, 1211 - display: "flex", 1212 - borderRadius: 12, 1213 - paddingBottom: "calc(22px - 1rem)", 1214 - fontSize: 14, 1215 - maxHeight: "1rem", 1216 - justifyContent: "flex-start", 1217 - //color: theme.textSecondary, 1218 - gap: 4, 1219 - alignItems: "center", 1220 - }} 1221 - className="text-gray-500 dark:text-gray-400" 1222 - > 1223 - <MdiRepost /> Reposted by @{isRepost}{" "} 1224 - </div> 1225 - )} 1226 - {!isQuote && ( 1227 - <div 1228 - style={{ 1229 - opacity: topReplyLine || (isReply && (true || expanded)) ? 0.5 : 0, 1230 - position: "absolute", 1231 - top: 0, 1232 - left: 36, // why 36 ??? 1233 - //left: 16 + (42 / 2), 1234 - width: 2, 1235 - //height: "100%", 1236 - height: isRepost ? "calc(16px + 1rem - 6px)" : 16 - 6, 1237 - // background: theme.textSecondary, 1238 - //opacity: 0.5, 1239 - // no flex here 1240 - }} 1241 - className="bg-gray-500 dark:bg-gray-400" 1242 - /> 1243 - )} 1438 + <div ref={ref} style={style} data-index={dataIndexPropPass}> 1244 1439 <div 1440 + //ref={ref} 1441 + key={salt + "-" + (post.uri || emergencySalt)} 1442 + onClick={ 1443 + isMainItem 1444 + ? onPostClick 1445 + : setMainItem 1446 + ? onPostClick 1447 + ? (e) => { 1448 + setMainItem({ post: post }); 1449 + onPostClick(e); 1450 + } 1451 + : () => { 1452 + setMainItem({ post: post }); 1453 + } 1454 + : undefined 1455 + } 1245 1456 style={{ 1246 - position: "absolute", 1247 - //top: isRepost ? "calc(16px + 1rem)" : 16, 1248 - //left: 16, 1249 - zIndex: 1, 1250 - top: isRepost ? "calc(16px + 1rem)" : isQuote ? 12 : 16, 1251 - left: isQuote ? 12 : 16, 1457 + //...style, 1458 + //border: "1px solid #e1e8ed", 1459 + //borderRadius: 12, 1460 + opacity: "1 !important", 1461 + background: "transparent", 1462 + paddingLeft: isQuote ? 12 : 16, 1463 + paddingRight: isQuote ? 12 : 16, 1464 + //paddingTop: 16, 1465 + paddingTop: isRepost ? 10 : isQuote ? 12 : topReplyLine ? 8 : 16, 1466 + //paddingBottom: bottomReplyLine ? 0 : 16, 1467 + paddingBottom: 0, 1468 + fontFamily: "system-ui, sans-serif", 1469 + //boxShadow: "0 2px 8px rgba(0,0,0,0.04)", 1470 + position: "relative", 1471 + // dont cursor: "pointer", 1472 + borderBottomWidth: bottomBorder ? (isQuote ? 0 : 1) : 0, 1252 1473 }} 1253 - onClick={onProfileClick} 1474 + className="border-gray-300 dark:border-gray-800" 1254 1475 > 1255 - <img 1256 - src={post.author.avatar || defaultpfp} 1257 - alt="avatar" 1258 - // transition={{ 1259 - // type: "spring", 1260 - // stiffness: 260, 1261 - // damping: 20, 1262 - // }} 1263 - style={{ 1264 - borderRadius: "50%", 1265 - marginRight: 12, 1266 - objectFit: "cover", 1267 - //background: theme.border, 1268 - //border: `1px solid ${theme.border}`, 1269 - width: isQuote ? 16 : 42, 1270 - height: isQuote ? 16 : 42, 1271 - }} 1272 - className="border border-gray-300 dark:border-gray-600 bg-gray-300 dark:bg-gray-600" 1273 - /> 1274 - </div> 1275 - <div style={{ display: "flex", alignItems: "flex-start", zIndex: 2 }}> 1276 - <div 1277 - style={{ 1278 - display: "flex", 1279 - flexDirection: "column", 1280 - alignSelf: "stretch", 1281 - alignItems: "center", 1282 - overflow: "hidden", 1283 - width: expanded || isQuote ? 0 : "auto", 1284 - marginRight: expanded || isQuote ? 0 : 12, 1285 - }} 1286 - > 1287 - {/* dummy for later use */} 1288 - <div style={{ width: 42, height: 42 + 8, minHeight: 42 + 8 }} /> 1289 - {/* reply line !!!! bottomReplyLine */} 1290 - {bottomReplyLine && ( 1476 + {isRepost && ( 1477 + <div 1478 + style={{ 1479 + marginLeft: 36, 1480 + display: "flex", 1481 + borderRadius: 12, 1482 + paddingBottom: "calc(22px - 1rem)", 1483 + fontSize: 14, 1484 + maxHeight: "1rem", 1485 + justifyContent: "flex-start", 1486 + //color: theme.textSecondary, 1487 + gap: 4, 1488 + alignItems: "center", 1489 + }} 1490 + className="text-gray-500 dark:text-gray-400" 1491 + > 1492 + <MdiRepost /> Reposted by @{isRepost}{" "} 1493 + </div> 1494 + )} 1495 + {!isQuote && ( 1496 + <div 1497 + style={{ 1498 + opacity: 1499 + topReplyLine || isReply /*&& (true || expanded)*/ ? 0.5 : 0, 1500 + position: "absolute", 1501 + top: 0, 1502 + left: 36, // why 36 ??? 1503 + //left: 16 + (42 / 2), 1504 + width: 2, 1505 + //height: "100%", 1506 + height: isRepost 1507 + ? "calc(16px + 1rem - 6px)" 1508 + : topReplyLine 1509 + ? 8 - 6 1510 + : 16 - 6, 1511 + // background: theme.textSecondary, 1512 + //opacity: 0.5, 1513 + // no flex here 1514 + }} 1515 + className="bg-gray-500 dark:bg-gray-400" 1516 + /> 1517 + )} 1518 + <HoverCard.Root> 1519 + <HoverCard.Trigger asChild> 1291 1520 <div 1521 + className={`absolute`} 1292 1522 style={{ 1293 - width: 2, 1294 - height: "100%", 1295 - //background: theme.textSecondary, 1296 - opacity: 0.5, 1297 - // no flex here 1298 - //color: "Red", 1299 - //zIndex: 99 1523 + top: isRepost 1524 + ? "calc(16px + 1rem)" 1525 + : isQuote 1526 + ? 12 1527 + : topReplyLine 1528 + ? 8 1529 + : 16, 1530 + left: isQuote ? 12 : 16, 1300 1531 }} 1301 - className="bg-gray-500 dark:bg-gray-400" 1302 - /> 1303 - )} 1304 - {/* <div 1532 + onClick={onProfileClick} 1533 + > 1534 + <img 1535 + src={post.author.avatar || defaultpfp} 1536 + alt="avatar" 1537 + className={`rounded-full object-cover border border-gray-300 dark:border-gray-800 bg-gray-300 dark:bg-gray-600`} 1538 + style={{ 1539 + width: isQuote ? 16 : 42, 1540 + height: isQuote ? 16 : 42, 1541 + }} 1542 + /> 1543 + </div> 1544 + </HoverCard.Trigger> 1545 + <HoverCard.Portal> 1546 + <HoverCard.Content 1547 + className="rounded-md p-4 w-72 bg-gray-50 dark:bg-gray-900 shadow-lg border border-gray-300 dark:border-gray-800 animate-slide-fade z-50" 1548 + side={"bottom"} 1549 + sideOffset={5} 1550 + onClick={onProfileClick} 1551 + > 1552 + <div className="flex flex-col gap-2"> 1553 + <div className="flex flex-row"> 1554 + <img 1555 + src={post.author.avatar || defaultpfp} 1556 + alt="avatar" 1557 + className="rounded-full w-[58px] h-[58px] object-cover border border-gray-300 dark:border-gray-800 bg-gray-300 dark:bg-gray-600" 1558 + /> 1559 + <div className=" flex-1 flex flex-row align-middle justify-end"> 1560 + <FollowButton targetdidorhandle={post.author.did} /> 1561 + </div> 1562 + </div> 1563 + <div className="flex flex-col gap-3"> 1564 + <div> 1565 + <div className="text-gray-900 dark:text-gray-100 font-medium text-md"> 1566 + {post.author.displayName || post.author.handle}{" "} 1567 + </div> 1568 + <div className="text-gray-500 dark:text-gray-400 text-md flex flex-row gap-1"> 1569 + <Mutual targetdidorhandle={post.author.did} />@{post.author.handle}{" "} 1570 + </div> 1571 + </div> 1572 + {uprrrsauthor?.description && ( 1573 + <div className="text-gray-700 dark:text-gray-300 text-sm text-left break-words line-clamp-3"> 1574 + {uprrrsauthor.description} 1575 + </div> 1576 + )} 1577 + {/* <div className="flex gap-4"> 1578 + <div className="flex gap-1"> 1579 + <div className="font-medium text-gray-900 dark:text-gray-100"> 1580 + 0 1581 + </div> 1582 + <div className="text-gray-500 dark:text-gray-400"> 1583 + Following 1584 + </div> 1585 + </div> 1586 + <div className="flex gap-1"> 1587 + <div className="font-medium text-gray-900 dark:text-gray-100"> 1588 + 2,900 1589 + </div> 1590 + <div className="text-gray-500 dark:text-gray-400"> 1591 + Followers 1592 + </div> 1593 + </div> 1594 + </div> */} 1595 + </div> 1596 + </div> 1597 + 1598 + {/* <HoverCard.Arrow className="fill-gray-50 dark:fill-gray-900" /> */} 1599 + </HoverCard.Content> 1600 + </HoverCard.Portal> 1601 + </HoverCard.Root> 1602 + 1603 + <div style={{ display: "flex", alignItems: "flex-start", zIndex: 2 }}> 1604 + <div 1605 + style={{ 1606 + display: "flex", 1607 + flexDirection: "column", 1608 + alignSelf: "stretch", 1609 + alignItems: "center", 1610 + overflow: "hidden", 1611 + width: expanded || isQuote ? 0 : "auto", 1612 + marginRight: expanded || isQuote ? 0 : 12, 1613 + }} 1614 + > 1615 + {/* dummy for later use */} 1616 + <div style={{ width: 42, height: 42 + 6, minHeight: 42 + 6 }} /> 1617 + {/* reply line !!!! bottomReplyLine */} 1618 + {bottomReplyLine && ( 1619 + <div 1620 + style={{ 1621 + width: 2, 1622 + height: "100%", 1623 + //background: theme.textSecondary, 1624 + opacity: 0.5, 1625 + // no flex here 1626 + //color: "Red", 1627 + //zIndex: 99 1628 + }} 1629 + className="bg-gray-500 dark:bg-gray-400" 1630 + /> 1631 + )} 1632 + {/* <div 1305 1633 layout 1306 1634 transition={{ duration: 0.2 }} 1307 1635 animate={{ height: expanded ? 0 : '100%' }} ··· 1311 1639 // no flex here 1312 1640 }} 1313 1641 /> */} 1314 - </div> 1315 - <div style={{ flex: 1, maxWidth: "100%" }}> 1316 - <div 1317 - style={{ 1318 - display: "flex", 1319 - flexDirection: "row", 1320 - alignItems: "center", 1321 - flexWrap: "nowrap", 1322 - maxWidth: `calc(100% - ${!expanded ? (isQuote ? 26 : 0) : 54}px)`, 1323 - width: `calc(100% - ${!expanded ? (isQuote ? 26 : 0) : 54}px)`, 1324 - marginLeft: !expanded ? (isQuote ? 26 : 0) : 54, 1325 - marginBottom: !expanded ? 4 : 6, 1326 - }} 1327 - > 1642 + </div> 1643 + <div style={{ flex: 1, maxWidth: "100%" }}> 1328 1644 <div 1329 1645 style={{ 1330 1646 display: "flex", 1331 - //overflow: "hidden", // hey why is overflow hidden unapplied 1332 - overflow: "hidden", 1333 - textOverflow: "ellipsis", 1334 - flexShrink: 1, 1335 - flexGrow: 1, 1336 - flexBasis: 0, 1337 - width: 0, 1338 - gap: expanded ? 0 : 6, 1339 - alignItems: expanded ? "flex-start" : "center", 1340 - flexDirection: expanded ? "column" : "row", 1341 - height: expanded ? 42 : "1rem", 1647 + flexDirection: "row", 1648 + alignItems: "center", 1649 + flexWrap: "nowrap", 1650 + maxWidth: `calc(100% - ${!expanded ? (isQuote ? 26 : 0) : 54}px)`, 1651 + width: `calc(100% - ${!expanded ? (isQuote ? 26 : 0) : 54}px)`, 1652 + marginLeft: !expanded ? (isQuote ? 26 : 0) : 54, 1653 + marginBottom: !expanded ? 4 : 6, 1342 1654 }} 1343 1655 > 1344 - <span 1656 + <div 1345 1657 style={{ 1346 1658 display: "flex", 1347 - fontWeight: 700, 1348 - fontSize: 16, 1659 + //overflow: "hidden", // hey why is overflow hidden unapplied 1349 1660 overflow: "hidden", 1350 1661 textOverflow: "ellipsis", 1351 - whiteSpace: "nowrap", 1352 1662 flexShrink: 1, 1353 - minWidth: 0, 1354 - gap: 4, 1355 - alignItems: "center", 1356 - //color: theme.text, 1663 + flexGrow: 1, 1664 + flexBasis: 0, 1665 + width: 0, 1666 + gap: expanded ? 0 : 6, 1667 + alignItems: expanded ? "flex-start" : "center", 1668 + flexDirection: expanded ? "column" : "row", 1669 + height: expanded ? 42 : "1rem", 1357 1670 }} 1358 - className="text-gray-900 dark:text-gray-100" 1359 1671 > 1360 - {/* verified checkmark */} 1361 - {post.author.displayName || post.author.handle}{" "} 1362 - {post.author.verification?.verifiedStatus == "valid" && ( 1363 - <MdiVerified /> 1364 - )} 1365 - </span> 1672 + <span 1673 + style={{ 1674 + display: "flex", 1675 + fontWeight: 700, 1676 + fontSize: 16, 1677 + overflow: "hidden", 1678 + textOverflow: "ellipsis", 1679 + whiteSpace: "nowrap", 1680 + flexShrink: 1, 1681 + minWidth: 0, 1682 + gap: 4, 1683 + alignItems: "center", 1684 + //color: theme.text, 1685 + }} 1686 + className="text-gray-900 dark:text-gray-100" 1687 + > 1688 + {/* verified checkmark */} 1689 + {post.author.displayName || post.author.handle}{" "} 1690 + {post.author.verification?.verifiedStatus == "valid" && ( 1691 + <MdiVerified /> 1692 + )} 1693 + </span> 1366 1694 1367 - <span 1695 + <span 1696 + style={{ 1697 + //color: theme.textSecondary, 1698 + fontSize: 16, 1699 + overflowX: "hidden", 1700 + textOverflow: "ellipsis", 1701 + whiteSpace: "nowrap", 1702 + flexShrink: 1, 1703 + flexGrow: 0, 1704 + minWidth: 0, 1705 + }} 1706 + className="text-gray-500 dark:text-gray-400" 1707 + > 1708 + @{post.author.handle} 1709 + </span> 1710 + </div> 1711 + <div 1368 1712 style={{ 1369 - //color: theme.textSecondary, 1370 - fontSize: 16, 1371 - overflowX: "hidden", 1372 - textOverflow: "ellipsis", 1373 - whiteSpace: "nowrap", 1374 - flexShrink: 1, 1375 - flexGrow: 0, 1376 - minWidth: 0, 1713 + display: "flex", 1714 + alignItems: "center", 1715 + height: "1rem", 1377 1716 }} 1378 - className="text-gray-500 dark:text-gray-400" 1379 1717 > 1380 - @{post.author.handle} 1381 - </span> 1718 + <span 1719 + style={{ 1720 + //color: theme.textSecondary, 1721 + fontSize: 16, 1722 + marginLeft: 8, 1723 + whiteSpace: "nowrap", 1724 + flexShrink: 0, 1725 + maxWidth: "100%", 1726 + }} 1727 + className="text-gray-500 dark:text-gray-400" 1728 + > 1729 + ยท {/* time placeholder */} 1730 + {shortTimeAgo(post.indexedAt)} 1731 + </span> 1732 + </div> 1382 1733 </div> 1383 - <div 1384 - style={{ 1385 - display: "flex", 1386 - alignItems: "center", 1387 - height: "1rem", 1388 - }} 1389 - > 1390 - <span 1734 + {/* reply indicator */} 1735 + {!!feedviewpostreplyhandle && ( 1736 + <div 1391 1737 style={{ 1738 + display: "flex", 1739 + borderRadius: 12, 1740 + paddingBottom: 2, 1741 + fontSize: 14, 1742 + justifyContent: "flex-start", 1392 1743 //color: theme.textSecondary, 1393 - fontSize: 16, 1394 - marginLeft: 8, 1395 - whiteSpace: "nowrap", 1396 - flexShrink: 0, 1397 - maxWidth: "100%", 1744 + gap: 4, 1745 + alignItems: "center", 1746 + //marginLeft: 36, 1747 + height: 1748 + !(expanded || isQuote) && !!feedviewpostreplyhandle 1749 + ? "1rem" 1750 + : 0, 1751 + opacity: 1752 + !(expanded || isQuote) && !!feedviewpostreplyhandle ? 1 : 0, 1398 1753 }} 1399 1754 className="text-gray-500 dark:text-gray-400" 1400 1755 > 1401 - ยท {/* time placeholder */} 1402 - {shortTimeAgo(post.indexedAt)} 1403 - </span> 1404 - </div> 1405 - </div> 1406 - {/* reply indicator */} 1407 - {!!feedviewpostreplyhandle && ( 1756 + <MdiReply /> Reply to @{feedviewpostreplyhandle} 1757 + </div> 1758 + )} 1408 1759 <div 1409 1760 style={{ 1410 - display: "flex", 1411 - borderRadius: 12, 1412 - paddingBottom: 2, 1413 - fontSize: 14, 1414 - justifyContent: "flex-start", 1415 - //color: theme.textSecondary, 1416 - gap: 4, 1417 - alignItems: "center", 1418 - //marginLeft: 36, 1419 - height: 1420 - !(expanded || isQuote) && !!feedviewpostreplyhandle 1421 - ? "1rem" 1422 - : 0, 1423 - opacity: 1424 - !(expanded || isQuote) && !!feedviewpostreplyhandle ? 1 : 0, 1761 + fontSize: 16, 1762 + marginBottom: !post.embed /*|| depth > 0*/ ? 0 : 8, 1763 + whiteSpace: "pre-wrap", 1764 + textAlign: "left", 1765 + overflowWrap: "anywhere", 1766 + wordBreak: "break-word", 1767 + //color: theme.text, 1425 1768 }} 1426 - className="text-gray-500 dark:text-gray-400" 1769 + className="text-gray-900 dark:text-gray-100" 1427 1770 > 1428 - <MdiReply /> Reply to @{feedviewpostreplyhandle} 1771 + {fedi ? ( 1772 + <> 1773 + <span 1774 + className="dangerousFediContent" 1775 + dangerouslySetInnerHTML={{ 1776 + __html: DOMPurify.sanitize(fedi), 1777 + }} 1778 + /> 1779 + </> 1780 + ) : ( 1781 + <> 1782 + {renderTextWithFacets({ 1783 + text: (post.record as { text?: string }).text ?? "", 1784 + facets: (post.record.facets as Facet[]) ?? [], 1785 + navigate: navigate, 1786 + })} 1787 + </> 1788 + )} 1429 1789 </div> 1430 - )} 1431 - <div 1432 - style={{ 1433 - fontSize: 16, 1434 - marginBottom: !post.embed /*|| depth > 0*/ ? 0 : 8, 1435 - whiteSpace: "pre-wrap", 1436 - textAlign: "left", 1437 - overflowWrap: "anywhere", 1438 - wordBreak: "break-word", 1439 - //color: theme.text, 1440 - }} 1441 - className="text-gray-900 dark:text-gray-100" 1442 - > 1443 - {renderTextWithFacets({ 1444 - text: (post.record as { text?: string }).text ?? "", 1445 - facets: (post.record.facets as Facet[]) ?? [], 1446 - navigate: navigate 1447 - })} 1448 - {} 1449 - </div> 1450 - {post.embed && depth < 1 ? ( 1451 - <PostEmbeds 1452 - embed={post.embed} 1453 - //moderation={moderation} 1454 - viewContext={PostEmbedViewContext.Feed} 1455 - salt={salt} 1456 - navigate={navigate} 1457 - /> 1458 - ) : null} 1459 - {post.embed && depth > 0 && ( 1460 - <> 1461 - <div className="border-gray-300 dark:border-gray-600 p-3 rounded-xl border italic text-gray-400 text-[14px]"> 1462 - (there is an embed here thats too deep to render) 1463 - </div> 1464 - </> 1465 - )} 1466 - <div style={{ paddingTop: post.embed && depth < 1 ? 4 : 0 }}> 1467 - <> 1468 - {expanded && ( 1790 + {post.embed && depth < 1 ? ( 1791 + <PostEmbeds 1792 + embed={post.embed} 1793 + //moderation={moderation} 1794 + viewContext={PostEmbedViewContext.Feed} 1795 + salt={salt} 1796 + navigate={navigate} 1797 + postid={{ did: post.author.did, rkey: parsed.rkey }} 1798 + nopics={nopics} 1799 + lightboxCallback={lightboxCallback} 1800 + /> 1801 + ) : null} 1802 + {post.embed && depth > 0 && ( 1803 + /* pretty bad hack imo. its trying to sync up with how the embed shim doesnt 1804 + hydrate embeds this deep but the connection here is implicit 1805 + todo: idk make this a real part of the embed shim so its not implicit */ 1806 + <> 1807 + <div className="border-gray-300 dark:border-gray-800 p-3 rounded-xl border italic text-gray-400 text-[14px]"> 1808 + (there is an embed here thats too deep to render) 1809 + </div> 1810 + </> 1811 + )} 1812 + <div style={{ paddingTop: post.embed && depth < 1 ? 4 : 0 }}> 1813 + <> 1814 + {expanded && ( 1815 + <div 1816 + style={{ 1817 + overflow: "hidden", 1818 + //color: theme.textSecondary, 1819 + fontSize: 14, 1820 + display: "flex", 1821 + borderBottomStyle: "solid", 1822 + //borderBottomColor: theme.border, 1823 + //background: "#f00", 1824 + // height: "1rem", 1825 + paddingTop: 4, 1826 + paddingBottom: 8, 1827 + borderBottomWidth: 1, 1828 + marginBottom: 8, 1829 + }} // important for height animation 1830 + className="text-gray-500 dark:text-gray-400 border-gray-200 dark:border-gray-800 was7" 1831 + > 1832 + {fullDateTimeFormat(post.indexedAt)} 1833 + </div> 1834 + )} 1835 + </> 1836 + {!isQuote && ( 1469 1837 <div 1470 1838 style={{ 1471 - overflow: "hidden", 1472 - //color: theme.textSecondary, 1473 - fontSize: 14, 1474 1839 display: "flex", 1475 - borderBottomStyle: "solid", 1476 - //borderBottomColor: theme.border, 1477 - //background: "#f00", 1478 - // height: "1rem", 1479 - paddingTop: 4, 1480 - paddingBottom: 8, 1481 - borderBottomWidth: 1, 1482 - marginBottom: 8, 1483 - }} // important for height animation 1484 - className="text-gray-500 dark:text-gray-400 border-gray-200 dark:border-gray-700" 1485 - > 1486 - {fullDateTimeFormat(post.indexedAt)} 1487 - </div> 1488 - )} 1489 - </> 1490 - {!isQuote && ( 1491 - <div 1492 - style={{ 1493 - display: "flex", 1494 - gap: 32, 1495 - paddingTop: 8, 1496 - //color: theme.textSecondary, 1497 - fontSize: 15, 1498 - justifyContent: "space-between", 1499 - //background: "#0f0", 1500 - }} 1501 - className="text-gray-500 dark:text-gray-400" 1502 - > 1503 - <span style={btnstyle}> 1504 - <MdiCommentOutline /> 1505 - {post.replyCount} 1506 - </span> 1507 - <HitSlopButton 1508 - onClick={() => { 1509 - repostOrUnrepostPost(); 1510 - }} 1511 - style={{ 1512 - ...btnstyle, 1513 - ...(hasRetweeted ? { color: "#5CEFAA" } : {}), 1840 + gap: 32, 1841 + paddingTop: 8, 1842 + //color: theme.textSecondary, 1843 + fontSize: 15, 1844 + justifyContent: "space-between", 1845 + //background: "#0f0", 1514 1846 }} 1847 + className="text-gray-500 dark:text-gray-400" 1515 1848 > 1516 - {hasRetweeted ? <MdiRepeatGreen /> : <MdiRepeat />} 1517 - {(post.repostCount || 0) + (hasRetweeted ? 1 : 0)} 1518 - </HitSlopButton> 1519 - <HitSlopButton 1520 - onClick={() => { 1521 - likeOrUnlikePost(); 1522 - }} 1523 - style={{ 1524 - ...btnstyle, 1525 - ...(hasLiked ? { color: "#EC4899" } : {}), 1526 - }} 1527 - > 1528 - {hasLiked ? <MdiCardsHeart /> : <MdiCardsHeartOutline />} 1529 - {(post.likeCount || 0) + (hasLiked ? 1 : 0)} 1530 - </HitSlopButton> 1531 - <div style={{ display: "flex", gap: 8 }}> 1849 + <HitSlopButton 1850 + onClick={() => { 1851 + setComposerPost({ kind: "reply", parent: post.uri }); 1852 + }} 1853 + style={{ 1854 + ...btnstyle, 1855 + }} 1856 + > 1857 + <MdiCommentOutline /> 1858 + {post.replyCount} 1859 + </HitSlopButton> 1860 + <DropdownMenu.Root modal={false}> 1861 + <DropdownMenu.Trigger asChild> 1862 + <div 1863 + style={{ 1864 + ...btnstyle, 1865 + ...(hasRetweeted ? { color: "#5CEFAA" } : {}), 1866 + }} 1867 + aria-label="Repost or quote post" 1868 + > 1869 + {hasRetweeted ? <MdiRepeatGreen /> : <MdiRepeat />} 1870 + {post.repostCount ?? 0} 1871 + </div> 1872 + </DropdownMenu.Trigger> 1873 + 1874 + <DropdownMenu.Portal> 1875 + <DropdownMenu.Content 1876 + align="start" 1877 + sideOffset={5} 1878 + className="bg-white dark:bg-gray-800 rounded-lg shadow-xl border border-gray-200 dark:border-gray-700 w-32 z-50 overflow-hidden" 1879 + > 1880 + <DropdownMenu.Item 1881 + onSelect={repostOrUnrepostPost} 1882 + className="px-3 py-2 text-sm flex items-center gap-2 cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:bg-gray-100 dark:focus:bg-gray-700" 1883 + > 1884 + <MdiRepeat 1885 + className={hasRetweeted ? "text-green-400" : ""} 1886 + /> 1887 + <span>{hasRetweeted ? "Undo Repost" : "Repost"}</span> 1888 + </DropdownMenu.Item> 1889 + 1890 + <DropdownMenu.Item 1891 + onSelect={() => { 1892 + setComposerPost({ 1893 + kind: "quote", 1894 + subject: post.uri, 1895 + }); 1896 + }} 1897 + className="px-3 py-2 text-sm flex items-center gap-2 cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:bg-gray-100 dark:focus:bg-gray-700" 1898 + > 1899 + {/* You might want a specific quote icon here */} 1900 + <MdiCommentOutline /> 1901 + <span>Quote</span> 1902 + </DropdownMenu.Item> 1903 + </DropdownMenu.Content> 1904 + </DropdownMenu.Portal> 1905 + </DropdownMenu.Root> 1532 1906 <HitSlopButton 1533 - onClick={async (e) => { 1534 - e.stopPropagation(); 1535 - try { 1536 - await navigator.clipboard.writeText( 1537 - "https://bsky.app" + 1538 - "/profile/" + 1539 - post.author.handle + 1540 - "/post/" + 1541 - post.uri.split("/").pop() 1542 - ); 1543 - } catch {} 1907 + onClick={() => { 1908 + likeOrUnlikePost(); 1544 1909 }} 1545 1910 style={{ 1546 1911 ...btnstyle, 1912 + ...(hasLiked ? { color: "#EC4899" } : {}), 1547 1913 }} 1548 1914 > 1549 - <MdiShareVariant /> 1915 + {hasLiked ? <MdiCardsHeart /> : <MdiCardsHeartOutline />} 1916 + {(post.likeCount || 0) + (hasLiked ? 1 : 0)} 1550 1917 </HitSlopButton> 1551 - <span style={btnstyle}> 1552 - <MdiMoreHoriz /> 1553 - </span> 1918 + <div style={{ display: "flex", gap: 8 }}> 1919 + <HitSlopButton 1920 + onClick={async (e) => { 1921 + e.stopPropagation(); 1922 + try { 1923 + await navigator.clipboard.writeText( 1924 + "https://bsky.app" + 1925 + "/profile/" + 1926 + post.author.handle + 1927 + "/post/" + 1928 + post.uri.split("/").pop() 1929 + ); 1930 + } catch (_e) { 1931 + // idk 1932 + } 1933 + }} 1934 + style={{ 1935 + ...btnstyle, 1936 + }} 1937 + > 1938 + <MdiShareVariant /> 1939 + </HitSlopButton> 1940 + <span style={btnstyle}> 1941 + <MdiMoreHoriz /> 1942 + </span> 1943 + </div> 1554 1944 </div> 1555 - </div> 1556 - )} 1945 + )} 1946 + </div> 1947 + <div 1948 + style={{ 1949 + //height: bottomReplyLine ? 16 : 0 1950 + height: isQuote ? 12 : 16, 1951 + }} 1952 + /> 1557 1953 </div> 1558 - <div 1559 - style={{ 1560 - //height: bottomReplyLine ? 16 : 0 1561 - height: isQuote ? 12 : 16, 1562 - }} 1563 - /> 1564 1954 </div> 1565 1955 </div> 1566 1956 </div> ··· 1652 2042 viewContext, 1653 2043 salt, 1654 2044 navigate, 2045 + postid, 2046 + nopics, 2047 + lightboxCallback, 1655 2048 }: { 1656 2049 embed?: Embed; 1657 2050 moderation?: ModerationDecision; ··· 1659 2052 allowNestedQuotes?: boolean; 1660 2053 viewContext?: PostEmbedViewContext; 1661 2054 salt: string; 1662 - navigate: ({}: any) => void; 2055 + navigate: (_: any) => void; 2056 + postid?: { did: string; rkey: string }; 2057 + nopics?: boolean; 2058 + lightboxCallback?: (d: LightboxProps) => void; 1663 2059 }) { 1664 - const [lightboxIndex, setLightboxIndex] = useState<number | null>(null); 2060 + //const [lightboxIndex, setLightboxIndex] = useState<number | null>(null); 2061 + function setLightboxIndex(number: number) { 2062 + navigate({ 2063 + to: "/profile/$did/post/$rkey/image/$i", 2064 + params: { 2065 + did: postid?.did, 2066 + rkey: postid?.rkey, 2067 + i: number.toString(), 2068 + }, 2069 + }); 2070 + } 1665 2071 if ( 1666 2072 AppBskyEmbedRecordWithMedia.isView(embed) && 1667 2073 AppBskyEmbedRecord.isViewRecord(embed.record.record) && ··· 1695 2101 viewContext={viewContext} 1696 2102 salt={salt} 1697 2103 navigate={navigate} 2104 + postid={postid} 2105 + nopics={nopics} 2106 + lightboxCallback={lightboxCallback} 1698 2107 /> 1699 2108 {/* padding empty div of 8px height */} 1700 2109 <div style={{ height: 12 }} /> ··· 1708 2117 //boxShadow: theme.cardShadow, 1709 2118 overflow: "hidden", 1710 2119 }} 1711 - className="shadow border border-gray-200 dark:border-gray-700" 2120 + className="shadow border border-gray-200 dark:border-gray-800 was7" 1712 2121 > 1713 2122 <UniversalPostRenderer 1714 2123 post={post} ··· 1716 2125 salt={salt} 1717 2126 onPostClick={(e) => { 1718 2127 e.stopPropagation(); 1719 - const parsed = parseAtUri(post.uri); 2128 + const parsed = new AtUri(post.uri); //parseAtUri(post.uri); 1720 2129 if (parsed) { 1721 2130 navigate({ 1722 2131 to: "/profile/$did/post/$rkey", 1723 - params: { did: parsed.did, rkey: parsed.rkey }, 2132 + params: { did: parsed.host, rkey: parsed.rkey }, 1724 2133 }); 1725 2134 } 1726 2135 }} ··· 1825 2234 //boxShadow: theme.cardShadow, 1826 2235 overflow: "hidden", 1827 2236 }} 1828 - className="shadow border border-gray-200 dark:border-gray-700" 2237 + className="shadow border border-gray-200 dark:border-gray-800 was7" 1829 2238 > 1830 2239 <UniversalPostRenderer 1831 2240 post={post} ··· 1833 2242 salt={salt} 1834 2243 onPostClick={(e) => { 1835 2244 e.stopPropagation(); 1836 - const parsed = parseAtUri(post.uri); 2245 + const parsed = new AtUri(post.uri); //parseAtUri(post.uri); 1837 2246 if (parsed) { 1838 2247 navigate({ 1839 2248 to: "/profile/$did/post/$rkey", 1840 - params: { did: parsed.did, rkey: parsed.rkey }, 2249 + params: { did: parsed.host, rkey: parsed.rkey }, 1841 2250 }); 1842 2251 } 1843 2252 }} ··· 1869 2278 src: img.fullsize, 1870 2279 alt: img.alt, 1871 2280 })); 2281 + console.log("rendering images"); 2282 + if (lightboxCallback) { 2283 + lightboxCallback({ images: lightboxImages }); 2284 + console.log("rendering images"); 2285 + } 2286 + 2287 + if (nopics) return; 1872 2288 1873 2289 if (images.length > 0) { 1874 2290 // const items = embed.images.map(img => ({ ··· 1898 2314 //border: `1px solid ${theme.border}`, 1899 2315 overflow: "hidden", 1900 2316 }} 1901 - className="border border-gray-200 dark:border-gray-700 bg-gray-200 dark:bg-gray-900" 2317 + className="border border-gray-200 dark:border-gray-800 was7 bg-gray-200 dark:bg-gray-900" 1902 2318 > 1903 - {lightboxIndex !== null && ( 2319 + {/* {lightboxIndex !== null && ( 1904 2320 <Lightbox 1905 2321 images={lightboxImages} 1906 2322 index={lightboxIndex} 1907 2323 onClose={() => setLightboxIndex(null)} 1908 2324 onNavigate={(newIndex) => setLightboxIndex(newIndex)} 2325 + post={postid} 1909 2326 /> 1910 - )} 2327 + )} */} 1911 2328 <img 1912 2329 src={image.fullsize} 1913 2330 alt={image.alt} ··· 1938 2355 overflow: "hidden", 1939 2356 //border: `1px solid ${theme.border}`, 1940 2357 }} 1941 - className="border border-gray-200 dark:border-gray-700" 2358 + className="border border-gray-200 dark:border-gray-800 was7" 1942 2359 > 1943 - {lightboxIndex !== null && ( 2360 + {/* {lightboxIndex !== null && ( 1944 2361 <Lightbox 1945 2362 images={lightboxImages} 1946 2363 index={lightboxIndex} 1947 2364 onClose={() => setLightboxIndex(null)} 1948 2365 onNavigate={(newIndex) => setLightboxIndex(newIndex)} 2366 + post={postid} 1949 2367 /> 1950 - )} 2368 + )} */} 1951 2369 {images.map((img, i) => ( 1952 2370 <div 1953 2371 key={i} ··· 1987 2405 //border: `1px solid ${theme.border}`, 1988 2406 // height: 240, // fixed height for cropping 1989 2407 }} 1990 - className="border border-gray-200 dark:border-gray-700" 2408 + className="border border-gray-200 dark:border-gray-800 was7" 1991 2409 > 1992 - {lightboxIndex !== null && ( 2410 + {/* {lightboxIndex !== null && ( 1993 2411 <Lightbox 1994 2412 images={lightboxImages} 1995 2413 index={lightboxIndex} 1996 2414 onClose={() => setLightboxIndex(null)} 1997 2415 onNavigate={(newIndex) => setLightboxIndex(newIndex)} 2416 + post={postid} 1998 2417 /> 1999 - )} 2418 + )} */} 2000 2419 {/* Left: 1:1 */} 2001 2420 <div 2002 2421 style={{ flex: 1, aspectRatio: "1 / 1", position: "relative" }} ··· 2071 2490 //border: `1px solid ${theme.border}`, 2072 2491 //aspectRatio: "3 / 2", // overall grid aspect 2073 2492 }} 2074 - className="border border-gray-200 dark:border-gray-700" 2493 + className="border border-gray-200 dark:border-gray-800 was7" 2075 2494 > 2076 - {lightboxIndex !== null && ( 2495 + {/* {lightboxIndex !== null && ( 2077 2496 <Lightbox 2078 2497 images={lightboxImages} 2079 2498 index={lightboxIndex} 2080 2499 onClose={() => setLightboxIndex(null)} 2081 2500 onNavigate={(newIndex) => setLightboxIndex(newIndex)} 2501 + post={postid} 2082 2502 /> 2083 - )} 2503 + )} */} 2084 2504 {images.map((img, i) => ( 2085 2505 <div 2086 2506 key={i} ··· 2171 2591 return <div />; 2172 2592 } 2173 2593 2174 - import { createPortal } from "react-dom"; 2175 - import type { Record } from "@atproto/api/dist/client/types/app/bsky/actor/profile"; 2176 - type LightboxProps = { 2177 - images: { src: string; alt?: string }[]; 2178 - index: number; 2179 - onClose: () => void; 2180 - onNavigate?: (newIndex: number) => void; 2181 - }; 2182 - export function Lightbox({ 2183 - images, 2184 - index, 2185 - onClose, 2186 - onNavigate, 2187 - }: LightboxProps) { 2188 - const image = images[index]; 2189 - 2190 - useEffect(() => { 2191 - function handleKey(e: KeyboardEvent) { 2192 - if (e.key === "Escape") onClose(); 2193 - if (e.key === "ArrowRight" && onNavigate) 2194 - onNavigate((index + 1) % images.length); 2195 - if (e.key === "ArrowLeft" && onNavigate) 2196 - onNavigate((index - 1 + images.length) % images.length); 2197 - } 2198 - window.addEventListener("keydown", handleKey); 2199 - return () => window.removeEventListener("keydown", handleKey); 2200 - }, [index, images.length, onClose, onNavigate]); 2201 - 2202 - return createPortal( 2203 - <div 2204 - className="fixed inset-0 z-50 flex items-center justify-center bg-black/80" 2205 - onClick={(e) => { 2206 - e.stopPropagation(); 2207 - onClose(); 2208 - }} 2209 - > 2210 - <img 2211 - src={image.src} 2212 - alt={image.alt} 2213 - className="max-h-[90vh] max-w-[90vw] object-contain rounded-lg shadow-lg" 2214 - onClick={(e) => e.stopPropagation()} 2215 - /> 2216 - 2217 - {images.length > 1 && ( 2218 - <> 2219 - <button 2220 - onClick={(e) => { 2221 - e.stopPropagation(); 2222 - onNavigate?.((index - 1 + images.length) % images.length); 2223 - }} 2224 - className="absolute left-4 top-1/2 -translate-y-1/2 text-white text-4xl h-8 w-8 rounded-full bg-gray-900 flex items-center justify-center" 2225 - > 2226 - <svg 2227 - xmlns="http://www.w3.org/2000/svg" 2228 - width={28} 2229 - height={28} 2230 - viewBox="0 0 24 24" 2231 - > 2232 - <g fill="none" fillRule="evenodd"> 2233 - <path d="M24 0v24H0V0zM12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.019-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z"></path> 2234 - <path 2235 - fill="currentColor" 2236 - d="M8.293 12.707a1 1 0 0 1 0-1.414l5.657-5.657a1 1 0 1 1 1.414 1.414L10.414 12l4.95 4.95a1 1 0 0 1-1.414 1.414z" 2237 - ></path> 2238 - </g> 2239 - </svg> 2240 - </button> 2241 - <button 2242 - onClick={(e) => { 2243 - e.stopPropagation(); 2244 - onNavigate?.((index + 1) % images.length); 2245 - }} 2246 - className="absolute right-4 top-1/2 -translate-y-1/2 text-white text-4xl h-8 w-8 rounded-full bg-gray-900 flex items-center justify-center" 2247 - > 2248 - <svg 2249 - xmlns="http://www.w3.org/2000/svg" 2250 - width={28} 2251 - height={28} 2252 - viewBox="0 0 24 24" 2253 - > 2254 - <g fill="none" fillRule="evenodd"> 2255 - <path d="M24 0v24H0V0zM12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.019-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z"></path> 2256 - <path 2257 - fill="currentColor" 2258 - d="M15.707 11.293a1 1 0 0 1 0 1.414l-5.657 5.657a1 1 0 1 1-1.414-1.414l4.95-4.95l-4.95-4.95a1 1 0 0 1 1.414-1.414z" 2259 - ></path> 2260 - </g> 2261 - </svg> 2262 - </button> 2263 - </> 2264 - )} 2265 - </div>, 2266 - document.body 2267 - ); 2268 - } 2269 - 2270 2594 function getDomain(url: string) { 2271 2595 try { 2272 2596 const { hostname } = new URL(url); ··· 2297 2621 for (let i = 0; i < bytes.length; i++) { 2298 2622 map[byteIndex++] = charIndex; 2299 2623 } 2300 - charIndex+=char.length; 2624 + charIndex += char.length; 2301 2625 } 2302 2626 2303 2627 return map; ··· 2331 2655 return { start, end, feature: f.features[0] }; 2332 2656 }); 2333 2657 } 2334 - function renderTextWithFacets({ 2658 + export function renderTextWithFacets({ 2335 2659 text, 2336 2660 facets, 2337 2661 navigate, 2338 2662 }: { 2339 2663 text: string; 2340 2664 facets: Facet[]; 2341 - navigate: ({}: any) => void; 2665 + navigate: (_: any) => void; 2342 2666 }) { 2343 2667 const ranges = extractFacetRanges(text, facets).sort( 2344 2668 (a: any, b: any) => a.start - b.start ··· 2353 2677 } 2354 2678 2355 2679 const fragment = text.slice(start, end); 2356 - // @ts-ignore 2680 + // @ts-expect-error i didnt bother with the correct types here sorry. bsky api types are cursed 2357 2681 if (feature.$type === "app.bsky.richtext.facet#link" && feature.uri) { 2358 2682 result.push( 2359 2683 <a 2360 - // @ts-ignore 2684 + // @ts-expect-error i didnt bother with the correct types here sorry. bsky api types are cursed 2361 2685 href={feature.uri} 2362 2686 key={start} 2363 2687 className="link" ··· 2377 2701 ); 2378 2702 } else if ( 2379 2703 feature.$type === "app.bsky.richtext.facet#mention" && 2380 - // @ts-ignore 2704 + // @ts-expect-error i didnt bother with the correct types here sorry. bsky api types are cursed 2381 2705 feature.did 2382 2706 ) { 2383 2707 result.push( ··· 2389 2713 e.stopPropagation(); 2390 2714 navigate({ 2391 2715 to: "/profile/$did", 2392 - // @ts-ignore 2393 - params: { did: feature.did}, 2716 + // @ts-expect-error i didnt bother with the correct types here sorry. bsky api types are cursed 2717 + params: { did: feature.did }, 2394 2718 }); 2395 2719 }} 2396 2720 > ··· 2486 2810 rel="noopener noreferrer" 2487 2811 onClick={(e) => { 2488 2812 e.stopPropagation(); 2489 - onOpen; 2813 + if (onOpen) onOpen(); 2490 2814 }} 2491 - /* @ts-ignore */ 2815 + /* @ts-expect-error css arent typed or something idk fuck you */ 2492 2816 style={linkStyle} 2493 2817 className="text-gray-500 dark:text-gray-400" 2494 2818 > 2495 - {/* @ts-ignore ehiaeih */} 2496 2819 <div 2497 2820 style={containerStyle as React.CSSProperties} 2498 - className="border border-gray-200 dark:border-gray-700" 2821 + className="border border-gray-200 dark:border-gray-800 was7" 2499 2822 > 2500 2823 {thumb && ( 2501 2824 <div ··· 2509 2832 marginBottom: 8, 2510 2833 //borderBottom: `1px solid ${theme.border}`, 2511 2834 }} 2512 - className="border-b border-gray-200 dark:border-gray-700" 2835 + className="border-b border-gray-200 dark:border-gray-800 was7" 2513 2836 > 2514 2837 <img 2515 2838 src={thumb} ··· 2533 2856 paddingTop: thumb ? 0 : 12, 2534 2857 }} 2535 2858 > 2536 - {/* @ts-ignore */} 2859 + {/* @ts-expect-error css */} 2537 2860 <div style={titleStyle} className="text-gray-900 dark:text-gray-100"> 2538 2861 {title} 2539 2862 </div> 2540 - {/* @ts-ignore */} 2541 2863 <div 2542 2864 style={descriptionStyle as React.CSSProperties} 2543 2865 className="text-gray-500 dark:text-gray-400" ··· 2636 2958 borderRadius: 12, 2637 2959 //border: `1px solid ${theme.border}`, 2638 2960 }} 2639 - className="border border-gray-200 dark:border-gray-700" 2961 + className="border border-gray-200 dark:border-gray-800 was7" 2640 2962 onClick={async (e) => { 2641 2963 e.stopPropagation(); 2642 2964 setPlaying(true); ··· 2677 2999 100 / (aspect ? aspect.width / aspect.height : 16 / 9) 2678 3000 }%`, // 16:9 = 56.25%, 4:3 = 75% 2679 3001 }} 2680 - className="border border-gray-200 dark:border-gray-700" 3002 + className="border border-gray-200 dark:border-gray-800 was7" 2681 3003 > 2682 3004 <ReactPlayer 2683 3005 src={url}
+60 -15
src/main.tsx
··· 1 - import { StrictMode } from "react"; 1 + import "~/styles/app.css"; 2 + 3 + import { createSyncStoragePersister } from "@tanstack/query-sync-storage-persister"; 4 + import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; 5 + import { persistQueryClient } from "@tanstack/react-query-persist-client"; 6 + import { createRouter, RouterProvider } from "@tanstack/react-router"; 7 + import { useSetAtom } from "jotai"; 8 + import { useEffect } from "react"; 9 + //import { StrictMode } from "react"; 2 10 import ReactDOM from "react-dom/client"; 3 - import { RouterProvider, createRouter } from "@tanstack/react-router"; 4 11 12 + import reportWebVitals from "./reportWebVitals.ts"; 5 13 // Import the generated route tree 6 14 import { routeTree } from "./routeTree.gen"; 7 - 8 - import "~/styles/app.css"; 9 - import reportWebVitals from "./reportWebVitals.ts"; 10 - import { QueryClient, QueryClientProvider, } from "@tanstack/react-query"; 11 - import { 12 - persistQueryClient, 13 - } from "@tanstack/react-query-persist-client"; 14 - import { createSyncStoragePersister } from "@tanstack/query-sync-storage-persister"; 15 + import { isAtTopAtom } from "./utils/atoms.ts"; 15 16 17 + //initAtomToCssVar(hueAtom, "--tw-gray-hue") 16 18 17 19 const queryClient = new QueryClient({ 18 20 defaultOptions: { ··· 28 30 persistQueryClient({ 29 31 queryClient, 30 32 persister: localStoragePersister, 31 - }) 33 + }); 32 34 33 35 // Create a new router instance 34 36 const router = createRouter({ ··· 54 56 root.render( 55 57 // double queries annoys me 56 58 // <StrictMode> 57 - <QueryClientProvider client={queryClient}> 58 - <RouterProvider router={router} /> 59 - </QueryClientProvider> 59 + <QueryClientProvider client={queryClient}> 60 + <ScrollTopWatcher /> 61 + <RouterProvider router={router} /> 62 + </QueryClientProvider> 60 63 // </StrictMode> 61 64 ); 62 65 } 63 66 64 67 // If you want to start measuring performance in your app, pass a function 65 - // to log results (for example: reportWebVitals(console.log)) 68 + // to log results (for example: reportWebVitals(// /*mass comment*/ console.log)) 66 69 // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 67 70 reportWebVitals(); 71 + 72 + export default function ScrollTopWatcher() { 73 + const setIsAtTop = useSetAtom(isAtTopAtom); 74 + useEffect(() => { 75 + const meta = document.querySelector('meta[name="theme-color"]'); 76 + let lastAtTop = window.scrollY === 0; 77 + let timeoutId: number | undefined; 78 + 79 + const setVars = (atTop: boolean) => { 80 + const root = document.documentElement; 81 + root.style.setProperty("--is-top", atTop ? "1" : "0"); 82 + 83 + const bg = getComputedStyle(root).getPropertyValue("--header-bg").trim(); 84 + if (meta && bg) meta.setAttribute("content", bg); 85 + setIsAtTop(atTop); 86 + }; 87 + 88 + const check = () => { 89 + const atTop = window.scrollY === 0; 90 + if (atTop !== lastAtTop) { 91 + lastAtTop = atTop; 92 + setVars(atTop); 93 + } 94 + }; 95 + 96 + const handleScroll = () => { 97 + if (timeoutId) clearTimeout(timeoutId); 98 + timeoutId = window.setTimeout(check, 2); 99 + }; 100 + 101 + // initialize 102 + setVars(lastAtTop); 103 + window.addEventListener("scroll", handleScroll, { passive: true }); 104 + 105 + return () => { 106 + window.removeEventListener("scroll", handleScroll); 107 + if (timeoutId) clearTimeout(timeoutId); 108 + }; 109 + }, []); 110 + 111 + return null; 112 + }
-149
src/providers/PassAuthProvider.tsx
··· 1 - import React, { createContext, useState, useEffect, useContext } from "react"; 2 - import { AtpAgent, type AtpSessionData } from "@atproto/api"; 3 - 4 - interface AuthContextValue { 5 - agent: AtpAgent | null; 6 - loginStatus: boolean; 7 - login: (user: string, password: string, service?: string) => Promise<void>; 8 - logout: () => Promise<void>; 9 - loading: boolean; 10 - authed: boolean | undefined; 11 - } 12 - 13 - const AuthContext = createContext<AuthContextValue>({} as AuthContextValue); 14 - 15 - export const AuthProvider = ({ children }: { children: React.ReactNode }) => { 16 - const [agent, setAgent] = useState<AtpAgent | null>(null); 17 - const [loginStatus, setLoginStatus] = useState(false); 18 - const [loading, setLoading] = useState(true); 19 - const [increment, setIncrement] = useState(0); 20 - const [authed, setAuthed] = useState<boolean | undefined>(undefined); 21 - 22 - useEffect(() => { 23 - const initialize = async () => { 24 - try { 25 - const service = localStorage.getItem("service"); 26 - // const user = await AsyncStorage.getItem('user'); 27 - // const password = await AsyncStorage.getItem('password'); 28 - const session = localStorage.getItem("sess"); 29 - 30 - if (service && session) { 31 - console.log("Auto-login service is:", service); 32 - const apiAgent = new AtpAgent({ service }); 33 - try { 34 - if (!apiAgent) { 35 - console.log("Agent is null or undefined"); 36 - return; 37 - } 38 - let sess: AtpSessionData = JSON.parse(session); 39 - console.log("resuming session is:", sess); 40 - const { data } = await apiAgent.resumeSession(sess); 41 - console.log("!!!8!!! agent resume session"); 42 - setAgent(apiAgent); 43 - setLoginStatus(true); 44 - setLoading(false); 45 - setAuthed(true); 46 - } catch (e) { 47 - console.log("Failed to resume session" + e); 48 - setLoginStatus(true); 49 - localStorage.removeItem("sess"); 50 - localStorage.removeItem("service"); 51 - const apiAgent = new AtpAgent({ service: "https://api.bsky.app" }); 52 - setAgent(apiAgent); 53 - setLoginStatus(true); 54 - setLoading(false); 55 - setAuthed(false); 56 - return; 57 - } 58 - } else { 59 - const apiAgent = new AtpAgent({ service: "https://api.bsky.app" }); 60 - setAgent(apiAgent); 61 - setLoginStatus(true); 62 - setLoading(false); 63 - setAuthed(false); 64 - } 65 - } catch (e) { 66 - console.log("Failed to auto-login:", e); 67 - } finally { 68 - setLoading(false); 69 - } 70 - }; 71 - 72 - initialize(); 73 - }, [increment]); 74 - 75 - const login = async ( 76 - user: string, 77 - password: string, 78 - service: string = "https://bsky.social", 79 - ) => { 80 - try { 81 - let sessionthing; 82 - const apiAgent = new AtpAgent({ 83 - service: service, 84 - persistSession: (evt, sess) => { 85 - sessionthing = sess; 86 - }, 87 - }); 88 - await apiAgent.login({ identifier: user, password }); 89 - console.log("!!!8!!! agent logged on"); 90 - 91 - localStorage.setItem("service", service); 92 - // await AsyncStorage.setItem('user', user); 93 - // await AsyncStorage.setItem('password', password); 94 - if (sessionthing) { 95 - localStorage.setItem("sess", JSON.stringify(sessionthing)); 96 - } else { 97 - localStorage.setItem("sess", "{}"); 98 - } 99 - 100 - setAgent(apiAgent); 101 - setLoginStatus(true); 102 - setAuthed(true); 103 - } catch (e) { 104 - console.error("Login failed:", e); 105 - } 106 - }; 107 - 108 - const logout = async () => { 109 - if (!agent) { 110 - console.error("Agent is null or undefined"); 111 - return; 112 - } 113 - setLoading(true); 114 - try { 115 - // check if its even in async storage before removing 116 - if (localStorage.getItem("service") && localStorage.getItem("sess")) { 117 - localStorage.removeItem("service"); 118 - localStorage.removeItem("sess"); 119 - } 120 - await agent.logout(); 121 - console.log("!!!8!!! agent logout"); 122 - setLoginStatus(false); 123 - setAuthed(undefined); 124 - await agent.com.atproto.server.deleteSession(); 125 - console.log("!!!8!!! agent deltesession"); 126 - //setAgent(null); 127 - setIncrement(increment + 1); 128 - } catch (e) { 129 - console.error("Logout failed:", e); 130 - } finally { 131 - setLoading(false); 132 - } 133 - }; 134 - 135 - // why the hell are we doing this 136 - /*if (loading) { 137 - return <div><span>Laoding...ae</span></div>; 138 - }*/ 139 - 140 - return ( 141 - <AuthContext.Provider 142 - value={{ agent, loginStatus, login, logout, loading, authed }} 143 - > 144 - {children} 145 - </AuthContext.Provider> 146 - ); 147 - }; 148 - 149 - export const useAuth = () => useContext(AuthContext);
-61
src/providers/PersistentStoreProvider.tsx
··· 1 - import React, { createContext, useContext, useCallback } from "react"; 2 - import { get as idbGet, set as idbSet, del as idbDel } from "idb-keyval"; 3 - 4 - type PersistentValue = { 5 - value: string; 6 - time: number; 7 - }; 8 - 9 - type PersistentStoreContextType = { 10 - get: (key: string) => Promise<PersistentValue | null>; 11 - set: (key: string, value: string) => Promise<void>; 12 - remove: (key: string) => Promise<void>; 13 - }; 14 - 15 - const PersistentStoreContext = createContext<PersistentStoreContextType | null>( 16 - null, 17 - ); 18 - 19 - export const PersistentStoreProvider: React.FC<{ 20 - children: React.ReactNode; 21 - }> = ({ children }) => { 22 - const get = useCallback( 23 - async (key: string): Promise<PersistentValue | null> => { 24 - if (typeof window === "undefined") return null; 25 - const raw = await idbGet(key); 26 - if (!raw) return null; 27 - try { 28 - return JSON.parse(raw) as PersistentValue; 29 - } catch { 30 - return null; 31 - } 32 - }, 33 - [], 34 - ); 35 - 36 - const set = useCallback(async (key: string, value: string) => { 37 - if (typeof window === "undefined") return; 38 - const entry: PersistentValue = { value, time: Date.now() }; 39 - await idbSet(key, JSON.stringify(entry)); 40 - }, []); 41 - 42 - const remove = useCallback(async (key: string) => { 43 - if (typeof window === "undefined") return; 44 - await idbDel(key); 45 - }, []); 46 - 47 - return ( 48 - <PersistentStoreContext.Provider value={{ get, set, remove }}> 49 - {children} 50 - </PersistentStoreContext.Provider> 51 - ); 52 - }; 53 - 54 - export const usePersistentStore = (): PersistentStoreContextType => { 55 - const context = useContext(PersistentStoreContext); 56 - if (!context) 57 - throw new Error( 58 - "usePersistentStore must be used within a PersistentStoreProvider", 59 - ); 60 - return context; 61 - };
+19 -18
src/providers/UnifiedAuthProvider.tsx
··· 1 1 // src/providers/UnifiedAuthProvider.tsx 2 - import React, { 3 - createContext, 4 - useState, 5 - useEffect, 6 - useContext, 7 - useCallback, 8 - } from "react"; 9 2 // Import both Agent and the (soon to be deprecated) AtpAgent 10 3 import { Agent, AtpAgent, type AtpSessionData } from "@atproto/api"; 11 - import { oauthClient } from "../utils/oauthClient"; // Adjust path if needed 12 4 import { 13 5 type OAuthSession, 14 6 TokenInvalidError, 15 7 TokenRefreshError, 16 8 TokenRevokedError, 17 9 } from "@atproto/oauth-client-browser"; 10 + import React, { 11 + createContext, 12 + use, 13 + useCallback, 14 + useEffect, 15 + useState, 16 + } from "react"; 17 + 18 + import { oauthClient } from "../utils/oauthClient"; // Adjust path if needed 18 19 19 20 // Define the unified status and authentication method 20 21 type AuthStatus = "loading" | "signedIn" | "signedOut"; ··· 52 53 try { 53 54 const oauthResult = await oauthClient.init(); 54 55 if (oauthResult) { 55 - console.log("OAuth session restored."); 56 + // /*mass comment*/ console.log("OAuth session restored."); 56 57 const apiAgent = new Agent(oauthResult.session); // Standard Agent 57 58 setAgent(apiAgent); 58 59 setOauthSession(oauthResult.session); ··· 70 71 const sessionString = localStorage.getItem("sess"); 71 72 72 73 if (service && sessionString) { 73 - console.log("Resuming password-based session using AtpAgent..."); 74 + // /*mass comment*/ console.log("Resuming password-based session using AtpAgent..."); 74 75 // Use the original, working AtpAgent logic 75 76 const apiAgent = new AtpAgent({ service }); 76 77 const session: AtpSessionData = JSON.parse(sessionString); 77 78 await apiAgent.resumeSession(session); 78 79 79 - console.log("Password-based session resumed successfully."); 80 + // /*mass comment*/ console.log("Password-based session resumed successfully."); 80 81 setAgent(apiAgent); // This works because AtpAgent is a subclass of Agent 81 82 setAuthMethod("password"); 82 83 setStatus("signedIn"); ··· 89 90 } 90 91 91 92 // --- 3. If neither worked, user is signed out --- 92 - console.log("No active session found."); 93 + // /*mass comment*/ console.log("No active session found."); 93 94 setStatus("signedOut"); 94 95 setAgent(null); 95 96 setAuthMethod(null); ··· 139 140 setAgent(apiAgent); // Store the AtpAgent instance in our state 140 141 setAuthMethod("password"); 141 142 setStatus("signedIn"); 142 - console.log("Successfully logged in with password."); 143 + // /*mass comment*/ console.log("Successfully logged in with password."); 143 144 } else { 144 145 throw new Error("Session data not persisted after login."); 145 146 } ··· 168 169 try { 169 170 if (authMethod === "oauth" && oauthSession) { 170 171 await oauthClient.revoke(oauthSession.sub); 171 - console.log("OAuth session revoked."); 172 + // /*mass comment*/ console.log("OAuth session revoked."); 172 173 } else if (authMethod === "password") { 173 174 localStorage.removeItem("service"); 174 175 localStorage.removeItem("sess"); 175 176 // AtpAgent has its own logout methods 176 177 await (agent as AtpAgent).com.atproto.server.deleteSession(); 177 - console.log("Password-based session deleted."); 178 + // /*mass comment*/ console.log("Password-based session deleted."); 178 179 } 179 180 } catch (e) { 180 181 console.error("Logout failed:", e); ··· 187 188 }, [status, authMethod, agent, oauthSession]); 188 189 189 190 return ( 190 - <AuthContext.Provider 191 + <AuthContext 191 192 value={{ 192 193 agent, 193 194 status, ··· 198 199 }} 199 200 > 200 201 {children} 201 - </AuthContext.Provider> 202 + </AuthContext> 202 203 ); 203 204 }; 204 205 205 - export const useAuth = () => useContext(AuthContext); 206 + export const useAuth = () => use(AuthContext);
+36 -5
src/routeTree.gen.ts
··· 21 21 import { Route as PathlessLayoutNestedLayoutRouteBRouteImport } from './routes/_pathlessLayout/_nested-layout/route-b' 22 22 import { Route as PathlessLayoutNestedLayoutRouteARouteImport } from './routes/_pathlessLayout/_nested-layout/route-a' 23 23 import { Route as ProfileDidPostRkeyRouteImport } from './routes/profile.$did/post.$rkey' 24 + import { Route as ProfileDidPostRkeyImageIRouteImport } from './routes/profile.$did/post.$rkey.image.$i' 24 25 25 26 const SettingsRoute = SettingsRouteImport.update({ 26 27 id: '/settings', ··· 83 84 path: '/profile/$did/post/$rkey', 84 85 getParentRoute: () => rootRouteImport, 85 86 } as any) 87 + const ProfileDidPostRkeyImageIRoute = 88 + ProfileDidPostRkeyImageIRouteImport.update({ 89 + id: '/image/$i', 90 + path: '/image/$i', 91 + getParentRoute: () => ProfileDidPostRkeyRoute, 92 + } as any) 86 93 87 94 export interface FileRoutesByFullPath { 88 95 '/': typeof IndexRoute ··· 94 101 '/route-a': typeof PathlessLayoutNestedLayoutRouteARoute 95 102 '/route-b': typeof PathlessLayoutNestedLayoutRouteBRoute 96 103 '/profile/$did': typeof ProfileDidIndexRoute 97 - '/profile/$did/post/$rkey': typeof ProfileDidPostRkeyRoute 104 + '/profile/$did/post/$rkey': typeof ProfileDidPostRkeyRouteWithChildren 105 + '/profile/$did/post/$rkey/image/$i': typeof ProfileDidPostRkeyImageIRoute 98 106 } 99 107 export interface FileRoutesByTo { 100 108 '/': typeof IndexRoute ··· 106 114 '/route-a': typeof PathlessLayoutNestedLayoutRouteARoute 107 115 '/route-b': typeof PathlessLayoutNestedLayoutRouteBRoute 108 116 '/profile/$did': typeof ProfileDidIndexRoute 109 - '/profile/$did/post/$rkey': typeof ProfileDidPostRkeyRoute 117 + '/profile/$did/post/$rkey': typeof ProfileDidPostRkeyRouteWithChildren 118 + '/profile/$did/post/$rkey/image/$i': typeof ProfileDidPostRkeyImageIRoute 110 119 } 111 120 export interface FileRoutesById { 112 121 __root__: typeof rootRouteImport ··· 121 130 '/_pathlessLayout/_nested-layout/route-a': typeof PathlessLayoutNestedLayoutRouteARoute 122 131 '/_pathlessLayout/_nested-layout/route-b': typeof PathlessLayoutNestedLayoutRouteBRoute 123 132 '/profile/$did/': typeof ProfileDidIndexRoute 124 - '/profile/$did/post/$rkey': typeof ProfileDidPostRkeyRoute 133 + '/profile/$did/post/$rkey': typeof ProfileDidPostRkeyRouteWithChildren 134 + '/profile/$did/post/$rkey/image/$i': typeof ProfileDidPostRkeyImageIRoute 125 135 } 126 136 export interface FileRouteTypes { 127 137 fileRoutesByFullPath: FileRoutesByFullPath ··· 136 146 | '/route-b' 137 147 | '/profile/$did' 138 148 | '/profile/$did/post/$rkey' 149 + | '/profile/$did/post/$rkey/image/$i' 139 150 fileRoutesByTo: FileRoutesByTo 140 151 to: 141 152 | '/' ··· 148 159 | '/route-b' 149 160 | '/profile/$did' 150 161 | '/profile/$did/post/$rkey' 162 + | '/profile/$did/post/$rkey/image/$i' 151 163 id: 152 164 | '__root__' 153 165 | '/' ··· 162 174 | '/_pathlessLayout/_nested-layout/route-b' 163 175 | '/profile/$did/' 164 176 | '/profile/$did/post/$rkey' 177 + | '/profile/$did/post/$rkey/image/$i' 165 178 fileRoutesById: FileRoutesById 166 179 } 167 180 export interface RootRouteChildren { ··· 173 186 SettingsRoute: typeof SettingsRoute 174 187 CallbackIndexRoute: typeof CallbackIndexRoute 175 188 ProfileDidIndexRoute: typeof ProfileDidIndexRoute 176 - ProfileDidPostRkeyRoute: typeof ProfileDidPostRkeyRoute 189 + ProfileDidPostRkeyRoute: typeof ProfileDidPostRkeyRouteWithChildren 177 190 } 178 191 179 192 declare module '@tanstack/react-router' { ··· 262 275 preLoaderRoute: typeof ProfileDidPostRkeyRouteImport 263 276 parentRoute: typeof rootRouteImport 264 277 } 278 + '/profile/$did/post/$rkey/image/$i': { 279 + id: '/profile/$did/post/$rkey/image/$i' 280 + path: '/image/$i' 281 + fullPath: '/profile/$did/post/$rkey/image/$i' 282 + preLoaderRoute: typeof ProfileDidPostRkeyImageIRouteImport 283 + parentRoute: typeof ProfileDidPostRkeyRoute 284 + } 265 285 } 266 286 } 267 287 ··· 295 315 PathlessLayoutRouteChildren, 296 316 ) 297 317 318 + interface ProfileDidPostRkeyRouteChildren { 319 + ProfileDidPostRkeyImageIRoute: typeof ProfileDidPostRkeyImageIRoute 320 + } 321 + 322 + const ProfileDidPostRkeyRouteChildren: ProfileDidPostRkeyRouteChildren = { 323 + ProfileDidPostRkeyImageIRoute: ProfileDidPostRkeyImageIRoute, 324 + } 325 + 326 + const ProfileDidPostRkeyRouteWithChildren = 327 + ProfileDidPostRkeyRoute._addFileChildren(ProfileDidPostRkeyRouteChildren) 328 + 298 329 const rootRouteChildren: RootRouteChildren = { 299 330 IndexRoute: IndexRoute, 300 331 PathlessLayoutRoute: PathlessLayoutRouteWithChildren, ··· 304 335 SettingsRoute: SettingsRoute, 305 336 CallbackIndexRoute: CallbackIndexRoute, 306 337 ProfileDidIndexRoute: ProfileDidIndexRoute, 307 - ProfileDidPostRkeyRoute: ProfileDidPostRkeyRoute, 338 + ProfileDidPostRkeyRoute: ProfileDidPostRkeyRouteWithChildren, 308 339 } 309 340 export const routeTree = rootRouteImport 310 341 ._addFileChildren(rootRouteChildren)
+564 -465
src/routes/__root.tsx
··· 2 2 3 3 // dont forget to run this 4 4 // npx @tanstack/router-cli generate 5 - 6 - import { useState, type SVGProps } from "react"; 5 + import type { QueryClient } from "@tanstack/react-query"; 7 6 import { 8 - HeadContent, 9 - Link, 10 - Outlet, 11 - Scripts, 12 - createRootRoute, 13 7 createRootRouteWithContext, 8 + // Link, 9 + // Outlet, 10 + Scripts, 14 11 useLocation, 15 12 useNavigate, 16 13 } from "@tanstack/react-router"; 17 14 import { TanStackRouterDevtools } from "@tanstack/react-router-devtools"; 15 + import { useAtom } from "jotai"; 18 16 import * as React from "react"; 17 + import { KeepAliveOutlet, KeepAliveProvider } from "tanstack-router-keepalive"; 18 + 19 + import { Composer } from "~/components/Composer"; 19 20 import { DefaultCatchBoundary } from "~/components/DefaultCatchBoundary"; 21 + import { Import } from "~/components/Import"; 20 22 import Login from "~/components/Login"; 21 23 import { NotFound } from "~/components/NotFound"; 22 - import appCss from "~/styles/app.css?url"; 23 - import { seo } from "~/utils/seo"; 24 + import { FluentEmojiHighContrastGlowingStar } from "~/components/Star"; 24 25 import { UnifiedAuthProvider, useAuth } from "~/providers/UnifiedAuthProvider"; 25 - import { PersistentStoreProvider } from "~/providers/PersistentStoreProvider"; 26 - import type Agent from "@atproto/api"; 27 - import type { QueryClient } from "@tanstack/react-query"; 26 + import { composerAtom, hueAtom, useAtomCssVar } from "~/utils/atoms"; 27 + import { seo } from "~/utils/seo"; 28 28 29 29 export const Route = createRootRouteWithContext<{ 30 30 queryClient: QueryClient; ··· 79 79 function RootComponent() { 80 80 return ( 81 81 <UnifiedAuthProvider> 82 - <PersistentStoreProvider> 83 - <RootDocument> 84 - <Outlet /> 85 - </RootDocument> 86 - </PersistentStoreProvider> 82 + <RootDocument> 83 + <KeepAliveProvider> 84 + <KeepAliveOutlet /> 85 + </KeepAliveProvider> 86 + </RootDocument> 87 87 </UnifiedAuthProvider> 88 88 ); 89 89 } 90 90 91 91 function RootDocument({ children }: { children: React.ReactNode }) { 92 + useAtomCssVar(hueAtom, "--tw-gray-hue"); 92 93 const location = useLocation(); 93 94 const navigate = useNavigate(); 94 95 const { agent } = useAuth(); 95 96 const authed = !!agent?.did; 96 97 const isHome = location.pathname === "/"; 97 98 const isNotifications = location.pathname.startsWith("/notifications"); 98 - const isProfile = agent && ((location.pathname === (`/profile/${agent?.did}`)) || (location.pathname === (`/profile/${encodeURIComponent(agent?.did??"")}`))); 99 + const isProfile = 100 + agent && 101 + (location.pathname === `/profile/${agent?.did}` || 102 + location.pathname === `/profile/${encodeURIComponent(agent?.did ?? "")}`); 103 + const isSettings = location.pathname.startsWith("/settings"); 104 + const isSearch = location.pathname.startsWith("/search"); 105 + const isFeeds = location.pathname.startsWith("/feeds"); 99 106 100 - const [postOpen, setPostOpen] = useState(false); 101 - const [postText, setPostText] = useState(""); 102 - const [posting, setPosting] = useState(false); 103 - const [postSuccess, setPostSuccess] = useState(false); 104 - const [postError, setPostError] = useState<string | null>(null); 107 + const locationEnum: 108 + | "feeds" 109 + | "search" 110 + | "settings" 111 + | "notifications" 112 + | "profile" 113 + | "home" = isFeeds 114 + ? "feeds" 115 + : isSearch 116 + ? "search" 117 + : isSettings 118 + ? "settings" 119 + : isNotifications 120 + ? "notifications" 121 + : isProfile 122 + ? "profile" 123 + : "home"; 105 124 106 - async function handlePost() { 107 - if (!agent) return; 108 - setPosting(true); 109 - setPostError(null); 110 - try { 111 - await agent.com.atproto.repo.createRecord({ 112 - collection: "app.bsky.feed.post", 113 - repo: agent.assertDid, 114 - record: { 115 - $type: "app.bsky.feed.post", 116 - text: postText, 117 - createdAt: new Date().toISOString(), 118 - }, 119 - }); 120 - setPostSuccess(true); 121 - setPostText(""); 122 - setTimeout(() => { 123 - setPostSuccess(false); 124 - setPostOpen(false); 125 - }, 1500); 126 - } catch (e: any) { 127 - setPostError(e?.message || "Failed to post"); 128 - } finally { 129 - setPosting(false); 130 - } 131 - } 125 + const [, setComposerPost] = useAtom(composerAtom); 132 126 133 127 return ( 134 128 <> 135 - {postOpen && ( 136 - <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40"> 137 - <div className="bg-white dark:bg-gray-900 rounded-lg shadow-lg p-6 w-full max-w-md relative"> 138 - <button 139 - className="absolute top-2 right-2 text-gray-400 hover:text-gray-700 dark:hover:text-gray-200" 140 - onClick={() => !posting && setPostOpen(false)} 141 - disabled={posting} 142 - aria-label="Close" 143 - > 144 - ร— 145 - </button> 146 - <h2 className="text-lg font-bold mb-2">Create Post</h2> 147 - {postSuccess ? ( 148 - <div className="flex flex-col items-center justify-center py-8"> 149 - <span className="text-green-500 text-4xl mb-2">โœ“</span> 150 - <span className="text-green-600">Posted!</span> 151 - </div> 152 - ) : ( 153 - <> 154 - <textarea 155 - className="w-full border rounded p-2 mb-2 dark:bg-gray-800 dark:border-gray-700" 156 - rows={4} 157 - placeholder="What's on your mind?" 158 - value={postText} 159 - onChange={(e) => setPostText(e.target.value)} 160 - disabled={posting} 161 - autoFocus 162 - /> 163 - {postError && ( 164 - <div className="text-red-500 text-sm mb-2">{postError}</div> 165 - )} 166 - <button 167 - className="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded disabled:opacity-50" 168 - onClick={handlePost} 169 - disabled={posting || !postText.trim()} 170 - > 171 - {posting ? "Posting..." : "Post"} 172 - </button> 173 - </> 174 - )} 175 - </div> 176 - </div> 177 - )} 129 + <Composer /> 178 130 179 131 <div className="min-h-screen flex justify-center bg-gray-50 dark:bg-gray-950"> 180 - <nav className="hidden lg:flex h-screen w-[250px] flex-col gap-2 p-4 dark:border-gray-800 sticky top-0 self-start"> 132 + <nav className="hidden lg:flex h-screen w-[250px] flex-col gap-0 p-4 dark:border-gray-800 sticky top-0 self-start"> 181 133 <div className="flex items-center gap-3 mb-4"> 182 - <img src="/redstar.png" alt="Red Dwarf Logo" className="w-8 h-8" /> 134 + <FluentEmojiHighContrastGlowingStar className="h-8 w-8" style={{color: "oklch(0.6616 0.2249 calc(25.88 + (var(--safe-hue) - 28))"}} /> 183 135 <span className="font-extrabold text-2xl tracking-tight text-gray-900 dark:text-gray-100"> 184 136 Red Dwarf{" "} 185 137 {/* <span className="text-gray-500 dark:text-gray-400 text-sm"> ··· 187 139 </span> */} 188 140 </span> 189 141 </div> 190 - <Link 142 + <MaterialNavItem 143 + InactiveIcon={ 144 + <IconMaterialSymbolsHomeOutline className="w-6 h-6" /> 145 + } 146 + ActiveIcon={<IconMaterialSymbolsHome className="w-6 h-6" />} 147 + active={locationEnum === "home"} 148 + onClickCallbback={() => 149 + navigate({ 150 + to: "/", 151 + //params: { did: agent.assertDid }, 152 + }) 153 + } 154 + text="Home" 155 + /> 156 + 157 + <MaterialNavItem 158 + InactiveIcon={<IconMaterialSymbolsSearch className="w-6 h-6" />} 159 + ActiveIcon={<IconMaterialSymbolsSearch className="w-6 h-6" />} 160 + active={locationEnum === "search"} 161 + onClickCallbback={() => 162 + navigate({ 163 + to: "/search", 164 + //params: { did: agent.assertDid }, 165 + }) 166 + } 167 + text="Explore" 168 + /> 169 + <MaterialNavItem 170 + InactiveIcon={ 171 + <IconMaterialSymbolsNotificationsOutline className="w-6 h-6" /> 172 + } 173 + ActiveIcon={ 174 + <IconMaterialSymbolsNotifications className="w-6 h-6" /> 175 + } 176 + active={locationEnum === "notifications"} 177 + onClickCallbback={() => 178 + navigate({ 179 + to: "/notifications", 180 + //params: { did: agent.assertDid }, 181 + }) 182 + } 183 + text="Notifications" 184 + /> 185 + <MaterialNavItem 186 + InactiveIcon={<IconMaterialSymbolsTag className="w-6 h-6" />} 187 + ActiveIcon={<IconMaterialSymbolsTag className="w-6 h-6" />} 188 + active={locationEnum === "feeds"} 189 + onClickCallbback={() => 190 + navigate({ 191 + to: "/feeds", 192 + //params: { did: agent.assertDid }, 193 + }) 194 + } 195 + text="Feeds" 196 + /> 197 + <MaterialNavItem 198 + InactiveIcon={ 199 + <IconMaterialSymbolsAccountCircleOutline className="w-6 h-6" /> 200 + } 201 + ActiveIcon={ 202 + <IconMaterialSymbolsAccountCircle className="w-6 h-6" /> 203 + } 204 + active={locationEnum === "profile"} 205 + onClickCallbback={() => { 206 + if (authed && agent && agent.assertDid) { 207 + //window.location.href = `/profile/${agent.assertDid}`; 208 + navigate({ 209 + to: "/profile/$did", 210 + params: { did: agent.assertDid }, 211 + }); 212 + } 213 + }} 214 + text="Profile" 215 + /> 216 + <MaterialNavItem 217 + InactiveIcon={ 218 + <IconMaterialSymbolsSettingsOutline className="w-6 h-6" /> 219 + } 220 + ActiveIcon={<IconMaterialSymbolsSettings className="w-6 h-6" />} 221 + active={locationEnum === "settings"} 222 + onClickCallbback={() => 223 + navigate({ 224 + to: "/settings", 225 + //params: { did: agent.assertDid }, 226 + }) 227 + } 228 + text="Settings" 229 + /> 230 + <div className="flex flex-row items-center justify-center mt-3"> 231 + <MaterialPillButton 232 + InactiveIcon={<IconMdiPencilOutline className="w-6 h-6" />} 233 + ActiveIcon={<IconMdiPencilOutline className="w-6 h-6" />} 234 + //active={true} 235 + onClickCallbback={() => setComposerPost({ kind: 'root' })} 236 + text="Post" 237 + /> 238 + </div> 239 + {/* <Link 191 240 to="/" 192 241 className={ 193 242 `py-2 px-4 hover:bg-gray-100 dark:hover:bg-gray-900 text-xl flex items-center gap-3 ` + 194 243 (isHome ? "font-bold" : "") 195 244 } 196 245 > 197 - {isHome ? ( 198 - <TablerHomeFilled width={28} height={28} /> 246 + {!isHome ? ( 247 + <IconMaterialSymbolsHomeOutline width={28} height={28} /> 199 248 ) : ( 200 - <TablerHome width={28} height={28} /> 249 + <IconMaterialSymbolsHome width={28} height={28} /> 201 250 )} 202 251 <span>Home</span> 203 252 </Link> ··· 208 257 (isNotifications ? "font-bold" : "") 209 258 } 210 259 > 211 - {isNotifications ? ( 212 - <TablerBellFilled width={28} height={28} /> 260 + {!isNotifications ? ( 261 + <IconMaterialSymbolsNotificationsOutline width={28} height={28} /> 213 262 ) : ( 214 - <TablerBell width={28} height={28} /> 263 + <IconMaterialSymbolsNotifications width={28} height={28} /> 215 264 )} 216 265 <span>Notifications</span> 217 266 </Link> ··· 222 271 }`} 223 272 > 224 273 {location.pathname.startsWith("/feeds") ? ( 225 - <TablerHashtagFilled width={28} height={28} /> 274 + <IconMaterialSymbolsTag width={28} height={28} /> 226 275 ) : ( 227 - <TablerHashtag width={28} height={28} /> 276 + <IconMaterialSymbolsTag width={28} height={28} /> 228 277 )} 229 278 <span>Feeds</span> 230 279 </Link> ··· 236 285 }`} 237 286 > 238 287 {location.pathname.startsWith("/search") ? ( 239 - <TablerSearchFilled width={28} height={28} /> 288 + <IconMaterialSymbolsSearch width={28} height={28} /> 240 289 ) : ( 241 - <TablerSearch width={28} height={28} /> 290 + <IconMaterialSymbolsSearch width={28} height={28} /> 242 291 )} 243 292 <span>Search</span> 244 293 </Link> ··· 252 301 navigate({ 253 302 to: "/profile/$did", 254 303 params: { did: agent.assertDid }, 255 - }) 304 + }); 256 305 } 257 306 }} 258 307 type="button" 259 308 > 260 - <TablerUserCircle width={28} height={28} /> 309 + {!isProfile ? ( 310 + <IconMaterialSymbolsAccountCircleOutline width={28} height={28} /> 311 + ) : ( 312 + <IconMaterialSymbolsAccountCircle width={28} height={28} /> 313 + )} 261 314 <span>Profile</span> 262 315 </button> 263 316 <Link ··· 266 319 location.pathname.startsWith("/settings") ? "font-bold" : "" 267 320 }`} 268 321 > 269 - {location.pathname.startsWith("/settings") ? ( 270 - <IonSettingsSharp width={28} height={28} /> 322 + {!location.pathname.startsWith("/settings") ? ( 323 + <IconMaterialSymbolsSettingsOutline width={28} height={28} /> 271 324 ) : ( 272 - <IonSettings width={28} height={28} /> 325 + <IconMaterialSymbolsSettings width={28} height={28} /> 273 326 )} 274 327 <span>Settings</span> 275 - </Link> 276 - <button 328 + </Link> */} 329 + {/* <button 277 330 className="mt-4 w-full flex items-center justify-center gap-3 py-3 px-0 mb-3 bg-gray-200 dark:bg-gray-800 hover:bg-gray-300 dark:hover:bg-gray-700 text-gray-900 dark:text-gray-100 text-xl font-bold rounded-full transition-colors shadow" 278 331 onClick={() => setPostOpen(true)} 279 332 type="button" 280 333 > 281 - <TablerEdit 334 + <IconMdiPencilOutline 282 335 width={24} 283 336 height={24} 284 337 className="text-gray-600 dark:text-gray-400" 285 338 /> 286 339 <span>Post</span> 287 - </button> 340 + </button> */} 288 341 <div className="flex-1"></div> 289 342 <a 290 343 href="https://tangled.sh/@whey.party/red-dwarf" ··· 315 368 </div> 316 369 </nav> 317 370 318 - <button 319 - className="lg:hidden fixed bottom-20 right-6 z-50 bg-gray-200 dark:bg-gray-800 hover:bg-gray-300 dark:hover:bg-gray-700 text-blue-600 dark:text-blue-400 rounded-full shadow-lg w-16 h-16 flex items-center justify-center border-4 border-white dark:border-gray-950 transition-all" 320 - style={{ boxShadow: "0 4px 24px 0 rgba(0,0,0,0.12)" }} 321 - onClick={() => setPostOpen(true)} 322 - type="button" 323 - aria-label="Create Post" 324 - > 325 - <TablerEdit 326 - width={24} 327 - height={24} 328 - className="text-gray-600 dark:text-gray-400" 371 + <nav className="hidden sm:flex items-center lg:hidden h-screen flex-col gap-2 p-4 dark:border-gray-800 sticky top-0 self-start"> 372 + <div className="flex items-center gap-3 mb-4"> 373 + <FluentEmojiHighContrastGlowingStar className="h-8 w-8" style={{color: "oklch(0.6616 0.2249 calc(25.88 + (var(--safe-hue) - 28))"}} /> 374 + </div> 375 + <MaterialNavItem 376 + small 377 + InactiveIcon={ 378 + <IconMaterialSymbolsHomeOutline className="w-6 h-6" /> 379 + } 380 + ActiveIcon={<IconMaterialSymbolsHome className="w-6 h-6" />} 381 + active={locationEnum === "home"} 382 + onClickCallbback={() => 383 + navigate({ 384 + to: "/", 385 + //params: { did: agent.assertDid }, 386 + }) 387 + } 388 + text="Home" 329 389 /> 330 - </button> 331 390 332 - <main className="w-full max-w-[600px] lg:border-x border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-950 pb-16 lg:pb-0"> 333 - <div className="lg:hidden flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-950"> 334 - <div className="flex items-center gap-2"> 335 - <img 336 - src="/redstar.png" 337 - alt="Red Dwarf Logo" 338 - className="w-6 h-6" 339 - /> 340 - <span className="font-bold text-lg text-gray-900 dark:text-gray-100"> 341 - Red Dwarf{" "} 342 - {/* <span className="text-gray-500 dark:text-gray-400 text-sm"> 343 - lite 344 - </span> */} 345 - </span> 346 - </div> 347 - <div className="flex items-center gap-2"> 348 - <Login compact={true} /> 349 - </div> 391 + <MaterialNavItem 392 + small 393 + InactiveIcon={<IconMaterialSymbolsSearch className="w-6 h-6" />} 394 + ActiveIcon={<IconMaterialSymbolsSearch className="w-6 h-6" />} 395 + active={locationEnum === "search"} 396 + onClickCallbback={() => 397 + navigate({ 398 + to: "/search", 399 + //params: { did: agent.assertDid }, 400 + }) 401 + } 402 + text="Explore" 403 + /> 404 + <MaterialNavItem 405 + small 406 + InactiveIcon={ 407 + <IconMaterialSymbolsNotificationsOutline className="w-6 h-6" /> 408 + } 409 + ActiveIcon={ 410 + <IconMaterialSymbolsNotifications className="w-6 h-6" /> 411 + } 412 + active={locationEnum === "notifications"} 413 + onClickCallbback={() => 414 + navigate({ 415 + to: "/notifications", 416 + //params: { did: agent.assertDid }, 417 + }) 418 + } 419 + text="Notifications" 420 + /> 421 + <MaterialNavItem 422 + small 423 + InactiveIcon={<IconMaterialSymbolsTag className="w-6 h-6" />} 424 + ActiveIcon={<IconMaterialSymbolsTag className="w-6 h-6" />} 425 + active={locationEnum === "feeds"} 426 + onClickCallbback={() => 427 + navigate({ 428 + to: "/feeds", 429 + //params: { did: agent.assertDid }, 430 + }) 431 + } 432 + text="Feeds" 433 + /> 434 + <MaterialNavItem 435 + small 436 + InactiveIcon={ 437 + <IconMaterialSymbolsAccountCircleOutline className="w-6 h-6" /> 438 + } 439 + ActiveIcon={ 440 + <IconMaterialSymbolsAccountCircle className="w-6 h-6" /> 441 + } 442 + active={locationEnum === "profile"} 443 + onClickCallbback={() => { 444 + if (authed && agent && agent.assertDid) { 445 + //window.location.href = `/profile/${agent.assertDid}`; 446 + navigate({ 447 + to: "/profile/$did", 448 + params: { did: agent.assertDid }, 449 + }); 450 + } 451 + }} 452 + text="Profile" 453 + /> 454 + <MaterialNavItem 455 + small 456 + InactiveIcon={ 457 + <IconMaterialSymbolsSettingsOutline className="w-6 h-6" /> 458 + } 459 + ActiveIcon={<IconMaterialSymbolsSettings className="w-6 h-6" />} 460 + active={locationEnum === "settings"} 461 + onClickCallbback={() => 462 + navigate({ 463 + to: "/settings", 464 + //params: { did: agent.assertDid }, 465 + }) 466 + } 467 + text="Settings" 468 + /> 469 + <div className="flex flex-row items-center justify-center mt-3"> 470 + <MaterialPillButton 471 + small 472 + InactiveIcon={<IconMdiPencilOutline className="w-6 h-6" />} 473 + ActiveIcon={<IconMdiPencilOutline className="w-6 h-6" />} 474 + //active={true} 475 + onClickCallbback={() => setComposerPost({ kind: 'root' })} 476 + text="Post" 477 + /> 350 478 </div> 479 + </nav> 351 480 481 + {agent?.did && ( 482 + <button 483 + className="lg:hidden fixed bottom-22 right-4 z-50 bg-gray-200 dark:bg-gray-800 hover:bg-gray-300 dark:hover:bg-gray-700 rounded-2xl w-14 h-14 flex items-center justify-center transition-all" 484 + style={{ boxShadow: "0 4px 24px 0 rgba(0,0,0,0.12)" }} 485 + onClick={() => setComposerPost({ kind: 'root' })} 486 + type="button" 487 + aria-label="Create Post" 488 + > 489 + <IconMdiPencilOutline 490 + width={24} 491 + height={24} 492 + className="text-gray-600 dark:text-gray-400" 493 + /> 494 + </button> 495 + )} 496 + 497 + <main className="w-full max-w-[600px] sm:border-x border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-950 pb-16 lg:pb-0 overflow-x-clip"> 352 498 {children} 353 499 </main> 354 500 355 501 <aside className="hidden lg:flex h-screen w-[250px] sticky top-0 self-start flex-col"> 502 + <div className="px-4 pt-4"><Import /></div> 356 503 <Login /> 357 504 358 505 <div className="flex-1"></div> 359 506 <p className="text-xs text-gray-400 dark:text-gray-500 text-justify mx-4 mb-4"> 360 - Red Dwarf is a bluesky client that uses Constellation and direct PDS 361 - queries. Skylite would be a self-hosted bluesky "instance". Stay 362 - tuned for the release of Skylite. 507 + Red Dwarf is a Bluesky client that does not rely on any Bluesky API App Servers. Instead, it uses Microcosm to fetch records directly from each users' PDS (via Slingshot) and connect them using backlinks (via Constellation) 363 508 </p> 364 509 </aside> 365 510 </div> 366 511 367 - <nav className="lg:hidden fixed bottom-0 left-0 right-0 bg-white dark:bg-gray-950 border-t border-gray-200 dark:border-gray-700 z-40"> 368 - <div className="flex justify-around items-center py-2"> 369 - <Link 370 - to="/" 371 - className={`flex flex-col items-center py-2 px-3 rounded-lg transition-colors flex-1 ${ 372 - isHome 373 - ? "text-gray-900 dark:text-gray-100" 374 - : "text-gray-600 dark:text-gray-400" 375 - }`} 376 - > 377 - {isHome ? ( 378 - <TablerHomeFilled width={24} height={24} /> 379 - ) : ( 380 - <TablerHome width={24} height={24} /> 381 - )} 382 - <span className="text-xs mt-1">Home</span> 383 - </Link> 384 - <Link 385 - to="/search" 386 - className={`flex flex-col items-center py-2 px-3 rounded-lg transition-colors flex-1 ${ 387 - location.pathname.startsWith("/search") 388 - ? "text-gray-900 dark:text-gray-100" 389 - : "text-gray-600 dark:text-gray-400" 390 - }`} 391 - > 392 - {location.pathname.startsWith("/search") ? ( 393 - <TablerSearchFilled width={24} height={24} /> 394 - ) : ( 395 - <TablerSearch width={24} height={24} /> 396 - )} 397 - <span className="text-xs mt-1">Search</span> 398 - </Link> 399 - <Link 400 - to="/notifications" 401 - className={`flex flex-col items-center py-2 px-3 rounded-lg transition-colors flex-1 ${ 402 - isNotifications 403 - ? "text-gray-900 dark:text-gray-100" 404 - : "text-gray-600 dark:text-gray-400" 405 - }`} 406 - > 407 - {isNotifications ? ( 408 - <TablerBellFilled width={24} height={24} /> 409 - ) : ( 410 - <TablerBell width={24} height={24} /> 411 - )} 412 - <span className="text-xs mt-1">Notifications</span> 413 - </Link> 414 - <button 415 - className={`flex flex-col items-center py-2 px-3 rounded-lg transition-colors flex-1 ${ 416 - isProfile 417 - ? "text-gray-900 dark:text-gray-100" 418 - : "text-gray-600 dark:text-gray-400" 419 - }`} 420 - onClick={() => { 421 - if (authed && agent && agent.assertDid) { 422 - //window.location.href = `/profile/${agent.assertDid}`; 512 + {agent?.did ? ( 513 + <nav className="sm:hidden fixed bottom-0 left-0 right-0 bg-gray-50 dark:bg-gray-900 border-0 shadow border-gray-200 dark:border-gray-700 z-40"> 514 + <div className="flex justify-around items-center p-2"> 515 + <MaterialNavItem 516 + small 517 + InactiveIcon={ 518 + <IconMaterialSymbolsHomeOutline className="w-6 h-6" /> 519 + } 520 + ActiveIcon={<IconMaterialSymbolsHome className="w-6 h-6" />} 521 + active={locationEnum === "home"} 522 + onClickCallbback={() => 523 + navigate({ 524 + to: "/", 525 + //params: { did: agent.assertDid }, 526 + }) 527 + } 528 + text="Home" 529 + /> 530 + {/* <Link 531 + to="/" 532 + className={`flex flex-col items-center py-2 px-3 rounded-lg transition-colors flex-1 ${ 533 + isHome 534 + ? "text-gray-900 dark:text-gray-100" 535 + : "text-gray-600 dark:text-gray-400" 536 + }`} 537 + > 538 + {!isHome ? ( 539 + <IconMaterialSymbolsHomeOutline width={24} height={24} /> 540 + ) : ( 541 + <IconMaterialSymbolsHome width={24} height={24} /> 542 + )} 543 + <span className="text-xs mt-1">Home</span> 544 + </Link> */} 545 + <MaterialNavItem 546 + small 547 + InactiveIcon={<IconMaterialSymbolsSearch className="w-6 h-6" />} 548 + ActiveIcon={<IconMaterialSymbolsSearch className="w-6 h-6" />} 549 + active={locationEnum === "search"} 550 + onClickCallbback={() => 551 + navigate({ 552 + to: "/search", 553 + //params: { did: agent.assertDid }, 554 + }) 555 + } 556 + text="Explore" 557 + /> 558 + {/* <Link 559 + to="/search" 560 + className={`flex flex-col items-center py-2 px-3 rounded-lg transition-colors flex-1 ${ 561 + location.pathname.startsWith("/search") 562 + ? "text-gray-900 dark:text-gray-100" 563 + : "text-gray-600 dark:text-gray-400" 564 + }`} 565 + > 566 + {!location.pathname.startsWith("/search") ? ( 567 + <IconMaterialSymbolsSearch width={24} height={24} /> 568 + ) : ( 569 + <IconMaterialSymbolsSearch width={24} height={24} /> 570 + )} 571 + <span className="text-xs mt-1">Search</span> 572 + </Link> */} 573 + <MaterialNavItem 574 + small 575 + InactiveIcon={ 576 + <IconMaterialSymbolsNotificationsOutline className="w-6 h-6" /> 577 + } 578 + ActiveIcon={ 579 + <IconMaterialSymbolsNotifications className="w-6 h-6" /> 580 + } 581 + active={locationEnum === "notifications"} 582 + onClickCallbback={() => 583 + navigate({ 584 + to: "/notifications", 585 + //params: { did: agent.assertDid }, 586 + }) 587 + } 588 + text="Notifications" 589 + /> 590 + {/* <Link 591 + to="/notifications" 592 + className={`flex flex-col items-center py-2 px-3 rounded-lg transition-colors flex-1 ${ 593 + isNotifications 594 + ? "text-gray-900 dark:text-gray-100" 595 + : "text-gray-600 dark:text-gray-400" 596 + }`} 597 + > 598 + {!isNotifications ? ( 599 + <IconMaterialSymbolsNotificationsOutline 600 + width={24} 601 + height={24} 602 + /> 603 + ) : ( 604 + <IconMaterialSymbolsNotifications width={24} height={24} /> 605 + )} 606 + <span className="text-xs mt-1">Notifications</span> 607 + </Link> */} 608 + <MaterialNavItem 609 + small 610 + InactiveIcon={ 611 + <IconMaterialSymbolsAccountCircleOutline className="w-6 h-6" /> 612 + } 613 + ActiveIcon={ 614 + <IconMaterialSymbolsAccountCircle className="w-6 h-6" /> 615 + } 616 + active={locationEnum === "profile"} 617 + onClickCallbback={() => { 618 + if (authed && agent && agent.assertDid) { 619 + //window.location.href = `/profile/${agent.assertDid}`; 620 + navigate({ 621 + to: "/profile/$did", 622 + params: { did: agent.assertDid }, 623 + }); 624 + } 625 + }} 626 + text="Profile" 627 + /> 628 + {/* <button 629 + className={`flex flex-col items-center py-2 px-3 rounded-lg transition-colors flex-1 ${ 630 + isProfile 631 + ? "text-gray-900 dark:text-gray-100" 632 + : "text-gray-600 dark:text-gray-400" 633 + }`} 634 + onClick={() => { 635 + if (authed && agent && agent.assertDid) { 636 + //window.location.href = `/profile/${agent.assertDid}`; 637 + navigate({ 638 + to: "/profile/$did", 639 + params: { did: agent.assertDid }, 640 + }); 641 + } 642 + }} 643 + type="button" 644 + > 645 + <IconMaterialSymbolsAccountCircleOutline width={24} height={24} /> 646 + <span className="text-xs mt-1">Profile</span> 647 + </button> */} 648 + <MaterialNavItem 649 + small 650 + InactiveIcon={ 651 + <IconMaterialSymbolsSettingsOutline className="w-6 h-6" /> 652 + } 653 + ActiveIcon={<IconMaterialSymbolsSettings className="w-6 h-6" />} 654 + active={locationEnum === "settings"} 655 + onClickCallbback={() => 423 656 navigate({ 424 - to: "/profile/$did", 425 - params: { did: agent.assertDid }, 657 + to: "/settings", 658 + //params: { did: agent.assertDid }, 426 659 }) 427 660 } 428 - }} 429 - type="button" 430 - > 431 - <TablerUserCircle width={24} height={24} /> 432 - <span className="text-xs mt-1">Profile</span> 433 - </button> 434 - <Link 435 - to="/settings" 436 - className={`flex flex-col items-center py-2 px-3 rounded-lg transition-colors flex-1 ${ 437 - location.pathname.startsWith("/settings") 438 - ? "text-gray-900 dark:text-gray-100" 439 - : "text-gray-600 dark:text-gray-400" 440 - }`} 441 - > 442 - {location.pathname.startsWith("/settings") ? ( 443 - <IonSettingsSharp width={24} height={24} /> 444 - ) : ( 445 - <IonSettings width={24} height={24} /> 446 - )} 447 - <span className="text-xs mt-1">Settings</span> 448 - </Link> 661 + text="Settings" 662 + /> 663 + {/* <Link 664 + to="/settings" 665 + className={`flex flex-col items-center py-2 px-3 rounded-lg transition-colors flex-1 ${ 666 + location.pathname.startsWith("/settings") 667 + ? "text-gray-900 dark:text-gray-100" 668 + : "text-gray-600 dark:text-gray-400" 669 + }`} 670 + > 671 + {!location.pathname.startsWith("/settings") ? ( 672 + <IconMaterialSymbolsSettingsOutline width={24} height={24} /> 673 + ) : ( 674 + <IconMaterialSymbolsSettings width={24} height={24} /> 675 + )} 676 + <span className="text-xs mt-1">Settings</span> 677 + </Link> */} 678 + </div> 679 + </nav> 680 + ) : ( 681 + <div className="lg:hidden flex items-center fixed bottom-0 left-0 right-0 justify-between px-4 py-3 border-0 shadow border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900 z-10"> 682 + <div className="flex items-center gap-2"> 683 + <FluentEmojiHighContrastGlowingStar className="h-6 w-6" style={{color: "oklch(0.6616 0.2249 calc(25.88 + (var(--safe-hue) - 28))"}} /> 684 + <span className="font-bold text-lg text-gray-900 dark:text-gray-100"> 685 + Red Dwarf{" "} 686 + {/* <span className="text-gray-500 dark:text-gray-400 text-sm"> 687 + lite 688 + </span> */} 689 + </span> 690 + </div> 691 + <div className="flex items-center gap-2"> 692 + <Login compact={true} popup={true} /> 693 + </div> 449 694 </div> 450 - </nav> 695 + )} 451 696 452 - <TanStackRouterDevtools position="bottom-right" /> 697 + <TanStackRouterDevtools position="bottom-left" /> 453 698 <Scripts /> 454 699 </> 455 700 ); 456 701 } 457 - export function TablerHashtag(props: SVGProps<SVGSVGElement>) { 458 - return ( 459 - <svg 460 - xmlns="http://www.w3.org/2000/svg" 461 - width={24} 462 - height={24} 463 - viewBox="0 0 24 24" 464 - {...props} 465 - > 466 - <path 467 - fill="none" 468 - stroke="currentColor" 469 - strokeLinecap="round" 470 - strokeLinejoin="round" 471 - strokeWidth={2} 472 - d="M5 9h14M5 15h14M11 4L7 20M17 4l-4 16" 473 - ></path> 474 - </svg> 475 - ); 476 - } 477 702 478 - export function TablerHashtagFilled(props: SVGProps<SVGSVGElement>) { 479 - return ( 480 - <svg 481 - xmlns="http://www.w3.org/2000/svg" 482 - width={24} 483 - height={24} 484 - viewBox="0 0 24 24" 485 - {...props} 486 - > 487 - <path 488 - fill="none" 489 - stroke="currentColor" 490 - strokeLinecap="round" 491 - strokeLinejoin="round" 492 - strokeWidth={3} 493 - d="M5 9h14M5 15h14M11 4L7 20M17 4l-4 16" 494 - ></path> 495 - </svg> 496 - ); 497 - } 498 - export function TablerEdit(props: SVGProps<SVGSVGElement>) { 499 - return ( 500 - <svg 501 - xmlns="http://www.w3.org/2000/svg" 502 - width={24} 503 - height={24} 504 - viewBox="0 0 24 24" 505 - className="text-white" 506 - {...props} 507 - > 508 - <g 509 - fill="none" 510 - stroke="currentColor" 511 - strokeLinecap="round" 512 - strokeLinejoin="round" 513 - strokeWidth={2} 514 - > 515 - <path d="M16.475 5.408a2.36 2.36 0 1 1 3.34 3.34L7.5 21H3v-4.5z"></path> 516 - </g> 517 - </svg> 518 - ); 519 - } 520 - export function TablerHome(props: SVGProps<SVGSVGElement>) { 521 - return ( 522 - <svg 523 - xmlns="http://www.w3.org/2000/svg" 524 - width={24} 525 - height={24} 526 - viewBox="0 0 24 24" 527 - className="text-gray-900 dark:text-gray-100 hover:text-gray-700 dark:hover:text-gray-300 transition-colors" 528 - {...props} 529 - > 530 - <g 531 - stroke="currentColor" 532 - strokeLinecap="round" 533 - strokeLinejoin="round" 534 - strokeWidth={2} 535 - fill="none" 703 + function MaterialNavItem({ 704 + InactiveIcon, 705 + ActiveIcon, 706 + text, 707 + active, 708 + onClickCallbback, 709 + small, 710 + }: { 711 + InactiveIcon: React.ReactElement; 712 + ActiveIcon: React.ReactElement; 713 + text: string; 714 + active: boolean; 715 + onClickCallbback: () => void; 716 + small?: boolean | string; 717 + }) { 718 + if (small) 719 + return ( 720 + <button 721 + className={`flex flex-col items-center rounded-lg transition-colors ${small} gap-1 ${ 722 + active 723 + ? "text-gray-900 dark:text-gray-100" 724 + : "text-gray-600 dark:text-gray-400" 725 + }`} 726 + onClick={() => { 727 + onClickCallbback(); 728 + }} 536 729 > 537 - <path d="M5 12H3l9-9l9 9h-2M5 12v7a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-7"></path> 538 - <path d="M9 21v-6a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v6"></path> 539 - </g> 540 - </svg> 541 - ); 542 - } 543 - export function TablerHomeFilled(props: SVGProps<SVGSVGElement>) { 544 - return ( 545 - <svg 546 - xmlns="http://www.w3.org/2000/svg" 547 - width={24} 548 - height={24} 549 - viewBox="0 0 24 24" 550 - className="text-gray-900 dark:text-gray-100 hover:text-gray-700 dark:hover:text-gray-300 transition-colors" 551 - {...props} 552 - > 553 - <path 554 - fill="currentColor" 555 - d="m12.707 2.293l9 9c.63.63.184 1.707-.707 1.707h-1v6a3 3 0 0 1-3 3h-1v-7a3 3 0 0 0-2.824-2.995L13 12h-2a3 3 0 0 0-3 3v7H7a3 3 0 0 1-3-3v-6H3c-.89 0-1.337-1.077-.707-1.707l9-9a1 1 0 0 1 1.414 0M13 14a1 1 0 0 1 1 1v7h-4v-7a1 1 0 0 1 .883-.993L11 14z" 556 - ></path> 557 - </svg> 558 - ); 559 - } 730 + <div 731 + className={`px-4 py-1 rounded-full flex items-center justify-center ${active ? " bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 hover:dark:bg-gray-700" : "hover:bg-gray-50 hover:dark:bg-gray-900"}`} 732 + > 733 + {active ? ActiveIcon : InactiveIcon} 734 + </div> 735 + <span 736 + className={`text-[12.8px] text-roboto ${active ? "font-medium" : ""}`} 737 + > 738 + {text} 739 + </span> 740 + </button> 741 + ); 560 742 561 - export function TablerBell(props: SVGProps<SVGSVGElement>) { 562 743 return ( 563 - <svg 564 - xmlns="http://www.w3.org/2000/svg" 565 - width={24} 566 - height={24} 567 - viewBox="0 0 24 24" 568 - {...props} 569 - > 570 - <path 571 - className="text-gray-900 dark:text-gray-100 hover:text-gray-700 dark:hover:text-gray-300 transition-colors" 572 - stroke="currentColor" 573 - strokeLinecap="round" 574 - strokeLinejoin="round" 575 - strokeWidth={2} 576 - d="M10 5a2 2 0 1 1 4 0a7 7 0 0 1 4 6v3a4 4 0 0 0 2 3H4a4 4 0 0 0 2-3v-3a7 7 0 0 1 4-6M9 17v1a3 3 0 0 0 6 0v-1" 577 - ></path> 578 - </svg> 579 - ); 580 - } 581 - export function TablerBellFilled(props: SVGProps<SVGSVGElement>) { 582 - return ( 583 - <svg 584 - xmlns="http://www.w3.org/2000/svg" 585 - width={24} 586 - height={24} 587 - viewBox="0 0 24 24" 588 - className="text-gray-900 dark:text-gray-100 hover:text-gray-700 dark:hover:text-gray-300 transition-colors" 589 - {...props} 590 - > 591 - <path 592 - fill="currentColor" 593 - stroke="currentColor" 594 - d="M14.235 19c.865 0 1.322 1.024.745 1.668A4 4 0 0 1 12 22a4 4 0 0 1-2.98-1.332c-.552-.616-.158-1.579.634-1.661l.11-.006zM12 2c1.358 0 2.506.903 2.875 2.141l.046.171l.008.043a8.01 8.01 0 0 1 4.024 6.069l.028.287L19 11v2.931l.021.136a3 3 0 0 0 1.143 1.847l.167.117l.162.099c.86.487.56 1.766-.377 1.864L20 18H4c-1.028 0-1.387-1.364-.493-1.87a3 3 0 0 0 1.472-2.063L5 13.924l.001-2.97A8 8 0 0 1 8.822 4.5l.248-.146l.01-.043a3 3 0 0 1 2.562-2.29l.182-.017z" 595 - ></path> 596 - </svg> 597 - ); 598 - } 599 - 600 - export function TablerUserCircle(props: SVGProps<SVGSVGElement>) { 601 - return ( 602 - <svg 603 - xmlns="http://www.w3.org/2000/svg" 604 - width={24} 605 - height={24} 606 - viewBox="0 0 24 24" 607 - className="text-gray-900 dark:text-gray-100 hover:text-gray-700 dark:hover:text-gray-300 transition-colors" 608 - {...props} 744 + <button 745 + className={`flex flex-row h-12 min-h-12 max-h-12 px-4 py-0.5 w-full items-center rounded-full transition-colors flex-1 gap-1 ${ 746 + active 747 + ? "text-gray-900 dark:text-gray-100 hover:bg-gray-300 dark:bg-gray-800 bg-gray-200 hover:dark:bg-gray-700" 748 + : "text-gray-600 dark:text-gray-400 hover:bg-gray-100 hover:dark:bg-gray-900" 749 + }`} 750 + onClick={() => { 751 + onClickCallbback(); 752 + }} 609 753 > 610 - <g 611 - fill="none" 612 - stroke="currentColor" 613 - strokeLinecap="round" 614 - strokeLinejoin="round" 615 - strokeWidth={2} 754 + <div className={`mr-4 ${active ? " " : " "}`}> 755 + {active ? ActiveIcon : InactiveIcon} 756 + </div> 757 + <span 758 + className={`text-[17px] text-roboto ${active ? "font-medium" : ""}`} 616 759 > 617 - <path d="M3 12a9 9 0 1 0 18 0a9 9 0 1 0-18 0"></path> 618 - <path d="M9 10a3 3 0 1 0 6 0a3 3 0 1 0-6 0m-2.832 8.849A4 4 0 0 1 10 16h4a4 4 0 0 1 3.834 2.855"></path> 619 - </g> 620 - </svg> 621 - ); 622 - } 623 - 624 - export function TablerSearch(props: SVGProps<SVGSVGElement>) { 625 - return ( 626 - <svg 627 - xmlns="http://www.w3.org/2000/svg" 628 - width={24} 629 - height={24} 630 - viewBox="0 0 24 24" 631 - //className="text-gray-400 dark:text-gray-500" 632 - {...props} 633 - > 634 - <g 635 - fill="none" 636 - stroke="currentColor" 637 - strokeLinecap="round" 638 - strokeLinejoin="round" 639 - strokeWidth={2} 640 - > 641 - <path d="M3 10a7 7 0 1 0 14 0a7 7 0 1 0-14 0"></path> 642 - <path d="m21 21l-6-6"></path> 643 - </g> 644 - </svg> 645 - ); 646 - } 647 - export function TablerSearchFilled(props: SVGProps<SVGSVGElement>) { 648 - return ( 649 - <svg 650 - xmlns="http://www.w3.org/2000/svg" 651 - width={24} 652 - height={24} 653 - viewBox="0 0 24 24" 654 - //className="text-gray-400 dark:text-gray-500" 655 - {...props} 656 - > 657 - <g 658 - fill="none" 659 - stroke="currentColor" 660 - strokeLinecap="round" 661 - strokeLinejoin="round" 662 - strokeWidth={3} 663 - > 664 - <path d="M3 10a7 7 0 1 0 14 0a7 7 0 1 0-14 0"></path> 665 - <path d="m21 21l-6-6"></path> 666 - </g> 667 - </svg> 760 + {text} 761 + </span> 762 + </button> 668 763 ); 669 764 } 670 765 671 - export function IonSettings(props: SVGProps<SVGSVGElement>) { 672 - return ( 673 - <svg 674 - xmlns="http://www.w3.org/2000/svg" 675 - width={24} 676 - height={24} 677 - viewBox="0 0 512 512" 678 - {...props} 679 - > 680 - <path 681 - fill="none" 682 - stroke="currentColor" 683 - strokeLinecap="round" 684 - strokeLinejoin="round" 685 - strokeWidth={32} 686 - d="M262.29 192.31a64 64 0 1 0 57.4 57.4a64.13 64.13 0 0 0-57.4-57.4M416.39 256a154 154 0 0 1-1.53 20.79l45.21 35.46a10.81 10.81 0 0 1 2.45 13.75l-42.77 74a10.81 10.81 0 0 1-13.14 4.59l-44.9-18.08a16.11 16.11 0 0 0-15.17 1.75A164.5 164.5 0 0 1 325 400.8a15.94 15.94 0 0 0-8.82 12.14l-6.73 47.89a11.08 11.08 0 0 1-10.68 9.17h-85.54a11.11 11.11 0 0 1-10.69-8.87l-6.72-47.82a16.07 16.07 0 0 0-9-12.22a155 155 0 0 1-21.46-12.57a16 16 0 0 0-15.11-1.71l-44.89 18.07a10.81 10.81 0 0 1-13.14-4.58l-42.77-74a10.8 10.8 0 0 1 2.45-13.75l38.21-30a16.05 16.05 0 0 0 6-14.08c-.36-4.17-.58-8.33-.58-12.5s.21-8.27.58-12.35a16 16 0 0 0-6.07-13.94l-38.19-30A10.81 10.81 0 0 1 49.48 186l42.77-74a10.81 10.81 0 0 1 13.14-4.59l44.9 18.08a16.11 16.11 0 0 0 15.17-1.75A164.5 164.5 0 0 1 187 111.2a15.94 15.94 0 0 0 8.82-12.14l6.73-47.89A11.08 11.08 0 0 1 213.23 42h85.54a11.11 11.11 0 0 1 10.69 8.87l6.72 47.82a16.07 16.07 0 0 0 9 12.22a155 155 0 0 1 21.46 12.57a16 16 0 0 0 15.11 1.71l44.89-18.07a10.81 10.81 0 0 1 13.14 4.58l42.77 74a10.8 10.8 0 0 1-2.45 13.75l-38.21 30a16.05 16.05 0 0 0-6.05 14.08c.33 4.14.55 8.3.55 12.47" 687 - ></path> 688 - </svg> 689 - ); 690 - } 691 - export function IonSettingsSharp(props: SVGProps<SVGSVGElement>) { 766 + function MaterialPillButton({ 767 + InactiveIcon, 768 + ActiveIcon, 769 + text, 770 + //active, 771 + onClickCallbback, 772 + small, 773 + }: { 774 + InactiveIcon: React.ReactElement; 775 + ActiveIcon: React.ReactElement; 776 + text: string; 777 + //active: boolean; 778 + onClickCallbback: () => void; 779 + small?: boolean | string; 780 + }) { 781 + const active = false; 692 782 return ( 693 - <svg 694 - xmlns="http://www.w3.org/2000/svg" 695 - width={24} 696 - height={24} 697 - viewBox="0 0 512 512" 698 - {...props} 783 + <button 784 + className={`flex border border-gray-400 dark:border-gray-400 flex-row h-12 min-h-12 max-h-12 ${small ? "p-3 w-12" : "px-4 py-0.5"} items-center rounded-full transition-colors gap-1 ${ 785 + active 786 + ? "text-gray-900 dark:text-gray-100 hover:bg-gray-300 dark:bg-gray-700 bg-gray-200 hover:dark:bg-gray-600" 787 + : "text-gray-600 dark:text-gray-400 hover:bg-gray-100 hover:dark:bg-gray-800" 788 + }`} 789 + onClick={() => { 790 + onClickCallbback(); 791 + }} 699 792 > 700 - <path 701 - fill="currentColor" 702 - d="M256 176a80 80 0 1 0 80 80a80.24 80.24 0 0 0-80-80m172.72 80a165.5 165.5 0 0 1-1.64 22.34l48.69 38.12a11.59 11.59 0 0 1 2.63 14.78l-46.06 79.52a11.64 11.64 0 0 1-14.14 4.93l-57.25-23a176.6 176.6 0 0 1-38.82 22.67l-8.56 60.78a11.93 11.93 0 0 1-11.51 9.86h-92.12a12 12 0 0 1-11.51-9.53l-8.56-60.78A169.3 169.3 0 0 1 151.05 393L93.8 416a11.64 11.64 0 0 1-14.14-4.92L33.6 331.57a11.59 11.59 0 0 1 2.63-14.78l48.69-38.12A175 175 0 0 1 83.28 256a165.5 165.5 0 0 1 1.64-22.34l-48.69-38.12a11.59 11.59 0 0 1-2.63-14.78l46.06-79.52a11.64 11.64 0 0 1 14.14-4.93l57.25 23a176.6 176.6 0 0 1 38.82-22.67l8.56-60.78A11.93 11.93 0 0 1 209.94 26h92.12a12 12 0 0 1 11.51 9.53l8.56 60.78A169.3 169.3 0 0 1 361 119l57.2-23a11.64 11.64 0 0 1 14.14 4.92l46.06 79.52a11.59 11.59 0 0 1-2.63 14.78l-48.69 38.12a175 175 0 0 1 1.64 22.66" 703 - ></path> 704 - </svg> 793 + <div className={`${!small && "mr-2"} ${active ? " " : " "}`}> 794 + {active ? ActiveIcon : InactiveIcon} 795 + </div> 796 + {!small && ( 797 + <span 798 + className={`text-[17px] text-roboto ${active ? "font-medium" : ""}`} 799 + > 800 + {text} 801 + </span> 802 + )} 803 + </button> 705 804 ); 706 805 }
+179 -178
src/routes/index.tsx
··· 1 1 import { createFileRoute } from "@tanstack/react-router"; 2 - import { 3 - CACHE_TIMEOUT, 4 - //cachedGetRecord, 5 - //cachedResolveIdentity, 6 - UniversalPostRendererATURILoader, 7 - } from "~/components/UniversalPostRenderer"; 2 + import { useAtom } from "jotai"; 8 3 import * as React from "react"; 4 + import { useEffect, useLayoutEffect } from "react"; 5 + 6 + import { Header } from "~/components/Header"; 7 + import { InfiniteCustomFeed } from "~/components/InfiniteCustomFeed"; 9 8 import { useAuth } from "~/providers/UnifiedAuthProvider"; 9 + import { 10 + agentAtom, 11 + authedAtom, 12 + feedScrollPositionsAtom, 13 + isAtTopAtom, 14 + selectedFeedUriAtom, 15 + store, 16 + } from "~/utils/atoms"; 10 17 //import { usePersistentStore } from "~/providers/PersistentStoreProvider"; 11 18 import { 19 + //constructArbitraryQuery, 20 + //constructIdentityQuery, 21 + //constructInfiniteFeedSkeletonQuery, 22 + //constructPostQuery, 23 + useQueryArbitrary, 12 24 useQueryIdentity, 13 - useQueryPost, 14 - useQueryFeedSkeleton, 15 25 useQueryPreferences, 16 - useQueryArbitrary, 17 - constructInfiniteFeedSkeletonQuery, 18 - constructArbitraryQuery, 19 - constructIdentityQuery, 20 - constructPostQuery, 21 26 } from "~/utils/useQuery"; 22 - import { InfiniteCustomFeed } from "~/components/InfiniteCustomFeed"; 23 - import { useAtom, useSetAtom } from "jotai"; 24 - import { 25 - selectedFeedUriAtom, 26 - store, 27 - agentAtom, 28 - authedAtom, 29 - feedScrollPositionsAtom, 30 - } from "~/utils/atoms"; 31 - import { useEffect, useLayoutEffect } from "react"; 32 27 33 28 export const Route = createFileRoute("/")({ 34 - loader: async ({ context }) => { 35 - const { queryClient } = context; 36 - const atomauth = store.get(authedAtom); 37 - const atomagent = store.get(agentAtom); 29 + // loader: async ({ context }) => { 30 + // const { queryClient } = context; 31 + // const atomauth = store.get(authedAtom); 32 + // const atomagent = store.get(agentAtom); 38 33 39 - let identitypds: string | undefined; 40 - const initialselectedfeed = store.get(selectedFeedUriAtom); 41 - if (atomagent && atomauth && atomagent?.did) { 42 - const identityopts = constructIdentityQuery(atomagent.did); 43 - const identityresultmaybe = 44 - await queryClient.ensureQueryData(identityopts); 45 - identitypds = identityresultmaybe?.pds; 46 - } 34 + // let identitypds: string | undefined; 35 + // const initialselectedfeed = store.get(selectedFeedUriAtom); 36 + // if (atomagent && atomauth && atomagent?.did) { 37 + // const identityopts = constructIdentityQuery(atomagent.did); 38 + // const identityresultmaybe = 39 + // await queryClient.ensureQueryData(identityopts); 40 + // identitypds = identityresultmaybe?.pds; 41 + // } 47 42 48 - const arbitraryopts = constructArbitraryQuery( 49 - initialselectedfeed ?? 50 - "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot" 51 - ); 52 - const feedGengetrecordquery = 53 - await queryClient.ensureQueryData(arbitraryopts); 54 - const feedServiceDid = (feedGengetrecordquery?.value as any)?.did; 55 - //queryClient.ensureInfiniteQueryData() 43 + // const arbitraryopts = constructArbitraryQuery( 44 + // initialselectedfeed ?? 45 + // "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot" 46 + // ); 47 + // const feedGengetrecordquery = 48 + // await queryClient.ensureQueryData(arbitraryopts); 49 + // const feedServiceDid = (feedGengetrecordquery?.value as any)?.did; 50 + // //queryClient.ensureInfiniteQueryData() 56 51 57 - const { queryKey, queryFn } = constructInfiniteFeedSkeletonQuery({ 58 - feedUri: 59 - initialselectedfeed ?? 60 - "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot", 61 - agent: atomagent ?? undefined, 62 - isAuthed: atomauth ?? false, 63 - pdsUrl: identitypds, 64 - feedServiceDid: feedServiceDid, 65 - }); 52 + // const { queryKey, queryFn } = constructInfiniteFeedSkeletonQuery({ 53 + // feedUri: 54 + // initialselectedfeed ?? 55 + // "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot", 56 + // agent: atomagent ?? undefined, 57 + // isAuthed: atomauth ?? false, 58 + // pdsUrl: identitypds, 59 + // feedServiceDid: feedServiceDid, 60 + // }); 66 61 67 - const res = await queryClient.ensureInfiniteQueryData({ 68 - queryKey, 69 - queryFn, 70 - initialPageParam: undefined as never, 71 - getNextPageParam: (lastPage: any) => lastPage.cursor as null | undefined, 72 - staleTime: Infinity, 73 - //refetchOnWindowFocus: false, 74 - //enabled: true, 75 - }); 76 - await Promise.all( 77 - res.pages.map(async (page) => { 78 - await Promise.all( 79 - page.feed.map(async (feedviewpost) => { 80 - if (!feedviewpost.post) return; 81 - console.log("preloading: ", feedviewpost.post); 82 - const opts = constructPostQuery(feedviewpost.post); 83 - try { 84 - await queryClient.ensureQueryData(opts); 85 - } catch (e) { 86 - console.log(" failed:", e); 87 - } 88 - }) 89 - ); 90 - }) 91 - ); 92 - }, 62 + // const res = await queryClient.ensureInfiniteQueryData({ 63 + // queryKey, 64 + // queryFn, 65 + // initialPageParam: undefined as never, 66 + // getNextPageParam: (lastPage: any) => lastPage.cursor as null | undefined, 67 + // staleTime: Infinity, 68 + // //refetchOnWindowFocus: false, 69 + // //enabled: true, 70 + // }); 71 + // await Promise.all( 72 + // res.pages.map(async (page) => { 73 + // await Promise.all( 74 + // page.feed.map(async (feedviewpost) => { 75 + // if (!feedviewpost.post) return; 76 + // // /*mass comment*/ console.log("preloading: ", feedviewpost.post); 77 + // const opts = constructPostQuery(feedviewpost.post); 78 + // try { 79 + // await queryClient.ensureQueryData(opts); 80 + // } catch (e) { 81 + // // /*mass comment*/ console.log(" failed:", e); 82 + // } 83 + // }) 84 + // ); 85 + // }) 86 + // ); 87 + // }, 93 88 component: Home, 94 - pendingComponent: PendingHome, 89 + pendingComponent: PendingHome, // PendingHome, 90 + staticData: { keepAlive: true }, 95 91 }); 96 92 function PendingHome() { 97 93 return <div>loading... (prefetching your timeline)</div>; 98 94 } 99 - function Home() { 95 + 96 + //function Homer() { 97 + // return <div></div> 98 + //} 99 + export function Home({ hidden = false }: { hidden?: boolean }) { 100 100 const { 101 101 agent, 102 102 status, ··· 116 116 }, [status, agent, authed]); 117 117 useEffect(() => { 118 118 if (agent) { 119 - // is it just me or is the type really weird here it should be Agent not AtpAgent 119 + // eslint-disable-next-line @typescript-eslint/ban-ts-comment 120 + // @ts-ignore is it just me or is the type really weird here it should be Agent not AtpAgent 120 121 store.set(agentAtom, agent); 121 122 } else { 122 123 store.set(agentAtom, null); ··· 141 142 // set, 142 143 // }); 143 144 144 - // console.log("alistoffeeds", prefs); 145 + // // /*mass comment*/ console.log("alistoffeeds", prefs); 145 146 // setPrefs(prefs || {}); 146 147 // } catch (err) { 147 148 // console.error("alistoffeeds Fetch error in preferences effect:", err); ··· 189 190 ? setPersistentSelectedFeed 190 191 : setUnauthedSelectedFeed; 191 192 192 - console.log("my selectedFeed is: ", selectedFeed); 193 + // /*mass comment*/ console.log("my selectedFeed is: ", selectedFeed); 193 194 React.useEffect(() => { 194 195 const fallbackFeed = 195 196 "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot"; ··· 231 232 // }); 232 233 233 234 // const fetchstringcomplex = `${pdsurl.pdsUrl}/xrpc/app.bsky.feed.getFeedSkeleton?feed=${selectedFeed}`; 234 - // console.log("fetching feed authed: " + fetchstringcomplex); 235 + // // /*mass comment*/ console.log("fetching feed authed: " + fetchstringcomplex); 235 236 236 237 // const feeddef = await cachedGetRecord({ 237 238 // atUri: selectedFeed, ··· 254 255 255 256 // if (!ignore) setFeed(data.feed || []); 256 257 // } else { 257 - // console.log("falling back"); 258 + // // /*mass comment*/ console.log("falling back"); 258 259 // // always use fallback feed for not logged in 259 260 // const fallbackFeed = 260 261 // "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot"; ··· 266 267 267 268 // //const feedservicedid = "did:web:discover.bsky.app" //feeddef.did; 268 269 // const fetchstringsimple = `https://discover.bsky.app/xrpc/app.bsky.feed.getFeedSkeleton?feed=${fallbackFeed}`; 269 - // console.log("fetching feed unauthed: " + fetchstringsimple); 270 + // // /*mass comment*/ console.log("fetching feed unauthed: " + fetchstringsimple); 270 271 271 272 // const res = await fetch(fetchstringsimple); 272 273 // if (!res.ok) throw new Error("Failed to fetch feed"); ··· 298 299 feedScrollPositionsAtom 299 300 ); 300 301 301 - const scrollRef = React.useRef<Record<string, number>>({}); 302 + const scrollPositionsRef = React.useRef(scrollPositions); 302 303 303 - useEffect(() => { 304 - const onScroll = () => { 305 - //if (!selectedFeed) return; 306 - scrollRef.current[selectedFeed ?? "null"] = window.scrollY; 307 - }; 308 - window.addEventListener("scroll", onScroll, { passive: true }); 309 - return () => window.removeEventListener("scroll", onScroll); 310 - }, [selectedFeed]); 311 - const [donerestored, setdonerestored] = React.useState(false); 304 + React.useEffect(() => { 305 + scrollPositionsRef.current = scrollPositions; 306 + }, [scrollPositions]); 312 307 313 - useEffect(() => { 314 - return () => { 315 - if (!donerestored) return; 316 - console.log("FEEDSCROLLSHIT saving at uhhh: ", scrollRef.current); 317 - //if (!selectedFeed) return; 318 - setScrollPositions((prev) => ({ 319 - ...prev, 320 - [selectedFeed ?? "null"]: 321 - scrollRef.current[selectedFeed ?? "null"] ?? 0, 322 - })); 323 - }; 324 - }, [selectedFeed, setScrollPositions, donerestored]); 308 + useLayoutEffect(() => { 309 + const savedPosition = scrollPositions[selectedFeed ?? "null"] ?? 0; 325 310 326 - const [restoringScrollPosition, setRestoringScrollPosition] = 327 - React.useState(false); 311 + window.scrollTo({ top: savedPosition, behavior: "instant" }); 312 + // eslint-disable-next-line react-hooks/exhaustive-deps 313 + }, [selectedFeed]); 328 314 329 315 useLayoutEffect(() => { 330 - setRestoringScrollPosition(true); 331 - const savedPosition = scrollPositions[selectedFeed ?? "null"] ?? 0; 316 + if (!selectedFeed) return; 332 317 333 - let raf = requestAnimationFrame(() => { 334 - // setRestoringScrollPosition(true); 335 - // raf = requestAnimationFrame(() => { 336 - // window.scrollTo({ top: savedPosition, behavior: "instant" }); 337 - // setRestoringScrollPosition(false); 338 - // setdonerestored(true); 339 - // }); 340 - window.scrollTo({ top: savedPosition, behavior: "instant" }); 341 - setRestoringScrollPosition(false); 342 - setdonerestored(true); 343 - }); 318 + const handleScroll = () => { 319 + scrollPositionsRef.current = { 320 + ...scrollPositionsRef.current, 321 + [selectedFeed]: window.scrollY, 322 + }; 323 + }; 324 + 325 + window.addEventListener("scroll", handleScroll, { passive: true }); 326 + return () => { 327 + window.removeEventListener("scroll", handleScroll); 344 328 345 - return () => cancelAnimationFrame(raf); 346 - }, [selectedFeed, scrollPositions]); 329 + setScrollPositions(scrollPositionsRef.current); 330 + }; 331 + }, [selectedFeed, setScrollPositions]); 347 332 348 333 const feedGengetrecordquery = useQueryArbitrary(selectedFeed ?? undefined); 349 334 const feedServiceDid = (feedGengetrecordquery?.data?.value as any)?.did; ··· 366 351 authed && agent && identity?.pds && feedServiceDid; 367 352 const isReadyForUnauthedFeed = !authed && selectedFeed; 368 353 354 + 355 + const [isAtTop] = useAtom(isAtTopAtom); 356 + 369 357 return ( 370 - <div className="relative flex flex-col divide-y divide-gray-200 dark:divide-gray-800"> 371 - <div className="flex items-center gap-2 px-4 py-2 h-[52px] sticky top-0 bg-white dark:bg-gray-950 z-10 border-b border-gray-200 dark:border-gray-700 overflow-x-auto overflow-y-hidden scroll-thin"> 372 - {savedFeeds.length > 0 ? ( 373 - savedFeeds.map((item: any, idx: number) => { 358 + <div 359 + className={`relative flex flex-col divide-y divide-gray-200 dark:divide-gray-800 ${hidden && "hidden"}`} 360 + > 361 + {savedFeeds.length > 0 ? ( 362 + <div className={`flex items-center px-4 py-2 h-[52px] sticky top-0 bg-[var(--header-bg-light)] dark:bg-[var(--header-bg-dark)] ${!isAtTop && "shadow-sm"} sm:shadow-none sm:bg-white sm:dark:bg-gray-950 z-10 border-0 sm:border-b border-gray-200 dark:border-gray-700 overflow-x-auto overflow-y-hidden scroll-thin`}> 363 + {savedFeeds.map((item: any, idx: number) => { 374 364 const label = item.value.split("/").pop() || item.value; 375 365 const isActive = selectedFeed === item.value; 376 366 return ( ··· 378 368 key={item.value || idx} 379 369 className={`px-3 py-1 rounded-full whitespace-nowrap font-medium transition-colors ${ 380 370 isActive 381 - ? "bg-gray-500 text-white" 382 - : item.pinned 383 - ? "bg-gray-200 text-gray-700 dark:bg-gray-700 dark:text-gray-200" 384 - : "bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-200" 371 + ? "text-gray-900 dark:text-gray-100 hover:bg-gray-300 dark:bg-gray-700 bg-gray-200 hover:dark:bg-gray-600" 372 + : "text-gray-600 dark:text-gray-400 hover:bg-gray-100 hover:dark:bg-gray-800" 373 + // ? "bg-gray-500 text-white" 374 + // : item.pinned 375 + // ? "bg-gray-200 text-gray-700 dark:bg-gray-700 dark:text-gray-200" 376 + // : "bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-200" 385 377 }`} 386 378 onClick={() => setSelectedFeed(item.value)} 387 379 title={item.value} 388 380 > 389 381 {label} 390 382 {item.pinned && ( 391 - <span className="ml-1 text-xs text-gray-700 dark:text-gray-200"> 383 + <span 384 + className={`ml-1 text-xs ${ 385 + isActive 386 + ? "text-gray-900 dark:text-gray-100" 387 + : "text-gray-600 dark:text-gray-400" 388 + }`} 389 + > 392 390 โ˜… 393 391 </span> 394 392 )} 395 393 </button> 396 394 ); 397 - }) 398 - ) : ( 399 - <span className="text-xl font-bold ml-2">Home</span> 400 - )} 401 - </div> 395 + })} 396 + </div> 397 + ) : ( 398 + // <span className="text-xl font-bold ml-2">Home</span> 399 + <Header title="Home" /> 400 + )} 402 401 {/* {isFeedLoading && <div className="p-4 text-gray-500">Loading...</div>} 403 402 {feedError && <div className="p-4 text-red-500">{feedError.message}</div>} 404 403 {!isFeedLoading && !feedError && feed.length === 0 && ( ··· 419 418 420 419 {isReadyForAuthedFeed || isReadyForUnauthedFeed ? ( 421 420 <InfiniteCustomFeed 421 + key={selectedFeed!} 422 422 feedUri={selectedFeed!} 423 423 pdsUrl={identity?.pds} 424 424 feedServiceDid={feedServiceDid} ··· 428 428 Select a feed to get started. 429 429 </div> 430 430 )} 431 - {false && restoringScrollPosition && ( 431 + {/* {false && restoringScrollPosition && ( 432 432 <div className="fixed top-1/2 left-1/2 right-1/2"> 433 433 restoringScrollPosition 434 434 </div> 435 - )} 435 + )} */} 436 436 </div> 437 437 ); 438 438 } 439 + // not even used lmaooo 439 440 440 - export async function cachedResolveDIDWEBDOC({ 441 - didweb, 442 - cacheTimeout = CACHE_TIMEOUT, 443 - get, 444 - set, 445 - }: { 446 - didweb: string; 447 - cacheTimeout?: number; 448 - get: (key: string) => any; 449 - set: (key: string, value: string) => void; 450 - }): Promise<any> { 451 - const isDidInput = didweb.startsWith("did:web:"); 452 - const cacheKey = `didwebdoc:${didweb}`; 453 - const now = Date.now(); 454 - const cached = get(cacheKey); 455 - if ( 456 - cached && 457 - cached.value && 458 - cached.time && 459 - now - cached.time < cacheTimeout 460 - ) { 461 - try { 462 - return JSON.parse(cached.value); 463 - } catch {} 464 - } 465 - const url = `https://free-fly-24.deno.dev/resolve-did-web?did=${encodeURIComponent( 466 - didweb 467 - )}`; 468 - const res = await fetch(url); 469 - if (!res.ok) throw new Error("Failed to resolve didwebdoc"); 470 - const data = await res.json(); 471 - set(cacheKey, JSON.stringify(data)); 472 - if (!isDidInput && data.did) { 473 - set(`didwebdoc:${data.did}`, JSON.stringify(data)); 474 - } 475 - return data; 476 - } 441 + // export async function cachedResolveDIDWEBDOC({ 442 + // didweb, 443 + // cacheTimeout = CACHE_TIMEOUT, 444 + // get, 445 + // set, 446 + // }: { 447 + // didweb: string; 448 + // cacheTimeout?: number; 449 + // get: (key: string) => any; 450 + // set: (key: string, value: string) => void; 451 + // }): Promise<any> { 452 + // const isDidInput = didweb.startsWith("did:web:"); 453 + // const cacheKey = `didwebdoc:${didweb}`; 454 + // const now = Date.now(); 455 + // const cached = get(cacheKey); 456 + // if ( 457 + // cached && 458 + // cached.value && 459 + // cached.time && 460 + // now - cached.time < cacheTimeout 461 + // ) { 462 + // try { 463 + // return JSON.parse(cached.value); 464 + // } catch (_e) {/* whatever*/ } 465 + // } 466 + // const url = `https://free-fly-24.deno.dev/resolve-did-web?did=${encodeURIComponent( 467 + // didweb 468 + // )}`; 469 + // const res = await fetch(url); 470 + // if (!res.ok) throw new Error("Failed to resolve didwebdoc"); 471 + // const data = await res.json(); 472 + // set(cacheKey, JSON.stringify(data)); 473 + // if (!isDidInput && data.did) { 474 + // set(`didwebdoc:${data.did}`, JSON.stringify(data)); 475 + // } 476 + // return data; 477 + // } 477 478 478 479 // export async function cachedGetPrefs({ 479 480 // did,
+31 -26
src/routes/notifications.tsx
··· 1 1 import { createFileRoute } from "@tanstack/react-router"; 2 - import React, { useEffect, useState, useRef } from "react"; 3 - import { useAuth } from "~/providers/PassAuthProvider"; 4 - import { usePersistentStore } from "~/providers/PersistentStoreProvider"; 2 + import { useAtom } from "jotai"; 3 + import React, { useEffect, useRef,useState } from "react"; 4 + 5 + import { useAuth } from "~/providers/UnifiedAuthProvider"; 6 + import { constellationURLAtom } from "~/utils/atoms"; 5 7 6 8 const HANDLE_DID_CACHE_TIMEOUT = 60 * 60 * 1000; // 1 hour 7 9 ··· 10 12 }); 11 13 12 14 function NotificationsComponent() { 13 - console.log("NotificationsComponent render"); 14 - const { agent, authed, loading: authLoading } = useAuth(); 15 - const { get, set } = usePersistentStore(); 15 + // /*mass comment*/ console.log("NotificationsComponent render"); 16 + const { agent, status } = useAuth(); 17 + const authed = !!agent?.did; 18 + const authLoading = status === "loading"; 16 19 const [did, setDid] = useState<string | null>(null); 17 20 const [resolving, setResolving] = useState(false); 18 21 const [error, setError] = useState<string | null>(null); ··· 28 31 }, [authed, agent, authLoading]); 29 32 30 33 async function handleSubmit() { 31 - console.log("handleSubmit called"); 34 + // /*mass comment*/ console.log("handleSubmit called"); 32 35 setError(null); 33 36 setResponses([null, null, null]); 34 37 const value = inputRef.current?.value?.trim() || ""; ··· 41 44 setResolving(true); 42 45 const cacheKey = `handleDid:${value}`; 43 46 const now = Date.now(); 44 - const cached = await get(cacheKey); 45 - if ( 46 - cached && 47 - cached.value && 48 - cached.time && 49 - now - cached.time < HANDLE_DID_CACHE_TIMEOUT 50 - ) { 51 - try { 52 - const data = JSON.parse(cached.value); 53 - setDid(data.did); 54 - setResolving(false); 55 - return; 56 - } catch {} 57 - } 47 + const cached = undefined // await get(cacheKey); 48 + // if ( 49 + // cached && 50 + // cached.value && 51 + // cached.time && 52 + // now - cached.time < HANDLE_DID_CACHE_TIMEOUT 53 + // ) { 54 + // try { 55 + // const data = JSON.parse(cached.value); 56 + // setDid(data.did); 57 + // setResolving(false); 58 + // return; 59 + // } catch {} 60 + // } 58 61 try { 59 62 const url = `https://free-fly-24.deno.dev/?handle=${encodeURIComponent(value)}`; 60 63 const res = await fetch(url); 61 64 if (!res.ok) throw new Error("Failed to resolve handle"); 62 65 const data = await res.json(); 63 - set(cacheKey, JSON.stringify(data)); 66 + //set(cacheKey, JSON.stringify(data)); 64 67 setDid(data.did); 65 68 } catch (e: any) { 66 69 setError("Failed to resolve handle: " + (e?.message || e)); ··· 69 72 } 70 73 } 71 74 75 + const [constellationURL] = useAtom(constellationURLAtom) 76 + 72 77 useEffect(() => { 73 78 if (!did) return; 74 79 setLoading(true); 75 80 setError(null); 76 81 const urls = [ 77 - `https://constellation.microcosm.blue/links?target=${encodeURIComponent(did)}&collection=app.bsky.feed.post&path=.facets[app.bsky.richtext.facet].features[app.bsky.richtext.facet%23mention].did`, 78 - `https://constellation.microcosm.blue/links?target=${encodeURIComponent(did)}&collection=app.bsky.feed.post&path=.facets[].features[app.bsky.richtext.facet%23mention].did`, 79 - `https://constellation.microcosm.blue/links?target=${encodeURIComponent(did)}&collection=app.bsky.graph.follow&path=.subject`, 82 + `https://${constellationURL}/links?target=${encodeURIComponent(did)}&collection=app.bsky.feed.post&path=.facets[app.bsky.richtext.facet].features[app.bsky.richtext.facet%23mention].did`, 83 + `https://${constellationURL}/links?target=${encodeURIComponent(did)}&collection=app.bsky.feed.post&path=.facets[].features[app.bsky.richtext.facet%23mention].did`, 84 + `https://${constellationURL}/links?target=${encodeURIComponent(did)}&collection=app.bsky.graph.follow&path=.subject`, 80 85 ]; 81 86 let ignore = false; 82 87 Promise.all( ··· 94 99 } catch (e: any) { 95 100 return { error: e?.message || String(e) }; 96 101 } 97 - }), 102 + }) 98 103 ) 99 104 .then((results) => { 100 105 if (!ignore) setResponses(results);
+214 -32
src/routes/profile.$did/index.tsx
··· 1 - import { createFileRoute, Link } from "@tanstack/react-router"; 2 - import React from "react"; 3 - import { UniversalPostRendererATURILoader } from "~/components/UniversalPostRenderer"; 1 + import { RichText } from "@atproto/api"; 4 2 import { useQueryClient } from "@tanstack/react-query"; 3 + import { createFileRoute, useNavigate } from "@tanstack/react-router"; 4 + import { useAtom } from "jotai"; 5 + import React, { type ReactNode, useEffect, useState } from "react"; 5 6 7 + import { Header } from "~/components/Header"; 6 8 import { 9 + renderTextWithFacets, 10 + UniversalPostRendererATURILoader, 11 + } from "~/components/UniversalPostRenderer"; 12 + import { useAuth } from "~/providers/UnifiedAuthProvider"; 13 + import { aturiListServiceAtom, imgCDNAtom } from "~/utils/atoms"; 14 + import { 15 + toggleFollow, 16 + useGetFollowState, 17 + useGetOneToOneState, 18 + } from "~/utils/followState"; 19 + import { 20 + useInfiniteQueryAturiList, 7 21 useQueryIdentity, 8 22 useQueryProfile, 9 - useInfiniteQueryAuthorFeed, 10 23 } from "~/utils/useQuery"; 11 24 12 25 export const Route = createFileRoute("/profile/$did/")({ ··· 14 27 }); 15 28 16 29 function ProfileComponent() { 30 + // booo bad this is not always the did it might be a handle, use identity.did instead 17 31 const { did } = Route.useParams(); 32 + //const navigate = useNavigate(); 18 33 const queryClient = useQueryClient(); 19 - 20 34 const { 21 35 data: identity, 22 36 isLoading: isIdentityLoading, ··· 25 39 26 40 const resolvedDid = did.startsWith("did:") ? did : identity?.did; 27 41 const resolvedHandle = did.startsWith("did:") ? identity?.handle : did; 28 - const pdsUrl = identity?.pds; 42 + //const pdsUrl = identity?.pds; 29 43 30 44 const profileUri = resolvedDid 31 45 ? `at://${resolvedDid}/app.bsky.actor.profile/self` 32 46 : undefined; 33 47 const { data: profileRecord } = useQueryProfile(profileUri); 34 48 const profile = profileRecord?.value; 49 + 50 + const [aturilistservice] = useAtom(aturiListServiceAtom); 35 51 36 52 const { 37 53 data: postsData, ··· 39 55 hasNextPage, 40 56 isFetchingNextPage, 41 57 isLoading: arePostsLoading, 42 - } = useInfiniteQueryAuthorFeed(resolvedDid, pdsUrl); 58 + } = useInfiniteQueryAturiList({ 59 + aturilistservice: aturilistservice, 60 + did: resolvedDid, 61 + collection: "app.bsky.feed.post", 62 + reverse: true 63 + }); 43 64 44 65 React.useEffect(() => { 45 66 if (postsData) { 46 67 postsData.pages.forEach((page) => { 47 - page.records.forEach((record) => { 68 + page.forEach((record) => { 48 69 if (!queryClient.getQueryData(["post", record.uri])) { 49 70 queryClient.setQueryData(["post", record.uri], record); 50 71 } ··· 54 75 }, [postsData, queryClient]); 55 76 56 77 const posts = React.useMemo( 57 - () => postsData?.pages.flatMap((page) => page.records) ?? [], 78 + () => postsData?.pages.flatMap((page) => page) ?? [], 58 79 [postsData] 59 80 ); 60 81 82 + const [imgcdn] = useAtom(imgCDNAtom); 83 + 61 84 function getAvatarUrl(p: typeof profile) { 62 85 const link = p?.avatar?.ref?.["$link"]; 63 86 if (!link || !resolvedDid) return null; 64 - return `https://cdn.bsky.app/img/avatar/plain/${resolvedDid}/${link}@jpeg`; 87 + return `https://${imgcdn}/img/avatar/plain/${resolvedDid}/${link}@jpeg`; 65 88 } 66 89 function getBannerUrl(p: typeof profile) { 67 90 const link = p?.banner?.ref?.["$link"]; 68 91 if (!link || !resolvedDid) return null; 69 - return `https://cdn.bsky.app/img/banner/plain/${resolvedDid}/${link}@jpeg`; 92 + return `https://${imgcdn}/img/banner/plain/${resolvedDid}/${link}@jpeg`; 70 93 } 71 94 72 95 const displayName = ··· 96 119 97 120 return ( 98 121 <> 99 - <div className="flex gap-2 px-4 py-2 h-[52px] sticky top-0 bg-white dark:bg-gray-950 z-10 border-b border-gray-200 dark:border-gray-700"> 122 + <Header 123 + title={`Profile`} 124 + backButtonCallback={() => { 125 + if (window.history.length > 1) { 126 + window.history.back(); 127 + } else { 128 + window.location.assign("/"); 129 + } 130 + }} 131 + /> 132 + {/* <div className="flex gap-2 px-4 py-2 h-[52px] sticky top-0 bg-white dark:bg-gray-950 z-10 border-b border-gray-200 dark:border-gray-700"> 100 133 <Link 101 134 to=".." 102 135 className="px-3 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-900 font-bold text-lg" 103 136 onClick={(e) => { 104 137 e.preventDefault(); 105 - window.history.length > 1 106 - ? window.history.back() 107 - : window.location.assign("/"); 138 + if (window.history.length > 1) { 139 + window.history.back() 140 + } else { 141 + window.location.assign("/"); 142 + } 108 143 }} 109 144 aria-label="Go back" 110 145 > 111 146 โ† 112 147 </Link> 113 148 <span className="text-xl font-bold ml-2">Profile</span> 114 - </div> 149 + </div> */} 115 150 116 151 {/* Profile Header */} 117 152 <div className="w-full max-w-2xl mx-auto overflow-hidden relative bg-gray-100 dark:bg-gray-900"> ··· 141 176 also delay the backfill to be on demand because it would be pretty intense 142 177 also save it persistently 143 178 */} 144 - {true ? ( 145 - <> 146 - <button className="rounded-full dark:bg-gray-600 bg-gray-300 px-3 py-2 text-[14px]"> 147 - Follow 148 - </button> 149 - <button className="rounded-full dark:bg-gray-600 bg-gray-300 px-3 py-2 text-[14px]"> 150 - Unfollow 151 - </button> 152 - </> 153 - ) : ( 154 - <button className="rounded-full dark:bg-gray-600 bg-gray-300 px-3 py-2 text-[14px]"> 155 - Edit Profile 156 - </button> 157 - )} 179 + <FollowButton targetdidorhandle={did} /> 158 180 <button className="rounded-full dark:bg-gray-600 bg-gray-300 px-3 py-2 text-[14px]"> 159 181 ... {/* todo: icon */} 160 182 </button> ··· 163 185 {/* Info Card */} 164 186 <div className="mt-16 pb-2 px-4 text-gray-900 dark:text-gray-100"> 165 187 <div className="font-bold text-2xl">{displayName}</div> 166 - <div className="text-gray-500 dark:text-gray-400 text-base mb-3"> 188 + <div className="text-gray-500 dark:text-gray-400 text-base mb-3 flex flex-row gap-1"> 189 + <Mutual targetdidorhandle={did} /> 167 190 {handle} 168 191 </div> 169 192 {description && ( 170 193 <div className="text-base leading-relaxed text-gray-800 dark:text-gray-300 mb-5 whitespace-pre-wrap break-words text-[15px]"> 171 - {description} 194 + {/* {description} */} 195 + <RichTextRenderer key={did} description={description} /> 172 196 </div> 173 197 )} 174 198 </div> ··· 211 235 </> 212 236 ); 213 237 } 238 + 239 + export function FollowButton({ 240 + targetdidorhandle, 241 + }: { 242 + targetdidorhandle: string; 243 + }) { 244 + const { agent } = useAuth(); 245 + const { data: identity } = useQueryIdentity(targetdidorhandle); 246 + const queryClient = useQueryClient(); 247 + 248 + const followRecords = useGetFollowState({ 249 + target: identity?.did ?? targetdidorhandle, 250 + user: agent?.did, 251 + }); 252 + 253 + return ( 254 + <> 255 + {identity?.did !== agent?.did ? ( 256 + <> 257 + {!(followRecords?.length && followRecords?.length > 0) ? ( 258 + <button 259 + onClick={(e) => { 260 + e.stopPropagation(); 261 + toggleFollow({ 262 + agent: agent || undefined, 263 + targetDid: identity?.did, 264 + followRecords: followRecords, 265 + queryClient: queryClient, 266 + }); 267 + }} 268 + className="rounded-full h-10 bg-gray-300 dark:bg-gray-600 hover:bg-gray-400 dark:hover:bg-gray-500 transition-colors px-4 py-2 text-[14px]" 269 + > 270 + Follow 271 + </button> 272 + ) : ( 273 + <button 274 + onClick={(e) => { 275 + e.stopPropagation(); 276 + toggleFollow({ 277 + agent: agent || undefined, 278 + targetDid: identity?.did, 279 + followRecords: followRecords, 280 + queryClient: queryClient, 281 + }); 282 + }} 283 + className="rounded-full h-10 bg-gray-300 dark:bg-gray-600 hover:bg-gray-400 dark:hover:bg-gray-500 transition-colors px-4 py-2 text-[14px]" 284 + > 285 + Unfollow 286 + </button> 287 + )} 288 + </> 289 + ) : ( 290 + <button className="rounded-full h-10 bg-gray-300 dark:bg-gray-600 hover:bg-gray-400 dark:hover:bg-gray-500 transition-colors px-4 py-2 text-[14px]"> 291 + Edit Profile 292 + </button> 293 + )} 294 + </> 295 + ); 296 + } 297 + 298 + export function Mutual({ targetdidorhandle }: { targetdidorhandle: string }) { 299 + const { agent } = useAuth(); 300 + const { data: identity } = useQueryIdentity(targetdidorhandle); 301 + 302 + const theyFollowYouRes = useGetOneToOneState( 303 + agent?.did 304 + ? { 305 + target: agent?.did, 306 + user: identity?.did ?? targetdidorhandle, 307 + collection: "app.bsky.graph.follow", 308 + path: ".subject", 309 + } 310 + : undefined 311 + ); 312 + 313 + const youFollowThemRes = useGetFollowState({ 314 + target: identity?.did ?? targetdidorhandle, 315 + user: agent?.did, 316 + }); 317 + 318 + const theyFollowYou: boolean = 319 + !!theyFollowYouRes?.length && theyFollowYouRes.length > 0; 320 + const youFollowThem: boolean = 321 + !!youFollowThemRes?.length && youFollowThemRes.length > 0; 322 + 323 + return ( 324 + <> 325 + {/* if not self */} 326 + {identity?.did !== agent?.did ? ( 327 + <> 328 + {theyFollowYou ? ( 329 + <> 330 + {youFollowThem ? ( 331 + <div className=" text-sm px-1.5 py-0.5 text-gray-500 bg-gray-200 dark:text-gray-400 dark:bg-gray-800 rounded-lg flex flex-row items-center justify-center"> 332 + mutuals 333 + </div> 334 + ) : ( 335 + <div className=" text-sm px-1.5 py-0.5 text-gray-500 bg-gray-200 dark:text-gray-400 dark:bg-gray-800 rounded-lg flex flex-row items-center justify-center"> 336 + follows you 337 + </div> 338 + )} 339 + </> 340 + ) : ( 341 + <></> 342 + )} 343 + </> 344 + ) : ( 345 + // lmao can someone be mutuals with themselves ?? 346 + <></> 347 + )} 348 + </> 349 + ); 350 + } 351 + 352 + export function RichTextRenderer({ description }: { description: string }) { 353 + const [richDescription, setRichDescription] = useState<string | ReactNode[]>( 354 + description 355 + ); 356 + const { agent } = useAuth(); 357 + const navigate = useNavigate(); 358 + 359 + useEffect(() => { 360 + let mounted = true; 361 + 362 + // setRichDescription(description); 363 + 364 + async function processRichText() { 365 + try { 366 + if (!agent?.did) return; 367 + const rt = new RichText({ text: description }); 368 + await rt.detectFacets(agent); 369 + 370 + if (!mounted) return; 371 + 372 + if (rt.facets) { 373 + setRichDescription( 374 + renderTextWithFacets({ text: rt.text, facets: rt.facets, navigate }) 375 + ); 376 + } else { 377 + setRichDescription(rt.text); 378 + } 379 + } catch (error) { 380 + console.error("Failed to detect facets:", error); 381 + if (mounted) { 382 + setRichDescription(description); 383 + } 384 + } 385 + } 386 + 387 + processRichText(); 388 + 389 + return () => { 390 + mounted = false; 391 + }; 392 + }, [description, agent, navigate]); 393 + 394 + return <>{richDescription}</>; 395 + }
+165
src/routes/profile.$did/post.$rkey.image.$i.tsx
··· 1 + import { 2 + createFileRoute, 3 + useNavigate, 4 + type UseNavigateResult, 5 + } from "@tanstack/react-router"; 6 + import { useEffect, useState } from "react"; 7 + import { createPortal } from "react-dom"; 8 + 9 + import { ProfilePostComponent } from "./post.$rkey"; 10 + 11 + export const Route = createFileRoute("/profile/$did/post/$rkey/image/$i")({ 12 + component: Lightbox, 13 + }); 14 + 15 + export type LightboxProps = { 16 + images: { src: string; alt?: string }[]; 17 + }; 18 + 19 + function nextprev({ 20 + index, 21 + images, 22 + navigate, 23 + did, 24 + rkey, 25 + prev, 26 + }: { 27 + index?: number; 28 + images?: LightboxProps["images"]; 29 + navigate: UseNavigateResult<string>; 30 + did: string; 31 + rkey: string; 32 + prev?: boolean; 33 + }) { 34 + const len = images?.length ?? 0; 35 + if (len === 0) return; 36 + 37 + const nextIndex = ((index ?? 0) + (prev ? -1 : 1) + len) % len; 38 + 39 + navigate({ 40 + to: "/profile/$did/post/$rkey/image/$i", 41 + params: { 42 + did, 43 + rkey, 44 + i: nextIndex.toString(), 45 + }, 46 + replace: true, 47 + }); 48 + } 49 + 50 + export function Lightbox() { 51 + console.log("hey the $i route is loaded w!!!"); 52 + const { did, rkey, i } = Route.useParams(); 53 + const [images, setImages] = useState<LightboxProps["images"] | undefined>( 54 + undefined 55 + ); 56 + const index = Number(i); 57 + const navigate = useNavigate(); 58 + const post = true; 59 + const image = images?.[index] ?? undefined; 60 + 61 + function lightboxCallback(d: LightboxProps) { 62 + console.log("callback actually called!"); 63 + setImages(d.images); 64 + } 65 + 66 + useEffect(() => { 67 + function handleKey(e: KeyboardEvent) { 68 + if (e.key === "Escape") window.history.back(); 69 + if (e.key === "ArrowRight") 70 + nextprev({ index, images, navigate, did, rkey }); 71 + //onNavigate((index + 1) % images.length); 72 + if (e.key === "ArrowLeft") 73 + nextprev({ index, images, navigate, did, rkey, prev: true }); 74 + //onNavigate((index - 1 + images.length) % images.length); 75 + } 76 + window.addEventListener("keydown", handleKey); 77 + return () => window.removeEventListener("keydown", handleKey); 78 + }, [index, navigate, did, rkey, images]); 79 + 80 + return createPortal( 81 + <> 82 + {post && ( 83 + <div 84 + onClick={(e) => { 85 + e.stopPropagation(); 86 + e.nativeEvent.stopImmediatePropagation(); 87 + }} 88 + className="lightbox-sidebar hidden lg:flex overscroll-none disablegutter border-l dark:border-gray-800 was7 border-gray-300 fixed z-50 top-0 right-0 flex-col max-w-[350px] min-w-[350px] max-h-screen overflow-y-scroll dark:bg-gray-950 bg-white" 89 + > 90 + <ProfilePostComponent 91 + key={`/profile/${did}/post/${rkey}`} 92 + did={did} 93 + rkey={rkey} 94 + nopics 95 + lightboxCallback={lightboxCallback} 96 + /> 97 + </div> 98 + )} 99 + <div 100 + className="lightbox fixed inset-0 z-50 flex items-center justify-center bg-black/80 w-screen lg:w-[calc(100vw-350px)] lg:max-w-[calc(100vw-350px)]" 101 + onClick={(e) => { 102 + e.stopPropagation(); 103 + window.history.back(); 104 + }} 105 + > 106 + <img 107 + src={image?.src} 108 + alt={image?.alt} 109 + className="max-h-[90%] max-w-[90%] object-contain rounded-lg shadow-lg" 110 + onClick={(e) => e.stopPropagation()} 111 + /> 112 + 113 + {(images?.length ?? 0) > 1 && ( 114 + <> 115 + <button 116 + onClick={(e) => { 117 + e.stopPropagation(); 118 + nextprev({ index, images, navigate, did, rkey, prev: true }); 119 + }} 120 + className="absolute left-4 top-1/2 -translate-y-1/2 text-white text-4xl h-8 w-8 rounded-full bg-gray-900 flex items-center justify-center" 121 + > 122 + <svg 123 + xmlns="http://www.w3.org/2000/svg" 124 + width={28} 125 + height={28} 126 + viewBox="0 0 24 24" 127 + > 128 + <g fill="none" fillRule="evenodd"> 129 + <path d="M24 0v24H0V0zM12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.019-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z"></path> 130 + <path 131 + fill="currentColor" 132 + d="M8.293 12.707a1 1 0 0 1 0-1.414l5.657-5.657a1 1 0 1 1 1.414 1.414L10.414 12l4.95 4.95a1 1 0 0 1-1.414 1.414z" 133 + ></path> 134 + </g> 135 + </svg> 136 + </button> 137 + <button 138 + onClick={(e) => { 139 + e.stopPropagation(); 140 + nextprev({ index, images, navigate, did, rkey }); 141 + }} 142 + className="absolute right-4 top-1/2 -translate-y-1/2 text-white text-4xl h-8 w-8 rounded-full bg-gray-900 flex items-center justify-center" 143 + > 144 + <svg 145 + xmlns="http://www.w3.org/2000/svg" 146 + width={28} 147 + height={28} 148 + viewBox="0 0 24 24" 149 + > 150 + <g fill="none" fillRule="evenodd"> 151 + <path d="M24 0v24H0V0zM12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.019-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z"></path> 152 + <path 153 + fill="currentColor" 154 + d="M15.707 11.293a1 1 0 0 1 0 1.414l-5.657 5.657a1 1 0 1 1-1.414-1.414l4.95-4.95l-4.95-4.95a1 1 0 0 1 1.414-1.414z" 155 + ></path> 156 + </g> 157 + </svg> 158 + </button> 159 + </> 160 + )} 161 + </div> 162 + </>, 163 + document.body 164 + ); 165 + }
+241 -70
src/routes/profile.$did/post.$rkey.tsx
··· 1 - import { useQueryClient } from "@tanstack/react-query"; 2 - import { createFileRoute, Link } from "@tanstack/react-router"; 1 + import { AtUri } from "@atproto/api"; 2 + import { useInfiniteQuery, useQueryClient } from "@tanstack/react-query"; 3 + import { createFileRoute, Outlet } from "@tanstack/react-router"; 4 + import { useAtom } from "jotai"; 3 5 import React, { useLayoutEffect } from "react"; 4 - import ShrinkingBox from "~/components/shrinkpadding"; 6 + 7 + import { Header } from "~/components/Header"; 5 8 import { UniversalPostRendererATURILoader } from "~/components/UniversalPostRenderer"; 9 + import { constellationURLAtom, slingshotURLAtom } from "~/utils/atoms"; 6 10 //import { usePersistentStore } from '~/providers/PersistentStoreProvider'; 7 11 import { 12 + constructPostQuery, 13 + type linksAllResponse, 14 + type linksRecordsResponse, 15 + useQueryConstellation, 8 16 useQueryIdentity, 9 17 useQueryPost, 10 - useQueryConstellation, 11 - constructPostQuery, 12 - useQueryArbitrary, 18 + yknowIReallyHateThisButWhateverGuardedConstructConstellationInfiniteQueryLinks, 13 19 } from "~/utils/useQuery"; 20 + 21 + import type { LightboxProps } from "./post.$rkey.image.$i"; 14 22 15 23 //const HANDLE_DID_CACHE_TIMEOUT = 60 * 60 * 1000; // 1 hour 16 24 ··· 33 41 ); 34 42 } 35 43 36 - function ProfilePostComponent({ did, rkey }: { did: string; rkey: string }) { 44 + export function ProfilePostComponent({ 45 + did, 46 + rkey, 47 + nopics, 48 + lightboxCallback, 49 + }: { 50 + did: string; 51 + rkey: string; 52 + nopics?: boolean; 53 + lightboxCallback?: (d: LightboxProps) => void; 54 + }) { 37 55 //const { get, set } = usePersistentStore(); 38 56 const queryClient = useQueryClient(); 39 57 // const [resolvedDid, setResolvedDid] = React.useState<string | null>(null); ··· 180 198 () => 181 199 resolvedDid 182 200 ? `at://${decodeURIComponent(resolvedDid)}/app.bsky.feed.post/${rkey}` 183 - : "", 201 + : undefined, 184 202 [resolvedDid, rkey] 185 203 ); 186 204 187 205 const { data: mainPost } = useQueryPost(atUri); 188 206 189 - const { data: repliesData } = useQueryConstellation({ 190 - method: "/links", 207 + console.log("atUri",atUri) 208 + 209 + const opdid = React.useMemo( 210 + () => 211 + atUri 212 + ? new AtUri(atUri).host 213 + : undefined, 214 + [atUri] 215 + ); 216 + 217 + // @ts-expect-error i hate overloads 218 + const { data: links } = useQueryConstellation(atUri?{ 219 + method: "/links/all", 191 220 target: atUri, 192 - collection: "app.bsky.feed.post", 193 - path: ".reply.parent.uri", 221 + } : { 222 + method: "undefined", 223 + target: "" 224 + })as { data: linksAllResponse | undefined }; 225 + 226 + //const [likes, setLikes] = React.useState<number | null>(null); 227 + //const [reposts, setReposts] = React.useState<number | null>(null); 228 + const [replyCount, setReplyCount] = React.useState<number | null>(null); 229 + 230 + React.useEffect(() => { 231 + // /*mass comment*/ console.log(JSON.stringify(links, null, 2)); 232 + // setLikes( 233 + // links 234 + // ? links?.links?.["app.bsky.feed.like"]?.[".subject.uri"]?.records || 0 235 + // : null 236 + // ); 237 + // setReposts( 238 + // links 239 + // ? links?.links?.["app.bsky.feed.repost"]?.[".subject.uri"]?.records || 0 240 + // : null 241 + // ); 242 + setReplyCount( 243 + links 244 + ? links?.links?.["app.bsky.feed.post"]?.[".reply.parent.uri"] 245 + ?.records || 0 246 + : null 247 + ); 248 + }, [links]); 249 + 250 + const { data: opreplies } = useQueryConstellation( 251 + !!opdid && replyCount && replyCount >= 25 252 + ? { 253 + method: "/links", 254 + target: atUri, 255 + // @ts-expect-error overloading sucks so much 256 + collection: "app.bsky.feed.post", 257 + path: ".reply.parent.uri", 258 + //cursor?: string; 259 + dids: [opdid], 260 + } 261 + : { 262 + method: "undefined", 263 + target: "", 264 + } 265 + ) as { data: linksRecordsResponse | undefined }; 266 + 267 + const opReplyAturis = 268 + opreplies?.linking_records.map( 269 + (r) => `at://${r.did}/${r.collection}/${r.rkey}`, 270 + ) ?? []; 271 + 272 + 273 + // const { data: repliesData } = useQueryConstellation({ 274 + // method: "/links", 275 + // target: atUri, 276 + // collection: "app.bsky.feed.post", 277 + // path: ".reply.parent.uri", 278 + // }); 279 + // const replies = repliesData?.linking_records.slice(0, 50) ?? []; 280 + const [constellationurl] = useAtom(constellationURLAtom) 281 + 282 + const infinitequeryresults = useInfiniteQuery({ 283 + ...yknowIReallyHateThisButWhateverGuardedConstructConstellationInfiniteQueryLinks( 284 + { 285 + constellation: constellationurl, 286 + method: "/links", 287 + target: atUri, 288 + collection: "app.bsky.feed.post", 289 + path: ".reply.parent.uri", 290 + } 291 + ), 292 + enabled: !!atUri, 194 293 }); 195 - const replies = repliesData?.linking_records.slice(0, 50) ?? []; 294 + 295 + const { 296 + data: infiniteRepliesData, 297 + fetchNextPage, 298 + hasNextPage, 299 + isFetchingNextPage, 300 + } = infinitequeryresults; 301 + 302 + // // auto-fetch all pages 303 + // useEffect(() => { 304 + // if ( 305 + // infinitequeryresults.hasNextPage && 306 + // !infinitequeryresults.isFetchingNextPage 307 + // ) { 308 + // console.log("Fetching the next page..."); 309 + // infinitequeryresults.fetchNextPage(); 310 + // } 311 + // }, [infinitequeryresults]); 312 + 313 + // const replyAturis = repliesData 314 + // ? repliesData.pages.flatMap((page) => 315 + // page 316 + // ? page.linking_records.map((record) => { 317 + // const aturi = `at://${record.did}/${record.collection}/${record.rkey}`; 318 + // return aturi; 319 + // }) 320 + // : [] 321 + // ) 322 + // : []; 323 + 324 + const replyAturis = React.useMemo(() => { 325 + // Get all replies from the standard infinite query 326 + const allReplies = 327 + infiniteRepliesData?.pages.flatMap( 328 + (page) => 329 + page?.linking_records.map( 330 + (r) => `at://${r.did}/${r.collection}/${r.rkey}`, 331 + ) ?? [], 332 + ) ?? []; 333 + 334 + if (replyCount && (replyCount < 25)) { 335 + // If count is low, just use the standard list and find the oldest OP reply to move to the top 336 + const opdidFromUri = atUri ? new AtUri(atUri).host : undefined; 337 + const oldestOpsIndex = allReplies.findIndex( 338 + (aturi) => new AtUri(aturi).host === opdidFromUri, 339 + ); 340 + if (oldestOpsIndex > 0) { 341 + const [oldestOpsReply] = allReplies.splice(oldestOpsIndex, 1); 342 + allReplies.unshift(oldestOpsReply); 343 + } 344 + return allReplies; 345 + } else { 346 + // If count is high, prioritize OP replies from the special query 347 + // and filter them out from the main list to avoid duplication. 348 + const opReplySet = new Set(opReplyAturis); 349 + const otherReplies = allReplies.filter((uri) => !opReplySet.has(uri)); 350 + return [...opReplyAturis, ...otherReplies]; 351 + } 352 + }, [infiniteRepliesData, opReplyAturis, replyCount, atUri]); 353 + 354 + // Find oldest OP reply 355 + const oldestOpsIndex = replyAturis.findIndex( 356 + (aturi) => new AtUri(aturi).host === opdid 357 + ); 358 + 359 + // Reorder: move oldest OP reply to the front 360 + if (oldestOpsIndex > 0) { 361 + const [oldestOpsReply] = replyAturis.splice(oldestOpsIndex, 1); 362 + replyAturis.unshift(oldestOpsReply); 363 + } 196 364 197 365 const [parents, setParents] = React.useState<any[]>([]); 198 366 const [parentsLoading, setParentsLoading] = React.useState(false); 199 367 200 368 const mainPostRef = React.useRef<HTMLDivElement>(null); 201 - const userHasScrolled = React.useRef(false); 369 + const hasPerformedInitialLayout = React.useRef(false); 202 370 203 - const scrollAnchor = React.useRef<{ top: number } | null>(null); 371 + const [layoutReady, setLayoutReady] = React.useState(false); 204 372 373 + useLayoutEffect(() => { 374 + if (parents.length > 0 && !layoutReady && mainPostRef.current) { 375 + const mainPostElement = mainPostRef.current; 205 376 206 - React.useEffect(() => { 207 - const onScroll = () => { 377 + if (window.scrollY === 0 && !hasPerformedInitialLayout.current) { 378 + const elementTop = mainPostElement.getBoundingClientRect().top; 379 + const headerOffset = 70; 208 380 209 - if (window.scrollY > 50) { 210 - userHasScrolled.current = true; 381 + const targetScrollY = elementTop - headerOffset; 211 382 212 - window.removeEventListener("scroll", onScroll); 383 + window.scrollBy(0, targetScrollY); 384 + 385 + hasPerformedInitialLayout.current = true; 213 386 } 214 - }; 215 - 216 - if (!userHasScrolled.current) { 217 - window.addEventListener("scroll", onScroll, { passive: true }); 387 + 388 + // todo idk what to do with this 389 + // eslint-disable-next-line react-hooks/set-state-in-effect 390 + setLayoutReady(true); 218 391 } 219 - return () => window.removeEventListener("scroll", onScroll); 220 - }, []); 392 + }, [parents, layoutReady]); 393 + 221 394 222 - useLayoutEffect(() => { 223 - if (parentsLoading && mainPostRef.current && !userHasScrolled.current) { 224 - scrollAnchor.current = { 225 - top: mainPostRef.current.getBoundingClientRect().top, 226 - }; 395 + const [slingshoturl] = useAtom(slingshotURLAtom) 396 + 397 + React.useEffect(() => { 398 + if (parentsLoading) { 399 + setLayoutReady(false); 227 400 } 228 - }, [parentsLoading]); 229 401 230 - useLayoutEffect(() => { 231 - if ( 232 - scrollAnchor.current && 233 - mainPostRef.current && 234 - !userHasScrolled.current 235 - ) { 236 - const newTop = mainPostRef.current.getBoundingClientRect().top; 237 - const topDiff = newTop - scrollAnchor.current.top; 238 - if (topDiff > 0) { 239 - window.scrollBy(0, topDiff); 240 - } 241 - scrollAnchor.current = null; 402 + if (!mainPost?.value?.reply?.parent?.uri && !parentsLoading) { 403 + setLayoutReady(true); 404 + hasPerformedInitialLayout.current = true; 242 405 } 243 - }, [parents]); 406 + }, [parentsLoading, mainPost]); 244 407 245 408 React.useEffect(() => { 246 409 if (!mainPost?.value?.reply?.parent?.uri) { ··· 259 422 while (currentParentUri && safetyCounter < MAX_PARENTS) { 260 423 try { 261 424 const parentPost = await queryClient.fetchQuery( 262 - constructPostQuery(currentParentUri) 425 + constructPostQuery(currentParentUri, slingshoturl) 263 426 ); 264 427 if (!parentPost) break; 265 428 parentChain.push(parentPost); ··· 291 454 292 455 return ( 293 456 <> 294 - <div className="flex items-center gap-2 px-4 py-2 h-[52px] sticky top-0 bg-white dark:bg-gray-950 z-10 border-b border-gray-200 dark:border-gray-700"> 295 - <Link 296 - to=".." 297 - className="px-3 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-900 font-bold text-lg" 298 - onClick={(e) => { 299 - e.preventDefault(); 300 - window.history.length > 1 301 - ? window.history.back() 302 - : window.location.assign("/"); 303 - }} 304 - aria-label="Go back" 305 - > 306 - โ† 307 - </Link> 308 - <span className="text-xl font-bold ml-2">Post</span> 309 - </div> 457 + <Outlet /> 458 + <Header 459 + title={`Post`} 460 + backButtonCallback={() => { 461 + if (window.history.length > 1) { 462 + window.history.back(); 463 + } else { 464 + window.location.assign("/"); 465 + } 466 + }} 467 + /> 310 468 311 469 {parentsLoading && ( 312 470 <div className="text-center text-gray-500 dark:text-gray-400 flex flex-row"> ··· 321 479 )} 322 480 323 481 {/* we should use the reply lines here thats provided by UPR*/} 324 - <div style={{ maxWidth: 600, margin: "0px auto 0", padding: 0 }}> 482 + <div style={{ maxWidth: 600, padding: 0 }}> 325 483 {parents.map((parent, index) => ( 326 484 <UniversalPostRendererATURILoader 327 485 key={parent.uri} ··· 337 495 atUri={atUri} 338 496 detailed={true} 339 497 topReplyLine={parentsLoading || parents.length > 0} 498 + nopics={!!nopics} 499 + lightboxCallback={lightboxCallback} 340 500 /> 341 501 </div> 342 502 <div 343 503 style={{ 344 504 maxWidth: 600, 345 - margin: "0px auto 0", 505 + //margin: "0px auto 0", 346 506 padding: 0, 347 - minHeight: "100dvh", 507 + minHeight: "80dvh", 508 + paddingBottom: "20dvh", 348 509 }} 349 510 > 350 511 <div ··· 358 519 Replies 359 520 </div> 360 521 <div style={{ display: "flex", flexDirection: "column", gap: 0 }}> 361 - {replies.length > 0 && 362 - replies.map((reply) => { 363 - const replyAtUri = `at://${reply.did}/app.bsky.feed.post/${reply.rkey}`; 522 + {replyAturis.length > 0 && 523 + replyAturis.map((reply) => { 524 + //const replyAtUri = `at://${reply.did}/app.bsky.feed.post/${reply.rkey}`; 364 525 return ( 365 526 <UniversalPostRendererATURILoader 366 - key={replyAtUri} 367 - atUri={replyAtUri} 527 + key={reply} 528 + atUri={reply} 529 + maxReplies={4} 368 530 /> 369 531 ); 370 532 })} 533 + {hasNextPage && ( 534 + <button 535 + onClick={() => fetchNextPage()} 536 + disabled={isFetchingNextPage} 537 + className="w-[calc(100%-2rem)] mx-4 my-4 px-4 py-2 bg-gray-100 dark:bg-gray-800 text-gray-800 dark:text-gray-200 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-700 font-semibold disabled:opacity-50" 538 + > 539 + {isFetchingNextPage ? "Loading..." : "Load More"} 540 + </button> 541 + )} 371 542 </div> 372 543 </div> 373 544 </>
+50 -1
src/routes/search.tsx
··· 1 1 import { createFileRoute } from "@tanstack/react-router"; 2 2 3 + import { Header } from "~/components/Header"; 4 + import { Import } from "~/components/Import"; 5 + 3 6 export const Route = createFileRoute("/search")({ 4 7 component: Search, 5 8 }); 6 9 7 10 export function Search() { 8 - return <div className="p-6">Search page (coming soon)</div>; 11 + return ( 12 + <> 13 + <Header 14 + title="Explore" 15 + backButtonCallback={() => { 16 + if (window.history.length > 1) { 17 + window.history.back(); 18 + } else { 19 + window.location.assign("/"); 20 + } 21 + }} 22 + /> 23 + <div className=" flex flex-col items-center mt-4 mx-4 gap-4"> 24 + <Import /> 25 + <div className="flex flex-col"> 26 + <p className="text-gray-600 dark:text-gray-400"> 27 + Sorry we dont have search. But instead, you can load some of these 28 + types of content into Red Dwarf: 29 + </p> 30 + <ul className="list-disc list-inside mt-2 text-gray-600 dark:text-gray-400"> 31 + <li> 32 + Bluesky URLs from supported clients (like{" "} 33 + <code className="text-sm">bsky.app</code> or{" "} 34 + <code className="text-sm">deer.social</code>). 35 + </li> 36 + <li> 37 + AT-URIs (e.g.,{" "} 38 + <code className="text-sm">at://did:example/collection/item</code> 39 + ). 40 + </li> 41 + <li> 42 + Plain handles (like{" "} 43 + <code className="text-sm">@username.bsky.social</code>). 44 + </li> 45 + <li> 46 + Direct DIDs (Decentralized Identifiers, starting with{" "} 47 + <code className="text-sm">did:</code>). 48 + </li> 49 + </ul> 50 + <p className="mt-2 text-gray-600 dark:text-gray-400"> 51 + Simply paste one of these into the import field above and press 52 + Enter to load the content. 53 + </p> 54 + </div> 55 + </div> 56 + </> 57 + ); 9 58 }
+189 -1
src/routes/settings.tsx
··· 1 1 import { createFileRoute } from "@tanstack/react-router"; 2 + import { useAtom } from "jotai"; 3 + import { Slider } from "radix-ui"; 4 + 5 + import { Header } from "~/components/Header"; 6 + import Login from "~/components/Login"; 7 + import { 8 + aturiListServiceAtom, 9 + constellationURLAtom, 10 + defaultaturilistservice, 11 + defaultconstellationURL, 12 + defaulthue, 13 + defaultImgCDN, 14 + defaultslingshotURL, 15 + defaultVideoCDN, 16 + hueAtom, 17 + imgCDNAtom, 18 + slingshotURLAtom, 19 + videoCDNAtom, 20 + } from "~/utils/atoms"; 2 21 3 22 export const Route = createFileRoute("/settings")({ 4 23 component: Settings, 5 24 }); 6 25 7 26 export function Settings() { 8 - return <div className="p-6">Settings page (coming soon)</div>; 27 + return ( 28 + <> 29 + <Header 30 + title="Settings" 31 + backButtonCallback={() => { 32 + if (window.history.length > 1) { 33 + window.history.back(); 34 + } else { 35 + window.location.assign("/"); 36 + } 37 + }} 38 + /> 39 + <div className="lg:hidden"> 40 + <Login /> 41 + </div> 42 + <div className="h-4" /> 43 + <TextInputSetting 44 + atom={constellationURLAtom} 45 + title={"Constellation"} 46 + description={ 47 + "Customize the Constellation instance to be used by Red Dwarf" 48 + } 49 + init={defaultconstellationURL} 50 + /> 51 + <TextInputSetting 52 + atom={slingshotURLAtom} 53 + title={"Slingshot"} 54 + description={"Customize the Slingshot instance to be used by Red Dwarf"} 55 + init={defaultslingshotURL} 56 + /> 57 + <TextInputSetting 58 + atom={aturiListServiceAtom} 59 + title={"AtUriListService"} 60 + description={"Customize the AtUriListService instance to be used by Red Dwarf"} 61 + init={defaultaturilistservice} 62 + /> 63 + <TextInputSetting 64 + atom={imgCDNAtom} 65 + title={"Image CDN"} 66 + description={ 67 + "Customize the Constellation instance to be used by Red Dwarf" 68 + } 69 + init={defaultImgCDN} 70 + /> 71 + <TextInputSetting 72 + atom={videoCDNAtom} 73 + title={"Video CDN"} 74 + description={"Customize the Slingshot instance to be used by Red Dwarf"} 75 + init={defaultVideoCDN} 76 + /> 77 + 78 + <Hue /> 79 + <p className="text-gray-500 dark:text-gray-400 py-4 px-6 text-sm"> 80 + please restart/refresh the app if changes arent applying correctly 81 + </p> 82 + </> 83 + ); 9 84 } 85 + function Hue() { 86 + const [hue, setHue] = useAtom(hueAtom); 87 + return ( 88 + <div className="flex flex-col px-4 mt-4 "> 89 + <span className="z-10">Hue</span> 90 + <div className="flex flex-row items-center gap-4"> 91 + <SliderComponent 92 + atom={hueAtom} 93 + max={360} 94 + /> 95 + <button 96 + onClick={() => setHue(defaulthue ?? 28)} 97 + className="px-6 py-2 h-12 rounded-full bg-gray-100 dark:bg-gray-800 98 + text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-700 transition" 99 + > 100 + Reset 101 + </button> 102 + </div> 103 + </div> 104 + ); 105 + } 106 + 107 + export function TextInputSetting({ 108 + atom, 109 + title, 110 + description, 111 + init, 112 + }: { 113 + atom: typeof constellationURLAtom; 114 + title?: string; 115 + description?: string; 116 + init?: string; 117 + }) { 118 + const [value, setValue] = useAtom(atom); 119 + return ( 120 + <div className="flex flex-col gap-2 px-4 py-2"> 121 + {/* <div> 122 + {title && ( 123 + <h3 className="text-sm font-medium text-gray-900 dark:text-gray-100"> 124 + {title} 125 + </h3> 126 + )} 127 + {description && ( 128 + <p className="text-sm text-gray-500 dark:text-gray-400"> 129 + {description} 130 + </p> 131 + )} 132 + </div> */} 133 + 134 + <div className="flex flex-row gap-2 items-center"> 135 + <div className="m3input-field m3input-label m3input-border size-md flex-1"> 136 + <input 137 + type="text" 138 + placeholder=" " 139 + value={value} 140 + onChange={(e) => setValue(e.target.value)} 141 + /> 142 + <label>{title}</label> 143 + </div> 144 + {/* <input 145 + type="text" 146 + value={value} 147 + onChange={(e) => setValue(e.target.value)} 148 + className="flex-1 px-3 py-2 rounded-lg bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-700 149 + text-gray-900 dark:text-gray-100 placeholder:text-gray-500 dark:placeholder:text-gray-400 150 + focus:outline-none focus:ring-2 focus:ring-gray-400 dark:focus:ring-gray-600" 151 + placeholder="Enter value..." 152 + /> */} 153 + <button 154 + onClick={() => setValue(init ?? "")} 155 + className="px-6 py-2 h-12 rounded-full bg-gray-100 dark:bg-gray-800 156 + text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-700 transition" 157 + > 158 + Reset 159 + </button> 160 + </div> 161 + </div> 162 + ); 163 + } 164 + 165 + 166 + interface SliderProps { 167 + atom: typeof hueAtom; 168 + min?: number; 169 + max?: number; 170 + step?: number; 171 + } 172 + 173 + export const SliderComponent: React.FC<SliderProps> = ({ 174 + atom, 175 + min = 0, 176 + max = 100, 177 + step = 1, 178 + }) => { 179 + 180 + const [value, setValue] = useAtom(atom) 181 + 182 + return ( 183 + <Slider.Root 184 + className="relative flex items-center w-full h-4" 185 + value={[value]} 186 + min={min} 187 + max={max} 188 + step={step} 189 + onValueChange={(v: number[]) => setValue(v[0])} 190 + > 191 + <Slider.Track className="relative flex-grow h-4 bg-gray-300 dark:bg-gray-700 rounded-full"> 192 + <Slider.Range className="absolute h-full bg-gray-500 dark:bg-gray-400 rounded-l-full rounded-r-none" /> 193 + </Slider.Track> 194 + <Slider.Thumb className="shadow-[0_0_0_8px_var(--color-white)] dark:shadow-[0_0_0_8px_var(--color-gray-950)] block w-[3px] h-12 bg-gray-500 dark:bg-gray-400 rounded-md focus:outline-none" /> 195 + </Slider.Root> 196 + ); 197 + };
+180 -13
src/styles/app.css
··· 1 + @import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Roboto:ital,wght@0,100..900;1,100..900&family=Spectral+SC:wght@500&display=swap'); 1 2 @import "tailwindcss"; 2 3 3 4 /* @theme { ··· 14 15 --color-gray-950: oklch(0.129 0.050 222.000); 15 16 } */ 16 17 18 + :root { 19 + --safe-hue: var(--tw-gray-hue, 28) 20 + } 21 + 17 22 @theme { 18 - --color-gray-50: oklch(0.984 0.012 28); 19 - --color-gray-100: oklch(0.968 0.017 28); 20 - --color-gray-200: oklch(0.929 0.025 28); 21 - --color-gray-300: oklch(0.869 0.035 28); 22 - --color-gray-400: oklch(0.704 0.05 28); 23 - --color-gray-500: oklch(0.554 0.06 28); 24 - --color-gray-600: oklch(0.446 0.058 28); 25 - --color-gray-700: oklch(0.372 0.058 28); 26 - --color-gray-800: oklch(0.279 0.055 28); 27 - --color-gray-900: oklch(0.208 0.055 28); 28 - --color-gray-950: oklch(0.129 0.055 28); 23 + --color-gray-50: oklch(0.984 0.012 var(--safe-hue)); 24 + --color-gray-100: oklch(0.968 0.017 var(--safe-hue)); 25 + --color-gray-200: oklch(0.929 0.025 var(--safe-hue)); 26 + --color-gray-300: oklch(0.869 0.035 var(--safe-hue)); 27 + --color-gray-400: oklch(0.704 0.05 var(--safe-hue)); 28 + --color-gray-500: oklch(0.554 0.06 var(--safe-hue)); 29 + --color-gray-600: oklch(0.446 0.058 var(--safe-hue)); 30 + --color-gray-700: oklch(0.372 0.058 var(--safe-hue)); 31 + --color-gray-800: oklch(0.279 0.055 var(--safe-hue)); 32 + --color-gray-900: oklch(0.208 0.055 var(--safe-hue)); 33 + --color-gray-950: oklch(0.129 0.055 var(--safe-hue)); 29 34 } 30 35 31 36 @layer base { ··· 48 53 } 49 54 50 55 @media (width >= 64rem /* 1024px */) { 51 - html, 52 - body { 56 + html:not(:has(.disablegutter)), 57 + body:not(:has(.disablegutter)) { 53 58 scrollbar-gutter: stable both-edges !important; 54 59 } 60 + html:has(.disablegutter), 61 + body:has(.disablegutter) { 62 + scrollbar-width: none; 63 + overflow-y: hidden; 64 + } 55 65 } 66 + 67 + .lightbox:has(+.lightbox-sidebar){ 68 + opacity: 0; 69 + } 70 + 56 71 .scroll-thin { 57 72 scrollbar-width: thin; 58 73 /*scrollbar-gutter: stable both-edges !important;*/ ··· 61 76 .scroll-none { 62 77 scrollbar-width: none; 63 78 } 79 + 80 + .dangerousFediContent { 81 + & a[href]{ 82 + text-decoration: none; 83 + color: rgb(29, 122, 242); 84 + word-break: break-all; 85 + } 86 + } 87 + 88 + .font-inter { 89 + font-family: "Inter", sans-serif; 90 + } 91 + .font-roboto { 92 + font-family: "Roboto", sans-serif; 93 + } 94 + 95 + :root { 96 + --header-bg-light: color-mix(in srgb, var(--color-white) calc(var(--is-top) * 100%), var(--color-gray-50)); 97 + --header-bg-dark: color-mix(in srgb, var(--color-gray-950) calc(var(--is-top) * 100%), var(--color-gray-900)); 98 + } 99 + 100 + :root { 101 + --header-bg: var(--header-bg-light); 102 + } 103 + @media (prefers-color-scheme: dark) { 104 + :root { 105 + --header-bg: var(--header-bg-dark); 106 + } 107 + } 108 + 109 + :root { 110 + --shadow-opacity: calc(1 - var(--is-top)); 111 + --tw-shadow-header: 0 2px 8px hsl(0 0% 0% / calc(var(--shadow-opacity) * 0.15)); 112 + } 113 + 114 + 115 + /* m3 input */ 116 + :root { 117 + --m3input-radius: 6px; 118 + --m3input-border-width: .0625rem; 119 + --m3input-font-size: 16px; 120 + --m3input-transition: 150ms cubic-bezier(.2, .8, .2, 1); 121 + /* light theme */ 122 + --m3input-bg: var(--color-gray-50); 123 + --m3input-border-color: var(--color-gray-400); 124 + --m3input-label-color: var(--color-gray-500); 125 + --m3input-text-color: var(--color-gray-900); 126 + --m3input-focus-color: var(--color-gray-600); 127 + } 128 + 129 + @media (prefers-color-scheme: dark) { 130 + :root { 131 + --m3input-bg: var(--color-gray-950); 132 + --m3input-border-color: var(--color-gray-700); 133 + --m3input-label-color: var(--color-gray-400); 134 + --m3input-text-color: var(--color-gray-50); 135 + --m3input-focus-color: var(--color-gray-400); 136 + } 137 + } 138 + 139 + /* reset page *//* 140 + html, 141 + body { 142 + background: var(--m3input-bg); 143 + margin: 0; 144 + padding: 1rem; 145 + color: var(--m3input-text-color); 146 + font-family: system-ui, sans-serif; 147 + font-size: var(--m3input-font-size); 148 + }*/ 149 + 150 + /* base wrapper */ 151 + .m3input-field.m3input-label.m3input-border { 152 + position: relative; 153 + display: inline-block; 154 + width: 100%; 155 + /*max-width: 400px;*/ 156 + } 157 + 158 + /* size variants */ 159 + .m3input-field.size-sm { 160 + --m3input-h: 40px; 161 + } 162 + 163 + .m3input-field.size-md { 164 + --m3input-h: 48px; 165 + } 166 + 167 + .m3input-field.size-lg { 168 + --m3input-h: 56px; 169 + } 170 + 171 + .m3input-field.size-xl { 172 + --m3input-h: 64px; 173 + } 174 + 175 + .m3input-field.m3input-label.m3input-border:not(.size-sm):not(.size-md):not(.size-lg):not(.size-xl) { 176 + --m3input-h: 48px; 177 + } 178 + 179 + /* outlined input */ 180 + .m3input-field.m3input-label.m3input-border input { 181 + width: 100%; 182 + height: var(--m3input-h); 183 + border: var(--m3input-border-width) solid var(--m3input-border-color); 184 + border-radius: var(--m3input-radius); 185 + background: var(--m3input-bg); 186 + color: var(--m3input-text-color); 187 + font-size: var(--m3input-font-size); 188 + padding: 0 12px; 189 + box-sizing: border-box; 190 + outline: none; 191 + transition: border-color var(--m3input-transition), box-shadow var(--m3input-transition); 192 + } 193 + 194 + /* focus ring */ 195 + .m3input-field.m3input-label.m3input-border input:focus { 196 + border-color: var(--m3input-focus-color); 197 + /*box-shadow: 0 0 0 2px color-mix(in srgb, var(--focus-color) 20%, transparent);*/ 198 + } 199 + 200 + /* label */ 201 + .m3input-field.m3input-label.m3input-border label { 202 + position: absolute; 203 + left: 12px; 204 + top: 50%; 205 + transform: translateY(-50%); 206 + background: var(--m3input-bg); 207 + padding: 0 .25em; 208 + color: var(--m3input-label-color); 209 + pointer-events: none; 210 + transition: all var(--m3input-transition); 211 + } 212 + 213 + /* float on focus or when filled */ 214 + .m3input-field.m3input-label.m3input-border input:focus+label, 215 + .m3input-field.m3input-label.m3input-border input:not(:placeholder-shown)+label { 216 + top: 0; 217 + transform: translateY(-50%) scale(.78); 218 + left: 0; 219 + color: var(--m3input-focus-color); 220 + } 221 + 222 + /* placeholder trick */ 223 + .m3input-field.m3input-label.m3input-border input::placeholder { 224 + color: transparent; 225 + } 226 + 227 + /* radix i love you but like cmon man */ 228 + body[data-scroll-locked]{ 229 + margin-left: var(--removed-body-scroll-bar-size) !important; 230 + }
+64 -6
src/utils/atoms.ts
··· 1 1 import type Agent from "@atproto/api"; 2 - import { atom, createStore } from "jotai"; 3 - import { atomWithStorage } from 'jotai/utils'; 2 + import { atom, createStore, useAtomValue } from "jotai"; 3 + import { atomWithStorage } from "jotai/utils"; 4 + import { useEffect } from "react"; 4 5 5 6 export const store = createStore(); 6 7 7 8 export const selectedFeedUriAtom = atomWithStorage<string | null>( 8 - 'selectedFeedUri', 9 + "selectedFeedUri", 9 10 null 10 11 ); 11 12 12 13 //export const feedScrollPositionsAtom = atom<Record<string, number>>({}); 13 14 14 15 export const feedScrollPositionsAtom = atomWithStorage<Record<string, number>>( 15 - 'feedscrollpositions', 16 + "feedscrollpositions", 16 17 {} 17 18 ); 18 19 19 20 export const likedPostsAtom = atomWithStorage<Record<string, string>>( 20 - 'likedPosts', 21 + "likedPosts", 21 22 {} 22 23 ); 23 24 24 - export const agentAtom = atom<Agent|null>(null); 25 + export const defaultconstellationURL = "constellation.microcosm.blue"; 26 + export const constellationURLAtom = atomWithStorage<string>( 27 + "constellationURL", 28 + defaultconstellationURL 29 + ); 30 + export const defaultslingshotURL = "slingshot.microcosm.blue"; 31 + export const slingshotURLAtom = atomWithStorage<string>( 32 + "slingshotURL", 33 + defaultslingshotURL 34 + ); 35 + export const defaultaturilistservice = "aturilistservice.reddwarf.app"; 36 + export const aturiListServiceAtom = atomWithStorage<string>( 37 + "aturilistservice", 38 + defaultaturilistservice 39 + ); 40 + export const defaultImgCDN = "cdn.bsky.app"; 41 + export const imgCDNAtom = atomWithStorage<string>("imgcdnurl", defaultImgCDN); 42 + export const defaultVideoCDN = "video.bsky.app"; 43 + export const videoCDNAtom = atomWithStorage<string>( 44 + "videocdnurl", 45 + defaultVideoCDN 46 + ); 47 + 48 + export const defaulthue = 28; 49 + export const hueAtom = atomWithStorage<number>("hue", defaulthue); 50 + 51 + export const isAtTopAtom = atom<boolean>(true); 52 + 53 + type ComposerState = 54 + | { kind: "closed" } 55 + | { kind: "root" } 56 + | { kind: "reply"; parent: string } 57 + | { kind: "quote"; subject: string }; 58 + export const composerAtom = atom<ComposerState>({ kind: "closed" }); 59 + 60 + export const agentAtom = atom<Agent | null>(null); 25 61 export const authedAtom = atom<boolean>(false); 62 + 63 + export function useAtomCssVar(atom: typeof hueAtom, cssVar: string) { 64 + const value = useAtomValue(atom); 65 + 66 + useEffect(() => { 67 + document.documentElement.style.setProperty(cssVar, value.toString()); 68 + }, [value, cssVar]); 69 + 70 + useEffect(() => { 71 + document.documentElement.style.setProperty(cssVar, value.toString()); 72 + }, []); 73 + } 74 + 75 + hueAtom.onMount = (setAtom) => { 76 + const stored = localStorage.getItem("hue"); 77 + if (stored != null) setAtom(Number(stored)); 78 + }; 79 + // export function initAtomToCssVar(atom: typeof hueAtom, cssVar: string) { 80 + // const initial = store.get(atom); 81 + // console.log("atom get ", initial); 82 + // document.documentElement.style.setProperty(cssVar, initial.toString()); 83 + // }
+163
src/utils/followState.ts
··· 1 + import { type Agent,AtUri } from "@atproto/api"; 2 + import { TID } from "@atproto/common-web"; 3 + import type { QueryClient } from "@tanstack/react-query"; 4 + 5 + import { type linksRecordsResponse,useQueryConstellation } from "./useQuery"; 6 + 7 + export function useGetFollowState({ 8 + target, 9 + user, 10 + }: { 11 + target: string; 12 + user?: string; 13 + }): string[] | undefined { 14 + const { data: followData } = useQueryConstellation( 15 + user 16 + ? { 17 + method: "/links", 18 + target: target, 19 + // @ts-expect-error overloading sucks so much 20 + collection: "app.bsky.graph.follow", 21 + path: ".subject", 22 + dids: [user], 23 + } 24 + : { method: "undefined", target: "whatever" } 25 + // overloading sucks so much 26 + ) as { data: linksRecordsResponse | undefined }; 27 + const follows = followData?.linking_records.slice(0, 50) ?? []; 28 + 29 + if (follows.length > 0) { 30 + return follows.map((linksRecord) => { 31 + return `at://${linksRecord.did}/${linksRecord.collection}/${linksRecord.rkey}`; 32 + }); 33 + } 34 + 35 + return undefined; 36 + } 37 + 38 + export function toggleFollow({ 39 + agent, 40 + targetDid, 41 + followRecords, 42 + queryClient, 43 + }: { 44 + agent?: Agent; 45 + targetDid?: string; 46 + followRecords: undefined | string[]; 47 + queryClient: QueryClient; 48 + }) { 49 + if (!agent?.did || !targetDid) return; 50 + 51 + const queryKey = [ 52 + "constellation", 53 + "/links", 54 + targetDid, 55 + "app.bsky.graph.follow", 56 + ".subject", 57 + undefined, 58 + [agent.did], 59 + ] as const; 60 + 61 + const updateCache = ( 62 + updater: ( 63 + oldData: linksRecordsResponse | undefined 64 + ) => linksRecordsResponse | undefined 65 + ) => { 66 + queryClient.setQueryData( 67 + queryKey, 68 + (oldData: linksRecordsResponse | undefined) => updater(oldData) 69 + ); 70 + }; 71 + 72 + if (typeof followRecords === "undefined") { 73 + const newRecord = { 74 + repo: agent.did, 75 + collection: "app.bsky.graph.follow", 76 + rkey: TID.next().toString(), 77 + record: { 78 + $type: "app.bsky.graph.follow", 79 + subject: targetDid, 80 + createdAt: new Date().toISOString(), 81 + }, 82 + }; 83 + 84 + updateCache((old) => { 85 + const newLinkingRecords = [newRecord, ...(old?.linking_records ?? [])]; 86 + return { 87 + ...old, 88 + linking_records: newLinkingRecords, 89 + } as linksRecordsResponse; 90 + }); 91 + 92 + agent.com.atproto.repo.createRecord(newRecord).catch((err) => { 93 + console.error("Follow failed, reverting cache:", err); 94 + // rollback cache 95 + updateCache((old) => { 96 + return { 97 + ...old, 98 + linking_records: 99 + old?.linking_records.filter((r) => r.rkey !== newRecord.rkey) ?? [], 100 + } as linksRecordsResponse; 101 + }); 102 + }); 103 + 104 + return; 105 + } 106 + 107 + followRecords.forEach((followRecord) => { 108 + const aturi = new AtUri(followRecord); 109 + agent.com.atproto.repo 110 + .deleteRecord({ 111 + repo: agent.did!, 112 + collection: "app.bsky.graph.follow", 113 + rkey: aturi.rkey, 114 + }) 115 + .catch(console.error); 116 + }); 117 + 118 + updateCache((old) => { 119 + if (!old?.linking_records) return old; 120 + return { 121 + ...old, 122 + linking_records: old.linking_records.filter( 123 + (rec) => 124 + !followRecords.includes( 125 + `at://${rec.did}/${rec.collection}/${rec.rkey}` 126 + ) 127 + ), 128 + }; 129 + }); 130 + } 131 + 132 + 133 + 134 + export function useGetOneToOneState(params?: { 135 + target: string; 136 + user: string; 137 + collection: string; 138 + path: string; 139 + }): string[] | undefined { 140 + const { data: arbitrarydata } = useQueryConstellation( 141 + params && params.user 142 + ? { 143 + method: "/links", 144 + target: params.target, 145 + // @ts-expect-error overloading sucks so much 146 + collection: params.collection, 147 + path: params.path, 148 + dids: [params.user], 149 + } 150 + : { method: "undefined", target: "whatever" } 151 + // overloading sucks so much 152 + ) as { data: linksRecordsResponse | undefined }; 153 + if (!params || !params.user) return undefined; 154 + const data = arbitrarydata?.linking_records.slice(0, 50) ?? []; 155 + 156 + if (data.length > 0) { 157 + return data.map((linksRecord) => { 158 + return `at://${linksRecord.did}/${linksRecord.collection}/${linksRecord.rkey}`; 159 + }); 160 + } 161 + 162 + return undefined; 163 + }
+4 -6
src/utils/oauthClient.ts
··· 1 - // src/helpers/oauthClient.ts 2 1 import { BrowserOAuthClient, type ClientMetadata } from '@atproto/oauth-client-browser'; 3 2 4 - // This is your app's PDS for resolving handles if not provided. 5 - // You might need to host your own or use a public one. 3 + // i tried making this https://pds-nd.whey.party but cors is annoying as fuck 6 4 const handleResolverPDS = 'https://bsky.social'; 7 5 8 - // This assumes your client-metadata.json is in the /public folder 9 - // and will be served at the root of your domain. 10 - import clientMetadata from '../../public/client-metadata.json' assert { type: 'json' }; 6 + // eslint-disable-next-line @typescript-eslint/ban-ts-comment 7 + // @ts-ignore this should be fine ? the vite plugin should generate this before errors 8 + import clientMetadata from '../../public/client-metadata.json' with { type: 'json' }; 11 9 12 10 export const oauthClient = new BrowserOAuthClient({ 13 11 // The type assertion is needed because the static import isn't strictly typed
+70 -71
src/utils/useHydrated.ts
··· 1 - import { useState, useEffect, useMemo } from "react"; 2 1 import { 2 + type $Typed, 3 + AppBskyActorDefs, 3 4 AppBskyEmbedExternal, 4 5 AppBskyEmbedImages, 5 6 AppBskyEmbedRecord, 6 7 AppBskyEmbedRecordWithMedia, 7 8 AppBskyEmbedVideo, 8 - AppBskyActorDefs, 9 9 AppBskyFeedPost, 10 10 AtUri, 11 - type $Typed, 12 11 } from "@atproto/api"; 13 - import * as ATPAPI from "@atproto/api" 12 + import { useAtom } from "jotai"; 13 + import { useMemo } from "react"; 14 14 15 - import { useQueryPost, useQueryProfile, useQueryIdentity } from "./useQuery"; 15 + import { imgCDNAtom, videoCDNAtom } from "./atoms"; 16 + import { useQueryIdentity, useQueryPost, useQueryProfile } from "./useQuery"; 16 17 17 - type QueryResultData<T extends (...args: any) => any> = ReturnType<T> extends 18 - | { data: infer D } 19 - | undefined 20 - ? D 21 - : never; 18 + type QueryResultData<T extends (...args: any) => any> = 19 + ReturnType<T> extends { data: infer D } | undefined ? D : never; 22 20 23 21 function asTyped<T extends { $type: string }>(obj: T): $Typed<T> { 24 22 return obj as $Typed<T>; ··· 27 25 export function hydrateEmbedImages( 28 26 embed: AppBskyEmbedImages.Main, 29 27 did: string, 28 + cdn: string 30 29 ): $Typed<AppBskyEmbedImages.View> { 31 30 return asTyped({ 32 31 $type: "app.bsky.embed.images#view" as const, ··· 35 34 const link = img.image.ref?.["$link"]; 36 35 if (!link) return null; 37 36 return { 38 - thumb: `https://cdn.bsky.app/img/feed_thumbnail/plain/${did}/${link}@jpeg`, 39 - fullsize: `https://cdn.bsky.app/img/feed_fullsize/plain/${did}/${link}@jpeg`, 37 + thumb: `https://${cdn}/img/feed_thumbnail/plain/${did}/${link}@jpeg`, 38 + fullsize: `https://${cdn}/img/feed_fullsize/plain/${did}/${link}@jpeg`, 40 39 alt: img.alt || "", 41 40 aspectRatio: img.aspectRatio, 42 41 }; ··· 48 47 export function hydrateEmbedExternal( 49 48 embed: AppBskyEmbedExternal.Main, 50 49 did: string, 50 + cdn: string 51 51 ): $Typed<AppBskyEmbedExternal.View> { 52 52 return asTyped({ 53 53 $type: "app.bsky.embed.external#view" as const, ··· 56 56 title: embed.external.title, 57 57 description: embed.external.description, 58 58 thumb: embed.external.thumb?.ref?.$link 59 - ? `https://cdn.bsky.app/img/feed_thumbnail/plain/${did}/${embed.external.thumb.ref.$link}@jpeg` 59 + ? `https://${cdn}/img/feed_thumbnail/plain/${did}/${embed.external.thumb.ref.$link}@jpeg` 60 60 : undefined, 61 61 }, 62 62 }); ··· 65 65 export function hydrateEmbedVideo( 66 66 embed: AppBskyEmbedVideo.Main, 67 67 did: string, 68 + videocdn: string 68 69 ): $Typed<AppBskyEmbedVideo.View> { 69 70 const videoLink = embed.video.ref.$link; 70 71 return asTyped({ 71 72 $type: "app.bsky.embed.video#view" as const, 72 - playlist: `https://video.bsky.app/watch/${did}/${videoLink}/playlist.m3u8`, 73 - thumbnail: `https://video.bsky.app/watch/${did}/${videoLink}/thumbnail.jpg`, 73 + playlist: `https://${videocdn}/watch/${did}/${videoLink}/playlist.m3u8`, 74 + thumbnail: `https://${videocdn}/watch/${did}/${videoLink}/thumbnail.jpg`, 74 75 aspectRatio: embed.aspectRatio, 75 76 cid: videoLink, 76 77 }); ··· 81 82 quotedPost: QueryResultData<typeof useQueryPost>, 82 83 quotedProfile: QueryResultData<typeof useQueryProfile>, 83 84 quotedIdentity: QueryResultData<typeof useQueryIdentity>, 85 + cdn: string 84 86 ): $Typed<AppBskyEmbedRecord.View> | undefined { 85 87 if (!quotedPost || !quotedProfile || !quotedIdentity) { 86 88 return undefined; ··· 92 94 handle: quotedIdentity.handle, 93 95 displayName: quotedProfile.value.displayName ?? quotedIdentity.handle, 94 96 avatar: quotedProfile.value.avatar?.ref?.$link 95 - ? `https://cdn.bsky.app/img/avatar/plain/${quotedIdentity.did}/${quotedProfile.value.avatar.ref.$link}@jpeg` 97 + ? `https://${cdn}/img/avatar/plain/${quotedIdentity.did}/${quotedProfile.value.avatar.ref.$link}@jpeg` 96 98 : undefined, 97 99 viewer: {}, 98 100 labels: [], ··· 123 125 quotedPost: QueryResultData<typeof useQueryPost>, 124 126 quotedProfile: QueryResultData<typeof useQueryProfile>, 125 127 quotedIdentity: QueryResultData<typeof useQueryIdentity>, 128 + cdn: string 126 129 ): $Typed<AppBskyEmbedRecordWithMedia.View> | undefined { 127 130 const hydratedRecord = hydrateEmbedRecord( 128 131 embed.record, 129 132 quotedPost, 130 133 quotedProfile, 131 134 quotedIdentity, 135 + cdn 132 136 ); 133 137 134 138 if (!hydratedRecord) return undefined; ··· 149 153 150 154 export function useHydratedEmbed( 151 155 embed: AppBskyFeedPost.Record["embed"], 152 - postAuthorDid: string | undefined, 156 + postAuthorDid: string | undefined 153 157 ) { 154 158 const recordInfo = useMemo(() => { 155 - if ( 156 - AppBskyEmbedRecordWithMedia.isMain(embed) 157 - ) { 159 + if (AppBskyEmbedRecordWithMedia.isMain(embed)) { 158 160 const recordUri = embed.record.record.uri; 159 161 const quotedAuthorDid = new AtUri(recordUri).hostname; 160 162 return { recordUri, quotedAuthorDid, isRecordType: true }; 161 - } else 162 - if ( 163 - AppBskyEmbedRecord.isMain(embed) 164 - ) { 163 + } else if (AppBskyEmbedRecord.isMain(embed)) { 165 164 const recordUri = embed.record.uri; 166 165 const quotedAuthorDid = new AtUri(recordUri).hostname; 167 166 return { recordUri, quotedAuthorDid, isRecordType: true }; ··· 172 171 isRecordType: false, 173 172 }; 174 173 }, [embed]); 175 - const { isRecordType, recordUri, quotedAuthorDid } = recordInfo; 176 174 175 + const { isRecordType, recordUri, quotedAuthorDid } = recordInfo; 177 176 178 177 const usequerypostresults = useQueryPost(recordUri); 179 - // const { 180 - // data: quotedPost, 181 - // isLoading: isLoadingPost, 182 - // error: postError, 183 - // } = usequerypostresults 184 178 185 - const profileUri = quotedAuthorDid ? `at://${quotedAuthorDid}/app.bsky.actor.profile/self` : undefined; 179 + const profileUri = quotedAuthorDid 180 + ? `at://${quotedAuthorDid}/app.bsky.actor.profile/self` 181 + : undefined; 186 182 187 183 const { 188 184 data: quotedProfile, ··· 190 186 error: profileError, 191 187 } = useQueryProfile(profileUri); 192 188 189 + const [imgcdn] = useAtom(imgCDNAtom); 190 + const [videocdn] = useAtom(videoCDNAtom); 191 + 193 192 const queryidentityresult = useQueryIdentity(quotedAuthorDid); 194 - // const { 195 - // data: quotedIdentity, 196 - // isLoading: isLoadingIdentity, 197 - // error: identityError, 198 - // } = queryidentityresult 199 193 200 - const [hydratedEmbed, setHydratedEmbed] = useState< 201 - HydratedEmbedView | undefined 202 - >(undefined); 194 + const hydratedEmbed: HydratedEmbedView | undefined = (() => { 195 + if (!embed || !postAuthorDid) return undefined; 203 196 204 - useEffect(() => { 205 - if (!embed || !postAuthorDid) { 206 - setHydratedEmbed(undefined); 207 - return; 208 - } 209 - 210 - if (isRecordType && (!usequerypostresults?.data || !quotedProfile || !queryidentityresult?.data)) { 211 - setHydratedEmbed(undefined); 212 - return; 197 + if ( 198 + isRecordType && 199 + (!usequerypostresults?.data || 200 + !quotedProfile || 201 + !queryidentityresult?.data) 202 + ) { 203 + return undefined; 213 204 } 214 205 215 206 try { 216 - let result: HydratedEmbedView | undefined; 217 - 218 207 if (AppBskyEmbedImages.isMain(embed)) { 219 - result = hydrateEmbedImages(embed, postAuthorDid); 208 + return hydrateEmbedImages(embed, postAuthorDid, imgcdn); 220 209 } else if (AppBskyEmbedExternal.isMain(embed)) { 221 - result = hydrateEmbedExternal(embed, postAuthorDid); 210 + return hydrateEmbedExternal(embed, postAuthorDid, imgcdn); 222 211 } else if (AppBskyEmbedVideo.isMain(embed)) { 223 - result = hydrateEmbedVideo(embed, postAuthorDid); 212 + return hydrateEmbedVideo(embed, postAuthorDid, videocdn); 224 213 } else if (AppBskyEmbedRecord.isMain(embed)) { 225 - result = hydrateEmbedRecord( 214 + return hydrateEmbedRecord( 226 215 embed, 227 216 usequerypostresults?.data, 228 217 quotedProfile, 229 218 queryidentityresult?.data, 219 + imgcdn 230 220 ); 231 221 } else if (AppBskyEmbedRecordWithMedia.isMain(embed)) { 232 222 let hydratedMedia: ··· 236 226 | undefined; 237 227 238 228 if (AppBskyEmbedImages.isMain(embed.media)) { 239 - hydratedMedia = hydrateEmbedImages(embed.media, postAuthorDid); 229 + hydratedMedia = hydrateEmbedImages( 230 + embed.media, 231 + postAuthorDid, 232 + imgcdn 233 + ); 240 234 } else if (AppBskyEmbedExternal.isMain(embed.media)) { 241 - hydratedMedia = hydrateEmbedExternal(embed.media, postAuthorDid); 235 + hydratedMedia = hydrateEmbedExternal( 236 + embed.media, 237 + postAuthorDid, 238 + imgcdn 239 + ); 242 240 } else if (AppBskyEmbedVideo.isMain(embed.media)) { 243 - hydratedMedia = hydrateEmbedVideo(embed.media, postAuthorDid); 241 + hydratedMedia = hydrateEmbedVideo( 242 + embed.media, 243 + postAuthorDid, 244 + videocdn 245 + ); 244 246 } 245 247 246 248 if (hydratedMedia) { 247 - result = hydrateEmbedRecordWithMedia( 249 + return hydrateEmbedRecordWithMedia( 248 250 embed, 249 251 hydratedMedia, 250 252 usequerypostresults?.data, 251 253 quotedProfile, 252 254 queryidentityresult?.data, 255 + imgcdn 253 256 ); 254 257 } 255 258 } 256 - setHydratedEmbed(result); 257 259 } catch (e) { 258 260 console.error("Error hydrating embed", e); 259 - setHydratedEmbed(undefined); 261 + return undefined; 260 262 } 261 - }, [ 262 - embed, 263 - postAuthorDid, 264 - isRecordType, 265 - usequerypostresults?.data, 266 - quotedProfile, 267 - queryidentityresult?.data, 268 - ]); 263 + })(); 269 264 270 265 const isLoading = isRecordType 271 - ? usequerypostresults?.isLoading || isLoadingProfile || queryidentityresult?.isLoading 266 + ? usequerypostresults?.isLoading || 267 + isLoadingProfile || 268 + queryidentityresult?.isLoading 272 269 : false; 273 - const error = usequerypostresults?.error || profileError || queryidentityresult?.error; 270 + 271 + const error = 272 + usequerypostresults?.error || profileError || queryidentityresult?.error; 274 273 275 274 return { data: hydratedEmbed, isLoading, error }; 276 - } 275 + }
+244 -39
src/utils/useQuery.ts
··· 1 + import * as ATPAPI from "@atproto/api"; 1 2 import { 3 + infiniteQueryOptions, 4 + type QueryFunctionContext, 2 5 queryOptions, 3 - useQuery, 4 6 useInfiniteQuery, 5 - type QueryFunctionContext, 6 - type UseQueryResult, 7 - type InfiniteData 8 - } from "@tanstack/react-query"; 9 - import * as ATPAPI from "@atproto/api"; 7 + useQuery, 8 + type UseQueryResult} from "@tanstack/react-query"; 9 + import { useAtom } from "jotai"; 10 + 11 + import { constellationURLAtom, slingshotURLAtom } from "./atoms"; 10 12 11 - export function constructIdentityQuery(didorhandle?: string) { 13 + export function constructIdentityQuery(didorhandle?: string, slingshoturl?: string) { 12 14 return queryOptions({ 13 15 queryKey: ["identity", didorhandle], 14 16 queryFn: async () => { 15 17 if (!didorhandle) return undefined as undefined 16 18 const res = await fetch( 17 - `https://slingshot.microcosm.blue/xrpc/com.bad-example.identity.resolveMiniDoc?identifier=${encodeURIComponent(didorhandle)}` 19 + `https://${slingshoturl}/xrpc/com.bad-example.identity.resolveMiniDoc?identifier=${encodeURIComponent(didorhandle)}` 18 20 ); 19 21 if (!res.ok) throw new Error("Failed to fetch post"); 20 22 try { ··· 28 30 return undefined; 29 31 } 30 32 }, 33 + staleTime: /*0,//*/ 5 * 60 * 1000, // 5 minutes 34 + gcTime: /*0//*/5 * 60 * 1000, 31 35 }); 32 36 } 33 37 export function useQueryIdentity(didorhandle: string): UseQueryResult< ··· 54 58 Error 55 59 > 56 60 export function useQueryIdentity(didorhandle?: string) { 57 - return useQuery(constructIdentityQuery(didorhandle)); 61 + const [slingshoturl] = useAtom(slingshotURLAtom) 62 + return useQuery(constructIdentityQuery(didorhandle, slingshoturl)); 58 63 } 59 64 60 - export function constructPostQuery(uri?: string) { 65 + export function constructPostQuery(uri?: string, slingshoturl?: string) { 61 66 return queryOptions({ 62 67 queryKey: ["post", uri], 63 68 queryFn: async () => { 64 69 if (!uri) return undefined as undefined 65 70 const res = await fetch( 66 - `https://slingshot.microcosm.blue/xrpc/com.bad-example.repo.getUriRecord?at_uri=${encodeURIComponent(uri)}` 71 + `https://${slingshoturl}/xrpc/com.bad-example.repo.getUriRecord?at_uri=${encodeURIComponent(uri)}` 67 72 ); 68 - if (!res.ok) throw new Error("Failed to fetch post"); 73 + let data: any; 74 + try { 75 + data = await res.json(); 76 + } catch { 77 + return undefined; 78 + } 79 + if (res.status === 400) return undefined; 80 + if (data?.error === "InvalidRequest" && data.message?.includes("Could not find repo")) { 81 + return undefined; // cache โ€œnot foundโ€ 82 + } 69 83 try { 70 - return (await res.json()) as { 84 + if (!res.ok) throw new Error("Failed to fetch post"); 85 + return (data) as { 71 86 uri: string; 72 87 cid: string; 73 - value: ATPAPI.AppBskyFeedPost.Record; 88 + value: any; 74 89 }; 75 90 } catch (_e) { 76 91 return undefined; 77 92 } 78 93 }, 94 + retry: (failureCount, error) => { 95 + // dont retry 400 errors 96 + if ((error as any)?.message?.includes("400")) return false; 97 + return failureCount < 2; 98 + }, 99 + staleTime: /*0,//*/ 5 * 60 * 1000, // 5 minutes 100 + gcTime: /*0//*/5 * 60 * 1000, 79 101 }); 80 102 } 81 103 export function useQueryPost(uri: string): UseQueryResult< ··· 100 122 Error 101 123 > 102 124 export function useQueryPost(uri?: string) { 103 - return useQuery(constructPostQuery(uri)); 125 + const [slingshoturl] = useAtom(slingshotURLAtom) 126 + return useQuery(constructPostQuery(uri, slingshoturl)); 104 127 } 105 128 106 - export function constructProfileQuery(uri?: string) { 129 + export function constructProfileQuery(uri?: string, slingshoturl?: string) { 107 130 return queryOptions({ 108 131 queryKey: ["profile", uri], 109 132 queryFn: async () => { 110 133 if (!uri) return undefined as undefined 111 134 const res = await fetch( 112 - `https://slingshot.microcosm.blue/xrpc/com.bad-example.repo.getUriRecord?at_uri=${encodeURIComponent(uri)}` 135 + `https://${slingshoturl}/xrpc/com.bad-example.repo.getUriRecord?at_uri=${encodeURIComponent(uri)}` 113 136 ); 114 - if (!res.ok) throw new Error("Failed to fetch post"); 137 + let data: any; 138 + try { 139 + data = await res.json(); 140 + } catch { 141 + return undefined; 142 + } 143 + if (res.status === 400) return undefined; 144 + if (data?.error === "InvalidRequest" && data.message?.includes("Could not find repo")) { 145 + return undefined; // cache โ€œnot foundโ€ 146 + } 115 147 try { 116 - return (await res.json()) as { 148 + if (!res.ok) throw new Error("Failed to fetch post"); 149 + return (data) as { 117 150 uri: string; 118 151 cid: string; 119 - value: ATPAPI.AppBskyActorProfile.Record; 152 + value: any; 120 153 }; 121 154 } catch (_e) { 122 155 return undefined; 123 156 } 124 157 }, 158 + retry: (failureCount, error) => { 159 + // dont retry 400 errors 160 + if ((error as any)?.message?.includes("400")) return false; 161 + return failureCount < 2; 162 + }, 163 + staleTime: /*0,//*/ 5 * 60 * 1000, // 5 minutes 164 + gcTime: /*0//*/5 * 60 * 1000, 125 165 }); 126 166 } 127 167 export function useQueryProfile(uri: string): UseQueryResult< ··· 146 186 Error 147 187 > 148 188 export function useQueryProfile(uri?: string) { 149 - return useQuery(constructProfileQuery(uri)); 189 + const [slingshoturl] = useAtom(slingshotURLAtom) 190 + return useQuery(constructProfileQuery(uri, slingshoturl)); 150 191 } 151 192 152 193 // export function constructConstellationQuery( ··· 182 223 // target: string 183 224 // ): QueryOptions<linksAllResponse, Error>; 184 225 export function constructConstellationQuery(query?:{ 226 + constellation: string, 185 227 method: 186 228 | "/links" 187 229 | "/links/distinct-dids" 188 230 | "/links/count" 189 231 | "/links/count/distinct-dids" 190 - | "/links/all", 232 + | "/links/all" 233 + | "undefined", 191 234 target: string, 192 235 collection?: string, 193 236 path?: string, 194 - cursor?: string 237 + cursor?: string, 238 + dids?: string[] 195 239 } 196 240 ) { 197 241 // : QueryOptions< ··· 203 247 // Error 204 248 // > 205 249 return queryOptions({ 206 - queryKey: ["post", query?.method, query?.target, query?.collection, query?.path, query?.cursor] as const, 250 + queryKey: ["constellation", query?.method, query?.target, query?.collection, query?.path, query?.cursor, query?.dids] as const, 207 251 queryFn: async () => { 208 - if (!query) return undefined as undefined 252 + if (!query || query.method === "undefined") return undefined as undefined 209 253 const method = query.method 210 254 const target = query.target 211 255 const collection = query?.collection 212 256 const path = query?.path 213 257 const cursor = query.cursor 258 + const dids = query?.dids 214 259 const res = await fetch( 215 - `https://constellation.microcosm.blue${method}?target=${encodeURIComponent(target)}${collection ? `&collection=${encodeURIComponent(collection)}` : ""}${path ? `&path=${encodeURIComponent(path)}` : ""}${cursor ? `&cursor=${encodeURIComponent(cursor)}` : ""}` 260 + `https://${query.constellation}${method}?target=${encodeURIComponent(target)}${collection ? `&collection=${encodeURIComponent(collection)}` : ""}${path ? `&path=${encodeURIComponent(path)}` : ""}${cursor ? `&cursor=${encodeURIComponent(cursor)}` : ""}${dids ? dids.map((did) => `&did=${encodeURIComponent(did)}`).join("") : ""}` 216 261 ); 217 262 if (!res.ok) throw new Error("Failed to fetch post"); 218 263 try { ··· 235 280 } 236 281 }, 237 282 // enforce short lifespan 238 - staleTime: 5 * 60 * 1000, // 5 minutes 239 - gcTime: 5 * 60 * 1000, 283 + staleTime: /*0,//*/ 5 * 60 * 1000, // 5 minutes 284 + gcTime: /*0//*/5 * 60 * 1000, 240 285 }); 241 286 } 242 287 export function useQueryConstellation(query: { ··· 245 290 collection: string; 246 291 path: string; 247 292 cursor?: string; 293 + dids?: string[]; 248 294 }): UseQueryResult<linksRecordsResponse, Error>; 249 295 export function useQueryConstellation(query: { 250 296 method: "/links/distinct-dids"; ··· 272 318 target: string; 273 319 }): UseQueryResult<linksAllResponse, Error>; 274 320 export function useQueryConstellation(): undefined; 321 + export function useQueryConstellation(query: { 322 + method: "undefined"; 323 + target: string; 324 + }): undefined; 275 325 export function useQueryConstellation(query?: { 276 326 method: 277 327 | "/links" 278 328 | "/links/distinct-dids" 279 329 | "/links/count" 280 330 | "/links/count/distinct-dids" 281 - | "/links/all"; 331 + | "/links/all" 332 + | "undefined"; 282 333 target: string; 283 334 collection?: string; 284 335 path?: string; 285 336 cursor?: string; 337 + dids?: string[]; 286 338 }): 287 339 | UseQueryResult< 288 340 | linksRecordsResponse ··· 294 346 > 295 347 | undefined { 296 348 //if (!query) return; 349 + const [constellationurl] = useAtom(constellationURLAtom) 297 350 return useQuery( 298 - constructConstellationQuery(query) 351 + constructConstellationQuery(query && {constellation: constellationurl, ...query}) 299 352 ); 300 353 } 301 354 ··· 304 357 collection: string; 305 358 rkey: string; 306 359 }; 307 - type linksRecordsResponse = { 360 + export type linksRecordsResponse = { 308 361 total: string; 309 362 linking_records: linksRecord[]; 310 363 cursor?: string; ··· 317 370 type linksCountResponse = { 318 371 total: string; 319 372 }; 320 - type linksAllResponse = { 373 + export type linksAllResponse = { 321 374 links: Record< 322 375 string, 323 376 Record< ··· 400 453 401 454 402 455 403 - export function constructArbitraryQuery(uri?: string) { 456 + export function constructArbitraryQuery(uri?: string, slingshoturl?: string) { 404 457 return queryOptions({ 405 458 queryKey: ["arbitrary", uri], 406 459 queryFn: async () => { 407 460 if (!uri) return undefined as undefined 408 461 const res = await fetch( 409 - `https://slingshot.microcosm.blue/xrpc/com.bad-example.repo.getUriRecord?at_uri=${encodeURIComponent(uri)}` 462 + `https://${slingshoturl}/xrpc/com.bad-example.repo.getUriRecord?at_uri=${encodeURIComponent(uri)}` 410 463 ); 411 - if (!res.ok) throw new Error("Failed to fetch post"); 464 + let data: any; 465 + try { 466 + data = await res.json(); 467 + } catch { 468 + return undefined; 469 + } 470 + if (res.status === 400) return undefined; 471 + if (data?.error === "InvalidRequest" && data.message?.includes("Could not find repo")) { 472 + return undefined; // cache โ€œnot foundโ€ 473 + } 412 474 try { 413 - return (await res.json()) as { 475 + if (!res.ok) throw new Error("Failed to fetch post"); 476 + return (data) as { 414 477 uri: string; 415 478 cid: string; 416 479 value: any; ··· 419 482 return undefined; 420 483 } 421 484 }, 485 + retry: (failureCount, error) => { 486 + // dont retry 400 errors 487 + if ((error as any)?.message?.includes("400")) return false; 488 + return failureCount < 2; 489 + }, 490 + staleTime: /*0,//*/ 5 * 60 * 1000, // 5 minutes 491 + gcTime: /*0//*/5 * 60 * 1000, 422 492 }); 423 493 } 424 494 export function useQueryArbitrary(uri: string): UseQueryResult< ··· 442 512 Error 443 513 >; 444 514 export function useQueryArbitrary(uri?: string) { 445 - return useQuery(constructArbitraryQuery(uri)); 515 + const [slingshoturl] = useAtom(slingshotURLAtom) 516 + return useQuery(constructArbitraryQuery(uri, slingshoturl)); 446 517 } 447 518 448 519 export function constructFallbackNothingQuery(){ ··· 494 565 }); 495 566 } 496 567 568 + export const ATURI_PAGE_LIMIT = 100; 569 + 570 + export interface AturiDirectoryAturisItem { 571 + uri: string; 572 + cid: string; 573 + rkey: string; 574 + } 575 + 576 + export type AturiDirectoryAturis = AturiDirectoryAturisItem[]; 577 + 578 + export function constructAturiListQuery(aturilistservice: string, did: string, collection: string, reverse?: boolean) { 579 + return queryOptions({ 580 + // A unique key for this query, including all parameters that affect the data. 581 + queryKey: ["aturiList", did, collection, { reverse }], 582 + 583 + // The function that fetches the data. 584 + queryFn: async ({ pageParam }: QueryFunctionContext) => { 585 + const cursor = pageParam as string | undefined; 586 + 587 + // Use URLSearchParams for safe and clean URL construction. 588 + const params = new URLSearchParams({ 589 + did, 590 + collection, 591 + }); 592 + 593 + if (cursor) { 594 + params.set("cursor", cursor); 595 + } 596 + 597 + // Add the reverse parameter if it's true 598 + if (reverse) { 599 + params.set("reverse", "true"); 600 + } 601 + 602 + const url = `https://${aturilistservice}/aturis?${params.toString()}`; 603 + 604 + const res = await fetch(url); 605 + if (!res.ok) { 606 + // You can add more specific error handling here 607 + throw new Error(`Failed to fetch AT-URI list for ${did}`); 608 + } 609 + 610 + return res.json() as Promise<AturiDirectoryAturis>; 611 + }, 612 + }); 613 + } 614 + 615 + export function useInfiniteQueryAturiList({aturilistservice, did, collection, reverse}:{aturilistservice: string, did: string | undefined, collection: string | undefined, reverse?: boolean}) { 616 + // We only enable the query if both `did` and `collection` are provided. 617 + const isEnabled = !!did && !!collection; 618 + 619 + const { queryKey, queryFn } = constructAturiListQuery(aturilistservice, did!, collection!, reverse); 620 + 621 + return useInfiniteQuery({ 622 + queryKey, 623 + queryFn, 624 + initialPageParam: undefined as never, // ???? what is this shit 625 + 626 + // @ts-expect-error i wouldve used as null | undefined, anyways 627 + getNextPageParam: (lastPage: AturiDirectoryAturis) => { 628 + // If the last page returned no records, we're at the end. 629 + if (!lastPage || lastPage.length === 0) { 630 + return undefined; 631 + } 632 + 633 + // If the number of records is less than our page limit, it must be the last page. 634 + if (lastPage.length < ATURI_PAGE_LIMIT) { 635 + return undefined; 636 + } 637 + 638 + // The cursor for the next page is the `rkey` of the last item we received. 639 + const lastItem = lastPage[lastPage.length - 1]; 640 + return lastItem.rkey; 641 + }, 642 + 643 + enabled: isEnabled, 644 + }); 645 + } 646 + 647 + 497 648 type FeedSkeletonPage = ATPAPI.AppBskyFeedGetFeedSkeleton.OutputSchema; 498 649 499 650 export function constructInfiniteFeedSkeletonQuery(options: { ··· 544 695 }) { 545 696 const { queryKey, queryFn } = constructInfiniteFeedSkeletonQuery(options); 546 697 547 - return useInfiniteQuery({ 698 + return {...useInfiniteQuery({ 548 699 queryKey, 549 700 queryFn, 550 701 initialPageParam: undefined as never, ··· 552 703 staleTime: Infinity, 553 704 refetchOnWindowFocus: false, 554 705 enabled: !!options.feedUri && (options.isAuthed ? !!options.agent && !!options.pdsUrl && !!options.feedServiceDid : true), 555 - }); 706 + }), queryKey: queryKey}; 707 + } 708 + 709 + 710 + export function yknowIReallyHateThisButWhateverGuardedConstructConstellationInfiniteQueryLinks(query?: { 711 + constellation: string, 712 + method: '/links' 713 + target?: string 714 + collection: string 715 + path: string 716 + }) { 717 + console.log( 718 + 'yknowIReallyHateThisButWhateverGuardedConstructConstellationInfiniteQueryLinks', 719 + query, 720 + ) 721 + 722 + return infiniteQueryOptions({ 723 + enabled: !!query?.target, 724 + queryKey: [ 725 + 'reddwarf_constellation', 726 + query?.method, 727 + query?.target, 728 + query?.collection, 729 + query?.path, 730 + ] as const, 731 + 732 + queryFn: async ({pageParam}: {pageParam?: string}) => { 733 + if (!query || !query?.target) return undefined 734 + 735 + const method = query.method 736 + const target = query.target 737 + const collection = query.collection 738 + const path = query.path 739 + const cursor = pageParam 740 + 741 + const res = await fetch( 742 + `https://${query.constellation}${method}?target=${encodeURIComponent(target)}${ 743 + collection ? `&collection=${encodeURIComponent(collection)}` : '' 744 + }${path ? `&path=${encodeURIComponent(path)}` : ''}${ 745 + cursor ? `&cursor=${encodeURIComponent(cursor)}` : '' 746 + }`, 747 + ) 748 + 749 + if (!res.ok) throw new Error('Failed to fetch') 750 + 751 + return (await res.json()) as linksRecordsResponse 752 + }, 753 + 754 + getNextPageParam: lastPage => { 755 + return (lastPage as any)?.cursor ?? undefined 756 + }, 757 + initialPageParam: undefined, 758 + staleTime: 5 * 60 * 1000, 759 + gcTime: 5 * 60 * 1000, 760 + }) 556 761 }
+1 -1
tsconfig.json
··· 5 5 "jsx": "react-jsx", 6 6 "module": "ESNext", 7 7 "lib": ["ES2022", "DOM", "DOM.Iterable"], 8 - "types": ["vite/client"], 8 + "types": ["vite/client", "unplugin-icons/types/react"], 9 9 10 10 /* Bundler mode */ 11 11 "moduleResolution": "bundler",
+33 -7
vite.config.ts
··· 1 - import { defineConfig } from "vite"; 2 - import viteReact from "@vitejs/plugin-react"; 1 + import { resolve } from "node:path"; 2 + 3 3 import tailwindcss from "@tailwindcss/vite"; 4 + import { TanStackRouterVite } from "@tanstack/router-plugin/vite"; 5 + import viteReact from "@vitejs/plugin-react"; 6 + import AutoImport from 'unplugin-auto-import/vite' 7 + import IconsResolver from 'unplugin-icons/resolver' 8 + import Icons from 'unplugin-icons/vite' 9 + import { defineConfig } from "vite"; 10 + 4 11 import { generateMetadataPlugin } from "./oauthdev.mts"; 5 12 6 - const PROD_URL = "https://reddwarf.whey.party" 13 + const PROD_URL = "https://reddwarf.app" 7 14 const DEV_URL = "https://local3768forumtest.whey.party" 8 15 9 16 function shp(url: string): string { 10 17 return url.replace(/^https?:\/\//, ''); 11 18 } 12 19 13 - import { TanStackRouterVite } from "@tanstack/router-plugin/vite"; 14 - import { resolve } from "node:path"; 15 - 16 20 // https://vitejs.dev/config/ 17 21 export default defineConfig({ 18 22 plugins: [ ··· 21 25 dev: DEV_URL, 22 26 }), 23 27 TanStackRouterVite({ autoCodeSplitting: true }), 24 - viteReact(), 28 + viteReact({ 29 + babel: { 30 + plugins: ['babel-plugin-react-compiler'], 31 + }, 32 + }), 25 33 tailwindcss(), 34 + AutoImport({ 35 + include: [ 36 + /\.[tj]sx?$/, // .ts, .tsx, .js, .jsx 37 + ], 38 + resolvers: [ 39 + IconsResolver({ 40 + prefix: 'Icon', 41 + extension: 'jsx', 42 + enabledCollections: ['mdi','material-symbols'], 43 + }), 44 + ], 45 + dts: 'src/auto-imports.d.ts', 46 + }), 47 + Icons({ 48 + //autoInstall: true, 49 + compiler: 'jsx', 50 + jsx: 'react' 51 + }), 26 52 ], 27 53 // test: { 28 54 // globals: true,