.gitmodules
.gitmodules
This is a binary file and will not be displayed.
+1
.npmrc
+1
.npmrc
···
···
1
+
@jsr:registry=https://npm.jsr.io
-1239
bun.lock
-1239
bun.lock
···
1
-
{
2
-
"lockfileVersion": 1,
3
-
"workspaces": {
4
-
"": {
5
-
"name": "mozzius.dev",
6
-
"dependencies": {
7
-
"@atcute/client": "^2.0.9",
8
-
"@atcute/whitewind": "^1.0.4",
9
-
"@atproto/lex-cli": "^0.8.3",
10
-
"@atproto/lexicon": "^0.4.14",
11
-
"@atproto/xrpc": "^0.7.7",
12
-
"@upstash/ratelimit": "^2.0.7",
13
-
"@upstash/redis": "^1.36.0",
14
-
"bright": "^1.0.0",
15
-
"envalid": "^8.1.1",
16
-
"lucide-react": "^0.477.0",
17
-
"multiformats": "^13.4.2",
18
-
"next": "15.5.9",
19
-
"next-plausible": "^3.12.5",
20
-
"react": "^19.2.3",
21
-
"react-dom": "^19.2.3",
22
-
"react-markdown": "^10.1.0",
23
-
"reading-time": "^1.5.0",
24
-
"rehype-format": "^5.0.1",
25
-
"rehype-raw": "^7.0.0",
26
-
"rehype-sanitize": "^6.0.0",
27
-
"rehype-stringify": "^10.0.1",
28
-
"remark-gfm": "^4.0.1",
29
-
"remark-parse": "^11.0.0",
30
-
"remark-rehype": "^11.1.2",
31
-
"rss": "^1.2.2",
32
-
"simple-icons": "^14.15.0",
33
-
"tailwind-merge": "^3.4.0",
34
-
"unified": "^11.0.5",
35
-
},
36
-
"devDependencies": {
37
-
"@ianvs/prettier-plugin-sort-imports": "^4.7.0",
38
-
"@tailwindcss/postcss": "^4.1.18",
39
-
"@types/node": "^24.10.4",
40
-
"@types/react": "^19.2.7",
41
-
"@types/react-dom": "^19.2.3",
42
-
"@types/rss": "^0.0.32",
43
-
"eslint": "^9.39.2",
44
-
"eslint-config-next": "15.2.1",
45
-
"eslint-config-prettier": "^10.1.8",
46
-
"postcss": "^8.5.6",
47
-
"prettier": "^3.7.4",
48
-
"prettier-plugin-tailwindcss": "^0.6.14",
49
-
"tailwindcss": "^4.1.18",
50
-
"typescript": "^5.9.3",
51
-
},
52
-
},
53
-
},
54
-
"packages": {
55
-
"@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
56
-
57
-
"@atcute/client": ["@atcute/client@2.0.9", "", {}, "sha512-QNDm9gMP6x9LY77ArwY+urQOBtQW74/onEAz42c40JxRm6Rl9K9cU4ROvNKJ+5cpVmEm1sthEWVRmDr5CSZENA=="],
58
-
59
-
"@atcute/whitewind": ["@atcute/whitewind@1.0.4", "", { "peerDependencies": { "@atcute/client": "^1.0.0 || ^2.0.0" } }, "sha512-kxgpfVBLaNuHNxTQw8J34ZbD7lWId42tPKhuijiV61ha+y2lDABvDcQTX9hugIVdO9amy8PCPbyTKct5ITEEbQ=="],
60
-
61
-
"@atproto/common-web": ["@atproto/common-web@0.4.3", "", { "dependencies": { "graphemer": "^1.4.0", "multiformats": "^9.9.0", "uint8arrays": "3.0.0", "zod": "^3.23.8" } }, "sha512-nRDINmSe4VycJzPo6fP/hEltBcULFxt9Kw7fQk6405FyAWZiTluYHlXOnU7GkQfeUK44OENG1qFTBcmCJ7e8pg=="],
62
-
63
-
"@atproto/lex-cli": ["@atproto/lex-cli@0.8.3", "", { "dependencies": { "@atproto/lexicon": "^0.4.11", "@atproto/syntax": "^0.4.0", "chalk": "^4.1.2", "commander": "^9.4.0", "prettier": "^3.2.5", "ts-morph": "^24.0.0", "yesno": "^0.4.0", "zod": "^3.23.8" }, "bin": { "lex": "dist/index.js" } }, "sha512-QXqJl25obi74Cr0vp2RslZsbcsTV8Bq+5+kZnQgzIb2XH9/KJhoS32jKJNbrbKY097K4HOXyDsHi6j3+xCWJcQ=="],
64
-
65
-
"@atproto/lex-data": ["@atproto/lex-data@0.0.3", "", { "dependencies": { "@atproto/syntax": "0.4.2", "multiformats": "^9.9.0", "tslib": "^2.8.1", "uint8arrays": "3.0.0", "unicode-segmenter": "^0.14.0" } }, "sha512-ivo1IpY/EX+RIpxPgCf4cPhQo5bfu4nrpa1vJCt8hCm9SfoonJkDFGa0n4SMw4JnXZoUcGcrJ46L+D8bH6GI2g=="],
66
-
67
-
"@atproto/lex-json": ["@atproto/lex-json@0.0.3", "", { "dependencies": { "@atproto/lex-data": "0.0.3", "tslib": "^2.8.1" } }, "sha512-ZVcY7XlRfdPYvQQ2WroKUepee0+NCovrSXgXURM3Xv+n5jflJCoczguROeRr8sN0xvT0ZbzMrDNHCUYKNnxcjw=="],
68
-
69
-
"@atproto/lexicon": ["@atproto/lexicon@0.4.14", "", { "dependencies": { "@atproto/common-web": "^0.4.2", "@atproto/syntax": "^0.4.0", "iso-datestring-validator": "^2.2.2", "multiformats": "^9.9.0", "zod": "^3.23.8" } }, "sha512-jiKpmH1QER3Gvc7JVY5brwrfo+etFoe57tKPQX/SmPwjvUsFnJAow5xLIryuBaJgFAhnTZViXKs41t//pahGHQ=="],
70
-
71
-
"@atproto/syntax": ["@atproto/syntax@0.4.1", "", {}, "sha512-CJdImtLAiFO+0z3BWTtxwk6aY5w4t8orHTMVJgkf++QRJWTxPbIFko/0hrkADB7n2EruDxDSeAgfUGehpH6ngw=="],
72
-
73
-
"@atproto/xrpc": ["@atproto/xrpc@0.7.7", "", { "dependencies": { "@atproto/lexicon": "^0.6.0", "zod": "^3.23.8" } }, "sha512-K1ZyO/BU8JNtXX5dmPp7b5UrkLMMqpsIa/Lrj5D3Su+j1Xwq1m6QJ2XJ1AgjEjkI1v4Muzm7klianLE6XGxtmA=="],
74
-
75
-
"@babel/code-frame": ["@babel/code-frame@7.26.2", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.25.9", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" } }, "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ=="],
76
-
77
-
"@babel/generator": ["@babel/generator@7.27.0", "", { "dependencies": { "@babel/parser": "^7.27.0", "@babel/types": "^7.27.0", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" } }, "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw=="],
78
-
79
-
"@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.9", "", {}, "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA=="],
80
-
81
-
"@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.9", "", {}, "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ=="],
82
-
83
-
"@babel/parser": ["@babel/parser@7.27.0", "", { "dependencies": { "@babel/types": "^7.27.0" }, "bin": "./bin/babel-parser.js" }, "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg=="],
84
-
85
-
"@babel/template": ["@babel/template@7.27.0", "", { "dependencies": { "@babel/code-frame": "^7.26.2", "@babel/parser": "^7.27.0", "@babel/types": "^7.27.0" } }, "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA=="],
86
-
87
-
"@babel/traverse": ["@babel/traverse@7.27.0", "", { "dependencies": { "@babel/code-frame": "^7.26.2", "@babel/generator": "^7.27.0", "@babel/parser": "^7.27.0", "@babel/template": "^7.27.0", "@babel/types": "^7.27.0", "debug": "^4.3.1", "globals": "^11.1.0" } }, "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA=="],
88
-
89
-
"@babel/types": ["@babel/types@7.27.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9" } }, "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg=="],
90
-
91
-
"@code-hike/lighter": ["@code-hike/lighter@1.0.3", "", { "dependencies": { "ansi-sequence-parser": "1.1.1", "tm-grammars": "^1.22.0" } }, "sha512-LU0TbZfu3L3fQZ7y9tZHttnxyFm7ewU96arGMFnjLbvFj+onYfVkznhQOmU1ZsQtv9rpQzZ313GRz6hCGDrlJQ=="],
92
-
93
-
"@emnapi/core": ["@emnapi/core@1.4.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.0.1", "tslib": "^2.4.0" } }, "sha512-H+N/FqT07NmLmt6OFFtDfwe8PNygprzBikrEMyQfgqSmT0vzE515Pz7R8izwB9q/zsH/MA64AKoul3sA6/CzVg=="],
94
-
95
-
"@emnapi/runtime": ["@emnapi/runtime@1.7.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA=="],
96
-
97
-
"@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.0.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw=="],
98
-
99
-
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g=="],
100
-
101
-
"@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="],
102
-
103
-
"@eslint/config-array": ["@eslint/config-array@0.21.1", "", { "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA=="],
104
-
105
-
"@eslint/config-helpers": ["@eslint/config-helpers@0.4.2", "", { "dependencies": { "@eslint/core": "^0.17.0" } }, "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw=="],
106
-
107
-
"@eslint/core": ["@eslint/core@0.17.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ=="],
108
-
109
-
"@eslint/eslintrc": ["@eslint/eslintrc@3.3.1", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ=="],
110
-
111
-
"@eslint/js": ["@eslint/js@9.39.2", "", {}, "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA=="],
112
-
113
-
"@eslint/object-schema": ["@eslint/object-schema@2.1.7", "", {}, "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA=="],
114
-
115
-
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.4.1", "", { "dependencies": { "@eslint/core": "^0.17.0", "levn": "^0.4.1" } }, "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA=="],
116
-
117
-
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
118
-
119
-
"@humanfs/node": ["@humanfs/node@0.16.6", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.3.0" } }, "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw=="],
120
-
121
-
"@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="],
122
-
123
-
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.2", "", {}, "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ=="],
124
-
125
-
"@ianvs/prettier-plugin-sort-imports": ["@ianvs/prettier-plugin-sort-imports@4.7.0", "", { "dependencies": { "@babel/generator": "^7.26.2", "@babel/parser": "^7.26.2", "@babel/traverse": "^7.25.9", "@babel/types": "^7.26.0", "semver": "^7.5.2" }, "peerDependencies": { "@prettier/plugin-oxc": "^0.0.4", "@vue/compiler-sfc": "2.7.x || 3.x", "content-tag": "^4.0.0", "prettier": "2 || 3 || ^4.0.0-0", "prettier-plugin-ember-template-tag": "^2.1.0" }, "optionalPeers": ["@prettier/plugin-oxc", "@vue/compiler-sfc", "content-tag", "prettier-plugin-ember-template-tag"] }, "sha512-soa2bPUJAFruLL4z/CnMfSEKGznm5ebz29fIa9PxYtu8HHyLKNE1NXAs6dylfw1jn/ilEIfO2oLLN6uAafb7DA=="],
126
-
127
-
"@img/colour": ["@img/colour@1.0.0", "", {}, "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw=="],
128
-
129
-
"@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="],
130
-
131
-
"@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="],
132
-
133
-
"@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="],
134
-
135
-
"@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="],
136
-
137
-
"@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="],
138
-
139
-
"@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="],
140
-
141
-
"@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="],
142
-
143
-
"@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.2.4", "", { "os": "linux", "cpu": "none" }, "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA=="],
144
-
145
-
"@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="],
146
-
147
-
"@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="],
148
-
149
-
"@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="],
150
-
151
-
"@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="],
152
-
153
-
"@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="],
154
-
155
-
"@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="],
156
-
157
-
"@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA=="],
158
-
159
-
"@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.2.4" }, "os": "linux", "cpu": "none" }, "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw=="],
160
-
161
-
"@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="],
162
-
163
-
"@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="],
164
-
165
-
"@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="],
166
-
167
-
"@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="],
168
-
169
-
"@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="],
170
-
171
-
"@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="],
172
-
173
-
"@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="],
174
-
175
-
"@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="],
176
-
177
-
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.8", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA=="],
178
-
179
-
"@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="],
180
-
181
-
"@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
182
-
183
-
"@jridgewell/set-array": ["@jridgewell/set-array@1.2.1", "", {}, "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="],
184
-
185
-
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="],
186
-
187
-
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="],
188
-
189
-
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.8", "", { "dependencies": { "@emnapi/core": "^1.4.0", "@emnapi/runtime": "^1.4.0", "@tybys/wasm-util": "^0.9.0" } }, "sha512-OBlgKdX7gin7OIq4fadsjpg+cp2ZphvAIKucHsNfTdJiqdOmOEwQd/bHi0VwNrcw5xpBJyUw6cK/QilCqy1BSg=="],
190
-
191
-
"@next/env": ["@next/env@15.5.9", "", {}, "sha512-4GlTZ+EJM7WaW2HEZcyU317tIQDjkQIyENDLxYJfSWlfqguN+dHkZgyQTV/7ykvobU7yEH5gKvreNrH4B6QgIg=="],
192
-
193
-
"@next/eslint-plugin-next": ["@next/eslint-plugin-next@15.2.1", "", { "dependencies": { "fast-glob": "3.3.1" } }, "sha512-6ppeToFd02z38SllzWxayLxjjNfzvc7Wm07gQOKSLjyASvKcXjNStZrLXMHuaWkhjqxe+cnhb2uzfWXm1VEj/Q=="],
194
-
195
-
"@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@15.5.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-IZwtxCEpI91HVU/rAUOOobWSZv4P2DeTtNaCdHqLcTJU4wdNXgAySvKa/qJCgR5m6KI8UsKDXtO2B31jcaw1Yw=="],
196
-
197
-
"@next/swc-darwin-x64": ["@next/swc-darwin-x64@15.5.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-UP6CaDBcqaCBuiq/gfCEJw7sPEoX1aIjZHnBWN9v9qYHQdMKvCKcAVs4OX1vIjeE+tC5EIuwDTVIoXpUes29lg=="],
198
-
199
-
"@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@15.5.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-NCslw3GrNIw7OgmRBxHtdWFQYhexoUCq+0oS2ccjyYLtcn1SzGzeM54jpTFonIMUjNbHmpKpziXnpxhSWLcmBA=="],
200
-
201
-
"@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@15.5.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-nfymt+SE5cvtTrG9u1wdoxBr9bVB7mtKTcj0ltRn6gkP/2Nu1zM5ei8rwP9qKQP0Y//umK+TtkKgNtfboBxRrw=="],
202
-
203
-
"@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@15.5.7", "", { "os": "linux", "cpu": "x64" }, "sha512-hvXcZvCaaEbCZcVzcY7E1uXN9xWZfFvkNHwbe/n4OkRhFWrs1J1QV+4U1BN06tXLdaS4DazEGXwgqnu/VMcmqw=="],
204
-
205
-
"@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@15.5.7", "", { "os": "linux", "cpu": "x64" }, "sha512-4IUO539b8FmF0odY6/SqANJdgwn1xs1GkPO5doZugwZ3ETF6JUdckk7RGmsfSf7ws8Qb2YB5It33mvNL/0acqA=="],
206
-
207
-
"@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@15.5.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-CpJVTkYI3ZajQkC5vajM7/ApKJUOlm6uP4BknM3XKvJ7VXAvCqSjSLmM0LKdYzn6nBJVSjdclx8nYJSa3xlTgQ=="],
208
-
209
-
"@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@15.5.7", "", { "os": "win32", "cpu": "x64" }, "sha512-gMzgBX164I6DN+9/PGA+9dQiwmTkE4TloBNx8Kv9UiGARsr9Nba7IpcBRA1iTV9vwlYnrE3Uy6I7Aj6qLjQuqw=="],
210
-
211
-
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
212
-
213
-
"@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="],
214
-
215
-
"@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
216
-
217
-
"@nolyfill/is-core-module": ["@nolyfill/is-core-module@1.0.39", "", {}, "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA=="],
218
-
219
-
"@rtsao/scc": ["@rtsao/scc@1.1.0", "", {}, "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g=="],
220
-
221
-
"@rushstack/eslint-patch": ["@rushstack/eslint-patch@1.11.0", "", {}, "sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ=="],
222
-
223
-
"@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="],
224
-
225
-
"@tailwindcss/node": ["@tailwindcss/node@4.1.18", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.6.1", "lightningcss": "1.30.2", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.1.18" } }, "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ=="],
226
-
227
-
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.18", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.18", "@tailwindcss/oxide-darwin-arm64": "4.1.18", "@tailwindcss/oxide-darwin-x64": "4.1.18", "@tailwindcss/oxide-freebsd-x64": "4.1.18", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18", "@tailwindcss/oxide-linux-arm64-musl": "4.1.18", "@tailwindcss/oxide-linux-x64-gnu": "4.1.18", "@tailwindcss/oxide-linux-x64-musl": "4.1.18", "@tailwindcss/oxide-wasm32-wasi": "4.1.18", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18", "@tailwindcss/oxide-win32-x64-msvc": "4.1.18" } }, "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A=="],
228
-
229
-
"@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.18", "", { "os": "android", "cpu": "arm64" }, "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q=="],
230
-
231
-
"@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.18", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A=="],
232
-
233
-
"@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.18", "", { "os": "darwin", "cpu": "x64" }, "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw=="],
234
-
235
-
"@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.18", "", { "os": "freebsd", "cpu": "x64" }, "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA=="],
236
-
237
-
"@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18", "", { "os": "linux", "cpu": "arm" }, "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA=="],
238
-
239
-
"@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.18", "", { "os": "linux", "cpu": "arm64" }, "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw=="],
240
-
241
-
"@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.18", "", { "os": "linux", "cpu": "arm64" }, "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg=="],
242
-
243
-
"@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.18", "", { "os": "linux", "cpu": "x64" }, "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g=="],
244
-
245
-
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.18", "", { "os": "linux", "cpu": "x64" }, "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ=="],
246
-
247
-
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.18", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.1.0", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.4.0" }, "cpu": "none" }, "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA=="],
248
-
249
-
"@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.18", "", { "os": "win32", "cpu": "arm64" }, "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA=="],
250
-
251
-
"@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.18", "", { "os": "win32", "cpu": "x64" }, "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q=="],
252
-
253
-
"@tailwindcss/postcss": ["@tailwindcss/postcss@4.1.18", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.1.18", "@tailwindcss/oxide": "4.1.18", "postcss": "^8.4.41", "tailwindcss": "4.1.18" } }, "sha512-Ce0GFnzAOuPyfV5SxjXGn0CubwGcuDB0zcdaPuCSzAa/2vII24JTkH+I6jcbXLb1ctjZMZZI6OjDaLPJQL1S0g=="],
254
-
255
-
"@ts-morph/common": ["@ts-morph/common@0.25.0", "", { "dependencies": { "minimatch": "^9.0.4", "path-browserify": "^1.0.1", "tinyglobby": "^0.2.9" } }, "sha512-kMnZz+vGGHi4GoHnLmMhGNjm44kGtKUXGnOvrKmMwAuvNjM/PgKVGfUnL7IDvK7Jb2QQ82jq3Zmp04Gy+r3Dkg=="],
256
-
257
-
"@tybys/wasm-util": ["@tybys/wasm-util@0.9.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw=="],
258
-
259
-
"@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="],
260
-
261
-
"@types/estree": ["@types/estree@1.0.7", "", {}, "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ=="],
262
-
263
-
"@types/estree-jsx": ["@types/estree-jsx@1.0.5", "", { "dependencies": { "@types/estree": "*" } }, "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg=="],
264
-
265
-
"@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="],
266
-
267
-
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
268
-
269
-
"@types/json5": ["@types/json5@0.0.29", "", {}, "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="],
270
-
271
-
"@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="],
272
-
273
-
"@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="],
274
-
275
-
"@types/node": ["@types/node@24.10.4", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-vnDVpYPMzs4wunl27jHrfmwojOGKya0xyM3sH+UE5iv5uPS6vX7UIoh6m+vQc5LGBq52HBKPIn/zcSZVzeDEZg=="],
276
-
277
-
"@types/react": ["@types/react@19.2.7", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg=="],
278
-
279
-
"@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="],
280
-
281
-
"@types/rss": ["@types/rss@0.0.32", "", {}, "sha512-2oKNqKyUY4RSdvl5eZR1n2Q9yvw3XTe3mQHsFPn9alaNBxfPnbXBtGP8R0SV8pK1PrVnLul0zx7izbm5/gF5Qw=="],
282
-
283
-
"@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="],
284
-
285
-
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.29.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.29.0", "@typescript-eslint/type-utils": "8.29.0", "@typescript-eslint/utils": "8.29.0", "@typescript-eslint/visitor-keys": "8.29.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-PAIpk/U7NIS6H7TEtN45SPGLQaHNgB7wSjsQV/8+KYokAb2T/gloOA/Bee2yd4/yKVhPKe5LlaUGhAZk5zmSaQ=="],
286
-
287
-
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.29.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.29.0", "@typescript-eslint/types": "8.29.0", "@typescript-eslint/typescript-estree": "8.29.0", "@typescript-eslint/visitor-keys": "8.29.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-8C0+jlNJOwQso2GapCVWWfW/rzaq7Lbme+vGUFKE31djwNncIpgXD7Cd4weEsDdkoZDjH0lwwr3QDQFuyrMg9g=="],
288
-
289
-
"@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.29.0", "", { "dependencies": { "@typescript-eslint/types": "8.29.0", "@typescript-eslint/visitor-keys": "8.29.0" } }, "sha512-aO1PVsq7Gm+tcghabUpzEnVSFMCU4/nYIgC2GOatJcllvWfnhrgW0ZEbnTxm36QsikmCN1K/6ZgM7fok2I7xNw=="],
290
-
291
-
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.29.0", "", { "dependencies": { "@typescript-eslint/typescript-estree": "8.29.0", "@typescript-eslint/utils": "8.29.0", "debug": "^4.3.4", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-ahaWQ42JAOx+NKEf5++WC/ua17q5l+j1GFrbbpVKzFL/tKVc0aYY8rVSYUpUvt2hUP1YBr7mwXzx+E/DfUWI9Q=="],
292
-
293
-
"@typescript-eslint/types": ["@typescript-eslint/types@8.29.0", "", {}, "sha512-wcJL/+cOXV+RE3gjCyl/V2G877+2faqvlgtso/ZRbTCnZazh0gXhe+7gbAnfubzN2bNsBtZjDvlh7ero8uIbzg=="],
294
-
295
-
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.29.0", "", { "dependencies": { "@typescript-eslint/types": "8.29.0", "@typescript-eslint/visitor-keys": "8.29.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-yOfen3jE9ISZR/hHpU/bmNvTtBW1NjRbkSFdZOksL1N+ybPEE7UVGMwqvS6CP022Rp00Sb0tdiIkhSCe6NI8ow=="],
296
-
297
-
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.29.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.29.0", "@typescript-eslint/types": "8.29.0", "@typescript-eslint/typescript-estree": "8.29.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-gX/A0Mz9Bskm8avSWFcK0gP7cZpbY4AIo6B0hWYFCaIsz750oaiWR4Jr2CI+PQhfW1CpcQr9OlfPS+kMFegjXA=="],
298
-
299
-
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.29.0", "", { "dependencies": { "@typescript-eslint/types": "8.29.0", "eslint-visitor-keys": "^4.2.0" } }, "sha512-Sne/pVz8ryR03NFK21VpN88dZ2FdQXOlq3VIklbrTYEt8yXtRFr9tvUhqvCeKjqYk5FSim37sHbooT6vzBTZcg=="],
300
-
301
-
"@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="],
302
-
303
-
"@unrs/resolver-binding-darwin-arm64": ["@unrs/resolver-binding-darwin-arm64@1.3.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-EpRILdWr3/xDa/7MoyfO7JuBIJqpBMphtu4+80BK1bRfFcniVT74h3Z7q1+WOc92FuIAYatB1vn9TJR67sORGw=="],
304
-
305
-
"@unrs/resolver-binding-darwin-x64": ["@unrs/resolver-binding-darwin-x64@1.3.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-ntj/g7lPyqwinMJWZ+DKHBse8HhVxswGTmNgFKJtdgGub3M3zp5BSZ3bvMP+kBT6dnYJLSVlDqdwOq1P8i0+/g=="],
306
-
307
-
"@unrs/resolver-binding-freebsd-x64": ["@unrs/resolver-binding-freebsd-x64@1.3.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-l6BT8f2CU821EW7U8hSUK8XPq4bmyTlt9Mn4ERrfjJNoCw0/JoHAh9amZZtV3cwC3bwwIat+GUnrcHTG9+qixw=="],
308
-
309
-
"@unrs/resolver-binding-linux-arm-gnueabihf": ["@unrs/resolver-binding-linux-arm-gnueabihf@1.3.3", "", { "os": "linux", "cpu": "arm" }, "sha512-8ScEc5a4y7oE2BonRvzJ+2GSkBaYWyh0/Ko4Q25e/ix6ANpJNhwEPZvCR6GVRmsQAYMIfQvYLdM6YEN+qRjnAQ=="],
310
-
311
-
"@unrs/resolver-binding-linux-arm-musleabihf": ["@unrs/resolver-binding-linux-arm-musleabihf@1.3.3", "", { "os": "linux", "cpu": "arm" }, "sha512-8qQ6l1VTzLNd3xb2IEXISOKwMGXDCzY/UNy/7SovFW2Sp0K3YbL7Ao7R18v6SQkLqQlhhqSBIFRk+u6+qu5R5A=="],
312
-
313
-
"@unrs/resolver-binding-linux-arm64-gnu": ["@unrs/resolver-binding-linux-arm64-gnu@1.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-v81R2wjqcWXJlQY23byqYHt9221h4anQ6wwN64oMD/WAE+FmxPHFZee5bhRkNVtzqO/q7wki33VFWlhiADwUeQ=="],
314
-
315
-
"@unrs/resolver-binding-linux-arm64-musl": ["@unrs/resolver-binding-linux-arm64-musl@1.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-cAOx/j0u5coMg4oct/BwMzvWJdVciVauUvsd+GQB/1FZYKQZmqPy0EjJzJGbVzFc6gbnfEcSqvQE6gvbGf2N8Q=="],
316
-
317
-
"@unrs/resolver-binding-linux-ppc64-gnu": ["@unrs/resolver-binding-linux-ppc64-gnu@1.3.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-mq2blqwErgDJD4gtFDlTX/HZ7lNP8YCHYFij2gkXPtMzrXxPW1hOtxL6xg4NWxvnj4bppppb0W3s/buvM55yfg=="],
318
-
319
-
"@unrs/resolver-binding-linux-s390x-gnu": ["@unrs/resolver-binding-linux-s390x-gnu@1.3.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-u0VRzfFYysarYHnztj2k2xr+eu9rmgoTUUgCCIT37Nr+j0A05Xk2c3RY8Mh5+DhCl2aYibihnaAEJHeR0UOFIQ=="],
320
-
321
-
"@unrs/resolver-binding-linux-x64-gnu": ["@unrs/resolver-binding-linux-x64-gnu@1.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-OrVo5ZsG29kBF0Ug95a2KidS16PqAMmQNozM6InbquOfW/udouk063e25JVLqIBhHLB2WyBnixOQ19tmeC/hIg=="],
322
-
323
-
"@unrs/resolver-binding-linux-x64-musl": ["@unrs/resolver-binding-linux-x64-musl@1.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-PYnmrwZ4HMp9SkrOhqPghY/aoL+Rtd4CQbr93GlrRTjK6kDzfMfgz3UH3jt6elrQAfupa1qyr1uXzeVmoEAxUA=="],
324
-
325
-
"@unrs/resolver-binding-wasm32-wasi": ["@unrs/resolver-binding-wasm32-wasi@1.3.3", "", { "dependencies": { "@napi-rs/wasm-runtime": "^0.2.7" }, "cpu": "none" }, "sha512-81AnQY6fShmktQw4hWDUIilsKSdvr/acdJ5azAreu2IWNlaJOKphJSsUVWE+yCk6kBMoQyG9ZHCb/krb5K0PEA=="],
326
-
327
-
"@unrs/resolver-binding-win32-arm64-msvc": ["@unrs/resolver-binding-win32-arm64-msvc@1.3.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-X/42BMNw7cW6xrB9syuP5RusRnWGoq+IqvJO8IDpp/BZg64J1uuIW6qA/1Cl13Y4LyLXbJVYbYNSKwR/FiHEng=="],
328
-
329
-
"@unrs/resolver-binding-win32-ia32-msvc": ["@unrs/resolver-binding-win32-ia32-msvc@1.3.3", "", { "os": "win32", "cpu": "ia32" }, "sha512-EGNnNGQxMU5aTN7js3ETYvuw882zcO+dsVjs+DwO2j/fRVKth87C8e2GzxW1L3+iWAXMyJhvFBKRavk9Og1Z6A=="],
330
-
331
-
"@unrs/resolver-binding-win32-x64-msvc": ["@unrs/resolver-binding-win32-x64-msvc@1.3.3", "", { "os": "win32", "cpu": "x64" }, "sha512-GraLbYqOJcmW1qY3osB+2YIiD62nVf2/bVLHZmrb4t/YSUwE03l7TwcDJl08T/Tm3SVhepX8RQkpzWbag/Sb4w=="],
332
-
333
-
"@upstash/core-analytics": ["@upstash/core-analytics@0.0.10", "", { "dependencies": { "@upstash/redis": "^1.28.3" } }, "sha512-7qJHGxpQgQr9/vmeS1PktEwvNAF7TI4iJDi8Pu2CFZ9YUGHZH4fOP5TfYlZ4aVxfopnELiE4BS4FBjyK7V1/xQ=="],
334
-
335
-
"@upstash/ratelimit": ["@upstash/ratelimit@2.0.7", "", { "dependencies": { "@upstash/core-analytics": "^0.0.10" }, "peerDependencies": { "@upstash/redis": "^1.34.3" } }, "sha512-qNQW4uBPKVk8c4wFGj2S/vfKKQxXx1taSJoSGBN36FeiVBBKHQgsjPbKUijZ9Xu5FyVK+pfiXWKIsQGyoje8Fw=="],
336
-
337
-
"@upstash/redis": ["@upstash/redis@1.36.0", "", { "dependencies": { "uncrypto": "^0.1.3" } }, "sha512-9zN2UV9QJGPnXfWU3yZBLVQaqqENDh7g+Y4J2vJuSxBCi9FQ0aUOtaXlzuFhnsiZvCqM+eS27ic+tgmkWUsfOg=="],
338
-
339
-
"acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
340
-
341
-
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
342
-
343
-
"ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
344
-
345
-
"ansi-sequence-parser": ["ansi-sequence-parser@1.1.1", "", {}, "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg=="],
346
-
347
-
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
348
-
349
-
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
350
-
351
-
"aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="],
352
-
353
-
"array-buffer-byte-length": ["array-buffer-byte-length@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "is-array-buffer": "^3.0.5" } }, "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw=="],
354
-
355
-
"array-includes": ["array-includes@3.1.8", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.4", "is-string": "^1.0.7" } }, "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ=="],
356
-
357
-
"array.prototype.findlast": ["array.prototype.findlast@1.2.5", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "es-shim-unscopables": "^1.0.2" } }, "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ=="],
358
-
359
-
"array.prototype.findlastindex": ["array.prototype.findlastindex@1.2.6", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", "define-properties": "^1.2.1", "es-abstract": "^1.23.9", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "es-shim-unscopables": "^1.1.0" } }, "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ=="],
360
-
361
-
"array.prototype.flat": ["array.prototype.flat@1.3.3", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-shim-unscopables": "^1.0.2" } }, "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg=="],
362
-
363
-
"array.prototype.flatmap": ["array.prototype.flatmap@1.3.3", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-shim-unscopables": "^1.0.2" } }, "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg=="],
364
-
365
-
"array.prototype.tosorted": ["array.prototype.tosorted@1.1.4", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.3", "es-errors": "^1.3.0", "es-shim-unscopables": "^1.0.2" } }, "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA=="],
366
-
367
-
"arraybuffer.prototype.slice": ["arraybuffer.prototype.slice@1.0.4", "", { "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "is-array-buffer": "^3.0.4" } }, "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ=="],
368
-
369
-
"ast-types-flow": ["ast-types-flow@0.0.8", "", {}, "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ=="],
370
-
371
-
"async-function": ["async-function@1.0.0", "", {}, "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA=="],
372
-
373
-
"available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="],
374
-
375
-
"axe-core": ["axe-core@4.10.3", "", {}, "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg=="],
376
-
377
-
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
378
-
379
-
"bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="],
380
-
381
-
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
382
-
383
-
"brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="],
384
-
385
-
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
386
-
387
-
"bright": ["bright@1.0.0", "", { "dependencies": { "@code-hike/lighter": "^1.0.2", "server-only": "^0.0.1" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-AX93OXFCdQQrnCmyZ85gazHhKBfKcTLnj7Hx3DM3vJwuU7VONDlB58vh3hJZ9rKWLTULbScAmuapgNgzK4u4fQ=="],
388
-
389
-
"call-bind": ["call-bind@1.0.8", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" } }, "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww=="],
390
-
391
-
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
392
-
393
-
"call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="],
394
-
395
-
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
396
-
397
-
"caniuse-lite": ["caniuse-lite@1.0.30001707", "", {}, "sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw=="],
398
-
399
-
"ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="],
400
-
401
-
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
402
-
403
-
"character-entities": ["character-entities@2.0.2", "", {}, "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="],
404
-
405
-
"character-entities-html4": ["character-entities-html4@2.1.0", "", {}, "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="],
406
-
407
-
"character-entities-legacy": ["character-entities-legacy@3.0.0", "", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="],
408
-
409
-
"character-reference-invalid": ["character-reference-invalid@2.0.1", "", {}, "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw=="],
410
-
411
-
"client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="],
412
-
413
-
"code-block-writer": ["code-block-writer@13.0.3", "", {}, "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg=="],
414
-
415
-
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
416
-
417
-
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
418
-
419
-
"comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="],
420
-
421
-
"commander": ["commander@9.5.0", "", {}, "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ=="],
422
-
423
-
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
424
-
425
-
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
426
-
427
-
"crypto-js": ["crypto-js@4.2.0", "", {}, "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="],
428
-
429
-
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
430
-
431
-
"damerau-levenshtein": ["damerau-levenshtein@1.0.8", "", {}, "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA=="],
432
-
433
-
"data-view-buffer": ["data-view-buffer@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-data-view": "^1.0.2" } }, "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ=="],
434
-
435
-
"data-view-byte-length": ["data-view-byte-length@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-data-view": "^1.0.2" } }, "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ=="],
436
-
437
-
"data-view-byte-offset": ["data-view-byte-offset@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" } }, "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ=="],
438
-
439
-
"debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
440
-
441
-
"decode-named-character-reference": ["decode-named-character-reference@1.1.0", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w=="],
442
-
443
-
"deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
444
-
445
-
"define-data-property": ["define-data-property@1.1.4", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="],
446
-
447
-
"define-properties": ["define-properties@1.2.1", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="],
448
-
449
-
"dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="],
450
-
451
-
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
452
-
453
-
"devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="],
454
-
455
-
"doctrine": ["doctrine@2.1.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw=="],
456
-
457
-
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
458
-
459
-
"emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
460
-
461
-
"enhanced-resolve": ["enhanced-resolve@5.18.3", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww=="],
462
-
463
-
"entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
464
-
465
-
"envalid": ["envalid@8.1.1", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-vOUfHxAFFvkBjbVQbBfgnCO9d3GcNfMMTtVfgqSU2rQGMFEVqWy9GBuoSfHnwGu7EqR0/GeukQcL3KjFBaga9w=="],
466
-
467
-
"es-abstract": ["es-abstract@1.23.9", "", { "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.3", "data-view-buffer": "^1.0.2", "data-view-byte-length": "^1.0.2", "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", "get-intrinsic": "^1.2.7", "get-proto": "^1.0.0", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "internal-slot": "^1.1.0", "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", "is-data-view": "^1.0.2", "is-regex": "^1.2.1", "is-shared-array-buffer": "^1.0.4", "is-string": "^1.1.1", "is-typed-array": "^1.1.15", "is-weakref": "^1.1.0", "math-intrinsics": "^1.1.0", "object-inspect": "^1.13.3", "object-keys": "^1.1.1", "object.assign": "^4.1.7", "own-keys": "^1.0.1", "regexp.prototype.flags": "^1.5.3", "safe-array-concat": "^1.1.3", "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", "set-proto": "^1.0.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.3", "typed-array-byte-length": "^1.0.3", "typed-array-byte-offset": "^1.0.4", "typed-array-length": "^1.0.7", "unbox-primitive": "^1.1.0", "which-typed-array": "^1.1.18" } }, "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA=="],
468
-
469
-
"es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
470
-
471
-
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
472
-
473
-
"es-iterator-helpers": ["es-iterator-helpers@1.2.1", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-abstract": "^1.23.6", "es-errors": "^1.3.0", "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.6", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "internal-slot": "^1.1.0", "iterator.prototype": "^1.1.4", "safe-array-concat": "^1.1.3" } }, "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w=="],
474
-
475
-
"es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
476
-
477
-
"es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="],
478
-
479
-
"es-shim-unscopables": ["es-shim-unscopables@1.1.0", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw=="],
480
-
481
-
"es-to-primitive": ["es-to-primitive@1.3.0", "", { "dependencies": { "is-callable": "^1.2.7", "is-date-object": "^1.0.5", "is-symbol": "^1.0.4" } }, "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g=="],
482
-
483
-
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
484
-
485
-
"eslint": ["eslint@9.39.2", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.1", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.39.2", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw=="],
486
-
487
-
"eslint-config-next": ["eslint-config-next@15.2.1", "", { "dependencies": { "@next/eslint-plugin-next": "15.2.1", "@rushstack/eslint-patch": "^1.10.3", "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^3.5.2", "eslint-plugin-import": "^2.31.0", "eslint-plugin-jsx-a11y": "^6.10.0", "eslint-plugin-react": "^7.37.0", "eslint-plugin-react-hooks": "^5.0.0" }, "peerDependencies": { "eslint": "^7.23.0 || ^8.0.0 || ^9.0.0", "typescript": ">=3.3.1" }, "optionalPeers": ["typescript"] }, "sha512-mhsprz7l0no8X+PdDnVHF4dZKu9YBJp2Rf6ztWbXBLJ4h6gxmW//owbbGJMBVUU+PibGJDAqZhW4pt8SC8HSow=="],
488
-
489
-
"eslint-config-prettier": ["eslint-config-prettier@10.1.8", "", { "peerDependencies": { "eslint": ">=7.0.0" }, "bin": { "eslint-config-prettier": "bin/cli.js" } }, "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w=="],
490
-
491
-
"eslint-import-resolver-node": ["eslint-import-resolver-node@0.3.9", "", { "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", "resolve": "^1.22.4" } }, "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g=="],
492
-
493
-
"eslint-import-resolver-typescript": ["eslint-import-resolver-typescript@3.10.0", "", { "dependencies": { "@nolyfill/is-core-module": "1.0.39", "debug": "^4.4.0", "get-tsconfig": "^4.10.0", "is-bun-module": "^2.0.0", "stable-hash": "^0.0.5", "tinyglobby": "^0.2.12", "unrs-resolver": "^1.3.2" }, "peerDependencies": { "eslint": "*", "eslint-plugin-import": "*", "eslint-plugin-import-x": "*" }, "optionalPeers": ["eslint-plugin-import", "eslint-plugin-import-x"] }, "sha512-aV3/dVsT0/H9BtpNwbaqvl+0xGMRGzncLyhm793NFGvbwGGvzyAykqWZ8oZlZuGwuHkwJjhWJkG1cM3ynvd2pQ=="],
494
-
495
-
"eslint-module-utils": ["eslint-module-utils@2.12.0", "", { "dependencies": { "debug": "^3.2.7" } }, "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg=="],
496
-
497
-
"eslint-plugin-import": ["eslint-plugin-import@2.31.0", "", { "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.8", "array.prototype.findlastindex": "^1.2.5", "array.prototype.flat": "^1.3.2", "array.prototype.flatmap": "^1.3.2", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", "eslint-module-utils": "^2.12.0", "hasown": "^2.0.2", "is-core-module": "^2.15.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "object.groupby": "^1.0.3", "object.values": "^1.2.0", "semver": "^6.3.1", "string.prototype.trimend": "^1.0.8", "tsconfig-paths": "^3.15.0" }, "peerDependencies": { "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A=="],
498
-
499
-
"eslint-plugin-jsx-a11y": ["eslint-plugin-jsx-a11y@6.10.2", "", { "dependencies": { "aria-query": "^5.3.2", "array-includes": "^3.1.8", "array.prototype.flatmap": "^1.3.2", "ast-types-flow": "^0.0.8", "axe-core": "^4.10.0", "axobject-query": "^4.1.0", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", "hasown": "^2.0.2", "jsx-ast-utils": "^3.3.5", "language-tags": "^1.0.9", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "safe-regex-test": "^1.0.3", "string.prototype.includes": "^2.0.1" }, "peerDependencies": { "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" } }, "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q=="],
500
-
501
-
"eslint-plugin-react": ["eslint-plugin-react@7.37.4", "", { "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", "array.prototype.flatmap": "^1.3.3", "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", "es-iterator-helpers": "^1.2.1", "estraverse": "^5.3.0", "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", "object.entries": "^1.1.8", "object.fromentries": "^2.0.8", "object.values": "^1.2.1", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", "string.prototype.matchall": "^4.0.12", "string.prototype.repeat": "^1.0.0" }, "peerDependencies": { "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, "sha512-BGP0jRmfYyvOyvMoRX/uoUeW+GqNj9y16bPQzqAHf3AYII/tDs+jMN0dBVkl88/OZwNGwrVFxE7riHsXVfy/LQ=="],
502
-
503
-
"eslint-plugin-react-hooks": ["eslint-plugin-react-hooks@5.2.0", "", { "peerDependencies": { "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg=="],
504
-
505
-
"eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="],
506
-
507
-
"eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="],
508
-
509
-
"espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="],
510
-
511
-
"esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="],
512
-
513
-
"esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="],
514
-
515
-
"estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
516
-
517
-
"estree-util-is-identifier-name": ["estree-util-is-identifier-name@3.0.0", "", {}, "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg=="],
518
-
519
-
"esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
520
-
521
-
"extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="],
522
-
523
-
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
524
-
525
-
"fast-glob": ["fast-glob@3.3.1", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.4" } }, "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg=="],
526
-
527
-
"fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="],
528
-
529
-
"fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="],
530
-
531
-
"fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="],
532
-
533
-
"fdir": ["fdir@6.4.3", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw=="],
534
-
535
-
"file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
536
-
537
-
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
538
-
539
-
"find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="],
540
-
541
-
"flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="],
542
-
543
-
"flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="],
544
-
545
-
"for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="],
546
-
547
-
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
548
-
549
-
"function.prototype.name": ["function.prototype.name@1.1.8", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "functions-have-names": "^1.2.3", "hasown": "^2.0.2", "is-callable": "^1.2.7" } }, "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q=="],
550
-
551
-
"functions-have-names": ["functions-have-names@1.2.3", "", {}, "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ=="],
552
-
553
-
"get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
554
-
555
-
"get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
556
-
557
-
"get-symbol-description": ["get-symbol-description@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6" } }, "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg=="],
558
-
559
-
"get-tsconfig": ["get-tsconfig@4.10.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A=="],
560
-
561
-
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
562
-
563
-
"globals": ["globals@11.12.0", "", {}, "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="],
564
-
565
-
"globalthis": ["globalthis@1.0.4", "", { "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" } }, "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ=="],
566
-
567
-
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
568
-
569
-
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
570
-
571
-
"graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="],
572
-
573
-
"has-bigints": ["has-bigints@1.1.0", "", {}, "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg=="],
574
-
575
-
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
576
-
577
-
"has-property-descriptors": ["has-property-descriptors@1.0.2", "", { "dependencies": { "es-define-property": "^1.0.0" } }, "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg=="],
578
-
579
-
"has-proto": ["has-proto@1.2.0", "", { "dependencies": { "dunder-proto": "^1.0.0" } }, "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ=="],
580
-
581
-
"has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
582
-
583
-
"has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="],
584
-
585
-
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
586
-
587
-
"hast-util-embedded": ["hast-util-embedded@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-is-element": "^3.0.0" } }, "sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA=="],
588
-
589
-
"hast-util-format": ["hast-util-format@1.1.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-embedded": "^3.0.0", "hast-util-minify-whitespace": "^1.0.0", "hast-util-phrasing": "^3.0.0", "hast-util-whitespace": "^3.0.0", "html-whitespace-sensitive-tag-names": "^3.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-yY1UDz6bC9rDvCWHpx12aIBGRG7krurX0p0Fm6pT547LwDIZZiNr8a+IHDogorAdreULSEzP82Nlv5SZkHZcjA=="],
590
-
591
-
"hast-util-from-parse5": ["hast-util-from-parse5@8.0.3", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "devlop": "^1.0.0", "hastscript": "^9.0.0", "property-information": "^7.0.0", "vfile": "^6.0.0", "vfile-location": "^5.0.0", "web-namespaces": "^2.0.0" } }, "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg=="],
592
-
593
-
"hast-util-has-property": ["hast-util-has-property@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA=="],
594
-
595
-
"hast-util-is-body-ok-link": ["hast-util-is-body-ok-link@3.0.1", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ=="],
596
-
597
-
"hast-util-is-element": ["hast-util-is-element@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g=="],
598
-
599
-
"hast-util-minify-whitespace": ["hast-util-minify-whitespace@1.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-embedded": "^3.0.0", "hast-util-is-element": "^3.0.0", "hast-util-whitespace": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw=="],
600
-
601
-
"hast-util-parse-selector": ["hast-util-parse-selector@4.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A=="],
602
-
603
-
"hast-util-phrasing": ["hast-util-phrasing@3.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-embedded": "^3.0.0", "hast-util-has-property": "^3.0.0", "hast-util-is-body-ok-link": "^3.0.0", "hast-util-is-element": "^3.0.0" } }, "sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ=="],
604
-
605
-
"hast-util-raw": ["hast-util-raw@9.1.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "@ungap/structured-clone": "^1.0.0", "hast-util-from-parse5": "^8.0.0", "hast-util-to-parse5": "^8.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "parse5": "^7.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0", "web-namespaces": "^2.0.0", "zwitch": "^2.0.0" } }, "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw=="],
606
-
607
-
"hast-util-sanitize": ["hast-util-sanitize@5.0.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@ungap/structured-clone": "^1.0.0", "unist-util-position": "^5.0.0" } }, "sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg=="],
608
-
609
-
"hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="],
610
-
611
-
"hast-util-to-jsx-runtime": ["hast-util-to-jsx-runtime@2.3.6", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "hast-util-whitespace": "^3.0.0", "mdast-util-mdx-expression": "^2.0.0", "mdast-util-mdx-jsx": "^3.0.0", "mdast-util-mdxjs-esm": "^2.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "style-to-js": "^1.0.0", "unist-util-position": "^5.0.0", "vfile-message": "^4.0.0" } }, "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg=="],
612
-
613
-
"hast-util-to-parse5": ["hast-util-to-parse5@8.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "property-information": "^6.0.0", "space-separated-tokens": "^2.0.0", "web-namespaces": "^2.0.0", "zwitch": "^2.0.0" } }, "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw=="],
614
-
615
-
"hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="],
616
-
617
-
"hastscript": ["hastscript@9.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-parse-selector": "^4.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0" } }, "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w=="],
618
-
619
-
"html-url-attributes": ["html-url-attributes@3.0.1", "", {}, "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ=="],
620
-
621
-
"html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="],
622
-
623
-
"html-whitespace-sensitive-tag-names": ["html-whitespace-sensitive-tag-names@3.0.1", "", {}, "sha512-q+310vW8zmymYHALr1da4HyXUQ0zgiIwIicEfotYPWGN0OJVEN/58IJ3A4GBYcEq3LGAZqKb+ugvP0GNB9CEAA=="],
624
-
625
-
"ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
626
-
627
-
"import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="],
628
-
629
-
"imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
630
-
631
-
"inline-style-parser": ["inline-style-parser@0.2.4", "", {}, "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q=="],
632
-
633
-
"internal-slot": ["internal-slot@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw=="],
634
-
635
-
"is-alphabetical": ["is-alphabetical@2.0.1", "", {}, "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ=="],
636
-
637
-
"is-alphanumerical": ["is-alphanumerical@2.0.1", "", { "dependencies": { "is-alphabetical": "^2.0.0", "is-decimal": "^2.0.0" } }, "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw=="],
638
-
639
-
"is-array-buffer": ["is-array-buffer@3.0.5", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" } }, "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A=="],
640
-
641
-
"is-async-function": ["is-async-function@2.1.1", "", { "dependencies": { "async-function": "^1.0.0", "call-bound": "^1.0.3", "get-proto": "^1.0.1", "has-tostringtag": "^1.0.2", "safe-regex-test": "^1.1.0" } }, "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ=="],
642
-
643
-
"is-bigint": ["is-bigint@1.1.0", "", { "dependencies": { "has-bigints": "^1.0.2" } }, "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ=="],
644
-
645
-
"is-boolean-object": ["is-boolean-object@1.2.2", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A=="],
646
-
647
-
"is-bun-module": ["is-bun-module@2.0.0", "", { "dependencies": { "semver": "^7.7.1" } }, "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ=="],
648
-
649
-
"is-callable": ["is-callable@1.2.7", "", {}, "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA=="],
650
-
651
-
"is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="],
652
-
653
-
"is-data-view": ["is-data-view@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "get-intrinsic": "^1.2.6", "is-typed-array": "^1.1.13" } }, "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw=="],
654
-
655
-
"is-date-object": ["is-date-object@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "has-tostringtag": "^1.0.2" } }, "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg=="],
656
-
657
-
"is-decimal": ["is-decimal@2.0.1", "", {}, "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A=="],
658
-
659
-
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
660
-
661
-
"is-finalizationregistry": ["is-finalizationregistry@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg=="],
662
-
663
-
"is-generator-function": ["is-generator-function@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "get-proto": "^1.0.0", "has-tostringtag": "^1.0.2", "safe-regex-test": "^1.1.0" } }, "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ=="],
664
-
665
-
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
666
-
667
-
"is-hexadecimal": ["is-hexadecimal@2.0.1", "", {}, "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg=="],
668
-
669
-
"is-map": ["is-map@2.0.3", "", {}, "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw=="],
670
-
671
-
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
672
-
673
-
"is-number-object": ["is-number-object@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw=="],
674
-
675
-
"is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="],
676
-
677
-
"is-regex": ["is-regex@1.2.1", "", { "dependencies": { "call-bound": "^1.0.2", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g=="],
678
-
679
-
"is-set": ["is-set@2.0.3", "", {}, "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg=="],
680
-
681
-
"is-shared-array-buffer": ["is-shared-array-buffer@1.0.4", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A=="],
682
-
683
-
"is-string": ["is-string@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA=="],
684
-
685
-
"is-symbol": ["is-symbol@1.1.1", "", { "dependencies": { "call-bound": "^1.0.2", "has-symbols": "^1.1.0", "safe-regex-test": "^1.1.0" } }, "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w=="],
686
-
687
-
"is-typed-array": ["is-typed-array@1.1.15", "", { "dependencies": { "which-typed-array": "^1.1.16" } }, "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ=="],
688
-
689
-
"is-weakmap": ["is-weakmap@2.0.2", "", {}, "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w=="],
690
-
691
-
"is-weakref": ["is-weakref@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew=="],
692
-
693
-
"is-weakset": ["is-weakset@2.0.4", "", { "dependencies": { "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" } }, "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ=="],
694
-
695
-
"isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
696
-
697
-
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
698
-
699
-
"iso-datestring-validator": ["iso-datestring-validator@2.2.2", "", {}, "sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA=="],
700
-
701
-
"iterator.prototype": ["iterator.prototype@1.1.5", "", { "dependencies": { "define-data-property": "^1.1.4", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.6", "get-proto": "^1.0.0", "has-symbols": "^1.1.0", "set-function-name": "^2.0.2" } }, "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g=="],
702
-
703
-
"jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="],
704
-
705
-
"js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
706
-
707
-
"js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="],
708
-
709
-
"jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="],
710
-
711
-
"json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="],
712
-
713
-
"json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
714
-
715
-
"json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="],
716
-
717
-
"json5": ["json5@1.0.2", "", { "dependencies": { "minimist": "^1.2.0" }, "bin": { "json5": "lib/cli.js" } }, "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA=="],
718
-
719
-
"jsx-ast-utils": ["jsx-ast-utils@3.3.5", "", { "dependencies": { "array-includes": "^3.1.6", "array.prototype.flat": "^1.3.1", "object.assign": "^4.1.4", "object.values": "^1.1.6" } }, "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ=="],
720
-
721
-
"keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
722
-
723
-
"language-subtag-registry": ["language-subtag-registry@0.3.23", "", {}, "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ=="],
724
-
725
-
"language-tags": ["language-tags@1.0.9", "", { "dependencies": { "language-subtag-registry": "^0.3.20" } }, "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA=="],
726
-
727
-
"levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
728
-
729
-
"lightningcss": ["lightningcss@1.30.2", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.30.2", "lightningcss-darwin-arm64": "1.30.2", "lightningcss-darwin-x64": "1.30.2", "lightningcss-freebsd-x64": "1.30.2", "lightningcss-linux-arm-gnueabihf": "1.30.2", "lightningcss-linux-arm64-gnu": "1.30.2", "lightningcss-linux-arm64-musl": "1.30.2", "lightningcss-linux-x64-gnu": "1.30.2", "lightningcss-linux-x64-musl": "1.30.2", "lightningcss-win32-arm64-msvc": "1.30.2", "lightningcss-win32-x64-msvc": "1.30.2" } }, "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ=="],
730
-
731
-
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.30.2", "", { "os": "android", "cpu": "arm64" }, "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A=="],
732
-
733
-
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA=="],
734
-
735
-
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ=="],
736
-
737
-
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA=="],
738
-
739
-
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.2", "", { "os": "linux", "cpu": "arm" }, "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA=="],
740
-
741
-
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A=="],
742
-
743
-
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA=="],
744
-
745
-
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w=="],
746
-
747
-
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA=="],
748
-
749
-
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ=="],
750
-
751
-
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw=="],
752
-
753
-
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
754
-
755
-
"lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
756
-
757
-
"longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="],
758
-
759
-
"loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="],
760
-
761
-
"lucide-react": ["lucide-react@0.477.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-yCf7aYxerFZAbd8jHJxjwe1j7jEMPptjnaOqdYeirFnEy85cNR3/L+o0I875CYFYya+eEVzZSbNuRk8BZPDpVw=="],
762
-
763
-
"magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
764
-
765
-
"markdown-table": ["markdown-table@3.0.4", "", {}, "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw=="],
766
-
767
-
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
768
-
769
-
"mdast-util-find-and-replace": ["mdast-util-find-and-replace@3.0.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "escape-string-regexp": "^5.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg=="],
770
-
771
-
"mdast-util-from-markdown": ["mdast-util-from-markdown@2.0.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "mdast-util-to-string": "^4.0.0", "micromark": "^4.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA=="],
772
-
773
-
"mdast-util-gfm": ["mdast-util-gfm@3.1.0", "", { "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-gfm-autolink-literal": "^2.0.0", "mdast-util-gfm-footnote": "^2.0.0", "mdast-util-gfm-strikethrough": "^2.0.0", "mdast-util-gfm-table": "^2.0.0", "mdast-util-gfm-task-list-item": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ=="],
774
-
775
-
"mdast-util-gfm-autolink-literal": ["mdast-util-gfm-autolink-literal@2.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "ccount": "^2.0.0", "devlop": "^1.0.0", "mdast-util-find-and-replace": "^3.0.0", "micromark-util-character": "^2.0.0" } }, "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ=="],
776
-
777
-
"mdast-util-gfm-footnote": ["mdast-util-gfm-footnote@2.1.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.1.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0" } }, "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ=="],
778
-
779
-
"mdast-util-gfm-strikethrough": ["mdast-util-gfm-strikethrough@2.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg=="],
780
-
781
-
"mdast-util-gfm-table": ["mdast-util-gfm-table@2.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "markdown-table": "^3.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg=="],
782
-
783
-
"mdast-util-gfm-task-list-item": ["mdast-util-gfm-task-list-item@2.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ=="],
784
-
785
-
"mdast-util-mdx-expression": ["mdast-util-mdx-expression@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ=="],
786
-
787
-
"mdast-util-mdx-jsx": ["mdast-util-mdx-jsx@3.2.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "devlop": "^1.1.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0", "parse-entities": "^4.0.0", "stringify-entities": "^4.0.0", "unist-util-stringify-position": "^4.0.0", "vfile-message": "^4.0.0" } }, "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q=="],
788
-
789
-
"mdast-util-mdxjs-esm": ["mdast-util-mdxjs-esm@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg=="],
790
-
791
-
"mdast-util-phrasing": ["mdast-util-phrasing@4.1.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "unist-util-is": "^6.0.0" } }, "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w=="],
792
-
793
-
"mdast-util-to-hast": ["mdast-util-to-hast@13.2.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@ungap/structured-clone": "^1.0.0", "devlop": "^1.0.0", "micromark-util-sanitize-uri": "^2.0.0", "trim-lines": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA=="],
794
-
795
-
"mdast-util-to-markdown": ["mdast-util-to-markdown@2.1.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "longest-streak": "^3.0.0", "mdast-util-phrasing": "^4.0.0", "mdast-util-to-string": "^4.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA=="],
796
-
797
-
"mdast-util-to-string": ["mdast-util-to-string@4.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0" } }, "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg=="],
798
-
799
-
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
800
-
801
-
"micromark": ["micromark@4.0.2", "", { "dependencies": { "@types/debug": "^4.0.0", "debug": "^4.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA=="],
802
-
803
-
"micromark-core-commonmark": ["micromark-core-commonmark@2.0.3", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-destination": "^2.0.0", "micromark-factory-label": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-factory-title": "^2.0.0", "micromark-factory-whitespace": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-html-tag-name": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg=="],
804
-
805
-
"micromark-extension-gfm": ["micromark-extension-gfm@3.0.0", "", { "dependencies": { "micromark-extension-gfm-autolink-literal": "^2.0.0", "micromark-extension-gfm-footnote": "^2.0.0", "micromark-extension-gfm-strikethrough": "^2.0.0", "micromark-extension-gfm-table": "^2.0.0", "micromark-extension-gfm-tagfilter": "^2.0.0", "micromark-extension-gfm-task-list-item": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w=="],
806
-
807
-
"micromark-extension-gfm-autolink-literal": ["micromark-extension-gfm-autolink-literal@2.1.0", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw=="],
808
-
809
-
"micromark-extension-gfm-footnote": ["micromark-extension-gfm-footnote@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw=="],
810
-
811
-
"micromark-extension-gfm-strikethrough": ["micromark-extension-gfm-strikethrough@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw=="],
812
-
813
-
"micromark-extension-gfm-table": ["micromark-extension-gfm-table@2.1.1", "", { "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg=="],
814
-
815
-
"micromark-extension-gfm-tagfilter": ["micromark-extension-gfm-tagfilter@2.0.0", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg=="],
816
-
817
-
"micromark-extension-gfm-task-list-item": ["micromark-extension-gfm-task-list-item@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw=="],
818
-
819
-
"micromark-factory-destination": ["micromark-factory-destination@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA=="],
820
-
821
-
"micromark-factory-label": ["micromark-factory-label@2.0.1", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg=="],
822
-
823
-
"micromark-factory-space": ["micromark-factory-space@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg=="],
824
-
825
-
"micromark-factory-title": ["micromark-factory-title@2.0.1", "", { "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw=="],
826
-
827
-
"micromark-factory-whitespace": ["micromark-factory-whitespace@2.0.1", "", { "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ=="],
828
-
829
-
"micromark-util-character": ["micromark-util-character@2.1.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q=="],
830
-
831
-
"micromark-util-chunked": ["micromark-util-chunked@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA=="],
832
-
833
-
"micromark-util-classify-character": ["micromark-util-classify-character@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q=="],
834
-
835
-
"micromark-util-combine-extensions": ["micromark-util-combine-extensions@2.0.1", "", { "dependencies": { "micromark-util-chunked": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg=="],
836
-
837
-
"micromark-util-decode-numeric-character-reference": ["micromark-util-decode-numeric-character-reference@2.0.2", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw=="],
838
-
839
-
"micromark-util-decode-string": ["micromark-util-decode-string@2.0.1", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "micromark-util-character": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ=="],
840
-
841
-
"micromark-util-encode": ["micromark-util-encode@2.0.1", "", {}, "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="],
842
-
843
-
"micromark-util-html-tag-name": ["micromark-util-html-tag-name@2.0.1", "", {}, "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA=="],
844
-
845
-
"micromark-util-normalize-identifier": ["micromark-util-normalize-identifier@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q=="],
846
-
847
-
"micromark-util-resolve-all": ["micromark-util-resolve-all@2.0.1", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg=="],
848
-
849
-
"micromark-util-sanitize-uri": ["micromark-util-sanitize-uri@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ=="],
850
-
851
-
"micromark-util-subtokenize": ["micromark-util-subtokenize@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA=="],
852
-
853
-
"micromark-util-symbol": ["micromark-util-symbol@2.0.1", "", {}, "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="],
854
-
855
-
"micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="],
856
-
857
-
"micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
858
-
859
-
"mime-db": ["mime-db@1.25.0", "", {}, "sha512-5k547tI4Cy+Lddr/hdjNbBEWBwSl8EBc5aSdKvedav8DReADgWJzcYiktaRIw3GtGC1jjwldXtTzvqJZmtvC7w=="],
860
-
861
-
"mime-types": ["mime-types@2.1.13", "", { "dependencies": { "mime-db": "~1.25.0" } }, "sha512-ryBDp1Z/6X90UvjUK3RksH0IBPM137T7cmg4OgD5wQBojlAiUwuok0QeELkim/72EtcYuNlmbkrcGuxj3Kl0YQ=="],
862
-
863
-
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
864
-
865
-
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
866
-
867
-
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
868
-
869
-
"multiformats": ["multiformats@13.4.2", "", {}, "sha512-eh6eHCrRi1+POZ3dA+Dq1C6jhP1GNtr9CRINMb67OKzqW9I5DUuZM/3jLPlzhgpGeiNUlEGEbkCYChXMCc/8DQ=="],
870
-
871
-
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
872
-
873
-
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
874
-
875
-
"next": ["next@15.5.9", "", { "dependencies": { "@next/env": "15.5.9", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "15.5.7", "@next/swc-darwin-x64": "15.5.7", "@next/swc-linux-arm64-gnu": "15.5.7", "@next/swc-linux-arm64-musl": "15.5.7", "@next/swc-linux-x64-gnu": "15.5.7", "@next/swc-linux-x64-musl": "15.5.7", "@next/swc-win32-arm64-msvc": "15.5.7", "@next/swc-win32-x64-msvc": "15.5.7", "sharp": "^0.34.3" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-agNLK89seZEtC5zUHwtut0+tNrc0Xw4FT/Dg+B/VLEo9pAcS9rtTKpek3V6kVcVwsB2YlqMaHdfZL4eLEVYuCg=="],
876
-
877
-
"next-plausible": ["next-plausible@3.12.5", "", { "peerDependencies": { "next": "^11.1.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 ", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-l1YMuTI9akb2u7z4hyTuxXpudy8KfSteRNXCYpWpnhAoBjaWQlv6sITai1TwcR7wWvVW8DFbLubvMQAsirAjcA=="],
878
-
879
-
"object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
880
-
881
-
"object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="],
882
-
883
-
"object-keys": ["object-keys@1.1.1", "", {}, "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="],
884
-
885
-
"object.assign": ["object.assign@4.1.7", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0", "has-symbols": "^1.1.0", "object-keys": "^1.1.1" } }, "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw=="],
886
-
887
-
"object.entries": ["object.entries@1.1.9", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", "define-properties": "^1.2.1", "es-object-atoms": "^1.1.1" } }, "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw=="],
888
-
889
-
"object.fromentries": ["object.fromentries@2.0.8", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2", "es-object-atoms": "^1.0.0" } }, "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ=="],
890
-
891
-
"object.groupby": ["object.groupby@1.0.3", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2" } }, "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ=="],
892
-
893
-
"object.values": ["object.values@1.2.1", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA=="],
894
-
895
-
"optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="],
896
-
897
-
"own-keys": ["own-keys@1.0.1", "", { "dependencies": { "get-intrinsic": "^1.2.6", "object-keys": "^1.1.1", "safe-push-apply": "^1.0.0" } }, "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg=="],
898
-
899
-
"p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
900
-
901
-
"p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
902
-
903
-
"parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="],
904
-
905
-
"parse-entities": ["parse-entities@4.0.2", "", { "dependencies": { "@types/unist": "^2.0.0", "character-entities-legacy": "^3.0.0", "character-reference-invalid": "^2.0.0", "decode-named-character-reference": "^1.0.0", "is-alphanumerical": "^2.0.0", "is-decimal": "^2.0.0", "is-hexadecimal": "^2.0.0" } }, "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw=="],
906
-
907
-
"parse5": ["parse5@7.2.1", "", { "dependencies": { "entities": "^4.5.0" } }, "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ=="],
908
-
909
-
"path-browserify": ["path-browserify@1.0.1", "", {}, "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g=="],
910
-
911
-
"path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
912
-
913
-
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
914
-
915
-
"path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="],
916
-
917
-
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
918
-
919
-
"picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="],
920
-
921
-
"possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="],
922
-
923
-
"postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
924
-
925
-
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
926
-
927
-
"prettier": ["prettier@3.7.4", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA=="],
928
-
929
-
"prettier-plugin-tailwindcss": ["prettier-plugin-tailwindcss@0.6.14", "", { "peerDependencies": { "@ianvs/prettier-plugin-sort-imports": "*", "@prettier/plugin-hermes": "*", "@prettier/plugin-oxc": "*", "@prettier/plugin-pug": "*", "@shopify/prettier-plugin-liquid": "*", "@trivago/prettier-plugin-sort-imports": "*", "@zackad/prettier-plugin-twig": "*", "prettier": "^3.0", "prettier-plugin-astro": "*", "prettier-plugin-css-order": "*", "prettier-plugin-import-sort": "*", "prettier-plugin-jsdoc": "*", "prettier-plugin-marko": "*", "prettier-plugin-multiline-arrays": "*", "prettier-plugin-organize-attributes": "*", "prettier-plugin-organize-imports": "*", "prettier-plugin-sort-imports": "*", "prettier-plugin-style-order": "*", "prettier-plugin-svelte": "*" }, "optionalPeers": ["@ianvs/prettier-plugin-sort-imports", "@prettier/plugin-hermes", "@prettier/plugin-oxc", "@prettier/plugin-pug", "@shopify/prettier-plugin-liquid", "@trivago/prettier-plugin-sort-imports", "@zackad/prettier-plugin-twig", "prettier-plugin-astro", "prettier-plugin-css-order", "prettier-plugin-import-sort", "prettier-plugin-jsdoc", "prettier-plugin-marko", "prettier-plugin-multiline-arrays", "prettier-plugin-organize-attributes", "prettier-plugin-organize-imports", "prettier-plugin-sort-imports", "prettier-plugin-style-order", "prettier-plugin-svelte"] }, "sha512-pi2e/+ZygeIqntN+vC573BcW5Cve8zUB0SSAGxqpB4f96boZF4M3phPVoOFCeypwkpRYdi7+jQ5YJJUwrkGUAg=="],
930
-
931
-
"prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="],
932
-
933
-
"property-information": ["property-information@7.0.0", "", {}, "sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg=="],
934
-
935
-
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
936
-
937
-
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
938
-
939
-
"react": ["react@19.2.3", "", {}, "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA=="],
940
-
941
-
"react-dom": ["react-dom@19.2.3", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.3" } }, "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg=="],
942
-
943
-
"react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
944
-
945
-
"react-markdown": ["react-markdown@10.1.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "hast-util-to-jsx-runtime": "^2.0.0", "html-url-attributes": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.0.0", "unified": "^11.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" }, "peerDependencies": { "@types/react": ">=18", "react": ">=18" } }, "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ=="],
946
-
947
-
"reading-time": ["reading-time@1.5.0", "", {}, "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg=="],
948
-
949
-
"reflect.getprototypeof": ["reflect.getprototypeof@1.0.10", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.9", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.7", "get-proto": "^1.0.1", "which-builtin-type": "^1.2.1" } }, "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw=="],
950
-
951
-
"regexp.prototype.flags": ["regexp.prototype.flags@1.5.4", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", "get-proto": "^1.0.1", "gopd": "^1.2.0", "set-function-name": "^2.0.2" } }, "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA=="],
952
-
953
-
"rehype-format": ["rehype-format@5.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-format": "^1.0.0" } }, "sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ=="],
954
-
955
-
"rehype-raw": ["rehype-raw@7.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-raw": "^9.0.0", "vfile": "^6.0.0" } }, "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww=="],
956
-
957
-
"rehype-sanitize": ["rehype-sanitize@6.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-sanitize": "^5.0.0" } }, "sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg=="],
958
-
959
-
"rehype-stringify": ["rehype-stringify@10.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-to-html": "^9.0.0", "unified": "^11.0.0" } }, "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA=="],
960
-
961
-
"remark-gfm": ["remark-gfm@4.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-gfm": "^3.0.0", "micromark-extension-gfm": "^3.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.0" } }, "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg=="],
962
-
963
-
"remark-parse": ["remark-parse@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", "micromark-util-types": "^2.0.0", "unified": "^11.0.0" } }, "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA=="],
964
-
965
-
"remark-rehype": ["remark-rehype@11.1.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "mdast-util-to-hast": "^13.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw=="],
966
-
967
-
"remark-stringify": ["remark-stringify@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-to-markdown": "^2.0.0", "unified": "^11.0.0" } }, "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw=="],
968
-
969
-
"resolve": ["resolve@1.22.10", "", { "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w=="],
970
-
971
-
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
972
-
973
-
"resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="],
974
-
975
-
"reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="],
976
-
977
-
"rss": ["rss@1.2.2", "", { "dependencies": { "mime-types": "2.1.13", "xml": "1.0.1" } }, "sha512-xUhRTgslHeCBeHAqaWSbOYTydN2f0tAzNXvzh3stjz7QDhQMzdgHf3pfgNIngeytQflrFPfy6axHilTETr6gDg=="],
978
-
979
-
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
980
-
981
-
"safe-array-concat": ["safe-array-concat@1.1.3", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "get-intrinsic": "^1.2.6", "has-symbols": "^1.1.0", "isarray": "^2.0.5" } }, "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q=="],
982
-
983
-
"safe-push-apply": ["safe-push-apply@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "isarray": "^2.0.5" } }, "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA=="],
984
-
985
-
"safe-regex-test": ["safe-regex-test@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-regex": "^1.2.1" } }, "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw=="],
986
-
987
-
"scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
988
-
989
-
"semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="],
990
-
991
-
"server-only": ["server-only@0.0.1", "", {}, "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA=="],
992
-
993
-
"set-function-length": ["set-function-length@1.2.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" } }, "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg=="],
994
-
995
-
"set-function-name": ["set-function-name@2.0.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", "has-property-descriptors": "^1.0.2" } }, "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ=="],
996
-
997
-
"set-proto": ["set-proto@1.0.0", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0" } }, "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw=="],
998
-
999
-
"sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="],
1000
-
1001
-
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
1002
-
1003
-
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
1004
-
1005
-
"side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="],
1006
-
1007
-
"side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="],
1008
-
1009
-
"side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="],
1010
-
1011
-
"side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="],
1012
-
1013
-
"simple-icons": ["simple-icons@14.15.0", "", {}, "sha512-yjlJ8skP4isCd4dQTDGFbv0hQgDIr57DbWaovEeHADPAZa5DBEAs+3ZnBb76ti+yz7/OzFI3SqTP1SKku1uhCw=="],
1014
-
1015
-
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
1016
-
1017
-
"space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="],
1018
-
1019
-
"stable-hash": ["stable-hash@0.0.5", "", {}, "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA=="],
1020
-
1021
-
"string.prototype.includes": ["string.prototype.includes@2.0.1", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.3" } }, "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg=="],
1022
-
1023
-
"string.prototype.matchall": ["string.prototype.matchall@4.0.12", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-abstract": "^1.23.6", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.6", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "internal-slot": "^1.1.0", "regexp.prototype.flags": "^1.5.3", "set-function-name": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA=="],
1024
-
1025
-
"string.prototype.repeat": ["string.prototype.repeat@1.0.0", "", { "dependencies": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" } }, "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w=="],
1026
-
1027
-
"string.prototype.trim": ["string.prototype.trim@1.2.10", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "define-data-property": "^1.1.4", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-object-atoms": "^1.0.0", "has-property-descriptors": "^1.0.2" } }, "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA=="],
1028
-
1029
-
"string.prototype.trimend": ["string.prototype.trimend@1.0.9", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ=="],
1030
-
1031
-
"string.prototype.trimstart": ["string.prototype.trimstart@1.0.8", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg=="],
1032
-
1033
-
"stringify-entities": ["stringify-entities@4.0.4", "", { "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" } }, "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="],
1034
-
1035
-
"strip-bom": ["strip-bom@3.0.0", "", {}, "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="],
1036
-
1037
-
"strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
1038
-
1039
-
"style-to-js": ["style-to-js@1.1.16", "", { "dependencies": { "style-to-object": "1.0.8" } }, "sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw=="],
1040
-
1041
-
"style-to-object": ["style-to-object@1.0.8", "", { "dependencies": { "inline-style-parser": "0.2.4" } }, "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g=="],
1042
-
1043
-
"styled-jsx": ["styled-jsx@5.1.6", "", { "dependencies": { "client-only": "0.0.1" }, "peerDependencies": { "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" } }, "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA=="],
1044
-
1045
-
"supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
1046
-
1047
-
"supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
1048
-
1049
-
"tailwind-merge": ["tailwind-merge@3.4.0", "", {}, "sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g=="],
1050
-
1051
-
"tailwindcss": ["tailwindcss@4.1.18", "", {}, "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw=="],
1052
-
1053
-
"tapable": ["tapable@2.2.1", "", {}, "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ=="],
1054
-
1055
-
"tinyglobby": ["tinyglobby@0.2.12", "", { "dependencies": { "fdir": "^6.4.3", "picomatch": "^4.0.2" } }, "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww=="],
1056
-
1057
-
"tm-grammars": ["tm-grammars@1.23.7", "", {}, "sha512-jrtCF2+/hNKsmoqrwYoir4mB8qZDMN9w9ho6QQx9U9Edqy32Dktpyw8hS+OEUBsSTypdQUtSYNQEdAKpIuQXhQ=="],
1058
-
1059
-
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
1060
-
1061
-
"trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="],
1062
-
1063
-
"trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="],
1064
-
1065
-
"ts-api-utils": ["ts-api-utils@2.1.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ=="],
1066
-
1067
-
"ts-morph": ["ts-morph@24.0.0", "", { "dependencies": { "@ts-morph/common": "~0.25.0", "code-block-writer": "^13.0.3" } }, "sha512-2OAOg/Ob5yx9Et7ZX4CvTCc0UFoZHwLEJ+dpDPSUi5TgwwlTlX47w+iFRrEwzUZwYACjq83cgjS/Da50Ga37uw=="],
1068
-
1069
-
"tsconfig-paths": ["tsconfig-paths@3.15.0", "", { "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg=="],
1070
-
1071
-
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
1072
-
1073
-
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
1074
-
1075
-
"typed-array-buffer": ["typed-array-buffer@1.0.3", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-typed-array": "^1.1.14" } }, "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw=="],
1076
-
1077
-
"typed-array-byte-length": ["typed-array-byte-length@1.0.3", "", { "dependencies": { "call-bind": "^1.0.8", "for-each": "^0.3.3", "gopd": "^1.2.0", "has-proto": "^1.2.0", "is-typed-array": "^1.1.14" } }, "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg=="],
1078
-
1079
-
"typed-array-byte-offset": ["typed-array-byte-offset@1.0.4", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "for-each": "^0.3.3", "gopd": "^1.2.0", "has-proto": "^1.2.0", "is-typed-array": "^1.1.15", "reflect.getprototypeof": "^1.0.9" } }, "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ=="],
1080
-
1081
-
"typed-array-length": ["typed-array-length@1.0.7", "", { "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", "is-typed-array": "^1.1.13", "possible-typed-array-names": "^1.0.0", "reflect.getprototypeof": "^1.0.6" } }, "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg=="],
1082
-
1083
-
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
1084
-
1085
-
"uint8arrays": ["uint8arrays@3.0.0", "", { "dependencies": { "multiformats": "^9.4.2" } }, "sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA=="],
1086
-
1087
-
"unbox-primitive": ["unbox-primitive@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", "has-symbols": "^1.1.0", "which-boxed-primitive": "^1.1.1" } }, "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw=="],
1088
-
1089
-
"uncrypto": ["uncrypto@0.1.3", "", {}, "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q=="],
1090
-
1091
-
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
1092
-
1093
-
"unicode-segmenter": ["unicode-segmenter@0.14.1", "", {}, "sha512-yHedxlEpUyD+u1UE8qAuCMXVdMLn7yUdlmd8WN7FGmO1ICnpE7LJfnmuXBB+T0zkie3qHsy8fSucqceI/MylOg=="],
1094
-
1095
-
"unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", "devlop": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", "vfile": "^6.0.0" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="],
1096
-
1097
-
"unist-util-is": ["unist-util-is@6.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw=="],
1098
-
1099
-
"unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="],
1100
-
1101
-
"unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="],
1102
-
1103
-
"unist-util-visit": ["unist-util-visit@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg=="],
1104
-
1105
-
"unist-util-visit-parents": ["unist-util-visit-parents@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw=="],
1106
-
1107
-
"unrs-resolver": ["unrs-resolver@1.3.3", "", { "optionalDependencies": { "@unrs/resolver-binding-darwin-arm64": "1.3.3", "@unrs/resolver-binding-darwin-x64": "1.3.3", "@unrs/resolver-binding-freebsd-x64": "1.3.3", "@unrs/resolver-binding-linux-arm-gnueabihf": "1.3.3", "@unrs/resolver-binding-linux-arm-musleabihf": "1.3.3", "@unrs/resolver-binding-linux-arm64-gnu": "1.3.3", "@unrs/resolver-binding-linux-arm64-musl": "1.3.3", "@unrs/resolver-binding-linux-ppc64-gnu": "1.3.3", "@unrs/resolver-binding-linux-s390x-gnu": "1.3.3", "@unrs/resolver-binding-linux-x64-gnu": "1.3.3", "@unrs/resolver-binding-linux-x64-musl": "1.3.3", "@unrs/resolver-binding-wasm32-wasi": "1.3.3", "@unrs/resolver-binding-win32-arm64-msvc": "1.3.3", "@unrs/resolver-binding-win32-ia32-msvc": "1.3.3", "@unrs/resolver-binding-win32-x64-msvc": "1.3.3" } }, "sha512-PFLAGQzYlyjniXdbmQ3dnGMZJXX5yrl2YS4DLRfR3BhgUsE1zpRIrccp9XMOGRfIHpdFvCn/nr5N1KMVda4x3A=="],
1108
-
1109
-
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
1110
-
1111
-
"vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="],
1112
-
1113
-
"vfile-location": ["vfile-location@5.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg=="],
1114
-
1115
-
"vfile-message": ["vfile-message@4.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw=="],
1116
-
1117
-
"web-namespaces": ["web-namespaces@2.0.1", "", {}, "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ=="],
1118
-
1119
-
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
1120
-
1121
-
"which-boxed-primitive": ["which-boxed-primitive@1.1.1", "", { "dependencies": { "is-bigint": "^1.1.0", "is-boolean-object": "^1.2.1", "is-number-object": "^1.1.1", "is-string": "^1.1.1", "is-symbol": "^1.1.1" } }, "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA=="],
1122
-
1123
-
"which-builtin-type": ["which-builtin-type@1.2.1", "", { "dependencies": { "call-bound": "^1.0.2", "function.prototype.name": "^1.1.6", "has-tostringtag": "^1.0.2", "is-async-function": "^2.0.0", "is-date-object": "^1.1.0", "is-finalizationregistry": "^1.1.0", "is-generator-function": "^1.0.10", "is-regex": "^1.2.1", "is-weakref": "^1.0.2", "isarray": "^2.0.5", "which-boxed-primitive": "^1.1.0", "which-collection": "^1.0.2", "which-typed-array": "^1.1.16" } }, "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q=="],
1124
-
1125
-
"which-collection": ["which-collection@1.0.2", "", { "dependencies": { "is-map": "^2.0.3", "is-set": "^2.0.3", "is-weakmap": "^2.0.2", "is-weakset": "^2.0.3" } }, "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw=="],
1126
-
1127
-
"which-typed-array": ["which-typed-array@1.1.19", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "for-each": "^0.3.5", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" } }, "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw=="],
1128
-
1129
-
"word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
1130
-
1131
-
"xml": ["xml@1.0.1", "", {}, "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw=="],
1132
-
1133
-
"yesno": ["yesno@0.4.0", "", {}, "sha512-tdBxmHvbXPBKYIg81bMCB7bVeDmHkRzk5rVJyYYXurwKkHq/MCd8rz4HSJUP7hW0H2NlXiq8IFiWvYKEHhlotA=="],
1134
-
1135
-
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
1136
-
1137
-
"zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
1138
-
1139
-
"zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="],
1140
-
1141
-
"@atproto/common-web/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="],
1142
-
1143
-
"@atproto/lex-cli/prettier": ["prettier@3.5.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw=="],
1144
-
1145
-
"@atproto/lex-data/@atproto/syntax": ["@atproto/syntax@0.4.2", "", {}, "sha512-X9XSRPinBy/0VQ677j8VXlBsYSsUXaiqxWVpGGxJYsAhugdQRb0jqaVKJFtm6RskeNkV6y9xclSUi9UYG/COrA=="],
1146
-
1147
-
"@atproto/lex-data/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="],
1148
-
1149
-
"@atproto/lexicon/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="],
1150
-
1151
-
"@atproto/xrpc/@atproto/lexicon": ["@atproto/lexicon@0.6.0", "", { "dependencies": { "@atproto/common-web": "^0.4.7", "@atproto/syntax": "^0.4.2", "iso-datestring-validator": "^2.2.2", "multiformats": "^9.9.0", "zod": "^3.23.8" } }, "sha512-5veb8aD+J5M0qszLJ+73KSFsFrJBgAY/nM1TSAJvGY7fNc9ZAT+PSUlmIyrdye9YznAZ07yktalls/TwNV7cHQ=="],
1152
-
1153
-
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
1154
-
1155
-
"@eslint/eslintrc/espree": ["espree@10.3.0", "", { "dependencies": { "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.0" } }, "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg=="],
1156
-
1157
-
"@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
1158
-
1159
-
"@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
1160
-
1161
-
"@napi-rs/wasm-runtime/@emnapi/runtime": ["@emnapi/runtime@1.4.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-64WYIf4UYcdLnbKn/umDlNjQDSS8AgZrI/R9+x5ilkUVFxXcA1Ebl+gQLc/6mERA4407Xof0R7wEyEuj091CVw=="],
1162
-
1163
-
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.7.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg=="],
1164
-
1165
-
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.7.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA=="],
1166
-
1167
-
"@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="],
1168
-
1169
-
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.0", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" }, "bundled": true }, "sha512-Fq6DJW+Bb5jaWE69/qOE0D1TUN9+6uWhCeZpdnSBk14pjLcCWR7Q8n49PTSPHazM37JqrsdpEthXy2xn6jWWiA=="],
1170
-
1171
-
"@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
1172
-
1173
-
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
1174
-
1175
-
"@ts-morph/common/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
1176
-
1177
-
"@typescript-eslint/typescript-estree/fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="],
1178
-
1179
-
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
1180
-
1181
-
"@typescript-eslint/utils/@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.5.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w=="],
1182
-
1183
-
"@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@4.2.0", "", {}, "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw=="],
1184
-
1185
-
"@upstash/core-analytics/@upstash/redis": ["@upstash/redis@1.34.7", "", { "dependencies": { "crypto-js": "^4.2.0" } }, "sha512-EJ/g+ttDL3MFS8WNDLj/Buybo3FpPw2IAFl4X8lxh8/l7YTq6kTqT6FKkq8eYRdN6lGlVw+W6qnmym734m39Tg=="],
1186
-
1187
-
"eslint-import-resolver-node/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
1188
-
1189
-
"eslint-module-utils/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
1190
-
1191
-
"eslint-plugin-import/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
1192
-
1193
-
"eslint-plugin-import/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
1194
-
1195
-
"eslint-plugin-react/resolve": ["resolve@2.0.0-next.5", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA=="],
1196
-
1197
-
"eslint-plugin-react/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
1198
-
1199
-
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
1200
-
1201
-
"hast-util-to-parse5/property-information": ["property-information@6.5.0", "", {}, "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig=="],
1202
-
1203
-
"lightningcss/detect-libc": ["detect-libc@2.0.3", "", {}, "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw=="],
1204
-
1205
-
"magic-string/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
1206
-
1207
-
"mdast-util-find-and-replace/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="],
1208
-
1209
-
"micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
1210
-
1211
-
"next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
1212
-
1213
-
"parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="],
1214
-
1215
-
"react-markdown/remark-rehype": ["remark-rehype@11.1.1", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "mdast-util-to-hast": "^13.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-g/osARvjkBXb6Wo0XvAeXQohVta8i84ACbenPpoSsxTOQH/Ae0/RGP4WZgnMH5pMLpsj4FG7OHmcIcXxpza8eQ=="],
1216
-
1217
-
"sharp/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
1218
-
1219
-
"uint8arrays/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="],
1220
-
1221
-
"@atproto/xrpc/@atproto/lexicon/@atproto/common-web": ["@atproto/common-web@0.4.7", "", { "dependencies": { "@atproto/lex-data": "0.0.3", "@atproto/lex-json": "0.0.3", "zod": "^3.23.8" } }, "sha512-vjw2+81KPo2/SAbbARGn64Ln+6JTI0FTI4xk8if0ebBfDxFRmHb2oSN1y77hzNq/ybGHqA2mecfhS03pxC5+lg=="],
1222
-
1223
-
"@atproto/xrpc/@atproto/lexicon/@atproto/syntax": ["@atproto/syntax@0.4.2", "", {}, "sha512-X9XSRPinBy/0VQ677j8VXlBsYSsUXaiqxWVpGGxJYsAhugdQRb0jqaVKJFtm6RskeNkV6y9xclSUi9UYG/COrA=="],
1224
-
1225
-
"@atproto/xrpc/@atproto/lexicon/multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="],
1226
-
1227
-
"@eslint/eslintrc/espree/acorn": ["acorn@8.14.1", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg=="],
1228
-
1229
-
"@eslint/eslintrc/espree/eslint-visitor-keys": ["eslint-visitor-keys@4.2.0", "", {}, "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw=="],
1230
-
1231
-
"@ts-morph/common/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
1232
-
1233
-
"@typescript-eslint/typescript-estree/fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
1234
-
1235
-
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
1236
-
1237
-
"@typescript-eslint/utils/@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
1238
-
}
1239
-
}
···
bun.lockb
bun.lockb
This is a binary file and will not be displayed.
+22
components.json
+22
components.json
···
···
1
+
{
2
+
"$schema": "https://ui.shadcn.com/schema.json",
3
+
"style": "new-york",
4
+
"rsc": true,
5
+
"tsx": true,
6
+
"tailwind": {
7
+
"config": "",
8
+
"css": "src/app/globals.css",
9
+
"baseColor": "neutral",
10
+
"cssVariables": true,
11
+
"prefix": ""
12
+
},
13
+
"iconLibrary": "lucide",
14
+
"aliases": {
15
+
"components": "#/components",
16
+
"utils": "#/lib/utils",
17
+
"ui": "#/components/ui",
18
+
"lib": "#/lib",
19
+
"hooks": "#/hooks"
20
+
},
21
+
"registries": {}
22
+
}
+2
lexicon-type.sh
+2
lexicon-type.sh
+248
-86
lexiconTypes/index.ts
+248
-86
lexiconTypes/index.ts
···
2
* GENERATED CODE - DO NOT MODIFY
3
*/
4
import {
5
-
ComAtprotoRepoCreateRecord,
6
-
ComAtprotoRepoDeleteRecord,
7
-
ComAtprotoRepoGetRecord,
8
-
ComAtprotoRepoListRecords,
9
-
} from "@atcute/client/lexicons";
10
-
import {
11
-
XrpcClient,
12
-
type FetchHandler,
13
-
type FetchHandlerOptions,
14
-
} from "@atproto/xrpc";
15
16
-
import { schemas } from "./lexicons.js";
17
-
import * as NetMmattRightNow from "./types/net/mmatt/right/now.js";
18
-
import { type OmitKey, type Un$Typed } from "./util.js";
19
20
-
export * as NetMmattRightNow from "./types/net/mmatt/right/now.js";
21
22
-
export class AtpBaseClient extends XrpcClient {
23
-
net: NetNS;
24
25
-
constructor(options: FetchHandler | FetchHandlerOptions) {
26
-
super(options, schemas);
27
-
this.net = new NetNS(this);
28
}
29
30
-
/** @deprecated use `this` instead */
31
-
get xrpc(): XrpcClient {
32
-
return this;
33
}
34
}
35
36
-
export class NetNS {
37
-
_client: XrpcClient;
38
-
mmatt: NetMmattNS;
39
40
-
constructor(client: XrpcClient) {
41
-
this._client = client;
42
-
this.mmatt = new NetMmattNS(client);
43
}
44
}
45
46
-
export class NetMmattNS {
47
-
_client: XrpcClient;
48
-
right: NetMmattRightNS;
49
50
-
constructor(client: XrpcClient) {
51
-
this._client = client;
52
-
this.right = new NetMmattRightNS(client);
53
}
54
}
55
56
-
export class NetMmattRightNS {
57
-
_client: XrpcClient;
58
-
now: NetMmattRightNowRecord;
59
60
-
constructor(client: XrpcClient) {
61
-
this._client = client;
62
-
this.now = new NetMmattRightNowRecord(client);
63
}
64
}
65
66
-
export class NetMmattRightNowRecord {
67
-
_client: XrpcClient;
68
69
-
constructor(client: XrpcClient) {
70
-
this._client = client;
71
}
72
73
-
async list(
74
-
params: OmitKey<ComAtprotoRepoListRecords.Params, "collection">,
75
-
): Promise<{
76
-
cursor?: string;
77
-
records: { uri: string; value: NetMmattRightNow.Record }[];
78
-
}> {
79
-
const res = await this._client.call("com.atproto.repo.listRecords", {
80
-
collection: "net.mmatt.right.now",
81
-
...params,
82
-
});
83
-
return res.data;
84
}
85
86
-
async get(
87
-
params: OmitKey<ComAtprotoRepoGetRecord.Params, "collection">,
88
-
): Promise<{ uri: string; cid: string; value: NetMmattRightNow.Record }> {
89
-
const res = await this._client.call("com.atproto.repo.getRecord", {
90
-
collection: "net.mmatt.right.now",
91
-
...params,
92
-
});
93
-
return res.data;
94
}
95
96
-
async create(
97
-
params: OmitKey<ComAtprotoRepoCreateRecord.Input, "collection" | "record">,
98
-
record: Un$Typed<NetMmattRightNow.Record>,
99
-
headers?: Record<string, string>,
100
-
): Promise<{ uri: string; cid: string }> {
101
-
const collection = "net.mmatt.right.now";
102
-
const res = await this._client.call(
103
-
"com.atproto.repo.createRecord",
104
-
undefined,
105
-
{ collection, ...params, record: { ...record, $type: collection } },
106
-
{ encoding: "application/json", headers },
107
-
);
108
-
return res.data;
109
}
110
111
-
async delete(
112
-
params: OmitKey<ComAtprotoRepoDeleteRecord.Input, "collection">,
113
-
headers?: Record<string, string>,
114
-
): Promise<void> {
115
-
await this._client.call(
116
-
"com.atproto.repo.deleteRecord",
117
-
undefined,
118
-
{ collection: "net.mmatt.right.now", ...params },
119
-
{ headers },
120
-
);
121
}
122
}
···
2
* GENERATED CODE - DO NOT MODIFY
3
*/
4
import {
5
+
type Auth,
6
+
type Options as XrpcOptions,
7
+
Server as XrpcServer,
8
+
type StreamConfigOrHandler,
9
+
type MethodConfigOrHandler,
10
+
createServer as createXrpcServer,
11
+
} from '@atproto/xrpc-server'
12
+
import { schemas } from './lexicons.js'
13
+
import * as FmTealAlphaActorGetProfile from './types/fm/teal/alpha/actor/getProfile.js'
14
+
import * as FmTealAlphaActorGetProfiles from './types/fm/teal/alpha/actor/getProfiles.js'
15
+
import * as FmTealAlphaActorSearchActors from './types/fm/teal/alpha/actor/searchActors.js'
16
+
import * as FmTealAlphaFeedGetActorFeed from './types/fm/teal/alpha/feed/getActorFeed.js'
17
+
import * as FmTealAlphaFeedGetPlay from './types/fm/teal/alpha/feed/getPlay.js'
18
+
import * as FmTealAlphaStatsGetLatest from './types/fm/teal/alpha/stats/getLatest.js'
19
+
import * as FmTealAlphaStatsGetTopArtists from './types/fm/teal/alpha/stats/getTopArtists.js'
20
+
import * as FmTealAlphaStatsGetTopReleases from './types/fm/teal/alpha/stats/getTopReleases.js'
21
+
import * as FmTealAlphaStatsGetUserTopArtists from './types/fm/teal/alpha/stats/getUserTopArtists.js'
22
+
import * as FmTealAlphaStatsGetUserTopReleases from './types/fm/teal/alpha/stats/getUserTopReleases.js'
23
24
+
export function createServer(options?: XrpcOptions): Server {
25
+
return new Server(options)
26
+
}
27
28
+
export class Server {
29
+
xrpc: XrpcServer
30
+
app: AppNS
31
+
fm: FmNS
32
+
net: NetNS
33
34
+
constructor(options?: XrpcOptions) {
35
+
this.xrpc = createXrpcServer(schemas, options)
36
+
this.app = new AppNS(this)
37
+
this.fm = new FmNS(this)
38
+
this.net = new NetNS(this)
39
+
}
40
+
}
41
+
42
+
export class AppNS {
43
+
_server: Server
44
+
bsky: AppBskyNS
45
46
+
constructor(server: Server) {
47
+
this._server = server
48
+
this.bsky = new AppBskyNS(server)
49
}
50
+
}
51
52
+
export class AppBskyNS {
53
+
_server: Server
54
+
richtext: AppBskyRichtextNS
55
+
56
+
constructor(server: Server) {
57
+
this._server = server
58
+
this.richtext = new AppBskyRichtextNS(server)
59
}
60
}
61
62
+
export class AppBskyRichtextNS {
63
+
_server: Server
64
65
+
constructor(server: Server) {
66
+
this._server = server
67
}
68
}
69
70
+
export class FmNS {
71
+
_server: Server
72
+
teal: FmTealNS
73
74
+
constructor(server: Server) {
75
+
this._server = server
76
+
this.teal = new FmTealNS(server)
77
}
78
}
79
80
+
export class FmTealNS {
81
+
_server: Server
82
+
alpha: FmTealAlphaNS
83
84
+
constructor(server: Server) {
85
+
this._server = server
86
+
this.alpha = new FmTealAlphaNS(server)
87
}
88
}
89
90
+
export class FmTealAlphaNS {
91
+
_server: Server
92
+
actor: FmTealAlphaActorNS
93
+
feed: FmTealAlphaFeedNS
94
+
stats: FmTealAlphaStatsNS
95
96
+
constructor(server: Server) {
97
+
this._server = server
98
+
this.actor = new FmTealAlphaActorNS(server)
99
+
this.feed = new FmTealAlphaFeedNS(server)
100
+
this.stats = new FmTealAlphaStatsNS(server)
101
}
102
+
}
103
104
+
export class FmTealAlphaActorNS {
105
+
_server: Server
106
+
107
+
constructor(server: Server) {
108
+
this._server = server
109
}
110
111
+
getProfile<A extends Auth = void>(
112
+
cfg: MethodConfigOrHandler<
113
+
A,
114
+
FmTealAlphaActorGetProfile.QueryParams,
115
+
FmTealAlphaActorGetProfile.HandlerInput,
116
+
FmTealAlphaActorGetProfile.HandlerOutput
117
+
>,
118
+
) {
119
+
const nsid = 'fm.teal.alpha.actor.getProfile' // @ts-ignore
120
+
return this._server.xrpc.method(nsid, cfg)
121
}
122
123
+
getProfiles<A extends Auth = void>(
124
+
cfg: MethodConfigOrHandler<
125
+
A,
126
+
FmTealAlphaActorGetProfiles.QueryParams,
127
+
FmTealAlphaActorGetProfiles.HandlerInput,
128
+
FmTealAlphaActorGetProfiles.HandlerOutput
129
+
>,
130
+
) {
131
+
const nsid = 'fm.teal.alpha.actor.getProfiles' // @ts-ignore
132
+
return this._server.xrpc.method(nsid, cfg)
133
}
134
135
+
searchActors<A extends Auth = void>(
136
+
cfg: MethodConfigOrHandler<
137
+
A,
138
+
FmTealAlphaActorSearchActors.QueryParams,
139
+
FmTealAlphaActorSearchActors.HandlerInput,
140
+
FmTealAlphaActorSearchActors.HandlerOutput
141
+
>,
142
+
) {
143
+
const nsid = 'fm.teal.alpha.actor.searchActors' // @ts-ignore
144
+
return this._server.xrpc.method(nsid, cfg)
145
+
}
146
+
}
147
+
148
+
export class FmTealAlphaFeedNS {
149
+
_server: Server
150
+
151
+
constructor(server: Server) {
152
+
this._server = server
153
+
}
154
+
155
+
getActorFeed<A extends Auth = void>(
156
+
cfg: MethodConfigOrHandler<
157
+
A,
158
+
FmTealAlphaFeedGetActorFeed.QueryParams,
159
+
FmTealAlphaFeedGetActorFeed.HandlerInput,
160
+
FmTealAlphaFeedGetActorFeed.HandlerOutput
161
+
>,
162
+
) {
163
+
const nsid = 'fm.teal.alpha.feed.getActorFeed' // @ts-ignore
164
+
return this._server.xrpc.method(nsid, cfg)
165
+
}
166
+
167
+
getPlay<A extends Auth = void>(
168
+
cfg: MethodConfigOrHandler<
169
+
A,
170
+
FmTealAlphaFeedGetPlay.QueryParams,
171
+
FmTealAlphaFeedGetPlay.HandlerInput,
172
+
FmTealAlphaFeedGetPlay.HandlerOutput
173
+
>,
174
+
) {
175
+
const nsid = 'fm.teal.alpha.feed.getPlay' // @ts-ignore
176
+
return this._server.xrpc.method(nsid, cfg)
177
+
}
178
+
}
179
+
180
+
export class FmTealAlphaStatsNS {
181
+
_server: Server
182
+
183
+
constructor(server: Server) {
184
+
this._server = server
185
+
}
186
+
187
+
getLatest<A extends Auth = void>(
188
+
cfg: MethodConfigOrHandler<
189
+
A,
190
+
FmTealAlphaStatsGetLatest.QueryParams,
191
+
FmTealAlphaStatsGetLatest.HandlerInput,
192
+
FmTealAlphaStatsGetLatest.HandlerOutput
193
+
>,
194
+
) {
195
+
const nsid = 'fm.teal.alpha.stats.getLatest' // @ts-ignore
196
+
return this._server.xrpc.method(nsid, cfg)
197
+
}
198
+
199
+
getTopArtists<A extends Auth = void>(
200
+
cfg: MethodConfigOrHandler<
201
+
A,
202
+
FmTealAlphaStatsGetTopArtists.QueryParams,
203
+
FmTealAlphaStatsGetTopArtists.HandlerInput,
204
+
FmTealAlphaStatsGetTopArtists.HandlerOutput
205
+
>,
206
+
) {
207
+
const nsid = 'fm.teal.alpha.stats.getTopArtists' // @ts-ignore
208
+
return this._server.xrpc.method(nsid, cfg)
209
+
}
210
+
211
+
getTopReleases<A extends Auth = void>(
212
+
cfg: MethodConfigOrHandler<
213
+
A,
214
+
FmTealAlphaStatsGetTopReleases.QueryParams,
215
+
FmTealAlphaStatsGetTopReleases.HandlerInput,
216
+
FmTealAlphaStatsGetTopReleases.HandlerOutput
217
+
>,
218
+
) {
219
+
const nsid = 'fm.teal.alpha.stats.getTopReleases' // @ts-ignore
220
+
return this._server.xrpc.method(nsid, cfg)
221
+
}
222
+
223
+
getUserTopArtists<A extends Auth = void>(
224
+
cfg: MethodConfigOrHandler<
225
+
A,
226
+
FmTealAlphaStatsGetUserTopArtists.QueryParams,
227
+
FmTealAlphaStatsGetUserTopArtists.HandlerInput,
228
+
FmTealAlphaStatsGetUserTopArtists.HandlerOutput
229
+
>,
230
+
) {
231
+
const nsid = 'fm.teal.alpha.stats.getUserTopArtists' // @ts-ignore
232
+
return this._server.xrpc.method(nsid, cfg)
233
+
}
234
+
235
+
getUserTopReleases<A extends Auth = void>(
236
+
cfg: MethodConfigOrHandler<
237
+
A,
238
+
FmTealAlphaStatsGetUserTopReleases.QueryParams,
239
+
FmTealAlphaStatsGetUserTopReleases.HandlerInput,
240
+
FmTealAlphaStatsGetUserTopReleases.HandlerOutput
241
+
>,
242
+
) {
243
+
const nsid = 'fm.teal.alpha.stats.getUserTopReleases' // @ts-ignore
244
+
return this._server.xrpc.method(nsid, cfg)
245
+
}
246
+
}
247
+
248
+
export class NetNS {
249
+
_server: Server
250
+
mmatt: NetMmattNS
251
+
252
+
constructor(server: Server) {
253
+
this._server = server
254
+
this.mmatt = new NetMmattNS(server)
255
+
}
256
+
}
257
+
258
+
export class NetMmattNS {
259
+
_server: Server
260
+
right: NetMmattRightNS
261
+
vitals: NetMmattVitalsNS
262
+
263
+
constructor(server: Server) {
264
+
this._server = server
265
+
this.right = new NetMmattRightNS(server)
266
+
this.vitals = new NetMmattVitalsNS(server)
267
+
}
268
+
}
269
+
270
+
export class NetMmattRightNS {
271
+
_server: Server
272
+
273
+
constructor(server: Server) {
274
+
this._server = server
275
+
}
276
+
}
277
+
278
+
export class NetMmattVitalsNS {
279
+
_server: Server
280
+
281
+
constructor(server: Server) {
282
+
this._server = server
283
}
284
}
+1291
-2
lexiconTypes/lexicons.ts
+1291
-2
lexiconTypes/lexicons.ts
···
10
import { type $Typed, is$typed, maybe$typed } from './util.js'
11
12
export const schemaDict = {
13
NetMmattRightNow: {
14
lexicon: 1,
15
id: 'net.mmatt.right.now',
16
defs: {
17
main: {
18
type: 'record',
19
-
description: "A personal lexicon for mmatt's statuslog.",
20
key: 'tid',
21
record: {
22
type: 'object',
23
-
required: ['createdAt', 'text'],
24
properties: {
25
createdAt: {
26
type: 'string',
···
36
description: 'The emoji of the status update',
37
},
38
},
39
},
40
},
41
},
···
73
}
74
75
export const ids = {
76
NetMmattRightNow: 'net.mmatt.right.now',
77
} as const
···
10
import { type $Typed, is$typed, maybe$typed } from './util.js'
11
12
export const schemaDict = {
13
+
AppBskyRichtextFacet: {
14
+
lexicon: 1,
15
+
id: 'app.bsky.richtext.facet',
16
+
defs: {
17
+
tag: {
18
+
type: 'object',
19
+
required: ['tag'],
20
+
properties: {
21
+
tag: {
22
+
type: 'string',
23
+
maxLength: 640,
24
+
maxGraphemes: 64,
25
+
},
26
+
},
27
+
description:
28
+
"Facet feature for a hashtag. The text usually includes a '#' prefix, but the facet reference should not (except in the case of 'double hash tags').",
29
+
},
30
+
link: {
31
+
type: 'object',
32
+
required: ['uri'],
33
+
properties: {
34
+
uri: {
35
+
type: 'string',
36
+
format: 'uri',
37
+
},
38
+
},
39
+
description:
40
+
'Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL.',
41
+
},
42
+
main: {
43
+
type: 'object',
44
+
required: ['index', 'features'],
45
+
properties: {
46
+
index: {
47
+
ref: 'lex:app.bsky.richtext.facet#byteSlice',
48
+
type: 'ref',
49
+
},
50
+
features: {
51
+
type: 'array',
52
+
items: {
53
+
refs: [
54
+
'lex:app.bsky.richtext.facet#mention',
55
+
'lex:app.bsky.richtext.facet#link',
56
+
'lex:app.bsky.richtext.facet#tag',
57
+
],
58
+
type: 'union',
59
+
},
60
+
},
61
+
},
62
+
description: 'Annotation of a sub-string within rich text.',
63
+
},
64
+
mention: {
65
+
type: 'object',
66
+
required: ['did'],
67
+
properties: {
68
+
did: {
69
+
type: 'string',
70
+
format: 'did',
71
+
},
72
+
},
73
+
description:
74
+
"Facet feature for mention of another account. The text is usually a handle, including a '@' prefix, but the facet reference is a DID.",
75
+
},
76
+
byteSlice: {
77
+
type: 'object',
78
+
required: ['byteStart', 'byteEnd'],
79
+
properties: {
80
+
byteEnd: {
81
+
type: 'integer',
82
+
minimum: 0,
83
+
},
84
+
byteStart: {
85
+
type: 'integer',
86
+
minimum: 0,
87
+
},
88
+
},
89
+
description:
90
+
'Specifies the sub-string range a facet feature applies to. Start index is inclusive, end index is exclusive. Indices are zero-indexed, counting bytes of the UTF-8 encoded text. NOTE: some languages, like Javascript, use UTF-16 or Unicode codepoints for string slice indexing; in these languages, convert to byte arrays before working with facets.',
91
+
},
92
+
},
93
+
},
94
+
FmTealAlphaActorDefs: {
95
+
lexicon: 1,
96
+
id: 'fm.teal.alpha.actor.defs',
97
+
defs: {
98
+
profileView: {
99
+
type: 'object',
100
+
properties: {
101
+
did: {
102
+
type: 'string',
103
+
description: 'The decentralized identifier of the actor',
104
+
},
105
+
displayName: {
106
+
type: 'string',
107
+
},
108
+
description: {
109
+
type: 'string',
110
+
description: 'Free-form profile description text.',
111
+
},
112
+
descriptionFacets: {
113
+
type: 'array',
114
+
description:
115
+
'Annotations of text in the profile description (mentions, URLs, hashtags, etc). May be changed to another (backwards compatible) lexicon.',
116
+
items: {
117
+
type: 'ref',
118
+
ref: 'lex:app.bsky.richtext.facet',
119
+
},
120
+
},
121
+
featuredItem: {
122
+
type: 'ref',
123
+
description:
124
+
"The user's most recent item featured on their profile.",
125
+
ref: 'lex:fm.teal.alpha.actor.profile#featuredItem',
126
+
},
127
+
avatar: {
128
+
type: 'string',
129
+
description: 'IPLD of the avatar',
130
+
},
131
+
banner: {
132
+
type: 'string',
133
+
description: 'IPLD of the banner image',
134
+
},
135
+
status: {
136
+
type: 'ref',
137
+
ref: 'lex:fm.teal.alpha.actor.defs#statusView',
138
+
},
139
+
createdAt: {
140
+
type: 'string',
141
+
format: 'datetime',
142
+
},
143
+
},
144
+
},
145
+
miniProfileView: {
146
+
type: 'object',
147
+
properties: {
148
+
did: {
149
+
type: 'string',
150
+
description: 'The decentralized identifier of the actor',
151
+
},
152
+
displayName: {
153
+
type: 'string',
154
+
},
155
+
handle: {
156
+
type: 'string',
157
+
},
158
+
avatar: {
159
+
type: 'string',
160
+
description: 'IPLD of the avatar',
161
+
},
162
+
},
163
+
},
164
+
statusView: {
165
+
type: 'object',
166
+
description: 'A declaration of the status of the actor.',
167
+
properties: {
168
+
time: {
169
+
type: 'string',
170
+
format: 'datetime',
171
+
description: 'The unix timestamp of when the item was recorded',
172
+
},
173
+
expiry: {
174
+
type: 'string',
175
+
format: 'datetime',
176
+
description:
177
+
'The unix timestamp of the expiry time of the item. If unavailable, default to 10 minutes past the start time.',
178
+
},
179
+
item: {
180
+
type: 'ref',
181
+
ref: 'lex:fm.teal.alpha.feed.defs#playView',
182
+
},
183
+
},
184
+
},
185
+
},
186
+
},
187
+
FmTealAlphaActorGetProfile: {
188
+
lexicon: 1,
189
+
id: 'fm.teal.alpha.actor.getProfile',
190
+
description:
191
+
'This lexicon is in a not officially released state. It is subject to change. | Retrieves a play given an author DID and record key.',
192
+
defs: {
193
+
main: {
194
+
type: 'query',
195
+
parameters: {
196
+
type: 'params',
197
+
required: ['actor'],
198
+
properties: {
199
+
actor: {
200
+
type: 'string',
201
+
format: 'at-identifier',
202
+
description: "The author's DID",
203
+
},
204
+
},
205
+
},
206
+
output: {
207
+
encoding: 'application/json',
208
+
schema: {
209
+
type: 'object',
210
+
required: ['actor'],
211
+
properties: {
212
+
actor: {
213
+
type: 'ref',
214
+
ref: 'lex:fm.teal.alpha.actor.defs#profileView',
215
+
},
216
+
},
217
+
},
218
+
},
219
+
},
220
+
},
221
+
},
222
+
FmTealAlphaActorGetProfiles: {
223
+
lexicon: 1,
224
+
id: 'fm.teal.alpha.actor.getProfiles',
225
+
description:
226
+
'This lexicon is in a not officially released state. It is subject to change. | Retrieves the associated profile.',
227
+
defs: {
228
+
main: {
229
+
type: 'query',
230
+
parameters: {
231
+
type: 'params',
232
+
required: ['actors'],
233
+
properties: {
234
+
actors: {
235
+
type: 'array',
236
+
items: {
237
+
type: 'string',
238
+
format: 'at-identifier',
239
+
},
240
+
description: 'Array of actor DIDs',
241
+
},
242
+
},
243
+
},
244
+
output: {
245
+
encoding: 'application/json',
246
+
schema: {
247
+
type: 'object',
248
+
required: ['actors'],
249
+
properties: {
250
+
actors: {
251
+
type: 'array',
252
+
items: {
253
+
type: 'ref',
254
+
ref: 'lex:fm.teal.alpha.actor.defs#miniProfileView',
255
+
},
256
+
},
257
+
},
258
+
},
259
+
},
260
+
},
261
+
},
262
+
},
263
+
FmTealAlphaActorProfile: {
264
+
lexicon: 1,
265
+
id: 'fm.teal.alpha.actor.profile',
266
+
defs: {
267
+
main: {
268
+
type: 'record',
269
+
description:
270
+
'This lexicon is in a not officially released state. It is subject to change. | A declaration of a teal.fm account profile.',
271
+
key: 'literal:self',
272
+
record: {
273
+
type: 'object',
274
+
properties: {
275
+
displayName: {
276
+
type: 'string',
277
+
maxGraphemes: 64,
278
+
maxLength: 640,
279
+
},
280
+
description: {
281
+
type: 'string',
282
+
description: 'Free-form profile description text.',
283
+
maxGraphemes: 256,
284
+
maxLength: 2560,
285
+
},
286
+
descriptionFacets: {
287
+
type: 'array',
288
+
description:
289
+
'Annotations of text in the profile description (mentions, URLs, hashtags, etc).',
290
+
items: {
291
+
type: 'ref',
292
+
ref: 'lex:app.bsky.richtext.facet',
293
+
},
294
+
},
295
+
featuredItem: {
296
+
type: 'ref',
297
+
description:
298
+
"The user's most recent item featured on their profile.",
299
+
ref: 'lex:fm.teal.alpha.actor.profile#featuredItem',
300
+
},
301
+
avatar: {
302
+
type: 'blob',
303
+
description:
304
+
"Small image to be displayed next to posts from account. AKA, 'profile picture'",
305
+
accept: ['image/png', 'image/jpeg'],
306
+
maxSize: 1000000,
307
+
},
308
+
banner: {
309
+
type: 'blob',
310
+
description:
311
+
'Larger horizontal image to display behind profile view.',
312
+
accept: ['image/png', 'image/jpeg'],
313
+
maxSize: 1000000,
314
+
},
315
+
createdAt: {
316
+
type: 'string',
317
+
format: 'datetime',
318
+
},
319
+
},
320
+
},
321
+
},
322
+
featuredItem: {
323
+
type: 'object',
324
+
required: ['mbid', 'type'],
325
+
properties: {
326
+
mbid: {
327
+
type: 'string',
328
+
description: 'The Musicbrainz ID of the item',
329
+
},
330
+
type: {
331
+
type: 'string',
332
+
description:
333
+
'The type of the item. Must be a valid Musicbrainz type, e.g. album, track, recording, etc.',
334
+
},
335
+
},
336
+
},
337
+
},
338
+
},
339
+
FmTealAlphaActorProfileStatus: {
340
+
lexicon: 1,
341
+
id: 'fm.teal.alpha.actor.profileStatus',
342
+
defs: {
343
+
main: {
344
+
type: 'record',
345
+
description:
346
+
'This lexicon is in a not officially released state. It is subject to change. | A declaration of the profile status of the actor.',
347
+
key: 'literal:self',
348
+
record: {
349
+
type: 'object',
350
+
required: ['completedOnboarding'],
351
+
properties: {
352
+
completedOnboarding: {
353
+
type: 'string',
354
+
description: 'The onboarding completion status',
355
+
knownValues: [
356
+
'none',
357
+
'profileOnboarding',
358
+
'playOnboarding',
359
+
'complete',
360
+
],
361
+
},
362
+
createdAt: {
363
+
type: 'string',
364
+
format: 'datetime',
365
+
description: 'The timestamp when this status was created',
366
+
},
367
+
updatedAt: {
368
+
type: 'string',
369
+
format: 'datetime',
370
+
description: 'The timestamp when this status was last updated',
371
+
},
372
+
},
373
+
},
374
+
},
375
+
},
376
+
},
377
+
FmTealAlphaActorSearchActors: {
378
+
lexicon: 1,
379
+
id: 'fm.teal.alpha.actor.searchActors',
380
+
description:
381
+
'This lexicon is in a not officially released state. It is subject to change. | Searches for actors based on profile contents.',
382
+
defs: {
383
+
main: {
384
+
type: 'query',
385
+
parameters: {
386
+
type: 'params',
387
+
required: ['q'],
388
+
properties: {
389
+
q: {
390
+
type: 'string',
391
+
description: 'The search query',
392
+
maxGraphemes: 128,
393
+
maxLength: 640,
394
+
},
395
+
limit: {
396
+
type: 'integer',
397
+
description: 'The maximum number of actors to return',
398
+
minimum: 1,
399
+
maximum: 25,
400
+
},
401
+
cursor: {
402
+
type: 'string',
403
+
description: 'Cursor for pagination',
404
+
},
405
+
},
406
+
},
407
+
output: {
408
+
encoding: 'application/json',
409
+
schema: {
410
+
type: 'object',
411
+
required: ['actors'],
412
+
properties: {
413
+
actors: {
414
+
type: 'array',
415
+
items: {
416
+
type: 'ref',
417
+
ref: 'lex:fm.teal.alpha.actor.defs#miniProfileView',
418
+
},
419
+
},
420
+
cursor: {
421
+
type: 'string',
422
+
description: 'Cursor for pagination',
423
+
},
424
+
},
425
+
},
426
+
},
427
+
},
428
+
},
429
+
},
430
+
FmTealAlphaActorStatus: {
431
+
lexicon: 1,
432
+
id: 'fm.teal.alpha.actor.status',
433
+
defs: {
434
+
main: {
435
+
type: 'record',
436
+
description:
437
+
'This lexicon is in a not officially released state. It is subject to change. | A declaration of the status of the actor. Only one can be shown at a time. If there are multiple, the latest record should be picked and earlier records should be deleted or tombstoned.',
438
+
key: 'literal:self',
439
+
record: {
440
+
type: 'object',
441
+
required: ['time', 'item'],
442
+
properties: {
443
+
time: {
444
+
type: 'string',
445
+
format: 'datetime',
446
+
description: 'The unix timestamp of when the item was recorded',
447
+
},
448
+
expiry: {
449
+
type: 'string',
450
+
format: 'datetime',
451
+
description:
452
+
'The unix timestamp of the expiry time of the item. If unavailable, default to 10 minutes past the start time.',
453
+
},
454
+
item: {
455
+
type: 'ref',
456
+
ref: 'lex:fm.teal.alpha.feed.defs#playView',
457
+
},
458
+
},
459
+
},
460
+
},
461
+
},
462
+
},
463
+
FmTealAlphaFeedDefs: {
464
+
lexicon: 1,
465
+
id: 'fm.teal.alpha.feed.defs',
466
+
description:
467
+
'This lexicon is in a not officially released state. It is subject to change. | Misc. items related to feeds.',
468
+
defs: {
469
+
playView: {
470
+
type: 'object',
471
+
required: ['trackName', 'artists'],
472
+
properties: {
473
+
trackName: {
474
+
type: 'string',
475
+
minLength: 1,
476
+
maxLength: 256,
477
+
maxGraphemes: 2560,
478
+
description: 'The name of the track',
479
+
},
480
+
trackMbId: {
481
+
type: 'string',
482
+
description: 'The Musicbrainz ID of the track',
483
+
},
484
+
recordingMbId: {
485
+
type: 'string',
486
+
description: 'The Musicbrainz recording ID of the track',
487
+
},
488
+
duration: {
489
+
type: 'integer',
490
+
description: 'The length of the track in seconds',
491
+
},
492
+
artists: {
493
+
type: 'array',
494
+
items: {
495
+
type: 'ref',
496
+
ref: 'lex:fm.teal.alpha.feed.defs#artist',
497
+
},
498
+
description: 'Array of artists in order of original appearance.',
499
+
},
500
+
releaseName: {
501
+
type: 'string',
502
+
maxLength: 256,
503
+
maxGraphemes: 2560,
504
+
description: 'The name of the release/album',
505
+
},
506
+
releaseMbId: {
507
+
type: 'string',
508
+
description: 'The Musicbrainz release ID',
509
+
},
510
+
isrc: {
511
+
type: 'string',
512
+
description: 'The ISRC code associated with the recording',
513
+
},
514
+
originUrl: {
515
+
type: 'string',
516
+
description: 'The URL associated with this track',
517
+
},
518
+
musicServiceBaseDomain: {
519
+
type: 'string',
520
+
description:
521
+
"The base domain of the music service. e.g. music.apple.com, tidal.com, spotify.com. Defaults to 'local' if not provided.",
522
+
},
523
+
submissionClientAgent: {
524
+
type: 'string',
525
+
maxLength: 256,
526
+
maxGraphemes: 2560,
527
+
description:
528
+
"A user-agent style string specifying the user agent. e.g. tealtracker/0.0.1b (Linux; Android 13; SM-A715F). Defaults to 'manual/unknown' if not provided.",
529
+
},
530
+
playedTime: {
531
+
type: 'string',
532
+
format: 'datetime',
533
+
description: 'The unix timestamp of when the track was played',
534
+
},
535
+
},
536
+
},
537
+
artist: {
538
+
type: 'object',
539
+
required: ['artistName'],
540
+
properties: {
541
+
artistName: {
542
+
type: 'string',
543
+
minLength: 1,
544
+
maxLength: 256,
545
+
maxGraphemes: 2560,
546
+
description: 'The name of the artist',
547
+
},
548
+
artistMbId: {
549
+
type: 'string',
550
+
description: 'The Musicbrainz ID of the artist',
551
+
},
552
+
},
553
+
},
554
+
},
555
+
},
556
+
FmTealAlphaFeedGetActorFeed: {
557
+
lexicon: 1,
558
+
id: 'fm.teal.alpha.feed.getActorFeed',
559
+
description:
560
+
"This lexicon is in a not officially released state. It is subject to change. | Retrieves multiple plays from the index or via an author's DID.",
561
+
defs: {
562
+
main: {
563
+
type: 'query',
564
+
parameters: {
565
+
type: 'params',
566
+
required: ['authorDID'],
567
+
properties: {
568
+
authorDID: {
569
+
type: 'string',
570
+
format: 'at-identifier',
571
+
description: "The author's DID for the play",
572
+
},
573
+
cursor: {
574
+
type: 'string',
575
+
description: 'The cursor to start the query from',
576
+
},
577
+
limit: {
578
+
type: 'integer',
579
+
description:
580
+
'The upper limit of tracks to get per request. Default is 20, max is 50.',
581
+
},
582
+
},
583
+
},
584
+
output: {
585
+
encoding: 'application/json',
586
+
schema: {
587
+
type: 'object',
588
+
required: ['plays'],
589
+
properties: {
590
+
plays: {
591
+
type: 'array',
592
+
items: {
593
+
type: 'ref',
594
+
ref: 'lex:fm.teal.alpha.feed.defs#playView',
595
+
},
596
+
},
597
+
},
598
+
},
599
+
},
600
+
},
601
+
},
602
+
},
603
+
FmTealAlphaFeedGetPlay: {
604
+
lexicon: 1,
605
+
id: 'fm.teal.alpha.feed.getPlay',
606
+
description:
607
+
'This lexicon is in a not officially released state. It is subject to change. | Retrieves a play given an author DID and record key.',
608
+
defs: {
609
+
main: {
610
+
type: 'query',
611
+
parameters: {
612
+
type: 'params',
613
+
required: ['authorDID', 'rkey'],
614
+
properties: {
615
+
authorDID: {
616
+
type: 'string',
617
+
format: 'at-identifier',
618
+
description: "The author's DID for the play",
619
+
},
620
+
rkey: {
621
+
type: 'string',
622
+
description: 'The record key of the play',
623
+
},
624
+
},
625
+
},
626
+
output: {
627
+
encoding: 'application/json',
628
+
schema: {
629
+
type: 'object',
630
+
required: ['play'],
631
+
properties: {
632
+
play: {
633
+
type: 'ref',
634
+
ref: 'lex:fm.teal.alpha.feed.defs#playView',
635
+
},
636
+
},
637
+
},
638
+
},
639
+
},
640
+
},
641
+
},
642
+
FmTealAlphaFeedPlay: {
643
+
lexicon: 1,
644
+
id: 'fm.teal.alpha.feed.play',
645
+
description:
646
+
"This lexicon is in a not officially released state. It is subject to change. | A declaration of a teal.fm play. Plays are submitted as a result of a user listening to a track. Plays should be marked as tracked when a user has listened to the entire track if it's under 2 minutes long, or half of the track's duration up to 4 minutes, whichever is longest.",
647
+
defs: {
648
+
main: {
649
+
type: 'record',
650
+
key: 'tid',
651
+
record: {
652
+
type: 'object',
653
+
required: ['trackName'],
654
+
properties: {
655
+
trackName: {
656
+
type: 'string',
657
+
minLength: 1,
658
+
maxLength: 256,
659
+
maxGraphemes: 2560,
660
+
description: 'The name of the track',
661
+
},
662
+
trackMbId: {
663
+
type: 'string',
664
+
description: 'The Musicbrainz ID of the track',
665
+
},
666
+
recordingMbId: {
667
+
type: 'string',
668
+
description: 'The Musicbrainz recording ID of the track',
669
+
},
670
+
duration: {
671
+
type: 'integer',
672
+
description: 'The length of the track in seconds',
673
+
},
674
+
artistNames: {
675
+
type: 'array',
676
+
items: {
677
+
type: 'string',
678
+
minLength: 1,
679
+
maxLength: 256,
680
+
maxGraphemes: 2560,
681
+
},
682
+
description:
683
+
"Array of artist names in order of original appearance. Prefer using 'artists'.",
684
+
},
685
+
artistMbIds: {
686
+
type: 'array',
687
+
items: {
688
+
type: 'string',
689
+
},
690
+
description:
691
+
"Array of Musicbrainz artist IDs. Prefer using 'artists'.",
692
+
},
693
+
artists: {
694
+
type: 'array',
695
+
items: {
696
+
type: 'ref',
697
+
ref: 'lex:fm.teal.alpha.feed.defs#artist',
698
+
},
699
+
description: 'Array of artists in order of original appearance.',
700
+
},
701
+
releaseName: {
702
+
type: 'string',
703
+
maxLength: 256,
704
+
maxGraphemes: 2560,
705
+
description: 'The name of the release/album',
706
+
},
707
+
releaseMbId: {
708
+
type: 'string',
709
+
description: 'The Musicbrainz release ID',
710
+
},
711
+
isrc: {
712
+
type: 'string',
713
+
description: 'The ISRC code associated with the recording',
714
+
},
715
+
originUrl: {
716
+
type: 'string',
717
+
description: 'The URL associated with this track',
718
+
},
719
+
musicServiceBaseDomain: {
720
+
type: 'string',
721
+
description:
722
+
"The base domain of the music service. e.g. music.apple.com, tidal.com, spotify.com. Defaults to 'local' if unavailable or not provided.",
723
+
},
724
+
submissionClientAgent: {
725
+
type: 'string',
726
+
maxLength: 256,
727
+
maxGraphemes: 2560,
728
+
description:
729
+
"A metadata string specifying the user agent where the format is `<app-identifier>/<version> (<kernel/OS-base>; <platform/OS-version>; <device-model>)`. If string is provided, only `app-identifier` and `version` are required. `app-identifier` is recommended to be in reverse dns format. Defaults to 'manual/unknown' if unavailable or not provided.",
730
+
},
731
+
playedTime: {
732
+
type: 'string',
733
+
format: 'datetime',
734
+
description: 'The unix timestamp of when the track was played',
735
+
},
736
+
trackDiscriminant: {
737
+
type: 'string',
738
+
maxLength: 128,
739
+
maxGraphemes: 1280,
740
+
description:
741
+
"Distinguishing information for track variants (e.g. 'Acoustic Version', 'Live at Wembley', 'Radio Edit', 'Demo'). Used to differentiate between different versions of the same base track while maintaining grouping capabilities.",
742
+
},
743
+
releaseDiscriminant: {
744
+
type: 'string',
745
+
maxLength: 128,
746
+
maxGraphemes: 1280,
747
+
description:
748
+
"Distinguishing information for release variants (e.g. 'Deluxe Edition', 'Remastered', '2023 Remaster', 'Special Edition'). Used to differentiate between different versions of the same base release while maintaining grouping capabilities.",
749
+
},
750
+
},
751
+
},
752
+
},
753
+
},
754
+
},
755
+
FmTealAlphaStatsDefs: {
756
+
lexicon: 1,
757
+
id: 'fm.teal.alpha.stats.defs',
758
+
defs: {
759
+
artistView: {
760
+
type: 'object',
761
+
required: ['mbid', 'name', 'playCount'],
762
+
properties: {
763
+
mbid: {
764
+
type: 'string',
765
+
description: 'MusicBrainz artist ID',
766
+
},
767
+
name: {
768
+
type: 'string',
769
+
description: 'Artist name',
770
+
},
771
+
playCount: {
772
+
type: 'integer',
773
+
description: 'Total number of plays for this artist',
774
+
},
775
+
},
776
+
},
777
+
releaseView: {
778
+
type: 'object',
779
+
required: ['mbid', 'name', 'playCount'],
780
+
properties: {
781
+
mbid: {
782
+
type: 'string',
783
+
description: 'MusicBrainz release ID',
784
+
},
785
+
name: {
786
+
type: 'string',
787
+
description: 'Release/album name',
788
+
},
789
+
playCount: {
790
+
type: 'integer',
791
+
description: 'Total number of plays for this release',
792
+
},
793
+
},
794
+
},
795
+
recordingView: {
796
+
type: 'object',
797
+
required: ['mbid', 'name', 'playCount'],
798
+
properties: {
799
+
mbid: {
800
+
type: 'string',
801
+
description: 'MusicBrainz recording ID',
802
+
},
803
+
name: {
804
+
type: 'string',
805
+
description: 'Recording/track name',
806
+
},
807
+
playCount: {
808
+
type: 'integer',
809
+
description: 'Total number of plays for this recording',
810
+
},
811
+
},
812
+
},
813
+
},
814
+
},
815
+
FmTealAlphaStatsGetLatest: {
816
+
lexicon: 1,
817
+
id: 'fm.teal.alpha.stats.getLatest',
818
+
defs: {
819
+
main: {
820
+
type: 'query',
821
+
description: 'Get latest plays globally',
822
+
parameters: {
823
+
type: 'params',
824
+
properties: {
825
+
limit: {
826
+
type: 'integer',
827
+
minimum: 1,
828
+
maximum: 100,
829
+
default: 50,
830
+
description: 'Number of latest plays to return',
831
+
},
832
+
},
833
+
},
834
+
output: {
835
+
encoding: 'application/json',
836
+
schema: {
837
+
type: 'object',
838
+
required: ['plays'],
839
+
properties: {
840
+
plays: {
841
+
type: 'array',
842
+
items: {
843
+
type: 'ref',
844
+
ref: 'lex:fm.teal.alpha.feed.defs#playView',
845
+
},
846
+
},
847
+
},
848
+
},
849
+
},
850
+
},
851
+
},
852
+
},
853
+
FmTealAlphaStatsGetTopArtists: {
854
+
lexicon: 1,
855
+
id: 'fm.teal.alpha.stats.getTopArtists',
856
+
description: 'Get top artists by play count',
857
+
defs: {
858
+
main: {
859
+
type: 'query',
860
+
parameters: {
861
+
type: 'params',
862
+
properties: {
863
+
period: {
864
+
type: 'string',
865
+
enum: ['all', '30days', '7days'],
866
+
default: 'all',
867
+
description: 'Time period for top artists',
868
+
},
869
+
limit: {
870
+
type: 'integer',
871
+
minimum: 1,
872
+
maximum: 100,
873
+
default: 50,
874
+
description: 'Number of artists to return',
875
+
},
876
+
cursor: {
877
+
type: 'string',
878
+
description: 'Pagination cursor',
879
+
},
880
+
},
881
+
},
882
+
output: {
883
+
encoding: 'application/json',
884
+
schema: {
885
+
type: 'object',
886
+
required: ['artists'],
887
+
properties: {
888
+
artists: {
889
+
type: 'array',
890
+
items: {
891
+
type: 'ref',
892
+
ref: 'lex:fm.teal.alpha.stats.defs#artistView',
893
+
},
894
+
},
895
+
cursor: {
896
+
type: 'string',
897
+
description: 'Next page cursor',
898
+
},
899
+
},
900
+
},
901
+
},
902
+
},
903
+
},
904
+
},
905
+
FmTealAlphaStatsGetTopReleases: {
906
+
lexicon: 1,
907
+
id: 'fm.teal.alpha.stats.getTopReleases',
908
+
description: 'Get top releases/albums by play count',
909
+
defs: {
910
+
main: {
911
+
type: 'query',
912
+
parameters: {
913
+
type: 'params',
914
+
properties: {
915
+
period: {
916
+
type: 'string',
917
+
enum: ['all', '30days', '7days'],
918
+
default: 'all',
919
+
description: 'Time period for top releases',
920
+
},
921
+
limit: {
922
+
type: 'integer',
923
+
minimum: 1,
924
+
maximum: 100,
925
+
default: 50,
926
+
description: 'Number of releases to return',
927
+
},
928
+
cursor: {
929
+
type: 'string',
930
+
description: 'Pagination cursor',
931
+
},
932
+
},
933
+
},
934
+
output: {
935
+
encoding: 'application/json',
936
+
schema: {
937
+
type: 'object',
938
+
required: ['releases'],
939
+
properties: {
940
+
releases: {
941
+
type: 'array',
942
+
items: {
943
+
type: 'ref',
944
+
ref: 'lex:fm.teal.alpha.stats.defs#releaseView',
945
+
},
946
+
},
947
+
cursor: {
948
+
type: 'string',
949
+
description: 'Next page cursor',
950
+
},
951
+
},
952
+
},
953
+
},
954
+
},
955
+
},
956
+
},
957
+
FmTealAlphaStatsGetUserTopArtists: {
958
+
lexicon: 1,
959
+
id: 'fm.teal.alpha.stats.getUserTopArtists',
960
+
description: "Get a user's top artists by play count",
961
+
defs: {
962
+
main: {
963
+
type: 'query',
964
+
parameters: {
965
+
type: 'params',
966
+
required: ['actor'],
967
+
properties: {
968
+
actor: {
969
+
type: 'string',
970
+
format: 'at-identifier',
971
+
description: "The user's DID or handle",
972
+
},
973
+
period: {
974
+
type: 'string',
975
+
enum: ['30days', '7days'],
976
+
default: '30days',
977
+
description: 'Time period for top artists',
978
+
},
979
+
limit: {
980
+
type: 'integer',
981
+
minimum: 1,
982
+
maximum: 100,
983
+
default: 50,
984
+
description: 'Number of artists to return',
985
+
},
986
+
cursor: {
987
+
type: 'string',
988
+
description: 'Pagination cursor',
989
+
},
990
+
},
991
+
},
992
+
output: {
993
+
encoding: 'application/json',
994
+
schema: {
995
+
type: 'object',
996
+
required: ['artists'],
997
+
properties: {
998
+
artists: {
999
+
type: 'array',
1000
+
items: {
1001
+
type: 'ref',
1002
+
ref: 'lex:fm.teal.alpha.stats.defs#artistView',
1003
+
},
1004
+
},
1005
+
cursor: {
1006
+
type: 'string',
1007
+
description: 'Next page cursor',
1008
+
},
1009
+
},
1010
+
},
1011
+
},
1012
+
},
1013
+
},
1014
+
},
1015
+
FmTealAlphaStatsGetUserTopReleases: {
1016
+
lexicon: 1,
1017
+
id: 'fm.teal.alpha.stats.getUserTopReleases',
1018
+
description: "Get a user's top releases/albums by play count",
1019
+
defs: {
1020
+
main: {
1021
+
type: 'query',
1022
+
parameters: {
1023
+
type: 'params',
1024
+
required: ['actor'],
1025
+
properties: {
1026
+
actor: {
1027
+
type: 'string',
1028
+
format: 'at-identifier',
1029
+
description: "The user's DID or handle",
1030
+
},
1031
+
period: {
1032
+
type: 'string',
1033
+
enum: ['30days', '7days'],
1034
+
default: '30days',
1035
+
description: 'Time period for top releases',
1036
+
},
1037
+
limit: {
1038
+
type: 'integer',
1039
+
minimum: 1,
1040
+
maximum: 100,
1041
+
default: 50,
1042
+
description: 'Number of releases to return',
1043
+
},
1044
+
cursor: {
1045
+
type: 'string',
1046
+
description: 'Pagination cursor',
1047
+
},
1048
+
},
1049
+
},
1050
+
output: {
1051
+
encoding: 'application/json',
1052
+
schema: {
1053
+
type: 'object',
1054
+
required: ['releases'],
1055
+
properties: {
1056
+
releases: {
1057
+
type: 'array',
1058
+
items: {
1059
+
type: 'ref',
1060
+
ref: 'lex:fm.teal.alpha.stats.defs#releaseView',
1061
+
},
1062
+
},
1063
+
cursor: {
1064
+
type: 'string',
1065
+
description: 'Next page cursor',
1066
+
},
1067
+
},
1068
+
},
1069
+
},
1070
+
},
1071
+
},
1072
+
},
1073
NetMmattRightNow: {
1074
lexicon: 1,
1075
id: 'net.mmatt.right.now',
1076
defs: {
1077
main: {
1078
type: 'record',
1079
key: 'tid',
1080
record: {
1081
type: 'object',
1082
properties: {
1083
createdAt: {
1084
type: 'string',
···
1094
description: 'The emoji of the status update',
1095
},
1096
},
1097
+
required: ['createdAt', 'text'],
1098
+
},
1099
+
description: "A personal lexicon for mmatt's statuslog.",
1100
+
},
1101
+
},
1102
+
},
1103
+
NetMmattVitalsCar: {
1104
+
lexicon: 1,
1105
+
id: 'net.mmatt.vitals.car',
1106
+
defs: {
1107
+
main: {
1108
+
type: 'record',
1109
+
key: 'tid',
1110
+
record: {
1111
+
type: 'object',
1112
+
properties: {
1113
+
createdAt: {
1114
+
type: 'string',
1115
+
format: 'datetime',
1116
+
description: 'The unix timestamp of when the vital was recorded',
1117
+
},
1118
+
carFuelRange: {
1119
+
type: 'integer',
1120
+
description: 'The car fuel range value in miles',
1121
+
},
1122
+
carPercentFuelRemaining: {
1123
+
type: 'string',
1124
+
description:
1125
+
'The car fuel level value in percentage (floating point string)',
1126
+
},
1127
+
amountRemaining: {
1128
+
type: 'string',
1129
+
description:
1130
+
'The car fuel amount remaining value (floating point string)',
1131
+
},
1132
+
carTraveledDistance: {
1133
+
type: 'integer',
1134
+
description: 'The car traveled distance value',
1135
+
},
1136
+
carMake: {
1137
+
type: 'string',
1138
+
description: 'The car make value',
1139
+
},
1140
+
carModel: {
1141
+
type: 'string',
1142
+
description: 'The car model value',
1143
+
},
1144
+
carYear: {
1145
+
type: 'integer',
1146
+
description: 'The car year value',
1147
+
},
1148
+
},
1149
+
required: [
1150
+
'createdAt',
1151
+
'carFuelRange',
1152
+
'carPercentFuelRemaining',
1153
+
'amountRemaining',
1154
+
'carTraveledDistance',
1155
+
],
1156
+
},
1157
+
},
1158
+
},
1159
+
},
1160
+
NetMmattVitalsPhone: {
1161
+
lexicon: 1,
1162
+
id: 'net.mmatt.vitals.phone',
1163
+
defs: {
1164
+
main: {
1165
+
type: 'record',
1166
+
key: 'tid',
1167
+
record: {
1168
+
type: 'object',
1169
+
properties: {
1170
+
createdAt: {
1171
+
type: 'string',
1172
+
format: 'datetime',
1173
+
description: 'The unix timestamp of when the vital was recorded',
1174
+
},
1175
+
phoneMotion: {
1176
+
type: 'string',
1177
+
description: 'The phone motion value',
1178
+
},
1179
+
phoneVolume: {
1180
+
type: 'string',
1181
+
description: 'The phone volume value',
1182
+
},
1183
+
phoneAppearance: {
1184
+
type: 'string',
1185
+
description: 'The phone appearance value',
1186
+
},
1187
+
phoneBrightness: {
1188
+
type: 'string',
1189
+
description: 'The phone brightness value',
1190
+
},
1191
+
phoneOrientation: {
1192
+
type: 'string',
1193
+
description: 'The phone orientation value',
1194
+
},
1195
+
phoneCellBars: {
1196
+
type: 'string',
1197
+
description: 'The phone cell bars value',
1198
+
},
1199
+
phoneCellNetwork: {
1200
+
type: 'string',
1201
+
description: 'The phone cell network value',
1202
+
},
1203
+
phoneBatteryLevel: {
1204
+
type: 'string',
1205
+
description: 'The phone battery level value',
1206
+
},
1207
+
phoneBatteryCharging: {
1208
+
type: 'string',
1209
+
description: 'The phone battery charging value',
1210
+
},
1211
+
phoneOs: {
1212
+
type: 'string',
1213
+
description: 'The phone OS value',
1214
+
},
1215
+
phoneOsVersion: {
1216
+
type: 'string',
1217
+
description: 'The phone OS version value',
1218
+
},
1219
+
phoneModel: {
1220
+
type: 'string',
1221
+
description: 'The phone model value',
1222
+
},
1223
+
},
1224
+
required: [
1225
+
'createdAt',
1226
+
'phoneMotion',
1227
+
'phoneVolume',
1228
+
'phoneAppearance',
1229
+
'phoneBrightness',
1230
+
'phoneOrientation',
1231
+
'phoneCellBars',
1232
+
'phoneCellNetwork',
1233
+
'phoneBatteryLevel',
1234
+
'phoneBatteryCharging',
1235
+
'phoneOs',
1236
+
'phoneOsVersion',
1237
+
'phoneModel',
1238
+
],
1239
+
},
1240
+
},
1241
+
},
1242
+
},
1243
+
NetMmattVitalsRings: {
1244
+
lexicon: 1,
1245
+
id: 'net.mmatt.vitals.rings',
1246
+
defs: {
1247
+
main: {
1248
+
type: 'record',
1249
+
key: 'tid',
1250
+
record: {
1251
+
type: 'object',
1252
+
properties: {
1253
+
createdAt: {
1254
+
type: 'string',
1255
+
format: 'datetime',
1256
+
description: 'The unix timestamp of when the vital was recorded',
1257
+
},
1258
+
ringsMove: {
1259
+
type: 'integer',
1260
+
description: 'The move ring value',
1261
+
},
1262
+
ringsExercise: {
1263
+
type: 'integer',
1264
+
description: 'The exercise ring value',
1265
+
},
1266
+
ringsStandHours: {
1267
+
type: 'integer',
1268
+
description: 'The stand hours ring value',
1269
+
},
1270
+
ringsMoveGoal: {
1271
+
type: 'integer',
1272
+
description: 'The move goal ring value',
1273
+
},
1274
+
ringsExerciseGoal: {
1275
+
type: 'integer',
1276
+
description: 'The exercise goal ring value',
1277
+
},
1278
+
ringsStandHoursGoal: {
1279
+
type: 'integer',
1280
+
description: 'The stand hours goal ring value',
1281
+
},
1282
+
ringsSteps: {
1283
+
type: 'integer',
1284
+
description: 'The steps value',
1285
+
},
1286
+
ringsBurnedCalories: {
1287
+
type: 'integer',
1288
+
description: 'The burned calories value',
1289
+
},
1290
+
heartRate: {
1291
+
type: 'integer',
1292
+
description: 'The heart rate value',
1293
+
},
1294
+
},
1295
+
required: [
1296
+
'createdAt',
1297
+
'ringsMove',
1298
+
'ringsExercise',
1299
+
'ringsStandHours',
1300
+
'ringsMoveGoal',
1301
+
'ringsExerciseGoal',
1302
+
'ringsStandHoursGoal',
1303
+
'ringsSteps',
1304
+
'ringsBurnedCalories',
1305
+
'heartRate',
1306
+
],
1307
},
1308
},
1309
},
···
1341
}
1342
1343
export const ids = {
1344
+
AppBskyRichtextFacet: 'app.bsky.richtext.facet',
1345
+
FmTealAlphaActorDefs: 'fm.teal.alpha.actor.defs',
1346
+
FmTealAlphaActorGetProfile: 'fm.teal.alpha.actor.getProfile',
1347
+
FmTealAlphaActorGetProfiles: 'fm.teal.alpha.actor.getProfiles',
1348
+
FmTealAlphaActorProfile: 'fm.teal.alpha.actor.profile',
1349
+
FmTealAlphaActorProfileStatus: 'fm.teal.alpha.actor.profileStatus',
1350
+
FmTealAlphaActorSearchActors: 'fm.teal.alpha.actor.searchActors',
1351
+
FmTealAlphaActorStatus: 'fm.teal.alpha.actor.status',
1352
+
FmTealAlphaFeedDefs: 'fm.teal.alpha.feed.defs',
1353
+
FmTealAlphaFeedGetActorFeed: 'fm.teal.alpha.feed.getActorFeed',
1354
+
FmTealAlphaFeedGetPlay: 'fm.teal.alpha.feed.getPlay',
1355
+
FmTealAlphaFeedPlay: 'fm.teal.alpha.feed.play',
1356
+
FmTealAlphaStatsDefs: 'fm.teal.alpha.stats.defs',
1357
+
FmTealAlphaStatsGetLatest: 'fm.teal.alpha.stats.getLatest',
1358
+
FmTealAlphaStatsGetTopArtists: 'fm.teal.alpha.stats.getTopArtists',
1359
+
FmTealAlphaStatsGetTopReleases: 'fm.teal.alpha.stats.getTopReleases',
1360
+
FmTealAlphaStatsGetUserTopArtists: 'fm.teal.alpha.stats.getUserTopArtists',
1361
+
FmTealAlphaStatsGetUserTopReleases: 'fm.teal.alpha.stats.getUserTopReleases',
1362
NetMmattRightNow: 'net.mmatt.right.now',
1363
+
NetMmattVitalsCar: 'net.mmatt.vitals.car',
1364
+
NetMmattVitalsPhone: 'net.mmatt.vitals.phone',
1365
+
NetMmattVitalsRings: 'net.mmatt.vitals.rings',
1366
} as const
+97
lexiconTypes/types/app/bsky/richtext/facet.ts
+97
lexiconTypes/types/app/bsky/richtext/facet.ts
···
···
1
+
/**
2
+
* GENERATED CODE - DO NOT MODIFY
3
+
*/
4
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+
import { CID } from 'multiformats/cid'
6
+
import { validate as _validate } from '../../../../lexicons'
7
+
import {
8
+
type $Typed,
9
+
is$typed as _is$typed,
10
+
type OmitKey,
11
+
} from '../../../../util'
12
+
13
+
const is$typed = _is$typed,
14
+
validate = _validate
15
+
const id = 'app.bsky.richtext.facet'
16
+
17
+
/** Facet feature for a hashtag. The text usually includes a '#' prefix, but the facet reference should not (except in the case of 'double hash tags'). */
18
+
export interface Tag {
19
+
$type?: 'app.bsky.richtext.facet#tag'
20
+
tag: string
21
+
}
22
+
23
+
const hashTag = 'tag'
24
+
25
+
export function isTag<V>(v: V) {
26
+
return is$typed(v, id, hashTag)
27
+
}
28
+
29
+
export function validateTag<V>(v: V) {
30
+
return validate<Tag & V>(v, id, hashTag)
31
+
}
32
+
33
+
/** Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL. */
34
+
export interface Link {
35
+
$type?: 'app.bsky.richtext.facet#link'
36
+
uri: string
37
+
}
38
+
39
+
const hashLink = 'link'
40
+
41
+
export function isLink<V>(v: V) {
42
+
return is$typed(v, id, hashLink)
43
+
}
44
+
45
+
export function validateLink<V>(v: V) {
46
+
return validate<Link & V>(v, id, hashLink)
47
+
}
48
+
49
+
/** Annotation of a sub-string within rich text. */
50
+
export interface Main {
51
+
$type?: 'app.bsky.richtext.facet'
52
+
index: ByteSlice
53
+
features: ($Typed<Mention> | $Typed<Link> | $Typed<Tag> | { $type: string })[]
54
+
}
55
+
56
+
const hashMain = 'main'
57
+
58
+
export function isMain<V>(v: V) {
59
+
return is$typed(v, id, hashMain)
60
+
}
61
+
62
+
export function validateMain<V>(v: V) {
63
+
return validate<Main & V>(v, id, hashMain)
64
+
}
65
+
66
+
/** Facet feature for mention of another account. The text is usually a handle, including a '@' prefix, but the facet reference is a DID. */
67
+
export interface Mention {
68
+
$type?: 'app.bsky.richtext.facet#mention'
69
+
did: string
70
+
}
71
+
72
+
const hashMention = 'mention'
73
+
74
+
export function isMention<V>(v: V) {
75
+
return is$typed(v, id, hashMention)
76
+
}
77
+
78
+
export function validateMention<V>(v: V) {
79
+
return validate<Mention & V>(v, id, hashMention)
80
+
}
81
+
82
+
/** Specifies the sub-string range a facet feature applies to. Start index is inclusive, end index is exclusive. Indices are zero-indexed, counting bytes of the UTF-8 encoded text. NOTE: some languages, like Javascript, use UTF-16 or Unicode codepoints for string slice indexing; in these languages, convert to byte arrays before working with facets. */
83
+
export interface ByteSlice {
84
+
$type?: 'app.bsky.richtext.facet#byteSlice'
85
+
byteEnd: number
86
+
byteStart: number
87
+
}
88
+
89
+
const hashByteSlice = 'byteSlice'
90
+
91
+
export function isByteSlice<V>(v: V) {
92
+
return is$typed(v, id, hashByteSlice)
93
+
}
94
+
95
+
export function validateByteSlice<V>(v: V) {
96
+
return validate<ByteSlice & V>(v, id, hashByteSlice)
97
+
}
+86
lexiconTypes/types/fm/teal/alpha/actor/defs.ts
+86
lexiconTypes/types/fm/teal/alpha/actor/defs.ts
···
···
1
+
/**
2
+
* GENERATED CODE - DO NOT MODIFY
3
+
*/
4
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+
import { CID } from 'multiformats/cid'
6
+
import { validate as _validate } from '../../../../../lexicons'
7
+
import {
8
+
type $Typed,
9
+
is$typed as _is$typed,
10
+
type OmitKey,
11
+
} from '../../../../../util'
12
+
import type * as AppBskyRichtextFacet from '../../../../app/bsky/richtext/facet.js'
13
+
import type * as FmTealAlphaActorProfile from './profile.js'
14
+
import type * as FmTealAlphaFeedDefs from '../feed/defs.js'
15
+
16
+
const is$typed = _is$typed,
17
+
validate = _validate
18
+
const id = 'fm.teal.alpha.actor.defs'
19
+
20
+
export interface ProfileView {
21
+
$type?: 'fm.teal.alpha.actor.defs#profileView'
22
+
/** The decentralized identifier of the actor */
23
+
did?: string
24
+
displayName?: string
25
+
/** Free-form profile description text. */
26
+
description?: string
27
+
/** Annotations of text in the profile description (mentions, URLs, hashtags, etc). May be changed to another (backwards compatible) lexicon. */
28
+
descriptionFacets?: AppBskyRichtextFacet.Main[]
29
+
featuredItem?: FmTealAlphaActorProfile.FeaturedItem
30
+
/** IPLD of the avatar */
31
+
avatar?: string
32
+
/** IPLD of the banner image */
33
+
banner?: string
34
+
status?: StatusView
35
+
createdAt?: string
36
+
}
37
+
38
+
const hashProfileView = 'profileView'
39
+
40
+
export function isProfileView<V>(v: V) {
41
+
return is$typed(v, id, hashProfileView)
42
+
}
43
+
44
+
export function validateProfileView<V>(v: V) {
45
+
return validate<ProfileView & V>(v, id, hashProfileView)
46
+
}
47
+
48
+
export interface MiniProfileView {
49
+
$type?: 'fm.teal.alpha.actor.defs#miniProfileView'
50
+
/** The decentralized identifier of the actor */
51
+
did?: string
52
+
displayName?: string
53
+
handle?: string
54
+
/** IPLD of the avatar */
55
+
avatar?: string
56
+
}
57
+
58
+
const hashMiniProfileView = 'miniProfileView'
59
+
60
+
export function isMiniProfileView<V>(v: V) {
61
+
return is$typed(v, id, hashMiniProfileView)
62
+
}
63
+
64
+
export function validateMiniProfileView<V>(v: V) {
65
+
return validate<MiniProfileView & V>(v, id, hashMiniProfileView)
66
+
}
67
+
68
+
/** A declaration of the status of the actor. */
69
+
export interface StatusView {
70
+
$type?: 'fm.teal.alpha.actor.defs#statusView'
71
+
/** The unix timestamp of when the item was recorded */
72
+
time?: string
73
+
/** The unix timestamp of the expiry time of the item. If unavailable, default to 10 minutes past the start time. */
74
+
expiry?: string
75
+
item?: FmTealAlphaFeedDefs.PlayView
76
+
}
77
+
78
+
const hashStatusView = 'statusView'
79
+
80
+
export function isStatusView<V>(v: V) {
81
+
return is$typed(v, id, hashStatusView)
82
+
}
83
+
84
+
export function validateStatusView<V>(v: V) {
85
+
return validate<StatusView & V>(v, id, hashStatusView)
86
+
}
+41
lexiconTypes/types/fm/teal/alpha/actor/getProfile.ts
+41
lexiconTypes/types/fm/teal/alpha/actor/getProfile.ts
···
···
1
+
/**
2
+
* GENERATED CODE - DO NOT MODIFY
3
+
*/
4
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+
import { CID } from 'multiformats/cid'
6
+
import { validate as _validate } from '../../../../../lexicons'
7
+
import {
8
+
type $Typed,
9
+
is$typed as _is$typed,
10
+
type OmitKey,
11
+
} from '../../../../../util'
12
+
import type * as FmTealAlphaActorDefs from './defs.js'
13
+
14
+
const is$typed = _is$typed,
15
+
validate = _validate
16
+
const id = 'fm.teal.alpha.actor.getProfile'
17
+
18
+
export type QueryParams = {
19
+
/** The author's DID */
20
+
actor: string
21
+
}
22
+
export type InputSchema = undefined
23
+
24
+
export interface OutputSchema {
25
+
actor: FmTealAlphaActorDefs.ProfileView
26
+
}
27
+
28
+
export type HandlerInput = void
29
+
30
+
export interface HandlerSuccess {
31
+
encoding: 'application/json'
32
+
body: OutputSchema
33
+
headers?: { [key: string]: string }
34
+
}
35
+
36
+
export interface HandlerError {
37
+
status: number
38
+
message?: string
39
+
}
40
+
41
+
export type HandlerOutput = HandlerError | HandlerSuccess
+41
lexiconTypes/types/fm/teal/alpha/actor/getProfiles.ts
+41
lexiconTypes/types/fm/teal/alpha/actor/getProfiles.ts
···
···
1
+
/**
2
+
* GENERATED CODE - DO NOT MODIFY
3
+
*/
4
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+
import { CID } from 'multiformats/cid'
6
+
import { validate as _validate } from '../../../../../lexicons'
7
+
import {
8
+
type $Typed,
9
+
is$typed as _is$typed,
10
+
type OmitKey,
11
+
} from '../../../../../util'
12
+
import type * as FmTealAlphaActorDefs from './defs.js'
13
+
14
+
const is$typed = _is$typed,
15
+
validate = _validate
16
+
const id = 'fm.teal.alpha.actor.getProfiles'
17
+
18
+
export type QueryParams = {
19
+
/** Array of actor DIDs */
20
+
actors: string[]
21
+
}
22
+
export type InputSchema = undefined
23
+
24
+
export interface OutputSchema {
25
+
actors: FmTealAlphaActorDefs.MiniProfileView[]
26
+
}
27
+
28
+
export type HandlerInput = void
29
+
30
+
export interface HandlerSuccess {
31
+
encoding: 'application/json'
32
+
body: OutputSchema
33
+
headers?: { [key: string]: string }
34
+
}
35
+
36
+
export interface HandlerError {
37
+
status: number
38
+
message?: string
39
+
}
40
+
41
+
export type HandlerOutput = HandlerError | HandlerSuccess
+60
lexiconTypes/types/fm/teal/alpha/actor/profile.ts
+60
lexiconTypes/types/fm/teal/alpha/actor/profile.ts
···
···
1
+
/**
2
+
* GENERATED CODE - DO NOT MODIFY
3
+
*/
4
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+
import { CID } from 'multiformats/cid'
6
+
import { validate as _validate } from '../../../../../lexicons'
7
+
import {
8
+
type $Typed,
9
+
is$typed as _is$typed,
10
+
type OmitKey,
11
+
} from '../../../../../util'
12
+
import type * as AppBskyRichtextFacet from '../../../../app/bsky/richtext/facet.js'
13
+
14
+
const is$typed = _is$typed,
15
+
validate = _validate
16
+
const id = 'fm.teal.alpha.actor.profile'
17
+
18
+
export interface Record {
19
+
$type: 'fm.teal.alpha.actor.profile'
20
+
displayName?: string
21
+
/** Free-form profile description text. */
22
+
description?: string
23
+
/** Annotations of text in the profile description (mentions, URLs, hashtags, etc). */
24
+
descriptionFacets?: AppBskyRichtextFacet.Main[]
25
+
featuredItem?: FeaturedItem
26
+
/** Small image to be displayed next to posts from account. AKA, 'profile picture' */
27
+
avatar?: BlobRef
28
+
/** Larger horizontal image to display behind profile view. */
29
+
banner?: BlobRef
30
+
createdAt?: string
31
+
[k: string]: unknown
32
+
}
33
+
34
+
const hashRecord = 'main'
35
+
36
+
export function isRecord<V>(v: V) {
37
+
return is$typed(v, id, hashRecord)
38
+
}
39
+
40
+
export function validateRecord<V>(v: V) {
41
+
return validate<Record & V>(v, id, hashRecord, true)
42
+
}
43
+
44
+
export interface FeaturedItem {
45
+
$type?: 'fm.teal.alpha.actor.profile#featuredItem'
46
+
/** The Musicbrainz ID of the item */
47
+
mbid: string
48
+
/** The type of the item. Must be a valid Musicbrainz type, e.g. album, track, recording, etc. */
49
+
type: string
50
+
}
51
+
52
+
const hashFeaturedItem = 'featuredItem'
53
+
54
+
export function isFeaturedItem<V>(v: V) {
55
+
return is$typed(v, id, hashFeaturedItem)
56
+
}
57
+
58
+
export function validateFeaturedItem<V>(v: V) {
59
+
return validate<FeaturedItem & V>(v, id, hashFeaturedItem)
60
+
}
+41
lexiconTypes/types/fm/teal/alpha/actor/profileStatus.ts
+41
lexiconTypes/types/fm/teal/alpha/actor/profileStatus.ts
···
···
1
+
/**
2
+
* GENERATED CODE - DO NOT MODIFY
3
+
*/
4
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+
import { CID } from 'multiformats/cid'
6
+
import { validate as _validate } from '../../../../../lexicons'
7
+
import {
8
+
type $Typed,
9
+
is$typed as _is$typed,
10
+
type OmitKey,
11
+
} from '../../../../../util'
12
+
13
+
const is$typed = _is$typed,
14
+
validate = _validate
15
+
const id = 'fm.teal.alpha.actor.profileStatus'
16
+
17
+
export interface Record {
18
+
$type: 'fm.teal.alpha.actor.profileStatus'
19
+
/** The onboarding completion status */
20
+
completedOnboarding:
21
+
| 'none'
22
+
| 'profileOnboarding'
23
+
| 'playOnboarding'
24
+
| 'complete'
25
+
| (string & {})
26
+
/** The timestamp when this status was created */
27
+
createdAt?: string
28
+
/** The timestamp when this status was last updated */
29
+
updatedAt?: string
30
+
[k: string]: unknown
31
+
}
32
+
33
+
const hashRecord = 'main'
34
+
35
+
export function isRecord<V>(v: V) {
36
+
return is$typed(v, id, hashRecord)
37
+
}
38
+
39
+
export function validateRecord<V>(v: V) {
40
+
return validate<Record & V>(v, id, hashRecord, true)
41
+
}
+47
lexiconTypes/types/fm/teal/alpha/actor/searchActors.ts
+47
lexiconTypes/types/fm/teal/alpha/actor/searchActors.ts
···
···
1
+
/**
2
+
* GENERATED CODE - DO NOT MODIFY
3
+
*/
4
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+
import { CID } from 'multiformats/cid'
6
+
import { validate as _validate } from '../../../../../lexicons'
7
+
import {
8
+
type $Typed,
9
+
is$typed as _is$typed,
10
+
type OmitKey,
11
+
} from '../../../../../util'
12
+
import type * as FmTealAlphaActorDefs from './defs.js'
13
+
14
+
const is$typed = _is$typed,
15
+
validate = _validate
16
+
const id = 'fm.teal.alpha.actor.searchActors'
17
+
18
+
export type QueryParams = {
19
+
/** The search query */
20
+
q: string
21
+
/** The maximum number of actors to return */
22
+
limit?: number
23
+
/** Cursor for pagination */
24
+
cursor?: string
25
+
}
26
+
export type InputSchema = undefined
27
+
28
+
export interface OutputSchema {
29
+
actors: FmTealAlphaActorDefs.MiniProfileView[]
30
+
/** Cursor for pagination */
31
+
cursor?: string
32
+
}
33
+
34
+
export type HandlerInput = void
35
+
36
+
export interface HandlerSuccess {
37
+
encoding: 'application/json'
38
+
body: OutputSchema
39
+
headers?: { [key: string]: string }
40
+
}
41
+
42
+
export interface HandlerError {
43
+
status: number
44
+
message?: string
45
+
}
46
+
47
+
export type HandlerOutput = HandlerError | HandlerSuccess
+36
lexiconTypes/types/fm/teal/alpha/actor/status.ts
+36
lexiconTypes/types/fm/teal/alpha/actor/status.ts
···
···
1
+
/**
2
+
* GENERATED CODE - DO NOT MODIFY
3
+
*/
4
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+
import { CID } from 'multiformats/cid'
6
+
import { validate as _validate } from '../../../../../lexicons'
7
+
import {
8
+
type $Typed,
9
+
is$typed as _is$typed,
10
+
type OmitKey,
11
+
} from '../../../../../util'
12
+
import type * as FmTealAlphaFeedDefs from '../feed/defs.js'
13
+
14
+
const is$typed = _is$typed,
15
+
validate = _validate
16
+
const id = 'fm.teal.alpha.actor.status'
17
+
18
+
export interface Record {
19
+
$type: 'fm.teal.alpha.actor.status'
20
+
/** The unix timestamp of when the item was recorded */
21
+
time: string
22
+
/** The unix timestamp of the expiry time of the item. If unavailable, default to 10 minutes past the start time. */
23
+
expiry?: string
24
+
item: FmTealAlphaFeedDefs.PlayView
25
+
[k: string]: unknown
26
+
}
27
+
28
+
const hashRecord = 'main'
29
+
30
+
export function isRecord<V>(v: V) {
31
+
return is$typed(v, id, hashRecord)
32
+
}
33
+
34
+
export function validateRecord<V>(v: V) {
35
+
return validate<Record & V>(v, id, hashRecord, true)
36
+
}
+71
lexiconTypes/types/fm/teal/alpha/feed/defs.ts
+71
lexiconTypes/types/fm/teal/alpha/feed/defs.ts
···
···
1
+
/**
2
+
* GENERATED CODE - DO NOT MODIFY
3
+
*/
4
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+
import { CID } from 'multiformats/cid'
6
+
import { validate as _validate } from '../../../../../lexicons'
7
+
import {
8
+
type $Typed,
9
+
is$typed as _is$typed,
10
+
type OmitKey,
11
+
} from '../../../../../util'
12
+
13
+
const is$typed = _is$typed,
14
+
validate = _validate
15
+
const id = 'fm.teal.alpha.feed.defs'
16
+
17
+
export interface PlayView {
18
+
$type?: 'fm.teal.alpha.feed.defs#playView'
19
+
/** The name of the track */
20
+
trackName: string
21
+
/** The Musicbrainz ID of the track */
22
+
trackMbId?: string
23
+
/** The Musicbrainz recording ID of the track */
24
+
recordingMbId?: string
25
+
/** The length of the track in seconds */
26
+
duration?: number
27
+
/** Array of artists in order of original appearance. */
28
+
artists: Artist[]
29
+
/** The name of the release/album */
30
+
releaseName?: string
31
+
/** The Musicbrainz release ID */
32
+
releaseMbId?: string
33
+
/** The ISRC code associated with the recording */
34
+
isrc?: string
35
+
/** The URL associated with this track */
36
+
originUrl?: string
37
+
/** The base domain of the music service. e.g. music.apple.com, tidal.com, spotify.com. Defaults to 'local' if not provided. */
38
+
musicServiceBaseDomain?: string
39
+
/** A user-agent style string specifying the user agent. e.g. tealtracker/0.0.1b (Linux; Android 13; SM-A715F). Defaults to 'manual/unknown' if not provided. */
40
+
submissionClientAgent?: string
41
+
/** The unix timestamp of when the track was played */
42
+
playedTime?: string
43
+
}
44
+
45
+
const hashPlayView = 'playView'
46
+
47
+
export function isPlayView<V>(v: V) {
48
+
return is$typed(v, id, hashPlayView)
49
+
}
50
+
51
+
export function validatePlayView<V>(v: V) {
52
+
return validate<PlayView & V>(v, id, hashPlayView)
53
+
}
54
+
55
+
export interface Artist {
56
+
$type?: 'fm.teal.alpha.feed.defs#artist'
57
+
/** The name of the artist */
58
+
artistName: string
59
+
/** The Musicbrainz ID of the artist */
60
+
artistMbId?: string
61
+
}
62
+
63
+
const hashArtist = 'artist'
64
+
65
+
export function isArtist<V>(v: V) {
66
+
return is$typed(v, id, hashArtist)
67
+
}
68
+
69
+
export function validateArtist<V>(v: V) {
70
+
return validate<Artist & V>(v, id, hashArtist)
71
+
}
+45
lexiconTypes/types/fm/teal/alpha/feed/getActorFeed.ts
+45
lexiconTypes/types/fm/teal/alpha/feed/getActorFeed.ts
···
···
1
+
/**
2
+
* GENERATED CODE - DO NOT MODIFY
3
+
*/
4
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+
import { CID } from 'multiformats/cid'
6
+
import { validate as _validate } from '../../../../../lexicons'
7
+
import {
8
+
type $Typed,
9
+
is$typed as _is$typed,
10
+
type OmitKey,
11
+
} from '../../../../../util'
12
+
import type * as FmTealAlphaFeedDefs from './defs.js'
13
+
14
+
const is$typed = _is$typed,
15
+
validate = _validate
16
+
const id = 'fm.teal.alpha.feed.getActorFeed'
17
+
18
+
export type QueryParams = {
19
+
/** The author's DID for the play */
20
+
authorDID: string
21
+
/** The cursor to start the query from */
22
+
cursor?: string
23
+
/** The upper limit of tracks to get per request. Default is 20, max is 50. */
24
+
limit?: number
25
+
}
26
+
export type InputSchema = undefined
27
+
28
+
export interface OutputSchema {
29
+
plays: FmTealAlphaFeedDefs.PlayView[]
30
+
}
31
+
32
+
export type HandlerInput = void
33
+
34
+
export interface HandlerSuccess {
35
+
encoding: 'application/json'
36
+
body: OutputSchema
37
+
headers?: { [key: string]: string }
38
+
}
39
+
40
+
export interface HandlerError {
41
+
status: number
42
+
message?: string
43
+
}
44
+
45
+
export type HandlerOutput = HandlerError | HandlerSuccess
+43
lexiconTypes/types/fm/teal/alpha/feed/getPlay.ts
+43
lexiconTypes/types/fm/teal/alpha/feed/getPlay.ts
···
···
1
+
/**
2
+
* GENERATED CODE - DO NOT MODIFY
3
+
*/
4
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+
import { CID } from 'multiformats/cid'
6
+
import { validate as _validate } from '../../../../../lexicons'
7
+
import {
8
+
type $Typed,
9
+
is$typed as _is$typed,
10
+
type OmitKey,
11
+
} from '../../../../../util'
12
+
import type * as FmTealAlphaFeedDefs from './defs.js'
13
+
14
+
const is$typed = _is$typed,
15
+
validate = _validate
16
+
const id = 'fm.teal.alpha.feed.getPlay'
17
+
18
+
export type QueryParams = {
19
+
/** The author's DID for the play */
20
+
authorDID: string
21
+
/** The record key of the play */
22
+
rkey: string
23
+
}
24
+
export type InputSchema = undefined
25
+
26
+
export interface OutputSchema {
27
+
play: FmTealAlphaFeedDefs.PlayView
28
+
}
29
+
30
+
export type HandlerInput = void
31
+
32
+
export interface HandlerSuccess {
33
+
encoding: 'application/json'
34
+
body: OutputSchema
35
+
headers?: { [key: string]: string }
36
+
}
37
+
38
+
export interface HandlerError {
39
+
status: number
40
+
message?: string
41
+
}
42
+
43
+
export type HandlerOutput = HandlerError | HandlerSuccess
+63
lexiconTypes/types/fm/teal/alpha/feed/play.ts
+63
lexiconTypes/types/fm/teal/alpha/feed/play.ts
···
···
1
+
/**
2
+
* GENERATED CODE - DO NOT MODIFY
3
+
*/
4
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+
import { CID } from 'multiformats/cid'
6
+
import { validate as _validate } from '../../../../../lexicons'
7
+
import {
8
+
type $Typed,
9
+
is$typed as _is$typed,
10
+
type OmitKey,
11
+
} from '../../../../../util'
12
+
import type * as FmTealAlphaFeedDefs from './defs.js'
13
+
14
+
const is$typed = _is$typed,
15
+
validate = _validate
16
+
const id = 'fm.teal.alpha.feed.play'
17
+
18
+
export interface Record {
19
+
$type: 'fm.teal.alpha.feed.play'
20
+
/** The name of the track */
21
+
trackName: string
22
+
/** The Musicbrainz ID of the track */
23
+
trackMbId?: string
24
+
/** The Musicbrainz recording ID of the track */
25
+
recordingMbId?: string
26
+
/** The length of the track in seconds */
27
+
duration?: number
28
+
/** Array of artist names in order of original appearance. Prefer using 'artists'. */
29
+
artistNames?: string[]
30
+
/** Array of Musicbrainz artist IDs. Prefer using 'artists'. */
31
+
artistMbIds?: string[]
32
+
/** Array of artists in order of original appearance. */
33
+
artists?: FmTealAlphaFeedDefs.Artist[]
34
+
/** The name of the release/album */
35
+
releaseName?: string
36
+
/** The Musicbrainz release ID */
37
+
releaseMbId?: string
38
+
/** The ISRC code associated with the recording */
39
+
isrc?: string
40
+
/** The URL associated with this track */
41
+
originUrl?: string
42
+
/** The base domain of the music service. e.g. music.apple.com, tidal.com, spotify.com. Defaults to 'local' if unavailable or not provided. */
43
+
musicServiceBaseDomain?: string
44
+
/** A metadata string specifying the user agent where the format is `<app-identifier>/<version> (<kernel/OS-base>; <platform/OS-version>; <device-model>)`. If string is provided, only `app-identifier` and `version` are required. `app-identifier` is recommended to be in reverse dns format. Defaults to 'manual/unknown' if unavailable or not provided. */
45
+
submissionClientAgent?: string
46
+
/** The unix timestamp of when the track was played */
47
+
playedTime?: string
48
+
/** Distinguishing information for track variants (e.g. 'Acoustic Version', 'Live at Wembley', 'Radio Edit', 'Demo'). Used to differentiate between different versions of the same base track while maintaining grouping capabilities. */
49
+
trackDiscriminant?: string
50
+
/** Distinguishing information for release variants (e.g. 'Deluxe Edition', 'Remastered', '2023 Remaster', 'Special Edition'). Used to differentiate between different versions of the same base release while maintaining grouping capabilities. */
51
+
releaseDiscriminant?: string
52
+
[k: string]: unknown
53
+
}
54
+
55
+
const hashRecord = 'main'
56
+
57
+
export function isRecord<V>(v: V) {
58
+
return is$typed(v, id, hashRecord)
59
+
}
60
+
61
+
export function validateRecord<V>(v: V) {
62
+
return validate<Record & V>(v, id, hashRecord, true)
63
+
}
+75
lexiconTypes/types/fm/teal/alpha/stats/defs.ts
+75
lexiconTypes/types/fm/teal/alpha/stats/defs.ts
···
···
1
+
/**
2
+
* GENERATED CODE - DO NOT MODIFY
3
+
*/
4
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+
import { CID } from 'multiformats/cid'
6
+
import { validate as _validate } from '../../../../../lexicons'
7
+
import {
8
+
type $Typed,
9
+
is$typed as _is$typed,
10
+
type OmitKey,
11
+
} from '../../../../../util'
12
+
13
+
const is$typed = _is$typed,
14
+
validate = _validate
15
+
const id = 'fm.teal.alpha.stats.defs'
16
+
17
+
export interface ArtistView {
18
+
$type?: 'fm.teal.alpha.stats.defs#artistView'
19
+
/** MusicBrainz artist ID */
20
+
mbid: string
21
+
/** Artist name */
22
+
name: string
23
+
/** Total number of plays for this artist */
24
+
playCount: number
25
+
}
26
+
27
+
const hashArtistView = 'artistView'
28
+
29
+
export function isArtistView<V>(v: V) {
30
+
return is$typed(v, id, hashArtistView)
31
+
}
32
+
33
+
export function validateArtistView<V>(v: V) {
34
+
return validate<ArtistView & V>(v, id, hashArtistView)
35
+
}
36
+
37
+
export interface ReleaseView {
38
+
$type?: 'fm.teal.alpha.stats.defs#releaseView'
39
+
/** MusicBrainz release ID */
40
+
mbid: string
41
+
/** Release/album name */
42
+
name: string
43
+
/** Total number of plays for this release */
44
+
playCount: number
45
+
}
46
+
47
+
const hashReleaseView = 'releaseView'
48
+
49
+
export function isReleaseView<V>(v: V) {
50
+
return is$typed(v, id, hashReleaseView)
51
+
}
52
+
53
+
export function validateReleaseView<V>(v: V) {
54
+
return validate<ReleaseView & V>(v, id, hashReleaseView)
55
+
}
56
+
57
+
export interface RecordingView {
58
+
$type?: 'fm.teal.alpha.stats.defs#recordingView'
59
+
/** MusicBrainz recording ID */
60
+
mbid: string
61
+
/** Recording/track name */
62
+
name: string
63
+
/** Total number of plays for this recording */
64
+
playCount: number
65
+
}
66
+
67
+
const hashRecordingView = 'recordingView'
68
+
69
+
export function isRecordingView<V>(v: V) {
70
+
return is$typed(v, id, hashRecordingView)
71
+
}
72
+
73
+
export function validateRecordingView<V>(v: V) {
74
+
return validate<RecordingView & V>(v, id, hashRecordingView)
75
+
}
+41
lexiconTypes/types/fm/teal/alpha/stats/getLatest.ts
+41
lexiconTypes/types/fm/teal/alpha/stats/getLatest.ts
···
···
1
+
/**
2
+
* GENERATED CODE - DO NOT MODIFY
3
+
*/
4
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+
import { CID } from 'multiformats/cid'
6
+
import { validate as _validate } from '../../../../../lexicons'
7
+
import {
8
+
type $Typed,
9
+
is$typed as _is$typed,
10
+
type OmitKey,
11
+
} from '../../../../../util'
12
+
import type * as FmTealAlphaFeedDefs from '../feed/defs.js'
13
+
14
+
const is$typed = _is$typed,
15
+
validate = _validate
16
+
const id = 'fm.teal.alpha.stats.getLatest'
17
+
18
+
export type QueryParams = {
19
+
/** Number of latest plays to return */
20
+
limit: number
21
+
}
22
+
export type InputSchema = undefined
23
+
24
+
export interface OutputSchema {
25
+
plays: FmTealAlphaFeedDefs.PlayView[]
26
+
}
27
+
28
+
export type HandlerInput = void
29
+
30
+
export interface HandlerSuccess {
31
+
encoding: 'application/json'
32
+
body: OutputSchema
33
+
headers?: { [key: string]: string }
34
+
}
35
+
36
+
export interface HandlerError {
37
+
status: number
38
+
message?: string
39
+
}
40
+
41
+
export type HandlerOutput = HandlerError | HandlerSuccess
+47
lexiconTypes/types/fm/teal/alpha/stats/getTopArtists.ts
+47
lexiconTypes/types/fm/teal/alpha/stats/getTopArtists.ts
···
···
1
+
/**
2
+
* GENERATED CODE - DO NOT MODIFY
3
+
*/
4
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+
import { CID } from 'multiformats/cid'
6
+
import { validate as _validate } from '../../../../../lexicons'
7
+
import {
8
+
type $Typed,
9
+
is$typed as _is$typed,
10
+
type OmitKey,
11
+
} from '../../../../../util'
12
+
import type * as FmTealAlphaStatsDefs from './defs.js'
13
+
14
+
const is$typed = _is$typed,
15
+
validate = _validate
16
+
const id = 'fm.teal.alpha.stats.getTopArtists'
17
+
18
+
export type QueryParams = {
19
+
/** Time period for top artists */
20
+
period: 'all' | '30days' | '7days'
21
+
/** Number of artists to return */
22
+
limit: number
23
+
/** Pagination cursor */
24
+
cursor?: string
25
+
}
26
+
export type InputSchema = undefined
27
+
28
+
export interface OutputSchema {
29
+
artists: FmTealAlphaStatsDefs.ArtistView[]
30
+
/** Next page cursor */
31
+
cursor?: string
32
+
}
33
+
34
+
export type HandlerInput = void
35
+
36
+
export interface HandlerSuccess {
37
+
encoding: 'application/json'
38
+
body: OutputSchema
39
+
headers?: { [key: string]: string }
40
+
}
41
+
42
+
export interface HandlerError {
43
+
status: number
44
+
message?: string
45
+
}
46
+
47
+
export type HandlerOutput = HandlerError | HandlerSuccess
+47
lexiconTypes/types/fm/teal/alpha/stats/getTopReleases.ts
+47
lexiconTypes/types/fm/teal/alpha/stats/getTopReleases.ts
···
···
1
+
/**
2
+
* GENERATED CODE - DO NOT MODIFY
3
+
*/
4
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+
import { CID } from 'multiformats/cid'
6
+
import { validate as _validate } from '../../../../../lexicons'
7
+
import {
8
+
type $Typed,
9
+
is$typed as _is$typed,
10
+
type OmitKey,
11
+
} from '../../../../../util'
12
+
import type * as FmTealAlphaStatsDefs from './defs.js'
13
+
14
+
const is$typed = _is$typed,
15
+
validate = _validate
16
+
const id = 'fm.teal.alpha.stats.getTopReleases'
17
+
18
+
export type QueryParams = {
19
+
/** Time period for top releases */
20
+
period: 'all' | '30days' | '7days'
21
+
/** Number of releases to return */
22
+
limit: number
23
+
/** Pagination cursor */
24
+
cursor?: string
25
+
}
26
+
export type InputSchema = undefined
27
+
28
+
export interface OutputSchema {
29
+
releases: FmTealAlphaStatsDefs.ReleaseView[]
30
+
/** Next page cursor */
31
+
cursor?: string
32
+
}
33
+
34
+
export type HandlerInput = void
35
+
36
+
export interface HandlerSuccess {
37
+
encoding: 'application/json'
38
+
body: OutputSchema
39
+
headers?: { [key: string]: string }
40
+
}
41
+
42
+
export interface HandlerError {
43
+
status: number
44
+
message?: string
45
+
}
46
+
47
+
export type HandlerOutput = HandlerError | HandlerSuccess
+49
lexiconTypes/types/fm/teal/alpha/stats/getUserTopArtists.ts
+49
lexiconTypes/types/fm/teal/alpha/stats/getUserTopArtists.ts
···
···
1
+
/**
2
+
* GENERATED CODE - DO NOT MODIFY
3
+
*/
4
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+
import { CID } from 'multiformats/cid'
6
+
import { validate as _validate } from '../../../../../lexicons'
7
+
import {
8
+
type $Typed,
9
+
is$typed as _is$typed,
10
+
type OmitKey,
11
+
} from '../../../../../util'
12
+
import type * as FmTealAlphaStatsDefs from './defs.js'
13
+
14
+
const is$typed = _is$typed,
15
+
validate = _validate
16
+
const id = 'fm.teal.alpha.stats.getUserTopArtists'
17
+
18
+
export type QueryParams = {
19
+
/** The user's DID or handle */
20
+
actor: string
21
+
/** Time period for top artists */
22
+
period: '30days' | '7days'
23
+
/** Number of artists to return */
24
+
limit: number
25
+
/** Pagination cursor */
26
+
cursor?: string
27
+
}
28
+
export type InputSchema = undefined
29
+
30
+
export interface OutputSchema {
31
+
artists: FmTealAlphaStatsDefs.ArtistView[]
32
+
/** Next page cursor */
33
+
cursor?: string
34
+
}
35
+
36
+
export type HandlerInput = void
37
+
38
+
export interface HandlerSuccess {
39
+
encoding: 'application/json'
40
+
body: OutputSchema
41
+
headers?: { [key: string]: string }
42
+
}
43
+
44
+
export interface HandlerError {
45
+
status: number
46
+
message?: string
47
+
}
48
+
49
+
export type HandlerOutput = HandlerError | HandlerSuccess
+49
lexiconTypes/types/fm/teal/alpha/stats/getUserTopReleases.ts
+49
lexiconTypes/types/fm/teal/alpha/stats/getUserTopReleases.ts
···
···
1
+
/**
2
+
* GENERATED CODE - DO NOT MODIFY
3
+
*/
4
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+
import { CID } from 'multiformats/cid'
6
+
import { validate as _validate } from '../../../../../lexicons'
7
+
import {
8
+
type $Typed,
9
+
is$typed as _is$typed,
10
+
type OmitKey,
11
+
} from '../../../../../util'
12
+
import type * as FmTealAlphaStatsDefs from './defs.js'
13
+
14
+
const is$typed = _is$typed,
15
+
validate = _validate
16
+
const id = 'fm.teal.alpha.stats.getUserTopReleases'
17
+
18
+
export type QueryParams = {
19
+
/** The user's DID or handle */
20
+
actor: string
21
+
/** Time period for top releases */
22
+
period: '30days' | '7days'
23
+
/** Number of releases to return */
24
+
limit: number
25
+
/** Pagination cursor */
26
+
cursor?: string
27
+
}
28
+
export type InputSchema = undefined
29
+
30
+
export interface OutputSchema {
31
+
releases: FmTealAlphaStatsDefs.ReleaseView[]
32
+
/** Next page cursor */
33
+
cursor?: string
34
+
}
35
+
36
+
export type HandlerInput = void
37
+
38
+
export interface HandlerSuccess {
39
+
encoding: 'application/json'
40
+
body: OutputSchema
41
+
headers?: { [key: string]: string }
42
+
}
43
+
44
+
export interface HandlerError {
45
+
status: number
46
+
message?: string
47
+
}
48
+
49
+
export type HandlerOutput = HandlerError | HandlerSuccess
+46
lexiconTypes/types/net/mmatt/vitals/car.ts
+46
lexiconTypes/types/net/mmatt/vitals/car.ts
···
···
1
+
/**
2
+
* GENERATED CODE - DO NOT MODIFY
3
+
*/
4
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+
import { CID } from 'multiformats/cid'
6
+
import { validate as _validate } from '../../../../lexicons'
7
+
import {
8
+
type $Typed,
9
+
is$typed as _is$typed,
10
+
type OmitKey,
11
+
} from '../../../../util'
12
+
13
+
const is$typed = _is$typed,
14
+
validate = _validate
15
+
const id = 'net.mmatt.vitals.car'
16
+
17
+
export interface Record {
18
+
$type: 'net.mmatt.vitals.car'
19
+
/** The unix timestamp of when the vital was recorded */
20
+
createdAt: string
21
+
/** The car fuel range value in miles */
22
+
carFuelRange: number
23
+
/** The car fuel level value in percentage (floating point string) */
24
+
carPercentFuelRemaining: string
25
+
/** The car fuel amount remaining value (floating point string) */
26
+
amountRemaining: string
27
+
/** The car traveled distance value */
28
+
carTraveledDistance: number
29
+
/** The car make value */
30
+
carMake?: string
31
+
/** The car model value */
32
+
carModel?: string
33
+
/** The car year value */
34
+
carYear?: number
35
+
[k: string]: unknown
36
+
}
37
+
38
+
const hashRecord = 'main'
39
+
40
+
export function isRecord<V>(v: V) {
41
+
return is$typed(v, id, hashRecord)
42
+
}
43
+
44
+
export function validateRecord<V>(v: V) {
45
+
return validate<Record & V>(v, id, hashRecord, true)
46
+
}
+56
lexiconTypes/types/net/mmatt/vitals/phone.ts
+56
lexiconTypes/types/net/mmatt/vitals/phone.ts
···
···
1
+
/**
2
+
* GENERATED CODE - DO NOT MODIFY
3
+
*/
4
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+
import { CID } from 'multiformats/cid'
6
+
import { validate as _validate } from '../../../../lexicons'
7
+
import {
8
+
type $Typed,
9
+
is$typed as _is$typed,
10
+
type OmitKey,
11
+
} from '../../../../util'
12
+
13
+
const is$typed = _is$typed,
14
+
validate = _validate
15
+
const id = 'net.mmatt.vitals.phone'
16
+
17
+
export interface Record {
18
+
$type: 'net.mmatt.vitals.phone'
19
+
/** The unix timestamp of when the vital was recorded */
20
+
createdAt: string
21
+
/** The phone motion value */
22
+
phoneMotion: string
23
+
/** The phone volume value */
24
+
phoneVolume: string
25
+
/** The phone appearance value */
26
+
phoneAppearance: string
27
+
/** The phone brightness value */
28
+
phoneBrightness: string
29
+
/** The phone orientation value */
30
+
phoneOrientation: string
31
+
/** The phone cell bars value */
32
+
phoneCellBars: string
33
+
/** The phone cell network value */
34
+
phoneCellNetwork: string
35
+
/** The phone battery level value */
36
+
phoneBatteryLevel: string
37
+
/** The phone battery charging value */
38
+
phoneBatteryCharging: string
39
+
/** The phone OS value */
40
+
phoneOs: string
41
+
/** The phone OS version value */
42
+
phoneOsVersion: string
43
+
/** The phone model value */
44
+
phoneModel: string
45
+
[k: string]: unknown
46
+
}
47
+
48
+
const hashRecord = 'main'
49
+
50
+
export function isRecord<V>(v: V) {
51
+
return is$typed(v, id, hashRecord)
52
+
}
53
+
54
+
export function validateRecord<V>(v: V) {
55
+
return validate<Record & V>(v, id, hashRecord, true)
56
+
}
+50
lexiconTypes/types/net/mmatt/vitals/rings.ts
+50
lexiconTypes/types/net/mmatt/vitals/rings.ts
···
···
1
+
/**
2
+
* GENERATED CODE - DO NOT MODIFY
3
+
*/
4
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+
import { CID } from 'multiformats/cid'
6
+
import { validate as _validate } from '../../../../lexicons'
7
+
import {
8
+
type $Typed,
9
+
is$typed as _is$typed,
10
+
type OmitKey,
11
+
} from '../../../../util'
12
+
13
+
const is$typed = _is$typed,
14
+
validate = _validate
15
+
const id = 'net.mmatt.vitals.rings'
16
+
17
+
export interface Record {
18
+
$type: 'net.mmatt.vitals.rings'
19
+
/** The unix timestamp of when the vital was recorded */
20
+
createdAt: string
21
+
/** The move ring value */
22
+
ringsMove: number
23
+
/** The exercise ring value */
24
+
ringsExercise: number
25
+
/** The stand hours ring value */
26
+
ringsStandHours: number
27
+
/** The move goal ring value */
28
+
ringsMoveGoal: number
29
+
/** The exercise goal ring value */
30
+
ringsExerciseGoal: number
31
+
/** The stand hours goal ring value */
32
+
ringsStandHoursGoal: number
33
+
/** The steps value */
34
+
ringsSteps: number
35
+
/** The burned calories value */
36
+
ringsBurnedCalories: number
37
+
/** The heart rate value */
38
+
heartRate: number
39
+
[k: string]: unknown
40
+
}
41
+
42
+
const hashRecord = 'main'
43
+
44
+
export function isRecord<V>(v: V) {
45
+
return is$typed(v, id, hashRecord)
46
+
}
47
+
48
+
export function validateRecord<V>(v: V) {
49
+
return validate<Record & V>(v, id, hashRecord, true)
50
+
}
+89
lexicons/app/bsky/richtext/facet.json
+89
lexicons/app/bsky/richtext/facet.json
···
···
1
+
{
2
+
"lexicon": 1,
3
+
"id": "app.bsky.richtext.facet",
4
+
"defs": {
5
+
"tag": {
6
+
"type": "object",
7
+
"required": [
8
+
"tag"
9
+
],
10
+
"properties": {
11
+
"tag": {
12
+
"type": "string",
13
+
"maxLength": 640,
14
+
"maxGraphemes": 64
15
+
}
16
+
},
17
+
"description": "Facet feature for a hashtag. The text usually includes a '#' prefix, but the facet reference should not (except in the case of 'double hash tags')."
18
+
},
19
+
"link": {
20
+
"type": "object",
21
+
"required": [
22
+
"uri"
23
+
],
24
+
"properties": {
25
+
"uri": {
26
+
"type": "string",
27
+
"format": "uri"
28
+
}
29
+
},
30
+
"description": "Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL."
31
+
},
32
+
"main": {
33
+
"type": "object",
34
+
"required": [
35
+
"index",
36
+
"features"
37
+
],
38
+
"properties": {
39
+
"index": {
40
+
"ref": "#byteSlice",
41
+
"type": "ref"
42
+
},
43
+
"features": {
44
+
"type": "array",
45
+
"items": {
46
+
"refs": [
47
+
"#mention",
48
+
"#link",
49
+
"#tag"
50
+
],
51
+
"type": "union"
52
+
}
53
+
}
54
+
},
55
+
"description": "Annotation of a sub-string within rich text."
56
+
},
57
+
"mention": {
58
+
"type": "object",
59
+
"required": [
60
+
"did"
61
+
],
62
+
"properties": {
63
+
"did": {
64
+
"type": "string",
65
+
"format": "did"
66
+
}
67
+
},
68
+
"description": "Facet feature for mention of another account. The text is usually a handle, including a '@' prefix, but the facet reference is a DID."
69
+
},
70
+
"byteSlice": {
71
+
"type": "object",
72
+
"required": [
73
+
"byteStart",
74
+
"byteEnd"
75
+
],
76
+
"properties": {
77
+
"byteEnd": {
78
+
"type": "integer",
79
+
"minimum": 0
80
+
},
81
+
"byteStart": {
82
+
"type": "integer",
83
+
"minimum": 0
84
+
}
85
+
},
86
+
"description": "Specifies the sub-string range a facet feature applies to. Start index is inclusive, end index is exclusive. Indices are zero-indexed, counting bytes of the UTF-8 encoded text. NOTE: some languages, like Javascript, use UTF-16 or Unicode codepoints for string slice indexing; in these languages, convert to byte arrays before working with facets."
87
+
}
88
+
}
89
+
}
+84
lexicons/fm/teal/alpha/actor/defs.json
+84
lexicons/fm/teal/alpha/actor/defs.json
···
···
1
+
{
2
+
"lexicon": 1,
3
+
"id": "fm.teal.alpha.actor.defs",
4
+
"defs": {
5
+
"profileView": {
6
+
"type": "object",
7
+
"properties": {
8
+
"did": {
9
+
"type": "string",
10
+
"description": "The decentralized identifier of the actor"
11
+
},
12
+
"displayName": {
13
+
"type": "string"
14
+
},
15
+
"description": {
16
+
"type": "string",
17
+
"description": "Free-form profile description text."
18
+
},
19
+
"descriptionFacets": {
20
+
"type": "array",
21
+
"description": "Annotations of text in the profile description (mentions, URLs, hashtags, etc). May be changed to another (backwards compatible) lexicon.",
22
+
"items": { "type": "ref", "ref": "app.bsky.richtext.facet" }
23
+
},
24
+
"featuredItem": {
25
+
"type": "ref",
26
+
"description": "The user's most recent item featured on their profile.",
27
+
"ref": "fm.teal.alpha.actor.profile#featuredItem"
28
+
},
29
+
"avatar": {
30
+
"type": "string",
31
+
"description": "IPLD of the avatar"
32
+
},
33
+
"banner": {
34
+
"type": "string",
35
+
"description": "IPLD of the banner image"
36
+
},
37
+
"status": {
38
+
"type": "ref",
39
+
"ref": "#statusView"
40
+
},
41
+
"createdAt": { "type": "string", "format": "datetime" }
42
+
}
43
+
},
44
+
"miniProfileView": {
45
+
"type": "object",
46
+
"properties": {
47
+
"did": {
48
+
"type": "string",
49
+
"description": "The decentralized identifier of the actor"
50
+
},
51
+
"displayName": {
52
+
"type": "string"
53
+
},
54
+
"handle": {
55
+
"type": "string"
56
+
},
57
+
"avatar": {
58
+
"type": "string",
59
+
"description": "IPLD of the avatar"
60
+
}
61
+
}
62
+
},
63
+
"statusView": {
64
+
"type": "object",
65
+
"description": "A declaration of the status of the actor.",
66
+
"properties": {
67
+
"time": {
68
+
"type": "string",
69
+
"format": "datetime",
70
+
"description": "The unix timestamp of when the item was recorded"
71
+
},
72
+
"expiry": {
73
+
"type": "string",
74
+
"format": "datetime",
75
+
"description": "The unix timestamp of the expiry time of the item. If unavailable, default to 10 minutes past the start time."
76
+
},
77
+
"item": {
78
+
"type": "ref",
79
+
"ref": "fm.teal.alpha.feed.defs#playView"
80
+
}
81
+
}
82
+
}
83
+
}
84
+
}
+34
lexicons/fm/teal/alpha/actor/getProfile.json
+34
lexicons/fm/teal/alpha/actor/getProfile.json
···
···
1
+
{
2
+
"lexicon": 1,
3
+
"id": "fm.teal.alpha.actor.getProfile",
4
+
"description": "This lexicon is in a not officially released state. It is subject to change. | Retrieves a play given an author DID and record key.",
5
+
"defs": {
6
+
"main": {
7
+
"type": "query",
8
+
"parameters": {
9
+
"type": "params",
10
+
"required": ["actor"],
11
+
"properties": {
12
+
"actor": {
13
+
"type": "string",
14
+
"format": "at-identifier",
15
+
"description": "The author's DID"
16
+
}
17
+
}
18
+
},
19
+
"output": {
20
+
"encoding": "application/json",
21
+
"schema": {
22
+
"type": "object",
23
+
"required": ["actor"],
24
+
"properties": {
25
+
"actor": {
26
+
"type": "ref",
27
+
"ref": "fm.teal.alpha.actor.defs#profileView"
28
+
}
29
+
}
30
+
}
31
+
}
32
+
}
33
+
}
34
+
}
+40
lexicons/fm/teal/alpha/actor/getProfiles.json
+40
lexicons/fm/teal/alpha/actor/getProfiles.json
···
···
1
+
{
2
+
"lexicon": 1,
3
+
"id": "fm.teal.alpha.actor.getProfiles",
4
+
"description": "This lexicon is in a not officially released state. It is subject to change. | Retrieves the associated profile.",
5
+
"defs": {
6
+
"main": {
7
+
"type": "query",
8
+
"parameters": {
9
+
"type": "params",
10
+
"required": ["actors"],
11
+
"properties": {
12
+
"actors": {
13
+
"type": "array",
14
+
"items": {
15
+
"type": "string",
16
+
"format": "at-identifier"
17
+
},
18
+
"description": "Array of actor DIDs"
19
+
}
20
+
}
21
+
},
22
+
"output": {
23
+
"encoding": "application/json",
24
+
"schema": {
25
+
"type": "object",
26
+
"required": ["actors"],
27
+
"properties": {
28
+
"actors": {
29
+
"type": "array",
30
+
"items": {
31
+
"type": "ref",
32
+
"ref": "fm.teal.alpha.actor.defs#miniProfileView"
33
+
}
34
+
}
35
+
}
36
+
}
37
+
}
38
+
}
39
+
}
40
+
}
+64
lexicons/fm/teal/alpha/actor/profile.json
+64
lexicons/fm/teal/alpha/actor/profile.json
···
···
1
+
{
2
+
"lexicon": 1,
3
+
"id": "fm.teal.alpha.actor.profile",
4
+
"defs": {
5
+
"main": {
6
+
"type": "record",
7
+
"description": "This lexicon is in a not officially released state. It is subject to change. | A declaration of a teal.fm account profile.",
8
+
"key": "literal:self",
9
+
"record": {
10
+
"type": "object",
11
+
"properties": {
12
+
"displayName": {
13
+
"type": "string",
14
+
"maxGraphemes": 64,
15
+
"maxLength": 640
16
+
},
17
+
"description": {
18
+
"type": "string",
19
+
"description": "Free-form profile description text.",
20
+
"maxGraphemes": 256,
21
+
"maxLength": 2560
22
+
},
23
+
"descriptionFacets": {
24
+
"type": "array",
25
+
"description": "Annotations of text in the profile description (mentions, URLs, hashtags, etc).",
26
+
"items": { "type": "ref", "ref": "app.bsky.richtext.facet" }
27
+
},
28
+
"featuredItem": {
29
+
"type": "ref",
30
+
"description": "The user's most recent item featured on their profile.",
31
+
"ref": "#featuredItem"
32
+
},
33
+
"avatar": {
34
+
"type": "blob",
35
+
"description": "Small image to be displayed next to posts from account. AKA, 'profile picture'",
36
+
"accept": ["image/png", "image/jpeg"],
37
+
"maxSize": 1000000
38
+
},
39
+
"banner": {
40
+
"type": "blob",
41
+
"description": "Larger horizontal image to display behind profile view.",
42
+
"accept": ["image/png", "image/jpeg"],
43
+
"maxSize": 1000000
44
+
},
45
+
"createdAt": { "type": "string", "format": "datetime" }
46
+
}
47
+
}
48
+
},
49
+
"featuredItem": {
50
+
"type": "object",
51
+
"required": ["mbid", "type"],
52
+
"properties": {
53
+
"mbid": {
54
+
"type": "string",
55
+
"description": "The Musicbrainz ID of the item"
56
+
},
57
+
"type": {
58
+
"type": "string",
59
+
"description": "The type of the item. Must be a valid Musicbrainz type, e.g. album, track, recording, etc."
60
+
}
61
+
}
62
+
}
63
+
}
64
+
}
+32
lexicons/fm/teal/alpha/actor/profileStatus.json
+32
lexicons/fm/teal/alpha/actor/profileStatus.json
···
···
1
+
{
2
+
"lexicon": 1,
3
+
"id": "fm.teal.alpha.actor.profileStatus",
4
+
"defs": {
5
+
"main": {
6
+
"type": "record",
7
+
"description": "This lexicon is in a not officially released state. It is subject to change. | A declaration of the profile status of the actor.",
8
+
"key": "literal:self",
9
+
"record": {
10
+
"type": "object",
11
+
"required": ["completedOnboarding"],
12
+
"properties": {
13
+
"completedOnboarding": {
14
+
"type": "string",
15
+
"description": "The onboarding completion status",
16
+
"knownValues": ["none", "profileOnboarding", "playOnboarding", "complete"]
17
+
},
18
+
"createdAt": {
19
+
"type": "string",
20
+
"format": "datetime",
21
+
"description": "The timestamp when this status was created"
22
+
},
23
+
"updatedAt": {
24
+
"type": "string",
25
+
"format": "datetime",
26
+
"description": "The timestamp when this status was last updated"
27
+
}
28
+
}
29
+
}
30
+
}
31
+
}
32
+
}
+52
lexicons/fm/teal/alpha/actor/searchActors.json
+52
lexicons/fm/teal/alpha/actor/searchActors.json
···
···
1
+
{
2
+
"lexicon": 1,
3
+
"id": "fm.teal.alpha.actor.searchActors",
4
+
"description": "This lexicon is in a not officially released state. It is subject to change. | Searches for actors based on profile contents.",
5
+
"defs": {
6
+
"main": {
7
+
"type": "query",
8
+
"parameters": {
9
+
"type": "params",
10
+
"required": ["q"],
11
+
"properties": {
12
+
"q": {
13
+
"type": "string",
14
+
"description": "The search query",
15
+
"maxGraphemes": 128,
16
+
"maxLength": 640
17
+
},
18
+
"limit": {
19
+
"type": "integer",
20
+
"description": "The maximum number of actors to return",
21
+
"minimum": 1,
22
+
"maximum": 25
23
+
},
24
+
"cursor": {
25
+
"type": "string",
26
+
"description": "Cursor for pagination"
27
+
}
28
+
}
29
+
},
30
+
"output": {
31
+
"encoding": "application/json",
32
+
"schema": {
33
+
"type": "object",
34
+
"required": ["actors"],
35
+
"properties": {
36
+
"actors": {
37
+
"type": "array",
38
+
"items": {
39
+
"type": "ref",
40
+
"ref": "fm.teal.alpha.actor.defs#miniProfileView"
41
+
}
42
+
},
43
+
"cursor": {
44
+
"type": "string",
45
+
"description": "Cursor for pagination"
46
+
}
47
+
}
48
+
}
49
+
}
50
+
}
51
+
}
52
+
}
+31
lexicons/fm/teal/alpha/actor/status.json
+31
lexicons/fm/teal/alpha/actor/status.json
···
···
1
+
{
2
+
"lexicon": 1,
3
+
"id": "fm.teal.alpha.actor.status",
4
+
"defs": {
5
+
"main": {
6
+
"type": "record",
7
+
"description": "This lexicon is in a not officially released state. It is subject to change. | A declaration of the status of the actor. Only one can be shown at a time. If there are multiple, the latest record should be picked and earlier records should be deleted or tombstoned.",
8
+
"key": "literal:self",
9
+
"record": {
10
+
"type": "object",
11
+
"required": ["time", "item"],
12
+
"properties": {
13
+
"time": {
14
+
"type": "string",
15
+
"format": "datetime",
16
+
"description": "The unix timestamp of when the item was recorded"
17
+
},
18
+
"expiry": {
19
+
"type": "string",
20
+
"format": "datetime",
21
+
"description": "The unix timestamp of the expiry time of the item. If unavailable, default to 10 minutes past the start time."
22
+
},
23
+
"item": {
24
+
"type": "ref",
25
+
"ref": "fm.teal.alpha.feed.defs#playView"
26
+
}
27
+
}
28
+
}
29
+
}
30
+
}
31
+
}
+90
lexicons/fm/teal/alpha/feed/defs.json
+90
lexicons/fm/teal/alpha/feed/defs.json
···
···
1
+
{
2
+
"lexicon": 1,
3
+
"id": "fm.teal.alpha.feed.defs",
4
+
"description": "This lexicon is in a not officially released state. It is subject to change. | Misc. items related to feeds.",
5
+
"defs": {
6
+
"playView": {
7
+
"type": "object",
8
+
"required": ["trackName", "artists"],
9
+
"properties": {
10
+
"trackName": {
11
+
"type": "string",
12
+
"minLength": 1,
13
+
"maxLength": 256,
14
+
"maxGraphemes": 2560,
15
+
"description": "The name of the track"
16
+
},
17
+
"trackMbId": {
18
+
"type": "string",
19
+
"description": "The Musicbrainz ID of the track"
20
+
},
21
+
"recordingMbId": {
22
+
"type": "string",
23
+
"description": "The Musicbrainz recording ID of the track"
24
+
},
25
+
"duration": {
26
+
"type": "integer",
27
+
"description": "The length of the track in seconds"
28
+
},
29
+
"artists": {
30
+
"type": "array",
31
+
"items": {
32
+
"type": "ref",
33
+
"ref": "#artist"
34
+
},
35
+
"description": "Array of artists in order of original appearance."
36
+
},
37
+
"releaseName": {
38
+
"type": "string",
39
+
"maxLength": 256,
40
+
"maxGraphemes": 2560,
41
+
"description": "The name of the release/album"
42
+
},
43
+
"releaseMbId": {
44
+
"type": "string",
45
+
"description": "The Musicbrainz release ID"
46
+
},
47
+
"isrc": {
48
+
"type": "string",
49
+
"description": "The ISRC code associated with the recording"
50
+
},
51
+
"originUrl": {
52
+
"type": "string",
53
+
"description": "The URL associated with this track"
54
+
},
55
+
"musicServiceBaseDomain": {
56
+
"type": "string",
57
+
"description": "The base domain of the music service. e.g. music.apple.com, tidal.com, spotify.com. Defaults to 'local' if not provided."
58
+
},
59
+
"submissionClientAgent": {
60
+
"type": "string",
61
+
"maxLength": 256,
62
+
"maxGraphemes": 2560,
63
+
"description": "A user-agent style string specifying the user agent. e.g. tealtracker/0.0.1b (Linux; Android 13; SM-A715F). Defaults to 'manual/unknown' if not provided."
64
+
},
65
+
"playedTime": {
66
+
"type": "string",
67
+
"format": "datetime",
68
+
"description": "The unix timestamp of when the track was played"
69
+
}
70
+
}
71
+
},
72
+
"artist": {
73
+
"type": "object",
74
+
"required": ["artistName"],
75
+
"properties": {
76
+
"artistName": {
77
+
"type": "string",
78
+
"minLength": 1,
79
+
"maxLength": 256,
80
+
"maxGraphemes": 2560,
81
+
"description": "The name of the artist"
82
+
},
83
+
"artistMbId": {
84
+
"type": "string",
85
+
"description": "The Musicbrainz ID of the artist"
86
+
}
87
+
}
88
+
}
89
+
}
90
+
}
+45
lexicons/fm/teal/alpha/feed/getActorFeed.json
+45
lexicons/fm/teal/alpha/feed/getActorFeed.json
···
···
1
+
{
2
+
"lexicon": 1,
3
+
"id": "fm.teal.alpha.feed.getActorFeed",
4
+
"description": "This lexicon is in a not officially released state. It is subject to change. | Retrieves multiple plays from the index or via an author's DID.",
5
+
"defs": {
6
+
"main": {
7
+
"type": "query",
8
+
"parameters": {
9
+
"type": "params",
10
+
"required": ["authorDID"],
11
+
"properties": {
12
+
"authorDID": {
13
+
"type": "string",
14
+
"format": "at-identifier",
15
+
"description": "The author's DID for the play"
16
+
},
17
+
"cursor": {
18
+
"type": "string",
19
+
"description": "The cursor to start the query from"
20
+
},
21
+
"limit": {
22
+
"type": "integer",
23
+
"description": "The upper limit of tracks to get per request. Default is 20, max is 50."
24
+
}
25
+
}
26
+
},
27
+
"output": {
28
+
"encoding": "application/json",
29
+
"schema": {
30
+
"type": "object",
31
+
"required": ["plays"],
32
+
"properties": {
33
+
"plays": {
34
+
"type": "array",
35
+
"items": {
36
+
"type": "ref",
37
+
"ref": "fm.teal.alpha.feed.defs#playView"
38
+
}
39
+
}
40
+
}
41
+
}
42
+
}
43
+
}
44
+
}
45
+
}
+38
lexicons/fm/teal/alpha/feed/getPlay.json
+38
lexicons/fm/teal/alpha/feed/getPlay.json
···
···
1
+
{
2
+
"lexicon": 1,
3
+
"id": "fm.teal.alpha.feed.getPlay",
4
+
"description": "This lexicon is in a not officially released state. It is subject to change. | Retrieves a play given an author DID and record key.",
5
+
"defs": {
6
+
"main": {
7
+
"type": "query",
8
+
"parameters": {
9
+
"type": "params",
10
+
"required": ["authorDID", "rkey"],
11
+
"properties": {
12
+
"authorDID": {
13
+
"type": "string",
14
+
"format": "at-identifier",
15
+
"description": "The author's DID for the play"
16
+
},
17
+
"rkey": {
18
+
"type": "string",
19
+
"description": "The record key of the play"
20
+
}
21
+
}
22
+
},
23
+
"output": {
24
+
"encoding": "application/json",
25
+
"schema": {
26
+
"type": "object",
27
+
"required": ["play"],
28
+
"properties": {
29
+
"play": {
30
+
"type": "ref",
31
+
"ref": "fm.teal.alpha.feed.defs#playView"
32
+
}
33
+
}
34
+
}
35
+
}
36
+
}
37
+
}
38
+
}
+107
lexicons/fm/teal/alpha/feed/play.json
+107
lexicons/fm/teal/alpha/feed/play.json
···
···
1
+
{
2
+
"lexicon": 1,
3
+
"id": "fm.teal.alpha.feed.play",
4
+
"description": "This lexicon is in a not officially released state. It is subject to change. | A declaration of a teal.fm play. Plays are submitted as a result of a user listening to a track. Plays should be marked as tracked when a user has listened to the entire track if it's under 2 minutes long, or half of the track's duration up to 4 minutes, whichever is longest.",
5
+
"defs": {
6
+
"main": {
7
+
"type": "record",
8
+
"key": "tid",
9
+
"record": {
10
+
"type": "object",
11
+
"required": ["trackName"],
12
+
"properties": {
13
+
"trackName": {
14
+
"type": "string",
15
+
"minLength": 1,
16
+
"maxLength": 256,
17
+
"maxGraphemes": 2560,
18
+
"description": "The name of the track"
19
+
},
20
+
"trackMbId": {
21
+
"type": "string",
22
+
23
+
"description": "The Musicbrainz ID of the track"
24
+
},
25
+
"recordingMbId": {
26
+
"type": "string",
27
+
"description": "The Musicbrainz recording ID of the track"
28
+
},
29
+
"duration": {
30
+
"type": "integer",
31
+
"description": "The length of the track in seconds"
32
+
},
33
+
"artistNames": {
34
+
"type": "array",
35
+
"items": {
36
+
"type": "string",
37
+
"minLength": 1,
38
+
"maxLength": 256,
39
+
"maxGraphemes": 2560
40
+
},
41
+
"description": "Array of artist names in order of original appearance. Prefer using 'artists'."
42
+
},
43
+
"artistMbIds": {
44
+
"type": "array",
45
+
"items": {
46
+
"type": "string"
47
+
},
48
+
"description": "Array of Musicbrainz artist IDs. Prefer using 'artists'."
49
+
},
50
+
"artists": {
51
+
"type": "array",
52
+
"items": {
53
+
"type": "ref",
54
+
"ref": "fm.teal.alpha.feed.defs#artist"
55
+
},
56
+
"description": "Array of artists in order of original appearance."
57
+
},
58
+
"releaseName": {
59
+
"type": "string",
60
+
"maxLength": 256,
61
+
"maxGraphemes": 2560,
62
+
"description": "The name of the release/album"
63
+
},
64
+
"releaseMbId": {
65
+
"type": "string",
66
+
"description": "The Musicbrainz release ID"
67
+
},
68
+
"isrc": {
69
+
"type": "string",
70
+
"description": "The ISRC code associated with the recording"
71
+
},
72
+
"originUrl": {
73
+
"type": "string",
74
+
"description": "The URL associated with this track"
75
+
},
76
+
"musicServiceBaseDomain": {
77
+
"type": "string",
78
+
"description": "The base domain of the music service. e.g. music.apple.com, tidal.com, spotify.com. Defaults to 'local' if unavailable or not provided."
79
+
},
80
+
"submissionClientAgent": {
81
+
"type": "string",
82
+
"maxLength": 256,
83
+
"maxGraphemes": 2560,
84
+
"description": "A metadata string specifying the user agent where the format is `<app-identifier>/<version> (<kernel/OS-base>; <platform/OS-version>; <device-model>)`. If string is provided, only `app-identifier` and `version` are required. `app-identifier` is recommended to be in reverse dns format. Defaults to 'manual/unknown' if unavailable or not provided."
85
+
},
86
+
"playedTime": {
87
+
"type": "string",
88
+
"format": "datetime",
89
+
"description": "The unix timestamp of when the track was played"
90
+
},
91
+
"trackDiscriminant": {
92
+
"type": "string",
93
+
"maxLength": 128,
94
+
"maxGraphemes": 1280,
95
+
"description": "Distinguishing information for track variants (e.g. 'Acoustic Version', 'Live at Wembley', 'Radio Edit', 'Demo'). Used to differentiate between different versions of the same base track while maintaining grouping capabilities."
96
+
},
97
+
"releaseDiscriminant": {
98
+
"type": "string",
99
+
"maxLength": 128,
100
+
"maxGraphemes": 1280,
101
+
"description": "Distinguishing information for release variants (e.g. 'Deluxe Edition', 'Remastered', '2023 Remaster', 'Special Edition'). Used to differentiate between different versions of the same base release while maintaining grouping capabilities."
102
+
}
103
+
}
104
+
}
105
+
}
106
+
}
107
+
}
+60
lexicons/fm/teal/alpha/stats/defs.json
+60
lexicons/fm/teal/alpha/stats/defs.json
···
···
1
+
{
2
+
"lexicon": 1,
3
+
"id": "fm.teal.alpha.stats.defs",
4
+
"defs": {
5
+
"artistView": {
6
+
"type": "object",
7
+
"required": ["mbid", "name", "playCount"],
8
+
"properties": {
9
+
"mbid": {
10
+
"type": "string",
11
+
"description": "MusicBrainz artist ID"
12
+
},
13
+
"name": {
14
+
"type": "string",
15
+
"description": "Artist name"
16
+
},
17
+
"playCount": {
18
+
"type": "integer",
19
+
"description": "Total number of plays for this artist"
20
+
}
21
+
}
22
+
},
23
+
"releaseView": {
24
+
"type": "object",
25
+
"required": ["mbid", "name", "playCount"],
26
+
"properties": {
27
+
"mbid": {
28
+
"type": "string",
29
+
"description": "MusicBrainz release ID"
30
+
},
31
+
"name": {
32
+
"type": "string",
33
+
"description": "Release/album name"
34
+
},
35
+
"playCount": {
36
+
"type": "integer",
37
+
"description": "Total number of plays for this release"
38
+
}
39
+
}
40
+
},
41
+
"recordingView": {
42
+
"type": "object",
43
+
"required": ["mbid", "name", "playCount"],
44
+
"properties": {
45
+
"mbid": {
46
+
"type": "string",
47
+
"description": "MusicBrainz recording ID"
48
+
},
49
+
"name": {
50
+
"type": "string",
51
+
"description": "Recording/track name"
52
+
},
53
+
"playCount": {
54
+
"type": "integer",
55
+
"description": "Total number of plays for this recording"
56
+
}
57
+
}
58
+
}
59
+
}
60
+
}
+38
lexicons/fm/teal/alpha/stats/getLatest.json
+38
lexicons/fm/teal/alpha/stats/getLatest.json
···
···
1
+
{
2
+
"lexicon": 1,
3
+
"id": "fm.teal.alpha.stats.getLatest",
4
+
"defs": {
5
+
"main": {
6
+
"type": "query",
7
+
"description": "Get latest plays globally",
8
+
"parameters": {
9
+
"type": "params",
10
+
"properties": {
11
+
"limit": {
12
+
"type": "integer",
13
+
"minimum": 1,
14
+
"maximum": 100,
15
+
"default": 50,
16
+
"description": "Number of latest plays to return"
17
+
}
18
+
}
19
+
},
20
+
"output": {
21
+
"encoding": "application/json",
22
+
"schema": {
23
+
"type": "object",
24
+
"required": ["plays"],
25
+
"properties": {
26
+
"plays": {
27
+
"type": "array",
28
+
"items": {
29
+
"type": "ref",
30
+
"ref": "fm.teal.alpha.feed.defs#playView"
31
+
}
32
+
}
33
+
}
34
+
}
35
+
}
36
+
}
37
+
}
38
+
}
+52
lexicons/fm/teal/alpha/stats/getTopArtists.json
+52
lexicons/fm/teal/alpha/stats/getTopArtists.json
···
···
1
+
{
2
+
"lexicon": 1,
3
+
"id": "fm.teal.alpha.stats.getTopArtists",
4
+
"description": "Get top artists by play count",
5
+
"defs": {
6
+
"main": {
7
+
"type": "query",
8
+
"parameters": {
9
+
"type": "params",
10
+
"properties": {
11
+
"period": {
12
+
"type": "string",
13
+
"enum": ["all", "30days", "7days"],
14
+
"default": "all",
15
+
"description": "Time period for top artists"
16
+
},
17
+
"limit": {
18
+
"type": "integer",
19
+
"minimum": 1,
20
+
"maximum": 100,
21
+
"default": 50,
22
+
"description": "Number of artists to return"
23
+
},
24
+
"cursor": {
25
+
"type": "string",
26
+
"description": "Pagination cursor"
27
+
}
28
+
}
29
+
},
30
+
"output": {
31
+
"encoding": "application/json",
32
+
"schema": {
33
+
"type": "object",
34
+
"required": ["artists"],
35
+
"properties": {
36
+
"artists": {
37
+
"type": "array",
38
+
"items": {
39
+
"type": "ref",
40
+
"ref": "fm.teal.alpha.stats.defs#artistView"
41
+
}
42
+
},
43
+
"cursor": {
44
+
"type": "string",
45
+
"description": "Next page cursor"
46
+
}
47
+
}
48
+
}
49
+
}
50
+
}
51
+
}
52
+
}
+52
lexicons/fm/teal/alpha/stats/getTopReleases.json
+52
lexicons/fm/teal/alpha/stats/getTopReleases.json
···
···
1
+
{
2
+
"lexicon": 1,
3
+
"id": "fm.teal.alpha.stats.getTopReleases",
4
+
"description": "Get top releases/albums by play count",
5
+
"defs": {
6
+
"main": {
7
+
"type": "query",
8
+
"parameters": {
9
+
"type": "params",
10
+
"properties": {
11
+
"period": {
12
+
"type": "string",
13
+
"enum": ["all", "30days", "7days"],
14
+
"default": "all",
15
+
"description": "Time period for top releases"
16
+
},
17
+
"limit": {
18
+
"type": "integer",
19
+
"minimum": 1,
20
+
"maximum": 100,
21
+
"default": 50,
22
+
"description": "Number of releases to return"
23
+
},
24
+
"cursor": {
25
+
"type": "string",
26
+
"description": "Pagination cursor"
27
+
}
28
+
}
29
+
},
30
+
"output": {
31
+
"encoding": "application/json",
32
+
"schema": {
33
+
"type": "object",
34
+
"required": ["releases"],
35
+
"properties": {
36
+
"releases": {
37
+
"type": "array",
38
+
"items": {
39
+
"type": "ref",
40
+
"ref": "fm.teal.alpha.stats.defs#releaseView"
41
+
}
42
+
},
43
+
"cursor": {
44
+
"type": "string",
45
+
"description": "Next page cursor"
46
+
}
47
+
}
48
+
}
49
+
}
50
+
}
51
+
}
52
+
}
+58
lexicons/fm/teal/alpha/stats/getUserTopArtists.json
+58
lexicons/fm/teal/alpha/stats/getUserTopArtists.json
···
···
1
+
{
2
+
"lexicon": 1,
3
+
"id": "fm.teal.alpha.stats.getUserTopArtists",
4
+
"description": "Get a user's top artists by play count",
5
+
"defs": {
6
+
"main": {
7
+
"type": "query",
8
+
"parameters": {
9
+
"type": "params",
10
+
"required": ["actor"],
11
+
"properties": {
12
+
"actor": {
13
+
"type": "string",
14
+
"format": "at-identifier",
15
+
"description": "The user's DID or handle"
16
+
},
17
+
"period": {
18
+
"type": "string",
19
+
"enum": ["30days", "7days"],
20
+
"default": "30days",
21
+
"description": "Time period for top artists"
22
+
},
23
+
"limit": {
24
+
"type": "integer",
25
+
"minimum": 1,
26
+
"maximum": 100,
27
+
"default": 50,
28
+
"description": "Number of artists to return"
29
+
},
30
+
"cursor": {
31
+
"type": "string",
32
+
"description": "Pagination cursor"
33
+
}
34
+
}
35
+
},
36
+
"output": {
37
+
"encoding": "application/json",
38
+
"schema": {
39
+
"type": "object",
40
+
"required": ["artists"],
41
+
"properties": {
42
+
"artists": {
43
+
"type": "array",
44
+
"items": {
45
+
"type": "ref",
46
+
"ref": "fm.teal.alpha.stats.defs#artistView"
47
+
}
48
+
},
49
+
"cursor": {
50
+
"type": "string",
51
+
"description": "Next page cursor"
52
+
}
53
+
}
54
+
}
55
+
}
56
+
}
57
+
}
58
+
}
+58
lexicons/fm/teal/alpha/stats/getUserTopReleases.json
+58
lexicons/fm/teal/alpha/stats/getUserTopReleases.json
···
···
1
+
{
2
+
"lexicon": 1,
3
+
"id": "fm.teal.alpha.stats.getUserTopReleases",
4
+
"description": "Get a user's top releases/albums by play count",
5
+
"defs": {
6
+
"main": {
7
+
"type": "query",
8
+
"parameters": {
9
+
"type": "params",
10
+
"required": ["actor"],
11
+
"properties": {
12
+
"actor": {
13
+
"type": "string",
14
+
"format": "at-identifier",
15
+
"description": "The user's DID or handle"
16
+
},
17
+
"period": {
18
+
"type": "string",
19
+
"enum": ["30days", "7days"],
20
+
"default": "30days",
21
+
"description": "Time period for top releases"
22
+
},
23
+
"limit": {
24
+
"type": "integer",
25
+
"minimum": 1,
26
+
"maximum": 100,
27
+
"default": 50,
28
+
"description": "Number of releases to return"
29
+
},
30
+
"cursor": {
31
+
"type": "string",
32
+
"description": "Pagination cursor"
33
+
}
34
+
}
35
+
},
36
+
"output": {
37
+
"encoding": "application/json",
38
+
"schema": {
39
+
"type": "object",
40
+
"required": ["releases"],
41
+
"properties": {
42
+
"releases": {
43
+
"type": "array",
44
+
"items": {
45
+
"type": "ref",
46
+
"ref": "fm.teal.alpha.stats.defs#releaseView"
47
+
}
48
+
},
49
+
"cursor": {
50
+
"type": "string",
51
+
"description": "Next page cursor"
52
+
}
53
+
}
54
+
}
55
+
}
56
+
}
57
+
}
58
+
}
+7
-4
lexicons/net/mmatt/right/now.json
+7
-4
lexicons/net/mmatt/right/now.json
···
4
"defs": {
5
"main": {
6
"type": "record",
7
-
"description": "A personal lexicon for mmatt's statuslog.",
8
"key": "tid",
9
"record": {
10
"type": "object",
11
-
"required": ["createdAt", "text"],
12
"properties": {
13
"createdAt": {
14
"type": "string",
···
23
"type": "string",
24
"description": "The emoji of the status update"
25
}
26
-
}
27
-
}
28
}
29
}
30
}
···
4
"defs": {
5
"main": {
6
"type": "record",
7
"key": "tid",
8
"record": {
9
"type": "object",
10
"properties": {
11
"createdAt": {
12
"type": "string",
···
21
"type": "string",
22
"description": "The emoji of the status update"
23
}
24
+
},
25
+
"required": [
26
+
"createdAt",
27
+
"text"
28
+
]
29
+
},
30
+
"description": "A personal lexicon for mmatt's statuslog."
31
}
32
}
33
}
+55
lexicons/net/mmatt/vitals/car.json
+55
lexicons/net/mmatt/vitals/car.json
···
···
1
+
{
2
+
"lexicon": 1,
3
+
"id": "net.mmatt.vitals.car",
4
+
"defs": {
5
+
"main": {
6
+
"type": "record",
7
+
"key": "tid",
8
+
"record": {
9
+
"type": "object",
10
+
"properties": {
11
+
"createdAt": {
12
+
"type": "string",
13
+
"format": "datetime",
14
+
"description": "The unix timestamp of when the vital was recorded"
15
+
},
16
+
"carFuelRange": {
17
+
"type": "integer",
18
+
"description": "The car fuel range value in miles"
19
+
},
20
+
"carPercentFuelRemaining": {
21
+
"type": "string",
22
+
"description": "The car fuel level value in percentage (floating point string)"
23
+
},
24
+
"amountRemaining": {
25
+
"type": "string",
26
+
"description": "The car fuel amount remaining value (floating point string)"
27
+
},
28
+
"carTraveledDistance": {
29
+
"type": "integer",
30
+
"description": "The car traveled distance value"
31
+
},
32
+
"carMake": {
33
+
"type": "string",
34
+
"description": "The car make value"
35
+
},
36
+
"carModel": {
37
+
"type": "string",
38
+
"description": "The car model value"
39
+
},
40
+
"carYear": {
41
+
"type": "integer",
42
+
"description": "The car year value"
43
+
}
44
+
},
45
+
"required": [
46
+
"createdAt",
47
+
"carFuelRange",
48
+
"carPercentFuelRemaining",
49
+
"amountRemaining",
50
+
"carTraveledDistance"
51
+
]
52
+
}
53
+
}
54
+
}
55
+
}
+83
lexicons/net/mmatt/vitals/phone.json
+83
lexicons/net/mmatt/vitals/phone.json
···
···
1
+
{
2
+
"lexicon": 1,
3
+
"id": "net.mmatt.vitals.phone",
4
+
"defs": {
5
+
"main": {
6
+
"type": "record",
7
+
"key": "tid",
8
+
"record": {
9
+
"type": "object",
10
+
"properties": {
11
+
"createdAt": {
12
+
"type": "string",
13
+
"format": "datetime",
14
+
"description": "The unix timestamp of when the vital was recorded"
15
+
},
16
+
"phoneMotion": {
17
+
"type": "string",
18
+
"description": "The phone motion value"
19
+
},
20
+
"phoneVolume": {
21
+
"type": "string",
22
+
"description": "The phone volume value"
23
+
},
24
+
"phoneAppearance": {
25
+
"type": "string",
26
+
"description": "The phone appearance value"
27
+
},
28
+
"phoneBrightness": {
29
+
"type": "string",
30
+
"description": "The phone brightness value"
31
+
},
32
+
"phoneOrientation": {
33
+
"type": "string",
34
+
"description": "The phone orientation value"
35
+
},
36
+
"phoneCellBars": {
37
+
"type": "string",
38
+
"description": "The phone cell bars value"
39
+
},
40
+
"phoneCellNetwork": {
41
+
"type": "string",
42
+
"description": "The phone cell network value"
43
+
},
44
+
"phoneBatteryLevel": {
45
+
"type": "string",
46
+
"description": "The phone battery level value"
47
+
},
48
+
"phoneBatteryCharging": {
49
+
"type": "string",
50
+
"description": "The phone battery charging value"
51
+
},
52
+
"phoneOs": {
53
+
"type": "string",
54
+
"description": "The phone OS value"
55
+
},
56
+
"phoneOsVersion": {
57
+
"type": "string",
58
+
"description": "The phone OS version value"
59
+
},
60
+
"phoneModel": {
61
+
"type": "string",
62
+
"description": "The phone model value"
63
+
}
64
+
},
65
+
"required": [
66
+
"createdAt",
67
+
"phoneMotion",
68
+
"phoneVolume",
69
+
"phoneAppearance",
70
+
"phoneBrightness",
71
+
"phoneOrientation",
72
+
"phoneCellBars",
73
+
"phoneCellNetwork",
74
+
"phoneBatteryLevel",
75
+
"phoneBatteryCharging",
76
+
"phoneOs",
77
+
"phoneOsVersion",
78
+
"phoneModel"
79
+
]
80
+
}
81
+
}
82
+
}
83
+
}
+68
lexicons/net/mmatt/vitals/rings.json
+68
lexicons/net/mmatt/vitals/rings.json
···
···
1
+
{
2
+
"lexicon": 1,
3
+
"id": "net.mmatt.vitals.rings",
4
+
"defs": {
5
+
"main": {
6
+
"type": "record",
7
+
"key": "tid",
8
+
"record": {
9
+
"type": "object",
10
+
"properties": {
11
+
"createdAt": {
12
+
"type": "string",
13
+
"format": "datetime",
14
+
"description": "The unix timestamp of when the vital was recorded"
15
+
},
16
+
"ringsMove": {
17
+
"type": "integer",
18
+
"description": "The move ring value"
19
+
},
20
+
"ringsExercise": {
21
+
"type": "integer",
22
+
"description": "The exercise ring value"
23
+
},
24
+
"ringsStandHours": {
25
+
"type": "integer",
26
+
"description": "The stand hours ring value"
27
+
},
28
+
"ringsMoveGoal": {
29
+
"type": "integer",
30
+
"description": "The move goal ring value"
31
+
},
32
+
"ringsExerciseGoal": {
33
+
"type": "integer",
34
+
"description": "The exercise goal ring value"
35
+
},
36
+
"ringsStandHoursGoal": {
37
+
"type": "integer",
38
+
"description": "The stand hours goal ring value"
39
+
},
40
+
"ringsSteps": {
41
+
"type": "integer",
42
+
"description": "The steps value"
43
+
},
44
+
"ringsBurnedCalories": {
45
+
"type": "integer",
46
+
"description": "The burned calories value"
47
+
},
48
+
"heartRate": {
49
+
"type": "integer",
50
+
"description": "The heart rate value"
51
+
}
52
+
},
53
+
"required": [
54
+
"createdAt",
55
+
"ringsMove",
56
+
"ringsExercise",
57
+
"ringsStandHours",
58
+
"ringsMoveGoal",
59
+
"ringsExerciseGoal",
60
+
"ringsStandHoursGoal",
61
+
"ringsSteps",
62
+
"ringsBurnedCalories",
63
+
"heartRate"
64
+
]
65
+
}
66
+
}
67
+
}
68
+
}
+7
lexicons.json
+7
lexicons.json
+9
-3
next.config.mjs
+9
-3
next.config.mjs
···
11
// search: '?did=did%3Aplc%3Ap2cp5gopk7mgjegy6wadk3ep&cid=**',
12
},
13
{
14
+
protocol: "https",
15
+
hostname: "pds.mmatt.net",
16
+
pathname: "/xrpc/com.atproto.sync.getBlob",
17
+
},
18
+
{
19
+
protocol: "https",
20
+
hostname: "evil.gay",
21
+
pathname: "/xrpc/com.atproto.sync.getBlob",
22
+
// search: '?did=did%3Aplc%3Ap2cp5gopk7mgjegy6wadk3ep&cid=**',
23
},
24
{
25
protocol: "https",
+30
-10
package.json
+30
-10
package.json
···
10
"lint": "next lint",
11
"format": "prettier -w src",
12
"typecheck": "tsc --noEmit",
13
-
"lexi": "lex gen-api ./lexiconTypes ./lexicons/net/mmatt/right/now.json"
14
},
15
"dependencies": {
16
-
"@atcute/client": "^2.0.9",
17
-
"@atcute/whitewind": "^1.0.4",
18
-
"@atproto/lex-cli": "^0.8.3",
19
-
"@atproto/lexicon": "^0.4.14",
20
"@atproto/xrpc": "^0.7.7",
21
"@upstash/ratelimit": "^2.0.7",
22
"@upstash/redis": "^1.36.0",
23
"bright": "^1.0.0",
24
"envalid": "^8.1.1",
25
-
"lucide-react": "^0.477.0",
26
"multiformats": "^13.4.2",
27
"next": "15.5.9",
28
"next-plausible": "^3.12.5",
29
"react": "^19.2.3",
30
"react-dom": "^19.2.3",
31
"react-markdown": "^10.1.0",
32
"reading-time": "^1.5.0",
33
"rehype-format": "^5.0.1",
34
"rehype-raw": "^7.0.0",
···
38
"remark-parse": "^11.0.0",
39
"remark-rehype": "^11.1.2",
40
"rss": "^1.2.2",
41
-
"simple-icons": "^14.15.0",
42
"tailwind-merge": "^3.4.0",
43
"unified": "^11.0.5"
44
},
45
"devDependencies": {
46
"@ianvs/prettier-plugin-sort-imports": "^4.7.0",
47
"@tailwindcss/postcss": "^4.1.18",
48
"@types/node": "^24.10.4",
49
"@types/react": "^19.2.7",
50
"@types/react-dom": "^19.2.3",
51
"@types/rss": "^0.0.32",
52
"eslint": "^9.39.2",
53
-
"eslint-config-next": "15.2.1",
54
"eslint-config-prettier": "^10.1.8",
55
"postcss": "^8.5.6",
56
"prettier": "^3.7.4",
57
-
"prettier-plugin-tailwindcss": "^0.6.14",
58
"tailwindcss": "^4.1.18",
59
"typescript": "^5.9.3"
60
-
}
61
}
···
10
"lint": "next lint",
11
"format": "prettier -w src",
12
"typecheck": "tsc --noEmit",
13
+
"build:lexicons": "tsp compile typelex/main.tsp",
14
+
"lexitypes": "./lexicon-type.sh",
15
+
"lpm": "node ./node_modules/@lpm/cli/bin.js"
16
},
17
"dependencies": {
18
+
"@atcute/atproto": "^3.1.10",
19
+
"@atcute/bluesky": "^3.2.14",
20
+
"@atcute/client": "^4.2.0",
21
+
"@atcute/whitewind": "^3.1.3",
22
+
"@atproto/lex-cli": "^0.9.8",
23
+
"@atproto/lexicon": "^0.5.2",
24
"@atproto/xrpc": "^0.7.7",
25
+
"@atproto/xrpc-server": "^0.9.6",
26
+
"@lpm/cli": "npm:@jsr/lpm__cli",
27
+
"@radix-ui/react-slot": "^1.2.4",
28
+
"@react-spring/web": "^10.0.3",
29
"@upstash/ratelimit": "^2.0.7",
30
"@upstash/redis": "^1.36.0",
31
"bright": "^1.0.0",
32
+
"class-variance-authority": "^0.7.1",
33
+
"clsx": "^2.1.1",
34
+
"embla-carousel-react": "^8.6.0",
35
"envalid": "^8.1.1",
36
+
"lucide-react": "^0.546.0",
37
+
"motion": "^12.23.26",
38
"multiformats": "^13.4.2",
39
"next": "15.5.9",
40
"next-plausible": "^3.12.5",
41
"react": "^19.2.3",
42
"react-dom": "^19.2.3",
43
"react-markdown": "^10.1.0",
44
+
"react-use-measure": "^2.1.7",
45
"reading-time": "^1.5.0",
46
"rehype-format": "^5.0.1",
47
"rehype-raw": "^7.0.0",
···
51
"remark-parse": "^11.0.0",
52
"remark-rehype": "^11.1.2",
53
"rss": "^1.2.2",
54
+
"simple-icons": "^15.22.0",
55
"tailwind-merge": "^3.4.0",
56
"unified": "^11.0.5"
57
},
58
"devDependencies": {
59
"@ianvs/prettier-plugin-sort-imports": "^4.7.0",
60
"@tailwindcss/postcss": "^4.1.18",
61
+
"@typelex/emitter": "^0.4.0",
62
+
"@types/express": "^5.0.6",
63
"@types/node": "^24.10.4",
64
"@types/react": "^19.2.7",
65
"@types/react-dom": "^19.2.3",
66
"@types/rss": "^0.0.32",
67
+
"@typespec/compiler": "^1.7.1",
68
"eslint": "^9.39.2",
69
+
"eslint-config-next": "15.5.6",
70
"eslint-config-prettier": "^10.1.8",
71
"postcss": "^8.5.6",
72
"prettier": "^3.7.4",
73
+
"prettier-plugin-tailwindcss": "^0.7.2",
74
"tailwindcss": "^4.1.18",
75
+
"tw-animate-css": "^1.4.0",
76
"typescript": "^5.9.3"
77
+
},
78
+
"trustedDependencies": [
79
+
"@tailwindcss/oxide"
80
+
]
81
}
+77
src/app/api/letterboxd-rss/route.ts
+77
src/app/api/letterboxd-rss/route.ts
···
···
1
+
import { NextResponse } from "next/server";
2
+
3
+
interface LetterboxdEntry {
4
+
title: string;
5
+
link: string;
6
+
pubDate: string;
7
+
description?: string;
8
+
}
9
+
10
+
export async function GET() {
11
+
try {
12
+
const response = await fetch("https://letterboxd.com/air2earth/rss/", {
13
+
headers: {
14
+
"User-Agent": "Mozilla/5.0 (compatible; LetterboxdRSSBot/1.0)",
15
+
},
16
+
});
17
+
18
+
if (!response.ok) {
19
+
throw new Error(`HTTP error! status: ${response.status}`);
20
+
}
21
+
22
+
const xmlText = await response.text();
23
+
24
+
// Parse XML to extract entries
25
+
const entries: LetterboxdEntry[] = [];
26
+
const itemRegex = /<item>([\s\S]*?)<\/item>/g;
27
+
let match;
28
+
29
+
while ((match = itemRegex.exec(xmlText)) !== null) {
30
+
const itemContent = match[1];
31
+
32
+
// Extract title - handle both CDATA and regular XML
33
+
let titleMatch = itemContent.match(
34
+
/<title><!\[CDATA\[([\s\S]*?)\]\]><\/title>/,
35
+
);
36
+
if (!titleMatch) {
37
+
titleMatch = itemContent.match(/<title>([^<]*)<\/title>/);
38
+
}
39
+
const title = titleMatch ? titleMatch[1] : "Unknown Title";
40
+
41
+
// Extract link
42
+
const linkMatch = itemContent.match(/<link>(.*?)<\/link>/);
43
+
const link = linkMatch ? linkMatch[1] : "";
44
+
45
+
// Extract pubDate
46
+
const pubDateMatch = itemContent.match(/<pubDate>(.*?)<\/pubDate>/);
47
+
const pubDate = pubDateMatch ? pubDateMatch[1] : new Date().toISOString();
48
+
49
+
// Extract description (optional) - handle multiline CDATA
50
+
const descriptionMatch = itemContent.match(
51
+
/<description><!\[CDATA\[([\s\S]*?)\]\]><\/description>/,
52
+
);
53
+
const description = descriptionMatch ? descriptionMatch[1] : undefined;
54
+
55
+
// Only include actual film entries (not lists or other content)
56
+
if (title && !title.includes("list") && !title.includes("watchlist")) {
57
+
entries.push({
58
+
title,
59
+
link,
60
+
pubDate,
61
+
description,
62
+
});
63
+
}
64
+
}
65
+
66
+
// Return the first few entries (most recent)
67
+
return NextResponse.json({
68
+
entries: entries.slice(0, 5),
69
+
});
70
+
} catch (error) {
71
+
console.error("Error fetching Letterboxd RSS:", error);
72
+
return NextResponse.json(
73
+
{ error: "Failed to fetch Letterboxd RSS" },
74
+
{ status: 500 },
75
+
);
76
+
}
77
+
}
+1
-1
src/app/blog/page.tsx
+1
-1
src/app/blog/page.tsx
+2
-9
src/app/deerdirectprivacypolicy/page.tsx
+2
-9
src/app/deerdirectprivacypolicy/page.tsx
···
1
import Markdown from "react-markdown";
2
import { Viewport, type Metadata } from "next";
3
-
import Image from "next/image";
4
import { Code as SyntaxHighlighter } from "bright";
5
import rehypeRaw from "rehype-raw";
6
import rehypeSanitize, { defaultSchema } from "rehype-sanitize";
···
165
{...props}
166
/>
167
),
168
-
img: ({ src, alt }) => (
169
<span className="block mt-8 w-full aspect-video relative">
170
-
<Image
171
-
src={typeof src === "string" ? src : ""}
172
-
alt={alt!}
173
-
className="object-contain"
174
-
quality={90}
175
-
fill
176
-
/>
177
</span>
178
),
179
}}
···
1
import Markdown from "react-markdown";
2
import { Viewport, type Metadata } from "next";
3
import { Code as SyntaxHighlighter } from "bright";
4
import rehypeRaw from "rehype-raw";
5
import rehypeSanitize, { defaultSchema } from "rehype-sanitize";
···
164
{...props}
165
/>
166
),
167
+
img: () => (
168
<span className="block mt-8 w-full aspect-video relative">
169
+
<p>image</p>
170
</span>
171
),
172
}}
+326
-5
src/app/globals.css
+326
-5
src/app/globals.css
···
1
@import "tailwindcss";
2
3
@theme inline {
4
--color-background: var(--background);
5
--color-foreground: var(--foreground);
6
7
-
--font-sans: var(--font-inter), sans-serif;
8
-
--font-serif: var(--font-libre-baskerville), serif;
9
--font-mono: var(--font-berkeley-mono), monospace;
10
}
11
12
/*
···
34
@layer utilities {
35
:root {
36
--background: #ffffff;
37
-
--foreground: #171717;
38
}
39
40
@media (prefers-color-scheme: dark) {
41
:root {
42
-
--background: #0a0a0a;
43
--foreground: #ededed;
44
}
45
}
···
47
body {
48
color: var(--foreground);
49
background: var(--background);
50
-
font-family: Arial, Helvetica, sans-serif;
51
}
52
53
@keyframes marquee {
···
101
.animate-fade-out {
102
animation: fadeOut 0.3s ease-in-out forwards;
103
}
104
}
105
106
.diagonal-pattern {
···
125
);
126
}
127
}
···
1
@import "tailwindcss";
2
+
@import "tw-animate-css";
3
+
/*
4
+
---break---
5
+
*/
6
+
@custom-variant dark (&:is(.dark *));
7
8
@theme inline {
9
--color-background: var(--background);
10
--color-foreground: var(--foreground);
11
12
+
--font-sans: var(--font-jersey), sans-serif;
13
+
--font-serif: var(--font-vt323), serif;
14
--font-mono: var(--font-berkeley-mono), monospace;
15
+
--color-sidebar-ring: var(--sidebar-ring);
16
+
--color-sidebar-border: var(--sidebar-border);
17
+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
18
+
--color-sidebar-accent: var(--sidebar-accent);
19
+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
20
+
--color-sidebar-primary: var(--sidebar-primary);
21
+
--color-sidebar-foreground: var(--sidebar-foreground);
22
+
--color-sidebar: var(--sidebar);
23
+
--color-chart-5: var(--chart-5);
24
+
--color-chart-4: var(--chart-4);
25
+
--color-chart-3: var(--chart-3);
26
+
--color-chart-2: var(--chart-2);
27
+
--color-chart-1: var(--chart-1);
28
+
--color-ring: var(--ring);
29
+
--color-input: var(--input);
30
+
--color-border: var(--border);
31
+
--color-destructive: var(--destructive);
32
+
--color-accent-foreground: var(--accent-foreground);
33
+
--color-accent: var(--accent);
34
+
--color-muted-foreground: var(--muted-foreground);
35
+
--color-muted: var(--muted);
36
+
--color-secondary-foreground: var(--secondary-foreground);
37
+
--color-secondary: var(--secondary);
38
+
--color-primary-foreground: var(--primary-foreground);
39
+
--color-primary: var(--primary);
40
+
--color-popover-foreground: var(--popover-foreground);
41
+
--color-popover: var(--popover);
42
+
--color-card-foreground: var(--card-foreground);
43
+
--color-card: var(--card);
44
+
--radius-sm: calc(var(--radius) - 4px);
45
+
--radius-md: calc(var(--radius) - 2px);
46
+
--radius-lg: var(--radius);
47
+
--radius-xl: calc(var(--radius) + 4px);
48
}
49
50
/*
···
72
@layer utilities {
73
:root {
74
--background: #ffffff;
75
+
--foreground: #000000;
76
}
77
78
@media (prefers-color-scheme: dark) {
79
:root {
80
+
--background: #000000;
81
--foreground: #ededed;
82
}
83
}
···
85
body {
86
color: var(--foreground);
87
background: var(--background);
88
}
89
90
@keyframes marquee {
···
138
.animate-fade-out {
139
animation: fadeOut 0.3s ease-in-out forwards;
140
}
141
+
142
+
/* Reduced motion support */
143
+
@media (prefers-reduced-motion: reduce) {
144
+
.animate-marquee,
145
+
.animate-fade-in,
146
+
.animate-fade-out {
147
+
animation: none;
148
+
}
149
+
150
+
/* Reduce video processing frequency for reduced motion */
151
+
.reduced-motion {
152
+
animation: none;
153
+
}
154
+
}
155
}
156
157
.diagonal-pattern {
···
176
);
177
}
178
}
179
+
180
+
/* Monochrome 2-bit pixelation/dithering effect */
181
+
.monochrome-video-filter {
182
+
position: relative;
183
+
overflow: hidden;
184
+
}
185
+
186
+
.monochrome-video-filter::before {
187
+
content: "";
188
+
position: absolute;
189
+
top: 0;
190
+
left: 0;
191
+
right: 0;
192
+
bottom: 0;
193
+
background:
194
+
/* Bayer matrix dithering pattern for authentic 2-bit look */ conic-gradient(
195
+
from 0deg at 0px 0px,
196
+
transparent 0deg,
197
+
transparent 45deg,
198
+
rgba(0, 0, 0, 0.15) 45deg,
199
+
rgba(0, 0, 0, 0.15) 90deg,
200
+
transparent 90deg,
201
+
transparent 135deg,
202
+
rgba(0, 0, 0, 0.15) 135deg,
203
+
rgba(0, 0, 0, 0.15) 180deg,
204
+
transparent 180deg,
205
+
transparent 225deg,
206
+
rgba(0, 0, 0, 0.15) 225deg,
207
+
rgba(0, 0, 0, 0.15) 270deg,
208
+
transparent 270deg,
209
+
transparent 315deg,
210
+
rgba(0, 0, 0, 0.15) 315deg,
211
+
rgba(0, 0, 0, 0.15) 360deg
212
+
);
213
+
background-size: 2px 2px;
214
+
pointer-events: none;
215
+
z-index: 2;
216
+
mix-blend-mode: multiply;
217
+
opacity: 0.8;
218
+
}
219
+
220
+
.monochrome-video-filter video {
221
+
filter: grayscale(100%) contrast(500%) brightness(0.5) saturate(0%)
222
+
sepia(100%) hue-rotate(0deg);
223
+
image-rendering: pixelated;
224
+
image-rendering: -moz-crisp-edges;
225
+
image-rendering: crisp-edges;
226
+
/* Force extreme pixelation by scaling down and up */
227
+
transform: scale(0.125);
228
+
transform-origin: top left;
229
+
width: 800%;
230
+
height: 800%;
231
+
}
232
+
233
+
/* Alternative dithering effect using CSS masks */
234
+
.monochrome-dither {
235
+
position: relative;
236
+
}
237
+
238
+
.monochrome-dither::after {
239
+
content: "";
240
+
position: absolute;
241
+
top: 0;
242
+
left: 0;
243
+
right: 0;
244
+
bottom: 0;
245
+
background:
246
+
/* Bayer matrix dithering pattern */
247
+
linear-gradient(
248
+
45deg,
249
+
transparent 0%,
250
+
transparent 25%,
251
+
rgba(0, 0, 0, 0.1) 25%,
252
+
rgba(0, 0, 0, 0.1) 50%,
253
+
transparent 50%,
254
+
transparent 75%,
255
+
rgba(0, 0, 0, 0.1) 75%,
256
+
rgba(0, 0, 0, 0.1) 100%
257
+
),
258
+
linear-gradient(
259
+
-45deg,
260
+
transparent 0%,
261
+
transparent 25%,
262
+
rgba(0, 0, 0, 0.1) 25%,
263
+
rgba(0, 0, 0, 0.1) 50%,
264
+
transparent 50%,
265
+
transparent 75%,
266
+
rgba(0, 0, 0, 0.1) 75%,
267
+
rgba(0, 0, 0, 0.1) 100%
268
+
);
269
+
background-size:
270
+
2px 2px,
271
+
2px 2px;
272
+
background-position:
273
+
0 0,
274
+
1px 1px;
275
+
pointer-events: none;
276
+
z-index: 2;
277
+
mix-blend-mode: multiply;
278
+
}
279
+
280
+
/* High contrast monochrome with pixelation */
281
+
.monochrome-pixelated {
282
+
filter: grayscale(100%) contrast(600%) brightness(0.4) saturate(0%)
283
+
sepia(100%) hue-rotate(0deg);
284
+
image-rendering: pixelated;
285
+
image-rendering: -moz-crisp-edges;
286
+
image-rendering: crisp-edges;
287
+
transform: scale(0.1);
288
+
transform-origin: top left;
289
+
width: 1000%;
290
+
height: 1000%;
291
+
}
292
+
293
+
/* Simple monochrome with ordered dithering */
294
+
.monochrome-simple {
295
+
position: relative;
296
+
}
297
+
298
+
.monochrome-simple video {
299
+
filter: grayscale(100%) contrast(400%) brightness(0.6) saturate(0%);
300
+
image-rendering: pixelated;
301
+
image-rendering: -moz-crisp-edges;
302
+
image-rendering: crisp-edges;
303
+
/* Add pixelation scaling */
304
+
transform: scale(0.2);
305
+
transform-origin: top left;
306
+
width: 500%;
307
+
height: 500%;
308
+
}
309
+
310
+
.monochrome-simple::after {
311
+
content: "";
312
+
position: absolute;
313
+
top: 0;
314
+
left: 0;
315
+
right: 0;
316
+
bottom: 0;
317
+
background:
318
+
/* Ordered dithering pattern */ repeating-conic-gradient(
319
+
from 0deg at 0px 0px,
320
+
transparent 0deg,
321
+
transparent 22.5deg,
322
+
rgba(0, 0, 0, 0.1) 22.5deg,
323
+
rgba(0, 0, 0, 0.1) 45deg,
324
+
transparent 45deg,
325
+
transparent 67.5deg,
326
+
rgba(0, 0, 0, 0.1) 67.5deg,
327
+
rgba(0, 0, 0, 0.1) 90deg,
328
+
transparent 90deg,
329
+
transparent 112.5deg,
330
+
rgba(0, 0, 0, 0.1) 112.5deg,
331
+
rgba(0, 0, 0, 0.1) 135deg,
332
+
transparent 135deg,
333
+
transparent 157.5deg,
334
+
rgba(0, 0, 0, 0.1) 157.5deg,
335
+
rgba(0, 0, 0, 0.1) 180deg,
336
+
transparent 180deg,
337
+
transparent 202.5deg,
338
+
rgba(0, 0, 0, 0.1) 202.5deg,
339
+
rgba(0, 0, 0, 0.1) 225deg,
340
+
transparent 225deg,
341
+
transparent 247.5deg,
342
+
rgba(0, 0, 0, 0.1) 247.5deg,
343
+
rgba(0, 0, 0, 0.1) 270deg,
344
+
transparent 270deg,
345
+
transparent 292.5deg,
346
+
rgba(0, 0, 0, 0.1) 292.5deg,
347
+
rgba(0, 0, 0, 0.1) 315deg,
348
+
transparent 315deg,
349
+
transparent 337.5deg,
350
+
rgba(0, 0, 0, 0.1) 337.5deg,
351
+
rgba(0, 0, 0, 0.1) 360deg
352
+
);
353
+
background-size: 4px 4px;
354
+
pointer-events: none;
355
+
z-index: 2;
356
+
mix-blend-mode: multiply;
357
+
opacity: 0.7;
358
+
}
359
+
360
+
/*
361
+
---break---
362
+
*/
363
+
364
+
:root {
365
+
--radius: 0.625rem;
366
+
--background: oklch(1 0 0);
367
+
--foreground: oklch(0.145 0 0);
368
+
--card: oklch(1 0 0);
369
+
--card-foreground: oklch(0.145 0 0);
370
+
--popover: oklch(1 0 0);
371
+
--popover-foreground: oklch(0.145 0 0);
372
+
--primary: oklch(0.205 0 0);
373
+
--primary-foreground: oklch(0.985 0 0);
374
+
--secondary: oklch(0.97 0 0);
375
+
--secondary-foreground: oklch(0.205 0 0);
376
+
--muted: oklch(0.97 0 0);
377
+
--muted-foreground: oklch(0.556 0 0);
378
+
--accent: oklch(0.97 0 0);
379
+
--accent-foreground: oklch(0.205 0 0);
380
+
--destructive: oklch(0.577 0.245 27.325);
381
+
--border: oklch(0.922 0 0);
382
+
--input: oklch(0.922 0 0);
383
+
--ring: oklch(0.708 0 0);
384
+
--chart-1: oklch(0.646 0.222 41.116);
385
+
--chart-2: oklch(0.6 0.118 184.704);
386
+
--chart-3: oklch(0.398 0.07 227.392);
387
+
--chart-4: oklch(0.828 0.189 84.429);
388
+
--chart-5: oklch(0.769 0.188 70.08);
389
+
--sidebar: oklch(0.985 0 0);
390
+
--sidebar-foreground: oklch(0.145 0 0);
391
+
--sidebar-primary: oklch(0.205 0 0);
392
+
--sidebar-primary-foreground: oklch(0.985 0 0);
393
+
--sidebar-accent: oklch(0.97 0 0);
394
+
--sidebar-accent-foreground: oklch(0.205 0 0);
395
+
--sidebar-border: oklch(0.922 0 0);
396
+
--sidebar-ring: oklch(0.708 0 0);
397
+
}
398
+
399
+
/*
400
+
---break---
401
+
*/
402
+
403
+
.dark {
404
+
--background: oklch(0.145 0 0);
405
+
--foreground: oklch(0.985 0 0);
406
+
--card: oklch(0.205 0 0);
407
+
--card-foreground: oklch(0.985 0 0);
408
+
--popover: oklch(0.205 0 0);
409
+
--popover-foreground: oklch(0.985 0 0);
410
+
--primary: oklch(0.922 0 0);
411
+
--primary-foreground: oklch(0.205 0 0);
412
+
--secondary: oklch(0.269 0 0);
413
+
--secondary-foreground: oklch(0.985 0 0);
414
+
--muted: oklch(0.269 0 0);
415
+
--muted-foreground: oklch(0.708 0 0);
416
+
--accent: oklch(0.269 0 0);
417
+
--accent-foreground: oklch(0.985 0 0);
418
+
--destructive: oklch(0.704 0.191 22.216);
419
+
--border: oklch(1 0 0 / 10%);
420
+
--input: oklch(1 0 0 / 15%);
421
+
--ring: oklch(0.556 0 0);
422
+
--chart-1: oklch(0.488 0.243 264.376);
423
+
--chart-2: oklch(0.696 0.17 162.48);
424
+
--chart-3: oklch(0.769 0.188 70.08);
425
+
--chart-4: oklch(0.627 0.265 303.9);
426
+
--chart-5: oklch(0.645 0.246 16.439);
427
+
--sidebar: oklch(0.205 0 0);
428
+
--sidebar-foreground: oklch(0.985 0 0);
429
+
--sidebar-primary: oklch(0.488 0.243 264.376);
430
+
--sidebar-primary-foreground: oklch(0.985 0 0);
431
+
--sidebar-accent: oklch(0.269 0 0);
432
+
--sidebar-accent-foreground: oklch(0.985 0 0);
433
+
--sidebar-border: oklch(1 0 0 / 10%);
434
+
--sidebar-ring: oklch(0.556 0 0);
435
+
}
436
+
437
+
/*
438
+
---break---
439
+
*/
440
+
441
+
@layer base {
442
+
* {
443
+
@apply border-border outline-ring/50;
444
+
}
445
+
body {
446
+
@apply bg-background text-foreground text-lg md:text-xl;
447
+
}
448
+
}
+12
-5
src/app/layout.tsx
+12
-5
src/app/layout.tsx
···
1
import type { Metadata, Viewport } from "next";
2
import NextPlausible from "next-plausible";
3
-
import { Inter } from "next/font/google";
4
5
import { cx } from "#/lib/cx";
6
7
import "./globals.css";
8
9
-
const sans = Inter({
10
-
variable: "--font-inter",
11
subsets: ["latin"],
12
-
weight: ["400", "500", "700"],
13
});
14
15
export const metadata: Metadata = {
···
52
</head>
53
<body
54
className={cx(
55
-
sans.variable,
56
57
"antialiased font-sans",
58
)}
···
1
import type { Metadata, Viewport } from "next";
2
import NextPlausible from "next-plausible";
3
+
import { VT323, Jersey_10 } from "next/font/google";
4
5
import { cx } from "#/lib/cx";
6
7
import "./globals.css";
8
9
+
const heading = VT323({
10
+
variable: "--font-vt323",
11
subsets: ["latin"],
12
+
weight: "400",
13
+
});
14
+
15
+
const body = Jersey_10({
16
+
variable: "--font-jersey",
17
+
subsets: ["latin"],
18
+
weight: "400",
19
});
20
21
export const metadata: Metadata = {
···
58
</head>
59
<body
60
className={cx(
61
+
heading.variable,
62
+
body.variable,
63
64
"antialiased font-sans",
65
)}
+25
-11
src/app/opengraph-image.tsx
+25
-11
src/app/opengraph-image.tsx
···
9
export const contentType = "image/png";
10
11
export default async function OpenGraphImage() {
12
-
const fontData = await loadGoogleFont("Inter:wght@100..900", "mmatt.net");
13
14
return new ImageResponse(
15
(
16
-
<div tw="h-full w-full bg-white flex flex-col justify-center items-center">
17
-
<h1
18
-
style={{
19
-
fontFamily: '"Inter"',
20
-
fontSize: 80,
21
-
fontWeight: 1000,
22
-
}}
23
>
24
-
mmatt.net
25
-
</h1>
26
</div>
27
),
28
{
29
...size,
30
fonts: [
31
{
32
-
name: "Inter",
33
data: fontData,
34
},
35
],
···
9
export const contentType = "image/png";
10
11
export default async function OpenGraphImage() {
12
+
const fontData = await loadGoogleFont("VT323", "mmatt.net");
13
14
return new ImageResponse(
15
(
16
+
<div
17
+
tw="h-full w-full flex items-center justify-center"
18
+
style={{
19
+
backgroundColor: "#ffffff",
20
+
color: "#000000",
21
+
border: "16px solid #000000",
22
+
}}
23
+
>
24
+
<div
25
+
tw="flex items-center justify-center"
26
+
style={{ width: "100%", height: "100%" }}
27
>
28
+
<h1
29
+
style={{
30
+
fontFamily: '"VT323"',
31
+
fontSize: 96,
32
+
lineHeight: 1.2,
33
+
letterSpacing: -1,
34
+
textTransform: "lowercase",
35
+
}}
36
+
>
37
+
mmatt.net
38
+
</h1>
39
+
</div>
40
</div>
41
),
42
{
43
...size,
44
fonts: [
45
{
46
+
name: "VT323",
47
data: fontData,
48
},
49
],
+37
-181
src/app/page.tsx
+37
-181
src/app/page.tsx
···
1
-
import Image from "next/image";
2
-
import Link from "next/link";
3
-
4
-
import LatestStatus from "#/components/latest-status";
5
-
import { PostList } from "#/components/post-list";
6
-
import { Paragraph, Title } from "#/components/typography";
7
8
-
import me from "../assets/matt.jpeg";
9
10
-
export const dynamic = "force-static";
11
-
export const revalidate = 3600; // 1 hour
12
13
export default function Home() {
14
return (
15
-
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-dvh p-8 pb-20 gap-16 sm:p-20">
16
-
<main className="flex flex-col gap-8 row-start-2 items-center sm:items-start w-full max-w-[600px]">
17
-
<div className="self-center flex flex-col">
18
-
<Image
19
-
src={me}
20
-
alt="Photo of Matt Morris, red hair, glasses, holding his iPhone in the mirror, taking a picture of himself."
21
-
width={100}
22
-
height={100}
23
-
className="rounded-lg"
24
-
/>
25
</div>
26
-
<Title level="h2">Hello!</Title>
27
-
<Paragraph>
28
-
my name is <b>matt morris</b> and i'm head technologist for{" "}
29
-
<a href="https://songish.app?via=mmatt.net" className="underline">
30
-
Songish
31
-
</a>
32
-
, part time maintainer for{" "}
33
-
<a href="https://teal.fm?via=mmatt.net" className="underline">
34
-
teal.fm
35
-
</a>
36
-
, resident at{" "}
37
-
<a href="https://opn.haus?via=mmatt.net" className="underline">
38
-
Open House*
39
-
</a>
40
-
, and student at{" "}
41
-
<a href="https://mtsu.edu?via=mmatt.net" className="underline">
42
-
MTSU
43
-
</a>{" "}
44
-
๐งโ๐ฌ
45
-
</Paragraph>
46
-
<Paragraph>
47
-
welcome to my new Work-In-Progress website! powered by{" "}
48
-
<a href="https://whtwnd.com?via=mmatt.net" className="underline">
49
-
WhiteWind
50
-
</a>{" "}
51
-
&{" "}
52
-
<a href="https://atproto.com?via=mmatt.net" className="underline">
53
-
ATProto
54
-
</a>
55
-
. this is a fork from the wonderful{" "}
56
-
<a
57
-
className="underline"
58
-
href="https://bsky.app/profile/did:plc:p2cp5gopk7mgjegy6wadk3ep"
59
-
>
60
-
@samuel.bsky.team
61
-
</a>{" "}
62
-
(originally{" "}
63
-
<a
64
-
href="https://github.com/mozzius/mozzius.dev"
65
-
className="underline"
66
-
>
67
-
here
68
-
</a>
69
-
, my repo{" "}
70
-
<a href="https://github.com/mmattbtw/atp-blog" className="underline">
71
-
here
72
-
</a>
73
-
) that I am going to continue to iterate on. hoping to add blog post
74
-
comments & reactions!
75
-
</Paragraph>
76
-
<Paragraph>my past projects include...</Paragraph>
77
-
<ul className="list-disc -mt-5">
78
-
<li>
79
-
<a
80
-
className="underline"
81
-
href="https://github.com/mmattDonk/AI-TTS-Donations"
82
-
>
83
-
the <b>first</b> free and open source AI Text to Speech program
84
-
for Twitch Streamers.
85
-
</a>
86
-
</li>
87
-
<li>
88
-
<a
89
-
className="underline"
90
-
href="https://github.com/mmattDonk/TwitchTunes"
91
-
>
92
-
the (at the time) best way for Spotify users to recieve Song
93
-
Requests on Twitch.
94
-
</a>
95
-
</li>
96
-
<li>
97
-
<a
98
-
className="underline"
99
-
href="https://github.com/mmattbtw/Super-VCs"
100
-
>
101
-
the <b>best</b> automatic voice channel bot on Discord.
102
-
</a>
103
-
</li>
104
-
<a className="underline" href="https://github.com/mmattbtw">
105
-
and more...
106
-
</a>
107
-
</ul>
108
109
-
<Paragraph>you can find me all over the web at:</Paragraph>
110
111
-
<ul className="list-disc -mt-5">
112
-
<li>
113
-
<a
114
-
className="underline"
115
-
href="https://bsky.app/profile/did:plc:tas6hj2xjrqben5653v5kohk"
116
-
rel="me"
117
-
>
118
-
bluesky
119
-
</a>
120
-
</li>
121
-
<li>
122
-
<a
123
-
className="underline"
124
-
href="https://youtube.com/@mmattbtw"
125
-
rel="me"
126
-
>
127
-
youtube
128
-
</a>
129
-
</li>
130
-
<li>
131
-
<a
132
-
className="underline"
133
-
href="https://github.com/mmattbtw"
134
-
rel="me"
135
-
>
136
-
github
137
-
</a>
138
-
</li>
139
-
<li>
140
-
<a className="underline" href="https://twitch.tv/mmattbtw" rel="me">
141
-
twitch
142
-
</a>
143
-
</li>
144
-
<li>
145
-
<a className="underline" href="https://social.lol/@matt" rel="me">
146
-
mastodon
147
-
</a>
148
-
</li>
149
-
<li>
150
-
<a
151
-
className="underline"
152
-
href="https://music.apple.com/profile/air2earth"
153
-
rel="me"
154
-
>
155
-
apple music
156
-
</a>
157
-
</li>
158
-
<li>
159
-
<a className="underline" href="https://matt.omg.lol">
160
-
everywhere else...
161
-
</a>
162
-
</li>
163
-
</ul>
164
-
165
-
<Paragraph>
166
-
my email is{" "}
167
-
<a className="underline" href="mailto:matt@mmatt.net" rel="me">
168
-
matt at mmatt.net
169
-
</a>
170
-
</Paragraph>
171
-
172
-
<LatestStatus />
173
-
174
-
<Title id="blog" level="h2">
175
-
Blog Posts:
176
-
</Title>
177
-
<div className="flex flex-row items-baseline gap-1">
178
-
<Link className="-mt-6 underline" href="/rss">
179
-
Subscribe via RSS
180
-
</Link>
181
-
<p> - </p>
182
-
<Link className="-mt-6 underline" href="/right/now">
183
-
right now: statuses
184
-
</Link>
185
</div>
186
-
<div className="flex flex-col gap-4 w-full">
187
-
<PostList />
188
-
</div>
189
-
</main>
190
-
</div>
191
);
192
}
···
1
+
import InfoBox from "#/components/info-box";
2
+
import Link from "#/components/ui/link";
3
4
+
import HomeVideoBackground from "../components/home-video-background";
5
6
+
// Revalidate every hour (3600 seconds)
7
+
export const revalidate = 3600;
8
9
export default function Home() {
10
return (
11
+
<main className="relative min-h-screen overflow-hidden">
12
+
<HomeVideoBackground />
13
+
<div className="absolute inset-0 z-10 min-h-screen">
14
+
<div className="max-w-xl pt-1.5 pl-1.5 space-y-4">
15
+
<h1 className="font-bold text-black dark:text-white bg-white dark:bg-black">
16
+
หโโฎ matt โฎโห
17
+
</h1>
18
+
<p className="text-black dark:text-white bg-white dark:bg-black">
19
+
(๏พยดใฎ`)๏พ*: ๏ฝฅ๏พ i'm a full time computer science student at{" "}
20
+
<Link href="https://mtsu.edu">MTSU</Link>, part time technologist
21
+
for <Link href="https://teal.fm">teal.fm</Link>, and a resident at{" "}
22
+
<Link href="https://opn.haus">Open House*</Link>.
23
+
</p>
24
+
<p>
25
+
<Link href="https://matt.omg.lol">
26
+
>> all over the web <<
27
+
</Link>
28
+
{" <_< ^_^ >_> "}
29
+
<Link href="mailto:matt@mmatt.net">>> mail me <<</Link>
30
+
</p>
31
+
<p>
32
+
<Link href="/writing">(;;;*_*) writing</Link>
33
+
</p>
34
</div>
35
36
+
{/* InfoBox positioned for desktop and mobile */}
37
+
<div className="fixed top-4 right-4 z-20 md:block hidden">
38
+
<InfoBox />
39
+
</div>
40
41
+
{/* Mobile InfoBox - positioned below main content */}
42
+
<div className="md:hidden pt-8 px-1.5">
43
+
<InfoBox />
44
</div>
45
+
</div>
46
+
</main>
47
);
48
}
+34
-19
src/app/post/[rkey]/opengraph-image.tsx
+34
-19
src/app/post/[rkey]/opengraph-image.tsx
···
19
const post = await getPost(rkey);
20
21
const fontData = await loadGoogleFont(
22
-
"Inter:wght@100..900",
23
"mmatt.net" + (post.value.title?.split(" || ")[0] ?? "Untitled"),
24
);
25
26
return new ImageResponse(
27
(
28
-
<div tw="h-full w-full bg-white flex flex-col justify-center items-center px-20">
29
-
<h1
30
style={{
31
-
fontFamily: '"Inter"',
32
-
fontSize: 80,
33
-
fontWeight: 900,
34
textAlign: "center",
35
-
fontOpticalSizing: "auto",
36
-
fontStyle: "normal",
37
}}
38
>
39
-
{post.value.title?.split(" || ")[0] ?? "Untitled"}
40
-
</h1>
41
-
<h1
42
-
style={{
43
-
fontSize: 32,
44
-
fontFamily: '"Inter"',
45
-
}}
46
-
>
47
-
mmatt.net
48
-
</h1>
49
</div>
50
),
51
{
52
...size,
53
fonts: [
54
{
55
-
name: "Inter",
56
data: fontData,
57
},
58
],
···
19
const post = await getPost(rkey);
20
21
const fontData = await loadGoogleFont(
22
+
"VT323",
23
"mmatt.net" + (post.value.title?.split(" || ")[0] ?? "Untitled"),
24
);
25
26
return new ImageResponse(
27
(
28
+
<div
29
+
tw="h-full w-full flex items-center justify-center px-20"
30
+
style={{
31
+
backgroundColor: "#ffffff",
32
+
color: "#000000",
33
+
border: "16px solid #000000",
34
+
}}
35
+
>
36
+
<div
37
+
tw="flex flex-col items-center justify-center"
38
style={{
39
+
width: "100%",
40
+
height: "100%",
41
textAlign: "center",
42
}}
43
>
44
+
<h1
45
+
style={{
46
+
fontFamily: '\"VT323\"',
47
+
fontSize: 80,
48
+
lineHeight: 1.2,
49
+
letterSpacing: -1,
50
+
}}
51
+
>
52
+
{post.value.title?.split(" || ")[0] ?? "Untitled"}
53
+
</h1>
54
+
<h2
55
+
style={{
56
+
fontFamily: '\"VT323\"',
57
+
fontSize: 36,
58
+
marginTop: 16,
59
+
}}
60
+
>
61
+
mmatt.net
62
+
</h2>
63
+
</div>
64
</div>
65
),
66
{
67
...size,
68
fonts: [
69
{
70
+
name: "VT323",
71
data: fontData,
72
},
73
],
+7
-13
src/app/right/now/page.tsx
+7
-13
src/app/right/now/page.tsx
···
1
import { ArrowLeftIcon } from "lucide-react";
2
import type { Metadata } from "next";
3
import Image from "next/image";
4
-
import Link from "next/link";
5
6
import { NowList } from "#/components/now-list";
7
import { Paragraph, Title } from "#/components/typography";
8
9
import me from "../../../assets/matt.jpeg";
10
···
23
return (
24
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-dvh p-8 pb-20 gap-16 sm:p-20">
25
<main className="flex flex-col gap-8 row-start-2 items-center sm:items-start w-full max-w-[600px]">
26
-
<Link
27
href="/"
28
className="hover:underline hover:underline-offset-4 font-medium"
29
>
30
<ArrowLeftIcon className="inline size-4 align-middle mb-px mr-1" />
31
Back
32
-
</Link>
33
<div className="self-center flex flex-col">
34
<Image
35
src={me}
···
43
<Title level="h2">matt: right now</Title>
44
<Paragraph>
45
view on{" "}
46
-
<a
47
-
href="https://bsky.app/profile/did:plc:rwb72l7iwkraojrbrbwitnkd"
48
-
className="underline"
49
-
>
50
Bluesky
51
-
</a>{" "}
52
-
and{" "}
53
-
<a href="https://status.lol/matt" className="underline">
54
-
status.lol
55
-
</a>
56
-
.
57
</Paragraph>
58
<div className="flex flex-col gap-4 w-full">
59
<NowList />
···
1
import { ArrowLeftIcon } from "lucide-react";
2
import type { Metadata } from "next";
3
import Image from "next/image";
4
+
import NextLink from "next/link";
5
6
import { NowList } from "#/components/now-list";
7
import { Paragraph, Title } from "#/components/typography";
8
+
import Link from "#/components/ui/link";
9
10
import me from "../../../assets/matt.jpeg";
11
···
24
return (
25
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-dvh p-8 pb-20 gap-16 sm:p-20">
26
<main className="flex flex-col gap-8 row-start-2 items-center sm:items-start w-full max-w-[600px]">
27
+
<NextLink
28
href="/"
29
className="hover:underline hover:underline-offset-4 font-medium"
30
>
31
<ArrowLeftIcon className="inline size-4 align-middle mb-px mr-1" />
32
Back
33
+
</NextLink>
34
<div className="self-center flex flex-col">
35
<Image
36
src={me}
···
44
<Title level="h2">matt: right now</Title>
45
<Paragraph>
46
view on{" "}
47
+
<Link href="https://bsky.app/profile/did:plc:rwb72l7iwkraojrbrbwitnkd">
48
Bluesky
49
+
</Link>{" "}
50
+
and <Link href="https://status.lol/matt">status.lol</Link>.
51
</Paragraph>
52
<div className="flex flex-col gap-4 w-full">
53
<NowList />
+5
-3
src/app/rss/route.ts
+5
-3
src/app/rss/route.ts
···
1
import rehypeFormat from "rehype-format";
2
import rehypeStringify from "rehype-stringify";
3
import remarkParse from "remark-parse";
···
21
});
22
23
for (const post of posts) {
24
-
const titleParts = post.value.title?.split(" || ") ?? ["Untitled", ""];
25
const title = titleParts[0];
26
const extractedDescription = titleParts.slice(1).join(" || ");
27
···
30
.use(remarkRehype)
31
.use(rehypeFormat)
32
.use(rehypeStringify)
33
-
.process(post.value.content)
34
.then((v) => v.toString());
35
36
const fullDescription = extractedDescription
···
41
title: title,
42
description: fullDescription,
43
url: `https://mmatt.net/post/${post.uri.split("/").pop()}`,
44
-
date: new Date(post.value.createdAt ?? Date.now()),
45
});
46
}
47
···
1
+
import { ComWhtwndBlogEntry } from "@atcute/whitewind";
2
import rehypeFormat from "rehype-format";
3
import rehypeStringify from "rehype-stringify";
4
import remarkParse from "remark-parse";
···
22
});
23
24
for (const post of posts) {
25
+
const postValue = post.value as ComWhtwndBlogEntry.Main;
26
+
const titleParts = postValue.title?.split(" || ") ?? ["Untitled", ""];
27
const title = titleParts[0];
28
const extractedDescription = titleParts.slice(1).join(" || ");
29
···
32
.use(remarkRehype)
33
.use(rehypeFormat)
34
.use(rehypeStringify)
35
+
.process(postValue.content)
36
.then((v) => v.toString());
37
38
const fullDescription = extractedDescription
···
43
title: title,
44
description: fullDescription,
45
url: `https://mmatt.net/post/${post.uri.split("/").pop()}`,
46
+
date: new Date(postValue.createdAt ?? Date.now()),
47
});
48
}
49
+1
-1
src/app/weblog/page.tsx
+1
-1
src/app/weblog/page.tsx
+22
src/app/writing/page.tsx
+22
src/app/writing/page.tsx
···
···
1
+
import { PostList } from "#/components/post-list";
2
+
3
+
import HomeVideoBackground from "../../components/home-video-background";
4
+
5
+
// Revalidate every hour (3600 seconds)
6
+
export const revalidate = 3600;
7
+
8
+
export default function WritingPage() {
9
+
return (
10
+
<main className="relative min-h-screen overflow-hidden">
11
+
<HomeVideoBackground />
12
+
<div className="absolute inset-0 z-10 min-h-screen">
13
+
<div className="max-w-xl pt-1.5 pl-1.5 space-y-4">
14
+
<h1 className="font-bold text-black dark:text-white bg-white dark:bg-black inline">
15
+
(;;;*_*) writing
16
+
</h1>
17
+
<PostList />
18
+
</div>
19
+
</div>
20
+
</main>
21
+
);
22
+
}
+15
src/components/home-video-background.tsx
+15
src/components/home-video-background.tsx
···
···
1
+
"use client";
2
+
3
+
import DitheredVideoFilter from "./video-filter";
4
+
5
+
export default function HomeVideoBackground() {
6
+
return (
7
+
<DitheredVideoFilter
8
+
videoSrc="https://wh9xsi1isi.ufs.sh/f/3pCuYtORE70iQcTd1tzKQmgchpDLvW6HRVeJosuUikOnjwbf"
9
+
pixelSize={3}
10
+
maxFPS={12}
11
+
maxWidth={1000}
12
+
className="fixed inset-0 w-screen h-screen object-cover -z-10 invert dark:invert-0"
13
+
/>
14
+
);
15
+
}
+261
src/components/info-box-client.tsx
+261
src/components/info-box-client.tsx
···
···
1
+
"use client";
2
+
3
+
import { useEffect, useState } from "react";
4
+
import { type AppBskyFeedPost } from "@atcute/bluesky";
5
+
import { ComWhtwndBlogEntry } from "@atcute/whitewind";
6
+
7
+
import { env } from "#/lib/env";
8
+
9
+
import { Record as TealPlayRecord } from "../../lexiconTypes/types/fm/teal/alpha/feed/play";
10
+
import { Record as NowRecord } from "../../lexiconTypes/types/net/mmatt/right/now";
11
+
import { Record as CarRecord } from "../../lexiconTypes/types/net/mmatt/vitals/car";
12
+
import {
13
+
Carousel,
14
+
CarouselContent,
15
+
CarouselItem,
16
+
type CarouselApi,
17
+
} from "./ui/carousel";
18
+
import Link from "./ui/link";
19
+
import { SlidingNumber } from "./ui/shadcn-io/sliding-number";
20
+
21
+
interface LetterboxdEntry {
22
+
title: string;
23
+
link: string;
24
+
pubDate: string;
25
+
description?: string;
26
+
}
27
+
28
+
interface InfoBoxData {
29
+
carInfo: CarRecord | null;
30
+
blogPost: ComWhtwndBlogEntry.Main | null;
31
+
blogPostRkey: string | null;
32
+
blueskyPost: AppBskyFeedPost.Main | null;
33
+
blueskyPostRkey: string | null;
34
+
tealPlay: TealPlayRecord | null;
35
+
letterboxdEntry: LetterboxdEntry | null;
36
+
nowEntry: NowRecord | null;
37
+
}
38
+
39
+
interface ContentItem {
40
+
id: string;
41
+
title: string;
42
+
content: React.ReactNode;
43
+
}
44
+
45
+
interface InfoBoxClientProps {
46
+
data: InfoBoxData;
47
+
}
48
+
49
+
export default function InfoBoxClient({ data }: InfoBoxClientProps) {
50
+
const [api, setApi] = useState<CarouselApi | undefined>();
51
+
52
+
const contentItems: ContentItem[] = [
53
+
// Car Info
54
+
...(data.carInfo
55
+
? [
56
+
{
57
+
id: "car",
58
+
title: "Car Info",
59
+
content: (
60
+
<div className="space-y-1 text-xs text-black dark:text-white">
61
+
<p>
62
+
Range:{" "}
63
+
<SlidingNumber number={data.carInfo.carFuelRange} inView />
64
+
</p>
65
+
<p>
66
+
Fuel:{" "}
67
+
<SlidingNumber
68
+
number={data.carInfo.carPercentFuelRemaining}
69
+
decimalPlaces={1}
70
+
inView
71
+
/>
72
+
</p>
73
+
<p>
74
+
Remaining:{" "}
75
+
<SlidingNumber
76
+
number={data.carInfo.amountRemaining}
77
+
decimalPlaces={1}
78
+
inView
79
+
/>
80
+
</p>
81
+
<p>
82
+
Distance:{" "}
83
+
<SlidingNumber
84
+
number={data.carInfo.carTraveledDistance}
85
+
inView
86
+
/>
87
+
</p>
88
+
</div>
89
+
),
90
+
},
91
+
]
92
+
: []),
93
+
94
+
// Blog Post
95
+
...(data.blogPost && data.blogPostRkey
96
+
? [
97
+
{
98
+
id: "blog",
99
+
title: "Latest Blog Post",
100
+
content: (
101
+
<div className="space-y-1 text-xs text-black dark:text-white">
102
+
<Link href={`/post/${data.blogPostRkey}`}>
103
+
{data.blogPost.title?.split(" || ")[0] || "Untitled Post"}
104
+
<br />
105
+
</Link>
106
+
<p className="text-gray-600 dark:text-gray-400">
107
+
{data.blogPost.title?.split(" || ")[1]}
108
+
</p>
109
+
<p className="text-gray-600 dark:text-gray-400">
110
+
{new Date(data.blogPost.createdAt ?? "").toLocaleDateString()}
111
+
</p>
112
+
</div>
113
+
),
114
+
},
115
+
]
116
+
: []),
117
+
118
+
// Bluesky Post
119
+
...(data.blueskyPost && data.blueskyPostRkey
120
+
? [
121
+
{
122
+
id: "bluesky",
123
+
title: "Latest Bluesky Post",
124
+
content: (
125
+
<div className="space-y-1 text-xs text-black dark:text-white">
126
+
<Link
127
+
href={`https://bsky.app/profile/${env.NEXT_PUBLIC_BSKY_DID}/post/${data.blueskyPostRkey}`}
128
+
>
129
+
{data.blueskyPost.text.length > 100
130
+
? `${data.blueskyPost.text.substring(0, 100)}...`
131
+
: data.blueskyPost.text}
132
+
</Link>
133
+
<p className="text-gray-600 dark:text-gray-400">
134
+
{new Date(data.blueskyPost.createdAt).toLocaleDateString()}
135
+
</p>
136
+
</div>
137
+
),
138
+
},
139
+
]
140
+
: []),
141
+
142
+
// Teal.fm Play
143
+
...(data.tealPlay
144
+
? [
145
+
{
146
+
id: "teal",
147
+
title: "Latest Teal.fm Play",
148
+
content: (
149
+
<div className="space-y-1 text-xs text-black dark:text-white">
150
+
<p className="font-medium">
151
+
{data.tealPlay.trackName || "Unknown Track"}
152
+
</p>
153
+
<p className="text-gray-600 dark:text-gray-400">
154
+
by{" "}
155
+
{data.tealPlay.artistNames?.[0] ||
156
+
data.tealPlay.artists?.[0]?.artistName ||
157
+
"Unknown Artist"}
158
+
</p>
159
+
<p className="text-gray-600 dark:text-gray-400">
160
+
{data.tealPlay.playedTime
161
+
? new Date(data.tealPlay.playedTime).toLocaleDateString()
162
+
: "Unknown date"}
163
+
</p>
164
+
</div>
165
+
),
166
+
},
167
+
]
168
+
: []),
169
+
170
+
// Letterboxd Entry
171
+
...(data.letterboxdEntry
172
+
? [
173
+
{
174
+
id: "letterboxd",
175
+
title: "Latest Letterboxd Watch",
176
+
content: (
177
+
<div className="space-y-1 text-xs text-black dark:text-white">
178
+
<Link href={data.letterboxdEntry.link}>
179
+
{data.letterboxdEntry.title}
180
+
</Link>
181
+
<p className="text-gray-600 dark:text-gray-400">
182
+
{new Date(data.letterboxdEntry.pubDate).toLocaleDateString()}
183
+
</p>
184
+
{data.letterboxdEntry.description && (
185
+
<p className="text-gray-600 dark:text-gray-400">
186
+
{(() => {
187
+
const cleanDescription =
188
+
data.letterboxdEntry.description.replace(
189
+
/<[^>]*>/g,
190
+
"",
191
+
);
192
+
return cleanDescription.length > 80
193
+
? `${cleanDescription.substring(0, 80)}...`
194
+
: cleanDescription;
195
+
})()}
196
+
</p>
197
+
)}
198
+
</div>
199
+
),
200
+
},
201
+
]
202
+
: []),
203
+
204
+
// Statuslog Entry
205
+
...(data.nowEntry
206
+
? [
207
+
{
208
+
id: "now",
209
+
title: "Latest Status",
210
+
content: (
211
+
<div className="space-y-1 text-xs text-black dark:text-white">
212
+
<p className="font-medium">
213
+
{data.nowEntry.emoji && (
214
+
<span className="mr-1">{data.nowEntry.emoji}</span>
215
+
)}
216
+
{data.nowEntry.text}
217
+
</p>
218
+
<p className="text-gray-600 dark:text-gray-400">
219
+
{new Date(data.nowEntry.createdAt).toLocaleDateString()}
220
+
</p>
221
+
</div>
222
+
),
223
+
},
224
+
]
225
+
: []),
226
+
];
227
+
228
+
// Auto-cycle through content every 5 seconds
229
+
useEffect(() => {
230
+
if (!api || contentItems.length <= 1) return;
231
+
232
+
const interval = setInterval(() => {
233
+
api.scrollNext();
234
+
}, 5000);
235
+
236
+
return () => clearInterval(interval);
237
+
}, [api, contentItems.length]);
238
+
239
+
if (contentItems.length === 0) {
240
+
return null;
241
+
}
242
+
243
+
return (
244
+
<div className="w-48 h-48 dark:border-white border-black border-2 rounded-lg bg-white dark:bg-black overflow-hidden">
245
+
<Carousel className="w-full h-full" opts={{ loop: true }} setApi={setApi}>
246
+
<CarouselContent className="h-full">
247
+
{contentItems.map((item) => (
248
+
<CarouselItem key={item.id} className="h-full px-6 py-3">
249
+
<div className="flex flex-col h-full">
250
+
<h2 className="text-sm font-bold mb-2 text-black dark:text-white">
251
+
{item.title}
252
+
</h2>
253
+
<div className="flex-1 overflow-hidden">{item.content}</div>
254
+
</div>
255
+
</CarouselItem>
256
+
))}
257
+
</CarouselContent>
258
+
</Carousel>
259
+
</div>
260
+
);
261
+
}
+168
src/components/info-box.tsx
+168
src/components/info-box.tsx
···
···
1
+
import { type AppBskyFeedPost } from "@atcute/bluesky";
2
+
import { ok } from "@atcute/client";
3
+
import { ComWhtwndBlogEntry } from "@atcute/whitewind";
4
+
5
+
import { bsky } from "#/lib/bsky";
6
+
import { env } from "#/lib/env";
7
+
8
+
import { Record as TealPlayRecord } from "../../lexiconTypes/types/fm/teal/alpha/feed/play";
9
+
import { Record as NowRecord } from "../../lexiconTypes/types/net/mmatt/right/now";
10
+
import { Record as CarRecord } from "../../lexiconTypes/types/net/mmatt/vitals/car";
11
+
import InfoBoxClient from "./info-box-client";
12
+
13
+
// Revalidate every hour (3600 seconds)
14
+
export const revalidate = 3600;
15
+
16
+
interface LetterboxdEntry {
17
+
title: string;
18
+
link: string;
19
+
pubDate: string;
20
+
description?: string;
21
+
}
22
+
23
+
interface InfoBoxData {
24
+
carInfo: CarRecord | null;
25
+
blogPost: ComWhtwndBlogEntry.Main | null;
26
+
blogPostRkey: string | null;
27
+
blueskyPost: AppBskyFeedPost.Main | null;
28
+
blueskyPostRkey: string | null;
29
+
tealPlay: TealPlayRecord | null;
30
+
letterboxdEntry: LetterboxdEntry | null;
31
+
nowEntry: NowRecord | null;
32
+
}
33
+
34
+
async function fetchLetterboxdData(): Promise<LetterboxdEntry | null> {
35
+
try {
36
+
const response = await fetch(
37
+
`${process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000"}/api/letterboxd-rss`,
38
+
);
39
+
if (response.ok) {
40
+
const data = await response.json();
41
+
if (data.entries && data.entries.length > 0) {
42
+
return data.entries[0];
43
+
}
44
+
}
45
+
} catch {
46
+
console.log("Letterboxd RSS not accessible");
47
+
}
48
+
return null;
49
+
}
50
+
51
+
export default async function InfoBox() {
52
+
const data: InfoBoxData = {
53
+
carInfo: null,
54
+
blogPost: null,
55
+
blogPostRkey: null,
56
+
blueskyPost: null,
57
+
blueskyPostRkey: null,
58
+
tealPlay: null,
59
+
letterboxdEntry: null,
60
+
nowEntry: null,
61
+
};
62
+
63
+
try {
64
+
// Fetch car info
65
+
const cars = await ok(
66
+
bsky.get("com.atproto.repo.listRecords", {
67
+
params: {
68
+
repo: env.NEXT_PUBLIC_BSKY_DID as `did:plc:${string}`,
69
+
collection: "net.mmatt.vitals.car",
70
+
limit: 1,
71
+
},
72
+
}),
73
+
);
74
+
if (cars.records.length > 0) {
75
+
data.carInfo = cars.records[0].value as CarRecord;
76
+
}
77
+
78
+
// Fetch latest blog post (com.whtwnd.blog.entry with visibility = public)
79
+
try {
80
+
const blog = await ok(
81
+
bsky.get("com.atproto.repo.listRecords", {
82
+
params: {
83
+
repo: env.NEXT_PUBLIC_BSKY_DID as `did:plc:${string}`,
84
+
collection: "com.whtwnd.blog.entry",
85
+
limit: 10,
86
+
},
87
+
}),
88
+
);
89
+
const publicPost = blog.records.find((record) => {
90
+
const value = record.value as ComWhtwndBlogEntry.Main;
91
+
return value.visibility === "public";
92
+
});
93
+
if (publicPost) {
94
+
data.blogPost = publicPost.value as ComWhtwndBlogEntry.Main;
95
+
data.blogPostRkey = publicPost.uri.split("/").pop() || null;
96
+
}
97
+
} catch {
98
+
console.log("Blog collection not found or accessible");
99
+
}
100
+
101
+
// Fetch latest Bluesky post (non-reply)
102
+
try {
103
+
const bluesky = await ok(
104
+
bsky.get("com.atproto.repo.listRecords", {
105
+
params: {
106
+
repo: env.NEXT_PUBLIC_BSKY_DID as `did:plc:${string}`,
107
+
collection: "app.bsky.feed.post",
108
+
limit: 10,
109
+
},
110
+
}),
111
+
);
112
+
// Find the first post that is not a reply (doesn't have reply field)
113
+
const nonReplyPost = bluesky.records.find((record) => {
114
+
const value = record.value as AppBskyFeedPost.Main;
115
+
return !value.reply;
116
+
});
117
+
if (nonReplyPost) {
118
+
data.blueskyPost = nonReplyPost.value as AppBskyFeedPost.Main;
119
+
data.blueskyPostRkey = nonReplyPost.uri.split("/").pop() || null;
120
+
}
121
+
} catch {
122
+
console.log("Bluesky posts not found or accessible");
123
+
}
124
+
125
+
// Fetch latest Teal.fm play
126
+
try {
127
+
const teal = await ok(
128
+
bsky.get("com.atproto.repo.listRecords", {
129
+
params: {
130
+
repo: env.NEXT_PUBLIC_BSKY_DID as `did:plc:${string}`,
131
+
collection: "fm.teal.alpha.feed.play",
132
+
limit: 1,
133
+
},
134
+
}),
135
+
);
136
+
if (teal.records.length > 0) {
137
+
data.tealPlay = teal.records[0].value as TealPlayRecord;
138
+
}
139
+
} catch {
140
+
console.log("Teal.fm plays not found or accessible");
141
+
}
142
+
143
+
// Fetch latest Letterboxd entry from RSS
144
+
data.letterboxdEntry = await fetchLetterboxdData();
145
+
146
+
// Fetch latest statuslog entry (net.mmatt.right.now)
147
+
try {
148
+
const now = await ok(
149
+
bsky.get("com.atproto.repo.listRecords", {
150
+
params: {
151
+
repo: env.NEXT_PUBLIC_BSKY_DID as `did:plc:${string}`,
152
+
collection: "net.mmatt.right.now",
153
+
limit: 1,
154
+
},
155
+
}),
156
+
);
157
+
if (now.records.length > 0) {
158
+
data.nowEntry = now.records[0].value as NowRecord;
159
+
}
160
+
} catch {
161
+
console.log("Statuslog entries not found or accessible");
162
+
}
163
+
} catch (error) {
164
+
console.error("Error fetching data:", error);
165
+
}
166
+
167
+
return <InfoBoxClient data={data} />;
168
+
}
+7
-25
src/components/post-list-item.tsx
+7
-25
src/components/post-list-item.tsx
···
1
"use client";
2
3
-
import Link from "next/link";
4
-
import { ComWhtwndBlogEntry } from "@atcute/client/lexicons";
5
6
-
import { PostInfo } from "./post-info";
7
-
import { Title } from "./typography";
8
9
export function PostListItem({
10
post,
11
rkey,
12
-
viewCount,
13
}: {
14
-
post: ComWhtwndBlogEntry.Record;
15
rkey: string;
16
viewCount?: React.ReactNode;
17
}) {
18
return (
19
-
<>
20
-
<Link href={`/post/${rkey}`} className="w-full group">
21
-
<article className="w-full flex flex-row border-b items-stretch relative transition-color backdrop-blur-sm hover:bg-slate-700/5 dark:hover:bg-slate-200/10">
22
-
<div className="flex-1 py-2 px-4 z-10 relative">
23
-
<Title className="text-lg" level="h3">
24
-
{post.title?.split(" || ")[0]}
25
-
</Title>
26
-
<PostInfo
27
-
content={post.content}
28
-
createdAt={post.createdAt}
29
-
className="text-xs mt-1"
30
-
desc={post.title?.split(" || ")[1]}
31
-
>
32
-
{viewCount}
33
-
</PostInfo>
34
-
</div>
35
-
</article>
36
-
</Link>
37
-
</>
38
);
39
}
···
1
"use client";
2
3
+
import { ComWhtwndBlogEntry } from "@atcute/whitewind";
4
5
+
import Link from "./ui/link";
6
7
export function PostListItem({
8
post,
9
rkey,
10
}: {
11
+
post: ComWhtwndBlogEntry.Main;
12
rkey: string;
13
viewCount?: React.ReactNode;
14
}) {
15
return (
16
+
<Link href={`/post/${rkey}`}>
17
+
{new Date(post.createdAt ?? "").toLocaleDateString()} -{" "}
18
+
{post.title?.split(" || ")[0]}
19
+
</Link>
20
);
21
}
+16
-12
src/components/post-list.tsx
+16
-12
src/components/post-list.tsx
···
12
new Date(a.value.createdAt ?? 0).getTime(),
13
);
14
15
-
return sortedPosts.map((record) => {
16
-
const post = record.value;
17
-
const rkey = record.uri.split("/").pop() || "";
18
-
return (
19
-
<PostListItem
20
-
key={record.uri}
21
-
post={post}
22
-
rkey={rkey}
23
-
viewCount={<ViewCount path={`/post/${rkey}`} />}
24
-
/>
25
-
);
26
-
});
27
}
···
12
new Date(a.value.createdAt ?? 0).getTime(),
13
);
14
15
+
return (
16
+
<div className="flex flex-col">
17
+
{sortedPosts.map((record) => {
18
+
const post = record.value;
19
+
const rkey = record.uri.split("/").pop() || "";
20
+
return (
21
+
<PostListItem
22
+
key={record.uri}
23
+
post={post}
24
+
rkey={rkey}
25
+
viewCount={<ViewCount path={`/post/${rkey}`} />}
26
+
/>
27
+
);
28
+
})}
29
+
</div>
30
+
);
31
}
+241
src/components/ui/carousel.tsx
+241
src/components/ui/carousel.tsx
···
···
1
+
"use client"
2
+
3
+
import * as React from "react"
4
+
import useEmblaCarousel, {
5
+
type UseEmblaCarouselType,
6
+
} from "embla-carousel-react"
7
+
import { ArrowLeft, ArrowRight } from "lucide-react"
8
+
9
+
import { cn } from "#/lib/utils"
10
+
import { Button } from "#/components/ui/button"
11
+
12
+
type CarouselApi = UseEmblaCarouselType[1]
13
+
type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
14
+
type CarouselOptions = UseCarouselParameters[0]
15
+
type CarouselPlugin = UseCarouselParameters[1]
16
+
17
+
type CarouselProps = {
18
+
opts?: CarouselOptions
19
+
plugins?: CarouselPlugin
20
+
orientation?: "horizontal" | "vertical"
21
+
setApi?: (api: CarouselApi) => void
22
+
}
23
+
24
+
type CarouselContextProps = {
25
+
carouselRef: ReturnType<typeof useEmblaCarousel>[0]
26
+
api: ReturnType<typeof useEmblaCarousel>[1]
27
+
scrollPrev: () => void
28
+
scrollNext: () => void
29
+
canScrollPrev: boolean
30
+
canScrollNext: boolean
31
+
} & CarouselProps
32
+
33
+
const CarouselContext = React.createContext<CarouselContextProps | null>(null)
34
+
35
+
function useCarousel() {
36
+
const context = React.useContext(CarouselContext)
37
+
38
+
if (!context) {
39
+
throw new Error("useCarousel must be used within a <Carousel />")
40
+
}
41
+
42
+
return context
43
+
}
44
+
45
+
function Carousel({
46
+
orientation = "horizontal",
47
+
opts,
48
+
setApi,
49
+
plugins,
50
+
className,
51
+
children,
52
+
...props
53
+
}: React.ComponentProps<"div"> & CarouselProps) {
54
+
const [carouselRef, api] = useEmblaCarousel(
55
+
{
56
+
...opts,
57
+
axis: orientation === "horizontal" ? "x" : "y",
58
+
},
59
+
plugins
60
+
)
61
+
const [canScrollPrev, setCanScrollPrev] = React.useState(false)
62
+
const [canScrollNext, setCanScrollNext] = React.useState(false)
63
+
64
+
const onSelect = React.useCallback((api: CarouselApi) => {
65
+
if (!api) return
66
+
setCanScrollPrev(api.canScrollPrev())
67
+
setCanScrollNext(api.canScrollNext())
68
+
}, [])
69
+
70
+
const scrollPrev = React.useCallback(() => {
71
+
api?.scrollPrev()
72
+
}, [api])
73
+
74
+
const scrollNext = React.useCallback(() => {
75
+
api?.scrollNext()
76
+
}, [api])
77
+
78
+
const handleKeyDown = React.useCallback(
79
+
(event: React.KeyboardEvent<HTMLDivElement>) => {
80
+
if (event.key === "ArrowLeft") {
81
+
event.preventDefault()
82
+
scrollPrev()
83
+
} else if (event.key === "ArrowRight") {
84
+
event.preventDefault()
85
+
scrollNext()
86
+
}
87
+
},
88
+
[scrollPrev, scrollNext]
89
+
)
90
+
91
+
React.useEffect(() => {
92
+
if (!api || !setApi) return
93
+
setApi(api)
94
+
}, [api, setApi])
95
+
96
+
React.useEffect(() => {
97
+
if (!api) return
98
+
onSelect(api)
99
+
api.on("reInit", onSelect)
100
+
api.on("select", onSelect)
101
+
102
+
return () => {
103
+
api?.off("select", onSelect)
104
+
}
105
+
}, [api, onSelect])
106
+
107
+
return (
108
+
<CarouselContext.Provider
109
+
value={{
110
+
carouselRef,
111
+
api: api,
112
+
opts,
113
+
orientation:
114
+
orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
115
+
scrollPrev,
116
+
scrollNext,
117
+
canScrollPrev,
118
+
canScrollNext,
119
+
}}
120
+
>
121
+
<div
122
+
onKeyDownCapture={handleKeyDown}
123
+
className={cn("relative", className)}
124
+
role="region"
125
+
aria-roledescription="carousel"
126
+
data-slot="carousel"
127
+
{...props}
128
+
>
129
+
{children}
130
+
</div>
131
+
</CarouselContext.Provider>
132
+
)
133
+
}
134
+
135
+
function CarouselContent({ className, ...props }: React.ComponentProps<"div">) {
136
+
const { carouselRef, orientation } = useCarousel()
137
+
138
+
return (
139
+
<div
140
+
ref={carouselRef}
141
+
className="overflow-hidden"
142
+
data-slot="carousel-content"
143
+
>
144
+
<div
145
+
className={cn(
146
+
"flex",
147
+
orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
148
+
className
149
+
)}
150
+
{...props}
151
+
/>
152
+
</div>
153
+
)
154
+
}
155
+
156
+
function CarouselItem({ className, ...props }: React.ComponentProps<"div">) {
157
+
const { orientation } = useCarousel()
158
+
159
+
return (
160
+
<div
161
+
role="group"
162
+
aria-roledescription="slide"
163
+
data-slot="carousel-item"
164
+
className={cn(
165
+
"min-w-0 shrink-0 grow-0 basis-full",
166
+
orientation === "horizontal" ? "pl-4" : "pt-4",
167
+
className
168
+
)}
169
+
{...props}
170
+
/>
171
+
)
172
+
}
173
+
174
+
function CarouselPrevious({
175
+
className,
176
+
variant = "outline",
177
+
size = "icon",
178
+
...props
179
+
}: React.ComponentProps<typeof Button>) {
180
+
const { orientation, scrollPrev, canScrollPrev } = useCarousel()
181
+
182
+
return (
183
+
<Button
184
+
data-slot="carousel-previous"
185
+
variant={variant}
186
+
size={size}
187
+
className={cn(
188
+
"absolute size-8 rounded-full",
189
+
orientation === "horizontal"
190
+
? "top-1/2 -left-12 -translate-y-1/2"
191
+
: "-top-12 left-1/2 -translate-x-1/2 rotate-90",
192
+
className
193
+
)}
194
+
disabled={!canScrollPrev}
195
+
onClick={scrollPrev}
196
+
{...props}
197
+
>
198
+
<ArrowLeft />
199
+
<span className="sr-only">Previous slide</span>
200
+
</Button>
201
+
)
202
+
}
203
+
204
+
function CarouselNext({
205
+
className,
206
+
variant = "outline",
207
+
size = "icon",
208
+
...props
209
+
}: React.ComponentProps<typeof Button>) {
210
+
const { orientation, scrollNext, canScrollNext } = useCarousel()
211
+
212
+
return (
213
+
<Button
214
+
data-slot="carousel-next"
215
+
variant={variant}
216
+
size={size}
217
+
className={cn(
218
+
"absolute size-8 rounded-full",
219
+
orientation === "horizontal"
220
+
? "top-1/2 -right-12 -translate-y-1/2"
221
+
: "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
222
+
className
223
+
)}
224
+
disabled={!canScrollNext}
225
+
onClick={scrollNext}
226
+
{...props}
227
+
>
228
+
<ArrowRight />
229
+
<span className="sr-only">Next slide</span>
230
+
</Button>
231
+
)
232
+
}
233
+
234
+
export {
235
+
type CarouselApi,
236
+
Carousel,
237
+
CarouselContent,
238
+
CarouselItem,
239
+
CarouselPrevious,
240
+
CarouselNext,
241
+
}
+40
src/components/ui/link.tsx
+40
src/components/ui/link.tsx
···
···
1
+
import { ReactNode } from "react";
2
+
import NextLink from "next/link";
3
+
4
+
interface LinkProps {
5
+
href: string;
6
+
children: ReactNode;
7
+
target?: string;
8
+
rel?: string;
9
+
className?: string;
10
+
}
11
+
12
+
export default function Link({
13
+
href,
14
+
children,
15
+
target,
16
+
rel,
17
+
className = "",
18
+
}: LinkProps) {
19
+
const isExternal = href.startsWith("http") || href.startsWith("mailto:");
20
+
const linkClassName = `underline bg-white dark:bg-black hover:text-white hover:bg-black dark:hover:text-black dark:hover:bg-white ${className}`;
21
+
22
+
if (isExternal) {
23
+
return (
24
+
<a
25
+
href={href}
26
+
target={target || "_blank"}
27
+
rel={rel || "noopener noreferrer"}
28
+
className={linkClassName}
29
+
>
30
+
{children}
31
+
</a>
32
+
);
33
+
}
34
+
35
+
return (
36
+
<NextLink href={href} className={linkClassName}>
37
+
{children}
38
+
</NextLink>
39
+
);
40
+
}
+235
src/components/ui/shadcn-io/sliding-number/index.tsx
+235
src/components/ui/shadcn-io/sliding-number/index.tsx
···
···
1
+
'use client';
2
+
3
+
import * as React from 'react';
4
+
import {
5
+
useSpring,
6
+
useTransform,
7
+
motion,
8
+
useInView,
9
+
type MotionValue,
10
+
type SpringOptions,
11
+
type UseInViewOptions,
12
+
} from 'motion/react';
13
+
import useMeasure from 'react-use-measure';
14
+
import { cn } from '#/lib/utils';
15
+
16
+
17
+
type SlidingNumberRollerProps = {
18
+
prevValue: number;
19
+
value: number;
20
+
place: number;
21
+
transition: SpringOptions;
22
+
};
23
+
24
+
function SlidingNumberRoller({
25
+
prevValue,
26
+
value,
27
+
place,
28
+
transition,
29
+
}: SlidingNumberRollerProps) {
30
+
const startNumber = Math.floor(prevValue / place) % 10;
31
+
const targetNumber = Math.floor(value / place) % 10;
32
+
const animatedValue = useSpring(startNumber, transition);
33
+
34
+
React.useEffect(() => {
35
+
animatedValue.set(targetNumber);
36
+
}, [targetNumber, animatedValue]);
37
+
38
+
const [measureRef, { height }] = useMeasure();
39
+
40
+
return (
41
+
<span
42
+
ref={measureRef}
43
+
data-slot="sliding-number-roller"
44
+
className="relative inline-block w-[1ch] overflow-x-visible overflow-y-clip leading-none tabular-nums"
45
+
>
46
+
<span className="invisible">0</span>
47
+
{Array.from({ length: 10 }, (_, i) => (
48
+
<SlidingNumberDisplay
49
+
key={i}
50
+
motionValue={animatedValue}
51
+
number={i}
52
+
height={height}
53
+
transition={transition}
54
+
/>
55
+
))}
56
+
</span>
57
+
);
58
+
}
59
+
60
+
type SlidingNumberDisplayProps = {
61
+
motionValue: MotionValue<number>;
62
+
number: number;
63
+
height: number;
64
+
transition: SpringOptions;
65
+
};
66
+
67
+
function SlidingNumberDisplay({
68
+
motionValue,
69
+
number,
70
+
height,
71
+
transition,
72
+
}: SlidingNumberDisplayProps) {
73
+
const y = useTransform(motionValue, (latest) => {
74
+
if (!height) return 0;
75
+
const currentNumber = latest % 10;
76
+
const offset = (10 + number - currentNumber) % 10;
77
+
let translateY = offset * height;
78
+
if (offset > 5) translateY -= 10 * height;
79
+
return translateY;
80
+
});
81
+
82
+
if (!height) {
83
+
return <span className="invisible absolute">{number}</span>;
84
+
}
85
+
86
+
return (
87
+
<motion.span
88
+
data-slot="sliding-number-display"
89
+
style={{ y }}
90
+
className="absolute inset-0 flex items-center justify-center"
91
+
transition={{ ...transition, type: 'spring' }}
92
+
>
93
+
{number}
94
+
</motion.span>
95
+
);
96
+
}
97
+
98
+
type SlidingNumberProps = React.ComponentProps<'span'> & {
99
+
number: number | string;
100
+
inView?: boolean;
101
+
inViewMargin?: UseInViewOptions['margin'];
102
+
inViewOnce?: boolean;
103
+
padStart?: boolean;
104
+
decimalSeparator?: string;
105
+
decimalPlaces?: number;
106
+
transition?: SpringOptions;
107
+
};
108
+
109
+
function SlidingNumber({
110
+
ref,
111
+
number,
112
+
className,
113
+
inView = false,
114
+
inViewMargin = '0px',
115
+
inViewOnce = true,
116
+
padStart = false,
117
+
decimalSeparator = '.',
118
+
decimalPlaces = 0,
119
+
transition = {
120
+
stiffness: 200,
121
+
damping: 20,
122
+
mass: 0.4,
123
+
},
124
+
...props
125
+
}: SlidingNumberProps) {
126
+
const localRef = React.useRef<HTMLSpanElement>(null);
127
+
React.useImperativeHandle(ref, () => localRef.current!);
128
+
129
+
const inViewResult = useInView(localRef, {
130
+
once: inViewOnce,
131
+
margin: inViewMargin,
132
+
});
133
+
const isInView = !inView || inViewResult;
134
+
135
+
const prevNumberRef = React.useRef<number>(0);
136
+
137
+
const effectiveNumber = React.useMemo(
138
+
() => (!isInView ? 0 : Math.abs(Number(number))),
139
+
[number, isInView],
140
+
);
141
+
142
+
const formatNumber = React.useCallback(
143
+
(num: number) =>
144
+
decimalPlaces != null ? num.toFixed(decimalPlaces) : num.toString(),
145
+
[decimalPlaces],
146
+
);
147
+
148
+
const numberStr = formatNumber(effectiveNumber);
149
+
const [newIntStrRaw, newDecStrRaw = ''] = numberStr.split('.');
150
+
const newIntStr =
151
+
padStart && newIntStrRaw?.length === 1 ? '0' + newIntStrRaw : newIntStrRaw;
152
+
153
+
const prevFormatted = formatNumber(prevNumberRef.current);
154
+
const [prevIntStrRaw = '', prevDecStrRaw = ''] = prevFormatted.split('.');
155
+
const prevIntStr =
156
+
padStart && prevIntStrRaw.length === 1
157
+
? '0' + prevIntStrRaw
158
+
: prevIntStrRaw;
159
+
160
+
const adjustedPrevInt = React.useMemo(() => {
161
+
return prevIntStr.length > (newIntStr?.length ?? 0)
162
+
? prevIntStr.slice(-(newIntStr?.length ?? 0))
163
+
: prevIntStr.padStart(newIntStr?.length ?? 0, '0');
164
+
}, [prevIntStr, newIntStr]);
165
+
166
+
const adjustedPrevDec = React.useMemo(() => {
167
+
if (!newDecStrRaw) return '';
168
+
return prevDecStrRaw.length > newDecStrRaw.length
169
+
? prevDecStrRaw.slice(0, newDecStrRaw.length)
170
+
: prevDecStrRaw.padEnd(newDecStrRaw.length, '0');
171
+
}, [prevDecStrRaw, newDecStrRaw]);
172
+
173
+
React.useEffect(() => {
174
+
if (isInView) prevNumberRef.current = effectiveNumber;
175
+
}, [effectiveNumber, isInView]);
176
+
177
+
const intDigitCount = newIntStr?.length ?? 0;
178
+
const intPlaces = React.useMemo(
179
+
() =>
180
+
Array.from({ length: intDigitCount }, (_, i) =>
181
+
Math.pow(10, intDigitCount - i - 1),
182
+
),
183
+
[intDigitCount],
184
+
);
185
+
const decPlaces = React.useMemo(
186
+
() =>
187
+
newDecStrRaw
188
+
? Array.from({ length: newDecStrRaw.length }, (_, i) =>
189
+
Math.pow(10, newDecStrRaw.length - i - 1),
190
+
)
191
+
: [],
192
+
[newDecStrRaw],
193
+
);
194
+
195
+
const newDecValue = newDecStrRaw ? parseInt(newDecStrRaw, 10) : 0;
196
+
const prevDecValue = adjustedPrevDec ? parseInt(adjustedPrevDec, 10) : 0;
197
+
198
+
return (
199
+
<span
200
+
ref={localRef}
201
+
data-slot="sliding-number"
202
+
className={cn('flex items-center', className)}
203
+
{...props}
204
+
>
205
+
{isInView && Number(number) < 0 && <span className="mr-1">-</span>}
206
+
207
+
{intPlaces.map((place) => (
208
+
<SlidingNumberRoller
209
+
key={`int-${place}`}
210
+
prevValue={parseInt(adjustedPrevInt, 10)}
211
+
value={parseInt(newIntStr ?? '0', 10)}
212
+
place={place}
213
+
transition={transition}
214
+
/>
215
+
))}
216
+
217
+
{newDecStrRaw && (
218
+
<>
219
+
<span>{decimalSeparator}</span>
220
+
{decPlaces.map((place) => (
221
+
<SlidingNumberRoller
222
+
key={`dec-${place}`}
223
+
prevValue={prevDecValue}
224
+
value={newDecValue}
225
+
place={place}
226
+
transition={transition}
227
+
/>
228
+
))}
229
+
</>
230
+
)}
231
+
</span>
232
+
);
233
+
}
234
+
235
+
export { SlidingNumber, type SlidingNumberProps };
+424
src/components/video-filter.tsx
+424
src/components/video-filter.tsx
···
···
1
+
"use client";
2
+
3
+
import { useCallback, useEffect, useRef, useState } from "react";
4
+
5
+
interface DitheredVideoFilterProps {
6
+
videoSrc: string;
7
+
pixelSize?: number;
8
+
ditherStrength?: number;
9
+
className?: string;
10
+
maxFPS?: number;
11
+
maxWidth?: number;
12
+
}
13
+
14
+
export default function DitheredVideoFilter({
15
+
videoSrc,
16
+
pixelSize = 4,
17
+
ditherStrength = 1,
18
+
className = "",
19
+
// maxFPS = 15, // Significantly reduced from 30fps
20
+
maxWidth = 640, // Limit maximum processing width
21
+
}: DitheredVideoFilterProps) {
22
+
const videoRef = useRef<HTMLVideoElement>(null);
23
+
const canvasRef = useRef<HTMLCanvasElement>(null);
24
+
const animationRef = useRef<number>(0);
25
+
const canvasContextRef = useRef<CanvasRenderingContext2D | null>(null);
26
+
27
+
// Reusable buffers to avoid memory allocations
28
+
const errorBufferRef = useRef<Float32Array | null>(null);
29
+
const lastDimensionsRef = useRef<{ width: number; height: number } | null>(
30
+
null,
31
+
);
32
+
33
+
// Performance optimization refs
34
+
const isProcessingRef = useRef(false);
35
+
const frameCountRef = useRef(0);
36
+
const lastTimeRef = useRef(0);
37
+
const frameSkipRef = useRef(0);
38
+
39
+
// Reduced motion support
40
+
const [reducedMotion, setReducedMotion] = useState(false);
41
+
const staticFrameRef = useRef<ImageData | null>(null);
42
+
const lastProcessedTimeRef = useRef(0);
43
+
44
+
// Error state for CORS issues
45
+
const [hasVideoError, setHasVideoError] = useState(false);
46
+
47
+
// Check for reduced motion preference
48
+
const checkReducedMotion = useCallback(() => {
49
+
if (typeof window !== "undefined") {
50
+
const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
51
+
setReducedMotion(mediaQuery.matches);
52
+
53
+
// Listen for changes to the preference
54
+
const handleChange = (e: MediaQueryListEvent) => {
55
+
setReducedMotion(e.matches);
56
+
};
57
+
58
+
mediaQuery.addEventListener("change", handleChange);
59
+
return () => mediaQuery.removeEventListener("change", handleChange);
60
+
}
61
+
return () => {};
62
+
}, []);
63
+
64
+
// Simplified dithering function with reduced memory usage
65
+
const applyDithering = useCallback(
66
+
(
67
+
imageData: ImageData,
68
+
width: number,
69
+
height: number,
70
+
useStaticPattern = false,
71
+
) => {
72
+
const data = imageData.data;
73
+
const pixelCount = width * height;
74
+
75
+
// Use a smaller buffer for error diffusion (only store grayscale values)
76
+
if (
77
+
!errorBufferRef.current ||
78
+
errorBufferRef.current.length !== pixelCount
79
+
) {
80
+
errorBufferRef.current = new Float32Array(pixelCount);
81
+
}
82
+
83
+
const errorBuffer = errorBufferRef.current;
84
+
errorBuffer.fill(0);
85
+
86
+
// Convert to grayscale and apply dithering
87
+
for (let i = 0; i < data.length; i += 4) {
88
+
const gray =
89
+
data[i] * 0.299 + data[i + 1] * 0.587 + data[i + 2] * 0.114;
90
+
const pixelIndex = i >> 2;
91
+
errorBuffer[pixelIndex] = gray;
92
+
93
+
let newPixel: number;
94
+
95
+
if (useStaticPattern) {
96
+
// For reduced motion, use a consistent pattern based on position
97
+
const x = (i / 4) % width;
98
+
const y = Math.floor(i / 4 / width);
99
+
const patternValue = (x + y) % 2;
100
+
const threshold = 128 + (patternValue - 0.5) * ditherStrength * 10;
101
+
newPixel = gray < threshold ? 0 : 255;
102
+
} else {
103
+
// Normal dithering with noise
104
+
const threshold = 128 + (Math.random() - 0.5) * ditherStrength * 20;
105
+
newPixel = gray < threshold ? 0 : 255;
106
+
}
107
+
108
+
// Set pixel directly
109
+
data[i] = data[i + 1] = data[i + 2] = newPixel;
110
+
data[i + 3] = 255;
111
+
}
112
+
113
+
return imageData;
114
+
},
115
+
[ditherStrength],
116
+
);
117
+
118
+
// Highly optimized processFrame function with aggressive frame skipping
119
+
const processFrame = useCallback(() => {
120
+
// Don't process anything if reduced motion is enabled or there's a video error
121
+
if (reducedMotion || hasVideoError) {
122
+
return;
123
+
}
124
+
125
+
const video = videoRef.current;
126
+
const canvas = canvasRef.current;
127
+
if (!video || !canvas) return;
128
+
129
+
// Prevent multiple simultaneous processing
130
+
if (isProcessingRef.current) return;
131
+
isProcessingRef.current = true;
132
+
133
+
if (video.paused || video.ended) {
134
+
isProcessingRef.current = false;
135
+
return;
136
+
}
137
+
138
+
const w = video.videoWidth;
139
+
const h = video.videoHeight;
140
+
141
+
// Check if video dimensions are available
142
+
if (w === 0 || h === 0) {
143
+
isProcessingRef.current = false;
144
+
animationRef.current = requestAnimationFrame(processFrame);
145
+
return;
146
+
}
147
+
148
+
// Aggressive frame skipping - process every 4th frame for 15fps target
149
+
frameSkipRef.current++;
150
+
if (frameSkipRef.current % 4 !== 0) {
151
+
isProcessingRef.current = false;
152
+
animationRef.current = requestAnimationFrame(processFrame);
153
+
return;
154
+
}
155
+
156
+
// Limit maximum processing resolution to reduce memory usage
157
+
const maxW = Math.min(w, maxWidth);
158
+
const maxH = Math.floor((h * maxW) / w);
159
+
160
+
// Only resize canvas if dimensions changed
161
+
if (canvas.width !== maxW || canvas.height !== maxH) {
162
+
canvas.width = maxW;
163
+
canvas.height = maxH;
164
+
canvasContextRef.current = null;
165
+
}
166
+
167
+
// Get or cache canvas context
168
+
if (!canvasContextRef.current) {
169
+
canvasContextRef.current = canvas.getContext("2d", {
170
+
willReadFrequently: true,
171
+
alpha: false, // Disable alpha for better performance
172
+
});
173
+
}
174
+
175
+
const ctx = canvasContextRef.current;
176
+
if (!ctx) {
177
+
isProcessingRef.current = false;
178
+
return;
179
+
}
180
+
181
+
// Draw video frame scaled down for pixelation (further reduced)
182
+
const scaledW = Math.floor(maxW / pixelSize);
183
+
const scaledH = Math.floor(maxH / pixelSize);
184
+
185
+
// Ensure minimum size to avoid errors
186
+
if (scaledW < 1 || scaledH < 1) {
187
+
isProcessingRef.current = false;
188
+
animationRef.current = requestAnimationFrame(processFrame);
189
+
return;
190
+
}
191
+
192
+
let imageData: ImageData;
193
+
try {
194
+
ctx.drawImage(video, 0, 0, scaledW, scaledH);
195
+
imageData = ctx.getImageData(0, 0, scaledW, scaledH);
196
+
} catch (error) {
197
+
// Handle CORS errors or other canvas manipulation issues
198
+
console.warn("Canvas manipulation blocked due to CORS policy:", error);
199
+
setHasVideoError(true);
200
+
isProcessingRef.current = false;
201
+
return;
202
+
}
203
+
204
+
// Apply dithering with reduced motion support
205
+
const dithered = applyDithering(imageData, scaledW, scaledH, reducedMotion);
206
+
ctx.putImageData(dithered, 0, 0);
207
+
208
+
// Store static frame for reduced motion
209
+
if (reducedMotion) {
210
+
staticFrameRef.current = dithered;
211
+
}
212
+
213
+
// Scale back up for pixelated effect
214
+
ctx.imageSmoothingEnabled = false;
215
+
ctx.drawImage(canvas, 0, 0, scaledW, scaledH, 0, 0, maxW, maxH);
216
+
217
+
isProcessingRef.current = false;
218
+
animationRef.current = requestAnimationFrame(processFrame);
219
+
}, [pixelSize, maxWidth, applyDithering, reducedMotion, hasVideoError]);
220
+
221
+
// Optimized event handlers with useCallback for better performance
222
+
const handlePlay = useCallback(() => {
223
+
if (!isProcessingRef.current && !reducedMotion && !hasVideoError) {
224
+
frameSkipRef.current = 0; // Reset frame skip counter
225
+
processFrame();
226
+
}
227
+
}, [processFrame, reducedMotion, hasVideoError]);
228
+
229
+
const handleLoadedMetadata = useCallback(() => {
230
+
const video = videoRef.current;
231
+
if (
232
+
video &&
233
+
!video.paused &&
234
+
!isProcessingRef.current &&
235
+
!reducedMotion &&
236
+
!hasVideoError
237
+
) {
238
+
frameSkipRef.current = 0; // Reset frame skip counter
239
+
processFrame();
240
+
}
241
+
}, [processFrame, reducedMotion, hasVideoError]);
242
+
243
+
const handleEnded = useCallback(() => {
244
+
// Video ended, restart processing for loop
245
+
const video = videoRef.current;
246
+
if (video && video.loop && !reducedMotion && !hasVideoError) {
247
+
// Reset frame counters for smooth loop
248
+
frameCountRef.current = 0;
249
+
frameSkipRef.current = 0;
250
+
// Small delay to ensure video is ready to loop
251
+
setTimeout(() => {
252
+
if (!video.paused && !isProcessingRef.current) {
253
+
processFrame();
254
+
}
255
+
}, 16); // ~1 frame at 60fps
256
+
}
257
+
}, [processFrame, reducedMotion, hasVideoError]);
258
+
259
+
// Enhanced cleanup function with memory management
260
+
const cleanup = useCallback(() => {
261
+
if (animationRef.current) {
262
+
cancelAnimationFrame(animationRef.current);
263
+
animationRef.current = 0;
264
+
}
265
+
266
+
// Clear canvas context
267
+
if (canvasContextRef.current) {
268
+
const canvas = canvasRef.current;
269
+
if (canvas) {
270
+
const ctx = canvasContextRef.current;
271
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
272
+
}
273
+
canvasContextRef.current = null;
274
+
}
275
+
276
+
// Clear error buffer to free memory
277
+
if (errorBufferRef.current) {
278
+
errorBufferRef.current = null;
279
+
}
280
+
281
+
// Reset all refs
282
+
isProcessingRef.current = false;
283
+
frameCountRef.current = 0;
284
+
frameSkipRef.current = 0;
285
+
lastTimeRef.current = 0;
286
+
lastDimensionsRef.current = null;
287
+
}, []);
288
+
289
+
// Initialize reduced motion detection
290
+
useEffect(() => {
291
+
const cleanup = checkReducedMotion();
292
+
return cleanup;
293
+
}, [checkReducedMotion]);
294
+
295
+
// Create static background for reduced motion
296
+
const createStaticBackground = useCallback(() => {
297
+
const canvas = canvasRef.current;
298
+
if (!canvas) return;
299
+
300
+
const ctx = canvas.getContext("2d");
301
+
if (!ctx) return;
302
+
303
+
// Set canvas size
304
+
const width = 640;
305
+
const height = 360;
306
+
canvas.width = width;
307
+
canvas.height = height;
308
+
309
+
// Create a static dithered pattern
310
+
const imageData = ctx.createImageData(width, height);
311
+
const data = imageData.data;
312
+
313
+
for (let i = 0; i < data.length; i += 4) {
314
+
const x = (i / 4) % width;
315
+
const y = Math.floor(i / 4 / width);
316
+
317
+
// Create a simple checkerboard pattern with some variation
318
+
const patternValue = (x + y) % 2;
319
+
const noise = Math.sin(x * 0.1) * Math.cos(y * 0.1) * 0.3;
320
+
const gray = 128 + patternValue * 50 + noise * 30;
321
+
322
+
const threshold = 128 + (patternValue - 0.5) * ditherStrength * 10;
323
+
const newPixel = gray < threshold ? 0 : 255;
324
+
325
+
data[i] = data[i + 1] = data[i + 2] = newPixel;
326
+
data[i + 3] = 255;
327
+
}
328
+
329
+
ctx.putImageData(imageData, 0, 0);
330
+
}, [ditherStrength]);
331
+
332
+
// Handle reduced motion state changes
333
+
useEffect(() => {
334
+
if (reducedMotion) {
335
+
// Stop ALL video processing and show static background
336
+
if (animationRef.current) {
337
+
cancelAnimationFrame(animationRef.current);
338
+
animationRef.current = 0;
339
+
}
340
+
isProcessingRef.current = false;
341
+
createStaticBackground();
342
+
} else {
343
+
// Resume normal processing
344
+
frameSkipRef.current = 0;
345
+
lastProcessedTimeRef.current = 0;
346
+
isProcessingRef.current = false;
347
+
if (!isProcessingRef.current) {
348
+
processFrame();
349
+
}
350
+
}
351
+
}, [reducedMotion, processFrame, createStaticBackground]);
352
+
353
+
useEffect(() => {
354
+
const video = videoRef.current;
355
+
if (!video) return;
356
+
357
+
// Add event listeners
358
+
video.addEventListener("play", handlePlay);
359
+
video.addEventListener("playing", handlePlay);
360
+
video.addEventListener("loadedmetadata", handleLoadedMetadata);
361
+
video.addEventListener("ended", handleEnded);
362
+
363
+
// Pause processing when tab becomes hidden to save memory
364
+
const handleVisibilityChange = () => {
365
+
if (document.hidden) {
366
+
cleanup();
367
+
} else if (!video.paused && !reducedMotion) {
368
+
frameSkipRef.current = 0;
369
+
processFrame();
370
+
}
371
+
};
372
+
373
+
document.addEventListener("visibilitychange", handleVisibilityChange);
374
+
375
+
return () => {
376
+
cleanup();
377
+
video.removeEventListener("play", handlePlay);
378
+
video.removeEventListener("playing", handlePlay);
379
+
video.removeEventListener("loadedmetadata", handleLoadedMetadata);
380
+
video.removeEventListener("ended", handleEnded);
381
+
document.removeEventListener("visibilitychange", handleVisibilityChange);
382
+
};
383
+
}, [
384
+
handlePlay,
385
+
handleLoadedMetadata,
386
+
handleEnded,
387
+
cleanup,
388
+
processFrame,
389
+
reducedMotion,
390
+
]);
391
+
392
+
return (
393
+
<div className={`relative ${className}`}>
394
+
<video
395
+
ref={videoRef}
396
+
src={videoSrc}
397
+
crossOrigin="anonymous"
398
+
className={`absolute inset-0 w-full h-full object-cover ${
399
+
hasVideoError ? "opacity-50" : "invisible"
400
+
} ${reducedMotion ? "reduced-motion" : ""}`}
401
+
autoPlay
402
+
loop
403
+
muted
404
+
playsInline
405
+
onError={(e) => {
406
+
console.error("Video error:", e);
407
+
setHasVideoError(true);
408
+
}}
409
+
onLoadStart={() => console.log("Video loading started")}
410
+
onLoadedMetadata={() => console.log("Video metadata loaded")}
411
+
/>
412
+
<canvas
413
+
ref={canvasRef}
414
+
className="absolute inset-0 w-full h-full object-cover"
415
+
style={{ imageRendering: "pixelated" }}
416
+
/>
417
+
{hasVideoError && (
418
+
<div className="absolute inset-0 flex items-center justify-center bg-gray-900 text-white text-sm opacity-75">
419
+
Video filter unavailable (CORS)
420
+
</div>
421
+
)}
422
+
</div>
423
+
);
424
+
}
+42
-39
src/lib/api.ts
+42
-39
src/lib/api.ts
···
1
-
import {
2
-
type ComAtprotoRepoListRecords,
3
-
type ComWhtwndBlogEntry,
4
-
} from "@atcute/client/lexicons";
5
6
-
import { NetMmattRightNow } from "../../lexiconTypes";
7
import { bsky } from "./bsky";
8
import { env } from "./env";
9
10
export async function getPosts() {
11
-
const posts = await bsky.get("com.atproto.repo.listRecords", {
12
-
params: {
13
-
repo: env.NEXT_PUBLIC_BSKY_DID,
14
-
collection: "com.whtwnd.blog.entry",
15
-
// todo: pagination
16
-
// hi this is matt from the forking realm i'm never going to implement pagination
17
-
},
18
-
});
19
-
return posts.data.records.filter(
20
-
drafts,
21
-
) as (ComAtprotoRepoListRecords.Record & {
22
-
value: ComWhtwndBlogEntry.Record;
23
})[];
24
}
25
26
export async function getLastestStatus() {
27
-
const posts = await bsky.get("com.atproto.repo.listRecords", {
28
-
params: {
29
-
repo: env.NEXT_PUBLIC_BSKY_DID,
30
-
collection: "net.mmatt.right.now",
31
-
limit: 1,
32
-
},
33
-
});
34
-
return posts.data.records[0] as ComAtprotoRepoListRecords.Record & {
35
-
value: NetMmattRightNow.Record;
36
};
37
}
38
39
export async function getStatuses() {
40
-
const posts = await bsky.get("com.atproto.repo.listRecords", {
41
-
params: {
42
-
repo: env.NEXT_PUBLIC_BSKY_DID,
43
-
collection: "net.mmatt.right.now",
44
-
// todo: pagination
45
-
// hi this is matt from the forking realm i'm never going to implement pagination
46
-
},
47
-
});
48
-
return posts.data.records as (ComAtprotoRepoListRecords.Record & {
49
-
value: NetMmattRightNow.Record;
50
})[];
51
}
52
53
function drafts(record: ComAtprotoRepoListRecords.Record) {
54
if (process.env.NODE_ENV === "development") return true;
55
-
const post = record.value as ComWhtwndBlogEntry.Record;
56
return post.visibility === "public";
57
}
58
59
export async function getPost(rkey: string) {
60
const post = await bsky.get("com.atproto.repo.getRecord", {
61
params: {
62
-
repo: env.NEXT_PUBLIC_BSKY_DID,
63
rkey: rkey,
64
collection: "com.whtwnd.blog.entry",
65
},
66
});
67
68
return post.data as ComAtprotoRepoListRecords.Record & {
69
-
value: ComWhtwndBlogEntry.Record;
70
};
71
}
···
1
+
import { type ComAtprotoRepoListRecords } from "@atcute/atproto";
2
+
import { ok } from "@atcute/client";
3
+
import { ComWhtwndBlogEntry } from "@atcute/whitewind";
4
5
+
import { Record } from "../../lexiconTypes/types/net/mmatt/right/now";
6
import { bsky } from "./bsky";
7
import { env } from "./env";
8
9
export async function getPosts() {
10
+
const posts = await ok(
11
+
bsky.get("com.atproto.repo.listRecords", {
12
+
params: {
13
+
repo: env.NEXT_PUBLIC_BSKY_DID as `did:plc:${string}`,
14
+
collection: "com.whtwnd.blog.entry",
15
+
// todo: pagination
16
+
// hi this is matt from the forking realm i'm never going to implement pagination
17
+
},
18
+
}),
19
+
);
20
+
return posts.records?.filter(drafts) as (ComAtprotoRepoListRecords.Record & {
21
+
value: ComWhtwndBlogEntry.Main;
22
})[];
23
}
24
25
export async function getLastestStatus() {
26
+
const posts = await ok(
27
+
bsky.get("com.atproto.repo.listRecords", {
28
+
params: {
29
+
repo: env.NEXT_PUBLIC_BSKY_DID as `did:plc:${string}`,
30
+
collection: "net.mmatt.right.now",
31
+
limit: 1,
32
+
},
33
+
}),
34
+
);
35
+
return posts.records[0] as ComAtprotoRepoListRecords.Record & {
36
+
value: Record;
37
};
38
}
39
40
export async function getStatuses() {
41
+
const posts = await ok(
42
+
bsky.get("com.atproto.repo.listRecords", {
43
+
params: {
44
+
repo: env.NEXT_PUBLIC_BSKY_DID as `did:plc:${string}`,
45
+
collection: "net.mmatt.right.now",
46
+
// todo: pagination
47
+
// hi this is matt from the forking realm i'm never going to implement pagination
48
+
},
49
+
}),
50
+
);
51
+
return posts.records as (ComAtprotoRepoListRecords.Record & {
52
+
value: Record;
53
})[];
54
}
55
56
function drafts(record: ComAtprotoRepoListRecords.Record) {
57
if (process.env.NODE_ENV === "development") return true;
58
+
const post = record.value as ComWhtwndBlogEntry.Main;
59
return post.visibility === "public";
60
}
61
62
export async function getPost(rkey: string) {
63
const post = await bsky.get("com.atproto.repo.getRecord", {
64
params: {
65
+
repo: env.NEXT_PUBLIC_BSKY_DID as `did:plc:${string}`,
66
rkey: rkey,
67
collection: "com.whtwnd.blog.entry",
68
},
69
});
70
71
return post.data as ComAtprotoRepoListRecords.Record & {
72
+
value: ComWhtwndBlogEntry.Main;
73
};
74
}
+2
-2
src/lib/bsky.ts
+2
-2
src/lib/bsky.ts
-8
src/lib/env.ts
-8
src/lib/env.ts
···
8
PLAUSIBLE_API_KEY: process.env.PLAUSIBLE_API_KEY,
9
NEXT_PUBLIC_BSKY_DID: process.env.NEXT_PUBLIC_BSKY_DID,
10
NEXT_PUBLIC_BSKY_PDS: process.env.NEXT_PUBLIC_BSKY_PDS,
11
-
TWILIO_ACCOUNT_SID: process.env.TWILIO_ACCOUNT_SID,
12
-
TWILIO_AUTH_TOKEN: process.env.TWILIO_AUTH_TOKEN,
13
-
TWILIO_PHONE_NUMBER: process.env.TWILIO_PHONE_NUMBER,
14
-
MY_PHONE_NUMBER: process.env.MY_PHONE_NUMBER,
15
};
16
17
// Use cleanEnv to validate and parse the environment variables
···
28
NEXT_PUBLIC_BSKY_PDS: url({
29
default: "https://evil.gay",
30
}),
31
-
TWILIO_ACCOUNT_SID: str({ default: "" }),
32
-
TWILIO_AUTH_TOKEN: str({ default: "" }),
33
-
TWILIO_PHONE_NUMBER: str({ default: "" }),
34
-
MY_PHONE_NUMBER: str({ default: "" }),
35
});
···
8
PLAUSIBLE_API_KEY: process.env.PLAUSIBLE_API_KEY,
9
NEXT_PUBLIC_BSKY_DID: process.env.NEXT_PUBLIC_BSKY_DID,
10
NEXT_PUBLIC_BSKY_PDS: process.env.NEXT_PUBLIC_BSKY_PDS,
11
};
12
13
// Use cleanEnv to validate and parse the environment variables
···
24
NEXT_PUBLIC_BSKY_PDS: url({
25
default: "https://evil.gay",
26
}),
27
});
+6
src/lib/utils.ts
+6
src/lib/utils.ts
+5
-20
tsconfig.json
+5
-20
tsconfig.json
···
1
{
2
"compilerOptions": {
3
-
"lib": [
4
-
"dom",
5
-
"dom.iterable",
6
-
"esnext"
7
-
],
8
"allowJs": true,
9
"skipLibCheck": true,
10
"strict": true,
···
22
}
23
],
24
"paths": {
25
-
"#/*": [
26
-
"./src/*"
27
-
]
28
},
29
"target": "ES2017"
30
},
31
-
"include": [
32
-
"next-env.d.ts",
33
-
"**/*.ts",
34
-
"**/*.tsx",
35
-
".next/types/**/*.ts"
36
-
],
37
-
"exclude": [
38
-
"node_modules"
39
-
],
40
-
"types": [
41
-
"@atcute/whitewind/lexicons"
42
-
]
43
}
···
1
{
2
"compilerOptions": {
3
+
"lib": ["dom", "dom.iterable", "esnext"],
4
"allowJs": true,
5
"skipLibCheck": true,
6
"strict": true,
···
18
}
19
],
20
"paths": {
21
+
"#/*": ["./src/*"]
22
},
23
"target": "ES2017"
24
},
25
+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26
+
"exclude": ["node_modules"],
27
+
"types": ["@atcute/whitewind", "@atcute/bluesky", "@atcute/atproto"]
28
}
+5
tspconfig.yaml
+5
tspconfig.yaml
+129
typelex/main.tsp
+129
typelex/main.tsp
···
···
1
+
import "@typelex/emitter";
2
+
3
+
namespace net.mmatt.right.now {
4
+
/** A personal lexicon for mmatt's statuslog. */
5
+
@rec("tid")
6
+
model Main {
7
+
/** The unix timestamp of when the status was recorded */
8
+
@required
9
+
createdAt: datetime;
10
+
/** The text of the status update */
11
+
@required
12
+
text: string;
13
+
/** The emoji of the status update */
14
+
emoji?: string;
15
+
}
16
+
}
17
+
18
+
namespace net.mmatt.vitals.rings {
19
+
@rec("tid")
20
+
model Main {
21
+
/** The unix timestamp of when the vital was recorded */
22
+
@required
23
+
createdAt: datetime;
24
+
25
+
/** The move ring value */
26
+
@required
27
+
ringsMove: integer;
28
+
/** The exercise ring value */
29
+
@required
30
+
ringsExercise: integer;
31
+
/** The stand hours ring value */
32
+
@required
33
+
ringsStandHours: integer;
34
+
35
+
/** The move goal ring value */
36
+
@required
37
+
ringsMoveGoal: integer;
38
+
/** The exercise goal ring value */
39
+
@required
40
+
ringsExerciseGoal: integer;
41
+
/** The stand hours goal ring value */
42
+
@required
43
+
ringsStandHoursGoal: integer;
44
+
45
+
/** The steps value */
46
+
@required
47
+
ringsSteps: integer;
48
+
/** The burned calories value */
49
+
@required
50
+
ringsBurnedCalories: integer;
51
+
52
+
/** The heart rate value */
53
+
@required
54
+
heartRate: integer;
55
+
}
56
+
}
57
+
58
+
namespace net.mmatt.vitals.phone {
59
+
@rec("tid")
60
+
model Main {
61
+
/** The unix timestamp of when the vital was recorded */
62
+
@required
63
+
createdAt: datetime;
64
+
/** The phone motion value */
65
+
@required
66
+
phoneMotion: string;
67
+
/** The phone volume value */
68
+
@required
69
+
phoneVolume: string;
70
+
/** The phone appearance value */
71
+
@required
72
+
phoneAppearance: string;
73
+
/** The phone brightness value */
74
+
@required
75
+
phoneBrightness: string;
76
+
/** The phone orientation value */
77
+
@required
78
+
phoneOrientation: string;
79
+
/** The phone cell bars value */
80
+
@required
81
+
phoneCellBars: string;
82
+
/** The phone cell network value */
83
+
@required
84
+
phoneCellNetwork: string;
85
+
/** The phone battery level value */
86
+
@required
87
+
phoneBatteryLevel: string;
88
+
/** The phone battery charging value */
89
+
@required
90
+
phoneBatteryCharging: string;
91
+
/** The phone OS value */
92
+
@required
93
+
phoneOs: string;
94
+
/** The phone OS version value */
95
+
@required
96
+
phoneOsVersion: string;
97
+
/** The phone model value */
98
+
@required
99
+
phoneModel: string;
100
+
}
101
+
}
102
+
103
+
namespace net.mmatt.vitals.car {
104
+
@rec("tid")
105
+
model Main {
106
+
/** The unix timestamp of when the vital was recorded */
107
+
@required
108
+
createdAt: datetime;
109
+
/** The car fuel range value in miles */
110
+
@required
111
+
carFuelRange: integer;
112
+
/** The car fuel level value in percentage (floating point string) */
113
+
@required
114
+
carPercentFuelRemaining: string;
115
+
/** The car fuel amount remaining value (floating point string) */
116
+
@required
117
+
amountRemaining: string;
118
+
/** The car traveled distance value */
119
+
@required
120
+
carTraveledDistance: integer;
121
+
122
+
/** The car make value */
123
+
carMake?: string;
124
+
/** The car model value */
125
+
carModel?: string;
126
+
/** The car year value */
127
+
carYear?: integer;
128
+
}
129
+
}