+1
env.d.ts
+1
env.d.ts
···
1
+
/// <reference types="@atcute/bluesky/lexicons" />
+20
index.html
+20
index.html
···
10
10
<div id="app"></div>
11
11
<script type="module" src="/src/main.tsx"></script>
12
12
</body>
13
+
<script>
14
+
(function () {
15
+
function getInitialColorMode() {
16
+
const persistedColorPreference = window.localStorage.getItem("theme");
17
+
const hasPersistedPreference =
18
+
typeof persistedColorPreference === "string";
19
+
if (hasPersistedPreference) {
20
+
return persistedColorPreference;
21
+
}
22
+
const mql = window.matchMedia("(prefers-color-scheme: dark)");
23
+
const hasMediaQueryPreference = typeof mql.matches === "boolean";
24
+
if (hasMediaQueryPreference) {
25
+
return mql.matches ? "dark" : "light";
26
+
}
27
+
return "light";
28
+
}
29
+
const colorMode = getInitialColorMode();
30
+
document.documentElement.className = colorMode;
31
+
})();
32
+
</script>
13
33
</html>
+12
package.json
+12
package.json
···
9
9
"preview": "vite preview"
10
10
},
11
11
"dependencies": {
12
+
"@atcute/bluesky": "^1.0.11",
13
+
"@atcute/client": "^2.0.6",
14
+
"@atcute/oauth-browser-client": "^1.0.7",
15
+
"@radix-ui/react-dialog": "^1.1.4",
16
+
"@radix-ui/react-separator": "^1.1.1",
17
+
"@radix-ui/react-slot": "^1.1.1",
18
+
"@radix-ui/react-tooltip": "^1.1.6",
19
+
"@tanstack/react-router": "^1.91.3",
12
20
"class-variance-authority": "^0.7.1",
13
21
"clsx": "^2.1.1",
22
+
"lexicons": "link:@atcute/bluesky/lexicons",
14
23
"lucide-react": "^0.469.0",
15
24
"preact": "^10.25.2",
25
+
"simple-icons": "^13.21.0",
16
26
"tailwind-merge": "^2.5.5",
17
27
"tailwindcss-animate": "^1.0.7"
18
28
},
19
29
"devDependencies": {
20
30
"@preact/preset-vite": "^2.9.3",
31
+
"@tanstack/router-devtools": "^1.91.3",
32
+
"@tanstack/router-plugin": "^1.91.1",
21
33
"@types/node": "^22.10.2",
22
34
"autoprefixer": "^10.4.20",
23
35
"postcss": "^8.4.49",
+1158
-8
pnpm-lock.yaml
+1158
-8
pnpm-lock.yaml
···
8
8
9
9
.:
10
10
dependencies:
11
+
'@atcute/bluesky':
12
+
specifier: ^1.0.11
13
+
version: 1.0.11(@atcute/client@2.0.6)
14
+
'@atcute/client':
15
+
specifier: ^2.0.6
16
+
version: 2.0.6
17
+
'@atcute/oauth-browser-client':
18
+
specifier: ^1.0.7
19
+
version: 1.0.7
20
+
'@radix-ui/react-dialog':
21
+
specifier: ^1.1.4
22
+
version: 1.1.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
23
+
'@radix-ui/react-separator':
24
+
specifier: ^1.1.1
25
+
version: 1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
26
+
'@radix-ui/react-slot':
27
+
specifier: ^1.1.1
28
+
version: 1.1.1(react@19.0.0)
29
+
'@radix-ui/react-tooltip':
30
+
specifier: ^1.1.6
31
+
version: 1.1.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
32
+
'@tanstack/react-router':
33
+
specifier: ^1.91.3
34
+
version: 1.91.3(@tanstack/router-generator@1.87.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
11
35
class-variance-authority:
12
36
specifier: ^0.7.1
13
37
version: 0.7.1
14
38
clsx:
15
39
specifier: ^2.1.1
16
40
version: 2.1.1
41
+
lexicons:
42
+
specifier: link:@atcute/bluesky/lexicons
43
+
version: link:@atcute/bluesky/lexicons
17
44
lucide-react:
18
45
specifier: ^0.469.0
19
46
version: 0.469.0(react@19.0.0)
20
47
preact:
21
48
specifier: ^10.25.2
22
49
version: 10.25.3
50
+
simple-icons:
51
+
specifier: ^13.21.0
52
+
version: 13.21.0
23
53
tailwind-merge:
24
54
specifier: ^2.5.5
25
55
version: 2.5.5
···
29
59
devDependencies:
30
60
'@preact/preset-vite':
31
61
specifier: ^2.9.3
32
-
version: 2.9.3(@babel/core@7.26.0)(preact@10.25.3)(vite@6.0.5(@types/node@22.10.2)(jiti@1.21.7)(yaml@2.6.1))
62
+
version: 2.9.3(@babel/core@7.26.0)(preact@10.25.3)(vite@6.0.5(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.6.1))
63
+
'@tanstack/router-devtools':
64
+
specifier: ^1.91.3
65
+
version: 1.91.3(@tanstack/react-router@1.91.3(@tanstack/router-generator@1.87.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(csstype@3.1.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
66
+
'@tanstack/router-plugin':
67
+
specifier: ^1.91.1
68
+
version: 1.91.1(vite@6.0.5(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.6.1))
33
69
'@types/node':
34
70
specifier: ^22.10.2
35
71
version: 22.10.2
···
47
83
version: 5.6.3
48
84
vite:
49
85
specifier: ^6.0.3
50
-
version: 6.0.5(@types/node@22.10.2)(jiti@1.21.7)(yaml@2.6.1)
86
+
version: 6.0.5(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.6.1)
51
87
52
88
packages:
53
89
···
58
94
'@ampproject/remapping@2.3.0':
59
95
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
60
96
engines: {node: '>=6.0.0'}
97
+
98
+
'@atcute/bluesky@1.0.11':
99
+
resolution: {integrity: sha512-j4wLJIzKWh0gmQZ7s5svhEVRThlzqyfstbM0qM/H1Y+ZIQESx5HtVu+390zAWzZoEKZYSyTM9+ctY39OiEGDQw==}
100
+
peerDependencies:
101
+
'@atcute/client': ^1.0.0 || ^2.0.0
102
+
103
+
'@atcute/client@2.0.6':
104
+
resolution: {integrity: sha512-mhdqEicGUx0s5HTFOLpz91rcLS9j/g63de0nmAqv7blhU3j+xBf4le54qr2YIXNfnReZI7EwLYLX/YIBez4LGA==}
105
+
106
+
'@atcute/oauth-browser-client@1.0.7':
107
+
resolution: {integrity: sha512-ikf3FscGZXYU+S0K4n9eDUMg6pS//g/Zr159+bznxO3Wn2JYBohEIxzy29OIEExXD/qAYMq9kfqvo2d0gs4JWQ==}
61
108
62
109
'@babel/code-frame@7.26.2':
63
110
resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==}
···
124
171
peerDependencies:
125
172
'@babel/core': ^7.0.0-0
126
173
174
+
'@babel/plugin-syntax-typescript@7.25.9':
175
+
resolution: {integrity: sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==}
176
+
engines: {node: '>=6.9.0'}
177
+
peerDependencies:
178
+
'@babel/core': ^7.0.0-0
179
+
127
180
'@babel/plugin-transform-react-jsx-development@7.25.9':
128
181
resolution: {integrity: sha512-9mj6rm7XVYs4mdLIpbZnHOYdpW42uoiBCTVowg7sP1thUOiANgMb4UtpRivR0pp5iL+ocvUv7X4mZgFRpJEzGw==}
129
182
engines: {node: '>=6.9.0'}
···
148
201
resolution: {integrity: sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==}
149
202
engines: {node: '>=6.9.0'}
150
203
204
+
'@esbuild/aix-ppc64@0.23.1':
205
+
resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==}
206
+
engines: {node: '>=18'}
207
+
cpu: [ppc64]
208
+
os: [aix]
209
+
151
210
'@esbuild/aix-ppc64@0.24.0':
152
211
resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==}
153
212
engines: {node: '>=18'}
154
213
cpu: [ppc64]
155
214
os: [aix]
156
215
216
+
'@esbuild/android-arm64@0.23.1':
217
+
resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==}
218
+
engines: {node: '>=18'}
219
+
cpu: [arm64]
220
+
os: [android]
221
+
157
222
'@esbuild/android-arm64@0.24.0':
158
223
resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==}
159
224
engines: {node: '>=18'}
160
225
cpu: [arm64]
161
226
os: [android]
162
227
228
+
'@esbuild/android-arm@0.23.1':
229
+
resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==}
230
+
engines: {node: '>=18'}
231
+
cpu: [arm]
232
+
os: [android]
233
+
163
234
'@esbuild/android-arm@0.24.0':
164
235
resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==}
165
236
engines: {node: '>=18'}
166
237
cpu: [arm]
167
238
os: [android]
168
239
240
+
'@esbuild/android-x64@0.23.1':
241
+
resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==}
242
+
engines: {node: '>=18'}
243
+
cpu: [x64]
244
+
os: [android]
245
+
169
246
'@esbuild/android-x64@0.24.0':
170
247
resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==}
171
248
engines: {node: '>=18'}
172
249
cpu: [x64]
173
250
os: [android]
174
251
252
+
'@esbuild/darwin-arm64@0.23.1':
253
+
resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==}
254
+
engines: {node: '>=18'}
255
+
cpu: [arm64]
256
+
os: [darwin]
257
+
175
258
'@esbuild/darwin-arm64@0.24.0':
176
259
resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==}
177
260
engines: {node: '>=18'}
178
261
cpu: [arm64]
179
262
os: [darwin]
180
263
264
+
'@esbuild/darwin-x64@0.23.1':
265
+
resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==}
266
+
engines: {node: '>=18'}
267
+
cpu: [x64]
268
+
os: [darwin]
269
+
181
270
'@esbuild/darwin-x64@0.24.0':
182
271
resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==}
183
272
engines: {node: '>=18'}
184
273
cpu: [x64]
185
274
os: [darwin]
186
275
276
+
'@esbuild/freebsd-arm64@0.23.1':
277
+
resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==}
278
+
engines: {node: '>=18'}
279
+
cpu: [arm64]
280
+
os: [freebsd]
281
+
187
282
'@esbuild/freebsd-arm64@0.24.0':
188
283
resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==}
189
284
engines: {node: '>=18'}
190
285
cpu: [arm64]
191
286
os: [freebsd]
192
287
288
+
'@esbuild/freebsd-x64@0.23.1':
289
+
resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==}
290
+
engines: {node: '>=18'}
291
+
cpu: [x64]
292
+
os: [freebsd]
293
+
193
294
'@esbuild/freebsd-x64@0.24.0':
194
295
resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==}
195
296
engines: {node: '>=18'}
196
297
cpu: [x64]
197
298
os: [freebsd]
198
299
300
+
'@esbuild/linux-arm64@0.23.1':
301
+
resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==}
302
+
engines: {node: '>=18'}
303
+
cpu: [arm64]
304
+
os: [linux]
305
+
199
306
'@esbuild/linux-arm64@0.24.0':
200
307
resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==}
201
308
engines: {node: '>=18'}
202
309
cpu: [arm64]
203
310
os: [linux]
204
311
312
+
'@esbuild/linux-arm@0.23.1':
313
+
resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==}
314
+
engines: {node: '>=18'}
315
+
cpu: [arm]
316
+
os: [linux]
317
+
205
318
'@esbuild/linux-arm@0.24.0':
206
319
resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==}
207
320
engines: {node: '>=18'}
208
321
cpu: [arm]
209
322
os: [linux]
210
323
324
+
'@esbuild/linux-ia32@0.23.1':
325
+
resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==}
326
+
engines: {node: '>=18'}
327
+
cpu: [ia32]
328
+
os: [linux]
329
+
211
330
'@esbuild/linux-ia32@0.24.0':
212
331
resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==}
213
332
engines: {node: '>=18'}
214
333
cpu: [ia32]
215
334
os: [linux]
216
335
336
+
'@esbuild/linux-loong64@0.23.1':
337
+
resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==}
338
+
engines: {node: '>=18'}
339
+
cpu: [loong64]
340
+
os: [linux]
341
+
217
342
'@esbuild/linux-loong64@0.24.0':
218
343
resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==}
219
344
engines: {node: '>=18'}
220
345
cpu: [loong64]
221
346
os: [linux]
222
347
348
+
'@esbuild/linux-mips64el@0.23.1':
349
+
resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==}
350
+
engines: {node: '>=18'}
351
+
cpu: [mips64el]
352
+
os: [linux]
353
+
223
354
'@esbuild/linux-mips64el@0.24.0':
224
355
resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==}
225
356
engines: {node: '>=18'}
226
357
cpu: [mips64el]
227
358
os: [linux]
228
359
360
+
'@esbuild/linux-ppc64@0.23.1':
361
+
resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==}
362
+
engines: {node: '>=18'}
363
+
cpu: [ppc64]
364
+
os: [linux]
365
+
229
366
'@esbuild/linux-ppc64@0.24.0':
230
367
resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==}
231
368
engines: {node: '>=18'}
232
369
cpu: [ppc64]
233
370
os: [linux]
234
371
372
+
'@esbuild/linux-riscv64@0.23.1':
373
+
resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==}
374
+
engines: {node: '>=18'}
375
+
cpu: [riscv64]
376
+
os: [linux]
377
+
235
378
'@esbuild/linux-riscv64@0.24.0':
236
379
resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==}
237
380
engines: {node: '>=18'}
238
381
cpu: [riscv64]
239
382
os: [linux]
240
383
384
+
'@esbuild/linux-s390x@0.23.1':
385
+
resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==}
386
+
engines: {node: '>=18'}
387
+
cpu: [s390x]
388
+
os: [linux]
389
+
241
390
'@esbuild/linux-s390x@0.24.0':
242
391
resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==}
243
392
engines: {node: '>=18'}
244
393
cpu: [s390x]
245
394
os: [linux]
246
395
396
+
'@esbuild/linux-x64@0.23.1':
397
+
resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==}
398
+
engines: {node: '>=18'}
399
+
cpu: [x64]
400
+
os: [linux]
401
+
247
402
'@esbuild/linux-x64@0.24.0':
248
403
resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==}
249
404
engines: {node: '>=18'}
250
405
cpu: [x64]
251
406
os: [linux]
407
+
408
+
'@esbuild/netbsd-x64@0.23.1':
409
+
resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==}
410
+
engines: {node: '>=18'}
411
+
cpu: [x64]
412
+
os: [netbsd]
252
413
253
414
'@esbuild/netbsd-x64@0.24.0':
254
415
resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==}
···
256
417
cpu: [x64]
257
418
os: [netbsd]
258
419
420
+
'@esbuild/openbsd-arm64@0.23.1':
421
+
resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==}
422
+
engines: {node: '>=18'}
423
+
cpu: [arm64]
424
+
os: [openbsd]
425
+
259
426
'@esbuild/openbsd-arm64@0.24.0':
260
427
resolution: {integrity: sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==}
261
428
engines: {node: '>=18'}
262
429
cpu: [arm64]
263
430
os: [openbsd]
264
431
432
+
'@esbuild/openbsd-x64@0.23.1':
433
+
resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==}
434
+
engines: {node: '>=18'}
435
+
cpu: [x64]
436
+
os: [openbsd]
437
+
265
438
'@esbuild/openbsd-x64@0.24.0':
266
439
resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==}
267
440
engines: {node: '>=18'}
268
441
cpu: [x64]
269
442
os: [openbsd]
443
+
444
+
'@esbuild/sunos-x64@0.23.1':
445
+
resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==}
446
+
engines: {node: '>=18'}
447
+
cpu: [x64]
448
+
os: [sunos]
270
449
271
450
'@esbuild/sunos-x64@0.24.0':
272
451
resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==}
···
274
453
cpu: [x64]
275
454
os: [sunos]
276
455
456
+
'@esbuild/win32-arm64@0.23.1':
457
+
resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==}
458
+
engines: {node: '>=18'}
459
+
cpu: [arm64]
460
+
os: [win32]
461
+
277
462
'@esbuild/win32-arm64@0.24.0':
278
463
resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==}
279
464
engines: {node: '>=18'}
280
465
cpu: [arm64]
281
466
os: [win32]
282
467
468
+
'@esbuild/win32-ia32@0.23.1':
469
+
resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==}
470
+
engines: {node: '>=18'}
471
+
cpu: [ia32]
472
+
os: [win32]
473
+
283
474
'@esbuild/win32-ia32@0.24.0':
284
475
resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==}
285
476
engines: {node: '>=18'}
286
477
cpu: [ia32]
287
478
os: [win32]
288
479
480
+
'@esbuild/win32-x64@0.23.1':
481
+
resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==}
482
+
engines: {node: '>=18'}
483
+
cpu: [x64]
484
+
os: [win32]
485
+
289
486
'@esbuild/win32-x64@0.24.0':
290
487
resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==}
291
488
engines: {node: '>=18'}
292
489
cpu: [x64]
293
490
os: [win32]
491
+
492
+
'@floating-ui/core@1.6.8':
493
+
resolution: {integrity: sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==}
494
+
495
+
'@floating-ui/dom@1.6.12':
496
+
resolution: {integrity: sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==}
497
+
498
+
'@floating-ui/react-dom@2.1.2':
499
+
resolution: {integrity: sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==}
500
+
peerDependencies:
501
+
react: '>=16.8.0'
502
+
react-dom: '>=16.8.0'
503
+
504
+
'@floating-ui/utils@0.2.8':
505
+
resolution: {integrity: sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==}
294
506
295
507
'@isaacs/cliui@8.0.2':
296
508
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
···
353
565
preact: ^10.4.0
354
566
vite: '>=2.0.0'
355
567
568
+
'@radix-ui/primitive@1.1.1':
569
+
resolution: {integrity: sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==}
570
+
571
+
'@radix-ui/react-arrow@1.1.1':
572
+
resolution: {integrity: sha512-NaVpZfmv8SKeZbn4ijN2V3jlHA9ngBG16VnIIm22nUR0Yk8KUALyBxT3KYEUnNuch9sTE8UTsS3whzBgKOL30w==}
573
+
peerDependencies:
574
+
'@types/react': '*'
575
+
'@types/react-dom': '*'
576
+
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
577
+
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
578
+
peerDependenciesMeta:
579
+
'@types/react':
580
+
optional: true
581
+
'@types/react-dom':
582
+
optional: true
583
+
584
+
'@radix-ui/react-compose-refs@1.1.1':
585
+
resolution: {integrity: sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==}
586
+
peerDependencies:
587
+
'@types/react': '*'
588
+
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
589
+
peerDependenciesMeta:
590
+
'@types/react':
591
+
optional: true
592
+
593
+
'@radix-ui/react-context@1.1.1':
594
+
resolution: {integrity: sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==}
595
+
peerDependencies:
596
+
'@types/react': '*'
597
+
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
598
+
peerDependenciesMeta:
599
+
'@types/react':
600
+
optional: true
601
+
602
+
'@radix-ui/react-dialog@1.1.4':
603
+
resolution: {integrity: sha512-Ur7EV1IwQGCyaAuyDRiOLA5JIUZxELJljF+MbM/2NC0BYwfuRrbpS30BiQBJrVruscgUkieKkqXYDOoByaxIoA==}
604
+
peerDependencies:
605
+
'@types/react': '*'
606
+
'@types/react-dom': '*'
607
+
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
608
+
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
609
+
peerDependenciesMeta:
610
+
'@types/react':
611
+
optional: true
612
+
'@types/react-dom':
613
+
optional: true
614
+
615
+
'@radix-ui/react-dismissable-layer@1.1.3':
616
+
resolution: {integrity: sha512-onrWn/72lQoEucDmJnr8uczSNTujT0vJnA/X5+3AkChVPowr8n1yvIKIabhWyMQeMvvmdpsvcyDqx3X1LEXCPg==}
617
+
peerDependencies:
618
+
'@types/react': '*'
619
+
'@types/react-dom': '*'
620
+
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
621
+
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
622
+
peerDependenciesMeta:
623
+
'@types/react':
624
+
optional: true
625
+
'@types/react-dom':
626
+
optional: true
627
+
628
+
'@radix-ui/react-focus-guards@1.1.1':
629
+
resolution: {integrity: sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==}
630
+
peerDependencies:
631
+
'@types/react': '*'
632
+
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
633
+
peerDependenciesMeta:
634
+
'@types/react':
635
+
optional: true
636
+
637
+
'@radix-ui/react-focus-scope@1.1.1':
638
+
resolution: {integrity: sha512-01omzJAYRxXdG2/he/+xy+c8a8gCydoQ1yOxnWNcRhrrBW5W+RQJ22EK1SaO8tb3WoUsuEw7mJjBozPzihDFjA==}
639
+
peerDependencies:
640
+
'@types/react': '*'
641
+
'@types/react-dom': '*'
642
+
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
643
+
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
644
+
peerDependenciesMeta:
645
+
'@types/react':
646
+
optional: true
647
+
'@types/react-dom':
648
+
optional: true
649
+
650
+
'@radix-ui/react-id@1.1.0':
651
+
resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==}
652
+
peerDependencies:
653
+
'@types/react': '*'
654
+
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
655
+
peerDependenciesMeta:
656
+
'@types/react':
657
+
optional: true
658
+
659
+
'@radix-ui/react-popper@1.2.1':
660
+
resolution: {integrity: sha512-3kn5Me69L+jv82EKRuQCXdYyf1DqHwD2U/sxoNgBGCB7K9TRc3bQamQ+5EPM9EvyPdli0W41sROd+ZU1dTCztw==}
661
+
peerDependencies:
662
+
'@types/react': '*'
663
+
'@types/react-dom': '*'
664
+
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
665
+
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
666
+
peerDependenciesMeta:
667
+
'@types/react':
668
+
optional: true
669
+
'@types/react-dom':
670
+
optional: true
671
+
672
+
'@radix-ui/react-portal@1.1.3':
673
+
resolution: {integrity: sha512-NciRqhXnGojhT93RPyDaMPfLH3ZSl4jjIFbZQ1b/vxvZEdHsBZ49wP9w8L3HzUQwep01LcWtkUvm0OVB5JAHTw==}
674
+
peerDependencies:
675
+
'@types/react': '*'
676
+
'@types/react-dom': '*'
677
+
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
678
+
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
679
+
peerDependenciesMeta:
680
+
'@types/react':
681
+
optional: true
682
+
'@types/react-dom':
683
+
optional: true
684
+
685
+
'@radix-ui/react-presence@1.1.2':
686
+
resolution: {integrity: sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==}
687
+
peerDependencies:
688
+
'@types/react': '*'
689
+
'@types/react-dom': '*'
690
+
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
691
+
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
692
+
peerDependenciesMeta:
693
+
'@types/react':
694
+
optional: true
695
+
'@types/react-dom':
696
+
optional: true
697
+
698
+
'@radix-ui/react-primitive@2.0.1':
699
+
resolution: {integrity: sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==}
700
+
peerDependencies:
701
+
'@types/react': '*'
702
+
'@types/react-dom': '*'
703
+
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
704
+
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
705
+
peerDependenciesMeta:
706
+
'@types/react':
707
+
optional: true
708
+
'@types/react-dom':
709
+
optional: true
710
+
711
+
'@radix-ui/react-separator@1.1.1':
712
+
resolution: {integrity: sha512-RRiNRSrD8iUiXriq/Y5n4/3iE8HzqgLHsusUSg5jVpU2+3tqcUFPJXHDymwEypunc2sWxDUS3UC+rkZRlHedsw==}
713
+
peerDependencies:
714
+
'@types/react': '*'
715
+
'@types/react-dom': '*'
716
+
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
717
+
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
718
+
peerDependenciesMeta:
719
+
'@types/react':
720
+
optional: true
721
+
'@types/react-dom':
722
+
optional: true
723
+
724
+
'@radix-ui/react-slot@1.1.1':
725
+
resolution: {integrity: sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==}
726
+
peerDependencies:
727
+
'@types/react': '*'
728
+
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
729
+
peerDependenciesMeta:
730
+
'@types/react':
731
+
optional: true
732
+
733
+
'@radix-ui/react-tooltip@1.1.6':
734
+
resolution: {integrity: sha512-TLB5D8QLExS1uDn7+wH/bjEmRurNMTzNrtq7IjaS4kjion9NtzsTGkvR5+i7yc9q01Pi2KMM2cN3f8UG4IvvXA==}
735
+
peerDependencies:
736
+
'@types/react': '*'
737
+
'@types/react-dom': '*'
738
+
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
739
+
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
740
+
peerDependenciesMeta:
741
+
'@types/react':
742
+
optional: true
743
+
'@types/react-dom':
744
+
optional: true
745
+
746
+
'@radix-ui/react-use-callback-ref@1.1.0':
747
+
resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==}
748
+
peerDependencies:
749
+
'@types/react': '*'
750
+
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
751
+
peerDependenciesMeta:
752
+
'@types/react':
753
+
optional: true
754
+
755
+
'@radix-ui/react-use-controllable-state@1.1.0':
756
+
resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==}
757
+
peerDependencies:
758
+
'@types/react': '*'
759
+
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
760
+
peerDependenciesMeta:
761
+
'@types/react':
762
+
optional: true
763
+
764
+
'@radix-ui/react-use-escape-keydown@1.1.0':
765
+
resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==}
766
+
peerDependencies:
767
+
'@types/react': '*'
768
+
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
769
+
peerDependenciesMeta:
770
+
'@types/react':
771
+
optional: true
772
+
773
+
'@radix-ui/react-use-layout-effect@1.1.0':
774
+
resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==}
775
+
peerDependencies:
776
+
'@types/react': '*'
777
+
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
778
+
peerDependenciesMeta:
779
+
'@types/react':
780
+
optional: true
781
+
782
+
'@radix-ui/react-use-rect@1.1.0':
783
+
resolution: {integrity: sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==}
784
+
peerDependencies:
785
+
'@types/react': '*'
786
+
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
787
+
peerDependenciesMeta:
788
+
'@types/react':
789
+
optional: true
790
+
791
+
'@radix-ui/react-use-size@1.1.0':
792
+
resolution: {integrity: sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==}
793
+
peerDependencies:
794
+
'@types/react': '*'
795
+
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
796
+
peerDependenciesMeta:
797
+
'@types/react':
798
+
optional: true
799
+
800
+
'@radix-ui/react-visually-hidden@1.1.1':
801
+
resolution: {integrity: sha512-vVfA2IZ9q/J+gEamvj761Oq1FpWgCDaNOOIfbPVp2MVPLEomUr5+Vf7kJGwQ24YxZSlQVar7Bes8kyTo5Dshpg==}
802
+
peerDependencies:
803
+
'@types/react': '*'
804
+
'@types/react-dom': '*'
805
+
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
806
+
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
807
+
peerDependenciesMeta:
808
+
'@types/react':
809
+
optional: true
810
+
'@types/react-dom':
811
+
optional: true
812
+
813
+
'@radix-ui/rect@1.1.0':
814
+
resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==}
815
+
356
816
'@rollup/pluginutils@4.2.1':
357
817
resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==}
358
818
engines: {node: '>= 8.0.0'}
···
452
912
cpu: [x64]
453
913
os: [win32]
454
914
915
+
'@tanstack/history@1.90.0':
916
+
resolution: {integrity: sha512-riNhDGm+fAwxgZRJ0J/36IZis1UDHsDCNIxfEodbw6BgTWJr0ah+G20V4HT91uBXiCqYFvX3somlfTLhS5yHDA==}
917
+
engines: {node: '>=12'}
918
+
919
+
'@tanstack/react-router@1.91.3':
920
+
resolution: {integrity: sha512-T6k50ApwcWKYjJB4VSK2WhXu/p40luynNJg5QC3oIqk24p0tLlgXIblXoTJzy7lVvDmQ4lwHCP9dBTvLy5NhVA==}
921
+
engines: {node: '>=12'}
922
+
peerDependencies:
923
+
'@tanstack/router-generator': ^1.87.7
924
+
react: '>=18'
925
+
react-dom: '>=18'
926
+
peerDependenciesMeta:
927
+
'@tanstack/router-generator':
928
+
optional: true
929
+
930
+
'@tanstack/react-store@0.6.1':
931
+
resolution: {integrity: sha512-6gOopOpPp1cAXkEyTEv6tMbAywwFunvIdCKN/SpEiButUayjXU+Q5Sp5Y3hREN3VMR4OA5+RI5SPhhJoqP9e4w==}
932
+
peerDependencies:
933
+
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
934
+
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
935
+
936
+
'@tanstack/router-devtools@1.91.3':
937
+
resolution: {integrity: sha512-b/WOhWEC7+Znh0+OrSGxl7RMCwHT5vX6fygDN1wh1yiUOjs32EJquu4c9deWzRDlF3jV6ji7XYWs1XgKXcsrww==}
938
+
engines: {node: '>=12'}
939
+
peerDependencies:
940
+
'@tanstack/react-router': ^1.91.3
941
+
react: '>=18'
942
+
react-dom: '>=18'
943
+
944
+
'@tanstack/router-generator@1.87.7':
945
+
resolution: {integrity: sha512-w9Px1C6DM0YNVXvu1VjUuZ5el0ykOeofEmEZBW83VUTzvCXFpcjPCHncU9FO9uXup8NFIxNfGz+xpwf93GoFnQ==}
946
+
engines: {node: '>=12'}
947
+
948
+
'@tanstack/router-plugin@1.91.1':
949
+
resolution: {integrity: sha512-+htKBNRKwdZjpgT0ee32oBb7gpH3o0cJUKvx74oTfZ9N5oth255pns1ka4Sa6lhC/gyvC3NLgk/lMqD7eVJejA==}
950
+
engines: {node: '>=12'}
951
+
peerDependencies:
952
+
'@rsbuild/core': '>=1.0.2'
953
+
vite: '>=5.0.0 || >=6.0.0'
954
+
webpack: '>=5.92.0'
955
+
peerDependenciesMeta:
956
+
'@rsbuild/core':
957
+
optional: true
958
+
vite:
959
+
optional: true
960
+
webpack:
961
+
optional: true
962
+
963
+
'@tanstack/store@0.6.0':
964
+
resolution: {integrity: sha512-+m2OBglsjXcLmmKOX6/9v8BDOCtyxhMmZLsRUDswOOSdIIR9mvv6i0XNKsmTh3AlYU8c1mRcodC8/Vyf+69VlQ==}
965
+
966
+
'@tanstack/virtual-file-routes@1.87.6':
967
+
resolution: {integrity: sha512-PTpeM8SHL7AJM0pJOacFvHribbUODS51qe9NsMqku4mogh6BWObY1EeVmeGnp9o3VngAEsf+rJMs2zqIVz3WFA==}
968
+
engines: {node: '>=12'}
969
+
970
+
'@types/babel__core@7.20.5':
971
+
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
972
+
973
+
'@types/babel__generator@7.6.8':
974
+
resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==}
975
+
976
+
'@types/babel__template@7.4.4':
977
+
resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==}
978
+
979
+
'@types/babel__traverse@7.20.6':
980
+
resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==}
981
+
455
982
'@types/estree@1.0.6':
456
983
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
457
984
458
985
'@types/node@22.10.2':
459
986
resolution: {integrity: sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==}
987
+
988
+
acorn@8.14.0:
989
+
resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==}
990
+
engines: {node: '>=0.4.0'}
991
+
hasBin: true
460
992
461
993
ansi-regex@5.0.1:
462
994
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
···
484
1016
arg@5.0.2:
485
1017
resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
486
1018
1019
+
aria-hidden@1.2.4:
1020
+
resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==}
1021
+
engines: {node: '>=10'}
1022
+
487
1023
autoprefixer@10.4.20:
488
1024
resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==}
489
1025
engines: {node: ^10 || ^12 || >=14}
490
1026
hasBin: true
491
1027
peerDependencies:
492
1028
postcss: ^8.1.0
1029
+
1030
+
babel-dead-code-elimination@1.0.8:
1031
+
resolution: {integrity: sha512-og6HQERk0Cmm+nTT4Od2wbPtgABXFMPaHACjbKLulZIFMkYyXZLkUGuAxdgpMJBrxyt/XFpSz++lNzjbcMnPkQ==}
493
1032
494
1033
babel-plugin-transform-hook-names@1.0.2:
495
1034
resolution: {integrity: sha512-5gafyjyyBTTdX/tQQ0hRgu4AhNHG/hqWi0ZZmg2xvs2FgRkJXzDNKBZCyoYqgFkovfDrgM8OoKg8karoUvWeCw==}
···
566
1105
engines: {node: '>=4'}
567
1106
hasBin: true
568
1107
1108
+
csstype@3.1.3:
1109
+
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
1110
+
569
1111
debug@4.4.0:
570
1112
resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==}
571
1113
engines: {node: '>=6.0'}
···
575
1117
supports-color:
576
1118
optional: true
577
1119
1120
+
detect-node-es@1.1.0:
1121
+
resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==}
1122
+
578
1123
didyoumean@1.2.2:
579
1124
resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
580
1125
···
609
1154
entities@4.5.0:
610
1155
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
611
1156
engines: {node: '>=0.12'}
1157
+
1158
+
esbuild@0.23.1:
1159
+
resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==}
1160
+
engines: {node: '>=18'}
1161
+
hasBin: true
612
1162
613
1163
esbuild@0.24.0:
614
1164
resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==}
···
652
1202
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
653
1203
engines: {node: '>=6.9.0'}
654
1204
1205
+
get-nonce@1.0.1:
1206
+
resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==}
1207
+
engines: {node: '>=6'}
1208
+
1209
+
get-tsconfig@4.8.1:
1210
+
resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==}
1211
+
655
1212
glob-parent@5.1.2:
656
1213
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
657
1214
engines: {node: '>= 6'}
···
668
1225
resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
669
1226
engines: {node: '>=4'}
670
1227
1228
+
goober@2.1.16:
1229
+
resolution: {integrity: sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==}
1230
+
peerDependencies:
1231
+
csstype: ^3.0.10
1232
+
671
1233
hasown@2.0.2:
672
1234
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
673
1235
engines: {node: '>= 0.4'}
···
775
1337
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
776
1338
hasBin: true
777
1339
1340
+
nanoid@5.0.9:
1341
+
resolution: {integrity: sha512-Aooyr6MXU6HpvvWXKoVoXwKMs/KyVakWwg7xQfv5/S/RIgJMy0Ifa45H9qqYy7pTCszrHzP21Uk4PZq2HpEM8Q==}
1342
+
engines: {node: ^18 || >=20}
1343
+
hasBin: true
1344
+
778
1345
node-html-parser@6.1.13:
779
1346
resolution: {integrity: sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==}
780
1347
···
873
1440
preact@10.25.3:
874
1441
resolution: {integrity: sha512-dzQmIFtM970z+fP9ziQ3yG4e3ULIbwZzJ734vaMVUTaKQ2+Ru1Ou/gjshOYVHCcd1rpAelC6ngjvjDXph98unQ==}
875
1442
1443
+
prettier@3.4.2:
1444
+
resolution: {integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==}
1445
+
engines: {node: '>=14'}
1446
+
hasBin: true
1447
+
876
1448
queue-microtask@1.2.3:
877
1449
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
878
1450
1451
+
react-dom@19.0.0:
1452
+
resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==}
1453
+
peerDependencies:
1454
+
react: ^19.0.0
1455
+
1456
+
react-remove-scroll-bar@2.3.8:
1457
+
resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==}
1458
+
engines: {node: '>=10'}
1459
+
peerDependencies:
1460
+
'@types/react': '*'
1461
+
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
1462
+
peerDependenciesMeta:
1463
+
'@types/react':
1464
+
optional: true
1465
+
1466
+
react-remove-scroll@2.6.2:
1467
+
resolution: {integrity: sha512-KmONPx5fnlXYJQqC62Q+lwIeAk64ws/cUw6omIumRzMRPqgnYqhSSti99nbj0Ry13bv7dF+BKn7NB+OqkdZGTw==}
1468
+
engines: {node: '>=10'}
1469
+
peerDependencies:
1470
+
'@types/react': '*'
1471
+
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
1472
+
peerDependenciesMeta:
1473
+
'@types/react':
1474
+
optional: true
1475
+
1476
+
react-style-singleton@2.2.3:
1477
+
resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==}
1478
+
engines: {node: '>=10'}
1479
+
peerDependencies:
1480
+
'@types/react': '*'
1481
+
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
1482
+
peerDependenciesMeta:
1483
+
'@types/react':
1484
+
optional: true
1485
+
879
1486
react@19.0.0:
880
1487
resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==}
881
1488
engines: {node: '>=0.10.0'}
···
887
1494
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
888
1495
engines: {node: '>=8.10.0'}
889
1496
1497
+
resolve-pkg-maps@1.0.0:
1498
+
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
1499
+
890
1500
resolve@1.22.10:
891
1501
resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==}
892
1502
engines: {node: '>= 0.4'}
···
904
1514
run-parallel@1.2.0:
905
1515
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
906
1516
1517
+
scheduler@0.25.0:
1518
+
resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==}
1519
+
907
1520
semver@6.3.1:
908
1521
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
909
1522
hasBin: true
···
920
1533
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
921
1534
engines: {node: '>=14'}
922
1535
1536
+
simple-icons@13.21.0:
1537
+
resolution: {integrity: sha512-LI5pVJPBv6oc79OMsffwb6kEqnmB8P1Cjg1crNUlhsxPETQ5UzbCKQdxU+7MW6+DD1qfPkla/vSKlLD4IfyXpQ==}
1538
+
engines: {node: '>=0.12.18'}
1539
+
923
1540
source-map-js@1.2.1:
924
1541
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
925
1542
engines: {node: '>=0.10.0'}
···
977
1594
thenify@3.3.1:
978
1595
resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
979
1596
1597
+
tiny-invariant@1.3.3:
1598
+
resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==}
1599
+
1600
+
tiny-warning@1.0.3:
1601
+
resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==}
1602
+
980
1603
to-regex-range@5.0.1:
981
1604
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
982
1605
engines: {node: '>=8.0'}
···
984
1607
ts-interface-checker@0.1.13:
985
1608
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
986
1609
1610
+
tslib@2.8.1:
1611
+
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
1612
+
1613
+
tsx@4.19.2:
1614
+
resolution: {integrity: sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==}
1615
+
engines: {node: '>=18.0.0'}
1616
+
hasBin: true
1617
+
987
1618
typescript@5.6.3:
988
1619
resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==}
989
1620
engines: {node: '>=14.17'}
···
991
1622
992
1623
undici-types@6.20.0:
993
1624
resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==}
1625
+
1626
+
unplugin@1.16.0:
1627
+
resolution: {integrity: sha512-5liCNPuJW8dqh3+DM6uNM2EI3MLLpCKp/KY+9pB5M2S2SR2qvvDHhKgBOaTWEbZTAws3CXfB0rKTIolWKL05VQ==}
1628
+
engines: {node: '>=14.0.0'}
994
1629
995
1630
update-browserslist-db@1.1.1:
996
1631
resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==}
···
998
1633
peerDependencies:
999
1634
browserslist: '>= 4.21.0'
1000
1635
1636
+
use-callback-ref@1.3.3:
1637
+
resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==}
1638
+
engines: {node: '>=10'}
1639
+
peerDependencies:
1640
+
'@types/react': '*'
1641
+
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
1642
+
peerDependenciesMeta:
1643
+
'@types/react':
1644
+
optional: true
1645
+
1646
+
use-sidecar@1.1.3:
1647
+
resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==}
1648
+
engines: {node: '>=10'}
1649
+
peerDependencies:
1650
+
'@types/react': '*'
1651
+
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
1652
+
peerDependenciesMeta:
1653
+
'@types/react':
1654
+
optional: true
1655
+
1656
+
use-sync-external-store@1.4.0:
1657
+
resolution: {integrity: sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==}
1658
+
peerDependencies:
1659
+
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
1660
+
1001
1661
util-deprecate@1.0.2:
1002
1662
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
1003
1663
···
1041
1701
yaml:
1042
1702
optional: true
1043
1703
1704
+
webpack-virtual-modules@0.6.2:
1705
+
resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==}
1706
+
1044
1707
which@2.0.2:
1045
1708
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
1046
1709
engines: {node: '>= 8'}
···
1062
1725
engines: {node: '>= 14'}
1063
1726
hasBin: true
1064
1727
1728
+
zod@3.24.1:
1729
+
resolution: {integrity: sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==}
1730
+
1065
1731
snapshots:
1066
1732
1067
1733
'@alloc/quick-lru@5.2.0': {}
···
1071
1737
'@jridgewell/gen-mapping': 0.3.8
1072
1738
'@jridgewell/trace-mapping': 0.3.25
1073
1739
1740
+
'@atcute/bluesky@1.0.11(@atcute/client@2.0.6)':
1741
+
dependencies:
1742
+
'@atcute/client': 2.0.6
1743
+
1744
+
'@atcute/client@2.0.6': {}
1745
+
1746
+
'@atcute/oauth-browser-client@1.0.7':
1747
+
dependencies:
1748
+
'@atcute/client': 2.0.6
1749
+
nanoid: 5.0.9
1750
+
1074
1751
'@babel/code-frame@7.26.2':
1075
1752
dependencies:
1076
1753
'@babel/helper-validator-identifier': 7.25.9
···
1157
1834
'@babel/core': 7.26.0
1158
1835
'@babel/helper-plugin-utils': 7.25.9
1159
1836
1837
+
'@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.26.0)':
1838
+
dependencies:
1839
+
'@babel/core': 7.26.0
1840
+
'@babel/helper-plugin-utils': 7.25.9
1841
+
1160
1842
'@babel/plugin-transform-react-jsx-development@7.25.9(@babel/core@7.26.0)':
1161
1843
dependencies:
1162
1844
'@babel/core': 7.26.0
···
1198
1880
'@babel/helper-string-parser': 7.25.9
1199
1881
'@babel/helper-validator-identifier': 7.25.9
1200
1882
1883
+
'@esbuild/aix-ppc64@0.23.1':
1884
+
optional: true
1885
+
1201
1886
'@esbuild/aix-ppc64@0.24.0':
1202
1887
optional: true
1203
1888
1889
+
'@esbuild/android-arm64@0.23.1':
1890
+
optional: true
1891
+
1204
1892
'@esbuild/android-arm64@0.24.0':
1205
1893
optional: true
1206
1894
1895
+
'@esbuild/android-arm@0.23.1':
1896
+
optional: true
1897
+
1207
1898
'@esbuild/android-arm@0.24.0':
1899
+
optional: true
1900
+
1901
+
'@esbuild/android-x64@0.23.1':
1208
1902
optional: true
1209
1903
1210
1904
'@esbuild/android-x64@0.24.0':
1211
1905
optional: true
1212
1906
1907
+
'@esbuild/darwin-arm64@0.23.1':
1908
+
optional: true
1909
+
1213
1910
'@esbuild/darwin-arm64@0.24.0':
1214
1911
optional: true
1215
1912
1913
+
'@esbuild/darwin-x64@0.23.1':
1914
+
optional: true
1915
+
1216
1916
'@esbuild/darwin-x64@0.24.0':
1917
+
optional: true
1918
+
1919
+
'@esbuild/freebsd-arm64@0.23.1':
1217
1920
optional: true
1218
1921
1219
1922
'@esbuild/freebsd-arm64@0.24.0':
1220
1923
optional: true
1221
1924
1925
+
'@esbuild/freebsd-x64@0.23.1':
1926
+
optional: true
1927
+
1222
1928
'@esbuild/freebsd-x64@0.24.0':
1223
1929
optional: true
1224
1930
1931
+
'@esbuild/linux-arm64@0.23.1':
1932
+
optional: true
1933
+
1225
1934
'@esbuild/linux-arm64@0.24.0':
1935
+
optional: true
1936
+
1937
+
'@esbuild/linux-arm@0.23.1':
1226
1938
optional: true
1227
1939
1228
1940
'@esbuild/linux-arm@0.24.0':
1229
1941
optional: true
1230
1942
1943
+
'@esbuild/linux-ia32@0.23.1':
1944
+
optional: true
1945
+
1231
1946
'@esbuild/linux-ia32@0.24.0':
1232
1947
optional: true
1233
1948
1949
+
'@esbuild/linux-loong64@0.23.1':
1950
+
optional: true
1951
+
1234
1952
'@esbuild/linux-loong64@0.24.0':
1953
+
optional: true
1954
+
1955
+
'@esbuild/linux-mips64el@0.23.1':
1235
1956
optional: true
1236
1957
1237
1958
'@esbuild/linux-mips64el@0.24.0':
1238
1959
optional: true
1239
1960
1961
+
'@esbuild/linux-ppc64@0.23.1':
1962
+
optional: true
1963
+
1240
1964
'@esbuild/linux-ppc64@0.24.0':
1241
1965
optional: true
1242
1966
1967
+
'@esbuild/linux-riscv64@0.23.1':
1968
+
optional: true
1969
+
1243
1970
'@esbuild/linux-riscv64@0.24.0':
1971
+
optional: true
1972
+
1973
+
'@esbuild/linux-s390x@0.23.1':
1244
1974
optional: true
1245
1975
1246
1976
'@esbuild/linux-s390x@0.24.0':
1247
1977
optional: true
1248
1978
1979
+
'@esbuild/linux-x64@0.23.1':
1980
+
optional: true
1981
+
1249
1982
'@esbuild/linux-x64@0.24.0':
1250
1983
optional: true
1251
1984
1985
+
'@esbuild/netbsd-x64@0.23.1':
1986
+
optional: true
1987
+
1252
1988
'@esbuild/netbsd-x64@0.24.0':
1253
1989
optional: true
1254
1990
1991
+
'@esbuild/openbsd-arm64@0.23.1':
1992
+
optional: true
1993
+
1255
1994
'@esbuild/openbsd-arm64@0.24.0':
1256
1995
optional: true
1257
1996
1997
+
'@esbuild/openbsd-x64@0.23.1':
1998
+
optional: true
1999
+
1258
2000
'@esbuild/openbsd-x64@0.24.0':
1259
2001
optional: true
1260
2002
2003
+
'@esbuild/sunos-x64@0.23.1':
2004
+
optional: true
2005
+
1261
2006
'@esbuild/sunos-x64@0.24.0':
1262
2007
optional: true
1263
2008
2009
+
'@esbuild/win32-arm64@0.23.1':
2010
+
optional: true
2011
+
1264
2012
'@esbuild/win32-arm64@0.24.0':
1265
2013
optional: true
1266
2014
2015
+
'@esbuild/win32-ia32@0.23.1':
2016
+
optional: true
2017
+
1267
2018
'@esbuild/win32-ia32@0.24.0':
1268
2019
optional: true
1269
2020
2021
+
'@esbuild/win32-x64@0.23.1':
2022
+
optional: true
2023
+
1270
2024
'@esbuild/win32-x64@0.24.0':
1271
2025
optional: true
1272
2026
2027
+
'@floating-ui/core@1.6.8':
2028
+
dependencies:
2029
+
'@floating-ui/utils': 0.2.8
2030
+
2031
+
'@floating-ui/dom@1.6.12':
2032
+
dependencies:
2033
+
'@floating-ui/core': 1.6.8
2034
+
'@floating-ui/utils': 0.2.8
2035
+
2036
+
'@floating-ui/react-dom@2.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
2037
+
dependencies:
2038
+
'@floating-ui/dom': 1.6.12
2039
+
react: 19.0.0
2040
+
react-dom: 19.0.0(react@19.0.0)
2041
+
2042
+
'@floating-ui/utils@0.2.8': {}
2043
+
1273
2044
'@isaacs/cliui@8.0.2':
1274
2045
dependencies:
1275
2046
string-width: 5.1.2
···
1311
2082
'@pkgjs/parseargs@0.11.0':
1312
2083
optional: true
1313
2084
1314
-
'@preact/preset-vite@2.9.3(@babel/core@7.26.0)(preact@10.25.3)(vite@6.0.5(@types/node@22.10.2)(jiti@1.21.7)(yaml@2.6.1))':
2085
+
'@preact/preset-vite@2.9.3(@babel/core@7.26.0)(preact@10.25.3)(vite@6.0.5(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.6.1))':
1315
2086
dependencies:
1316
2087
'@babel/code-frame': 7.26.2
1317
2088
'@babel/core': 7.26.0
1318
2089
'@babel/plugin-transform-react-jsx': 7.25.9(@babel/core@7.26.0)
1319
2090
'@babel/plugin-transform-react-jsx-development': 7.25.9(@babel/core@7.26.0)
1320
-
'@prefresh/vite': 2.4.6(preact@10.25.3)(vite@6.0.5(@types/node@22.10.2)(jiti@1.21.7)(yaml@2.6.1))
2091
+
'@prefresh/vite': 2.4.6(preact@10.25.3)(vite@6.0.5(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.6.1))
1321
2092
'@rollup/pluginutils': 4.2.1
1322
2093
babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.26.0)
1323
2094
debug: 4.4.0
···
1326
2097
node-html-parser: 6.1.13
1327
2098
source-map: 0.7.4
1328
2099
stack-trace: 1.0.0-pre2
1329
-
vite: 6.0.5(@types/node@22.10.2)(jiti@1.21.7)(yaml@2.6.1)
2100
+
vite: 6.0.5(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.6.1)
1330
2101
transitivePeerDependencies:
1331
2102
- preact
1332
2103
- supports-color
···
1339
2110
1340
2111
'@prefresh/utils@1.2.0': {}
1341
2112
1342
-
'@prefresh/vite@2.4.6(preact@10.25.3)(vite@6.0.5(@types/node@22.10.2)(jiti@1.21.7)(yaml@2.6.1))':
2113
+
'@prefresh/vite@2.4.6(preact@10.25.3)(vite@6.0.5(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.6.1))':
1343
2114
dependencies:
1344
2115
'@babel/core': 7.26.0
1345
2116
'@prefresh/babel-plugin': 0.5.1
···
1347
2118
'@prefresh/utils': 1.2.0
1348
2119
'@rollup/pluginutils': 4.2.1
1349
2120
preact: 10.25.3
1350
-
vite: 6.0.5(@types/node@22.10.2)(jiti@1.21.7)(yaml@2.6.1)
2121
+
vite: 6.0.5(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.6.1)
1351
2122
transitivePeerDependencies:
1352
2123
- supports-color
1353
2124
2125
+
'@radix-ui/primitive@1.1.1': {}
2126
+
2127
+
'@radix-ui/react-arrow@1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
2128
+
dependencies:
2129
+
'@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
2130
+
react: 19.0.0
2131
+
react-dom: 19.0.0(react@19.0.0)
2132
+
2133
+
'@radix-ui/react-compose-refs@1.1.1(react@19.0.0)':
2134
+
dependencies:
2135
+
react: 19.0.0
2136
+
2137
+
'@radix-ui/react-context@1.1.1(react@19.0.0)':
2138
+
dependencies:
2139
+
react: 19.0.0
2140
+
2141
+
'@radix-ui/react-dialog@1.1.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
2142
+
dependencies:
2143
+
'@radix-ui/primitive': 1.1.1
2144
+
'@radix-ui/react-compose-refs': 1.1.1(react@19.0.0)
2145
+
'@radix-ui/react-context': 1.1.1(react@19.0.0)
2146
+
'@radix-ui/react-dismissable-layer': 1.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
2147
+
'@radix-ui/react-focus-guards': 1.1.1(react@19.0.0)
2148
+
'@radix-ui/react-focus-scope': 1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
2149
+
'@radix-ui/react-id': 1.1.0(react@19.0.0)
2150
+
'@radix-ui/react-portal': 1.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
2151
+
'@radix-ui/react-presence': 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
2152
+
'@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
2153
+
'@radix-ui/react-slot': 1.1.1(react@19.0.0)
2154
+
'@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0)
2155
+
aria-hidden: 1.2.4
2156
+
react: 19.0.0
2157
+
react-dom: 19.0.0(react@19.0.0)
2158
+
react-remove-scroll: 2.6.2(react@19.0.0)
2159
+
2160
+
'@radix-ui/react-dismissable-layer@1.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
2161
+
dependencies:
2162
+
'@radix-ui/primitive': 1.1.1
2163
+
'@radix-ui/react-compose-refs': 1.1.1(react@19.0.0)
2164
+
'@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
2165
+
'@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0)
2166
+
'@radix-ui/react-use-escape-keydown': 1.1.0(react@19.0.0)
2167
+
react: 19.0.0
2168
+
react-dom: 19.0.0(react@19.0.0)
2169
+
2170
+
'@radix-ui/react-focus-guards@1.1.1(react@19.0.0)':
2171
+
dependencies:
2172
+
react: 19.0.0
2173
+
2174
+
'@radix-ui/react-focus-scope@1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
2175
+
dependencies:
2176
+
'@radix-ui/react-compose-refs': 1.1.1(react@19.0.0)
2177
+
'@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
2178
+
'@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0)
2179
+
react: 19.0.0
2180
+
react-dom: 19.0.0(react@19.0.0)
2181
+
2182
+
'@radix-ui/react-id@1.1.0(react@19.0.0)':
2183
+
dependencies:
2184
+
'@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0)
2185
+
react: 19.0.0
2186
+
2187
+
'@radix-ui/react-popper@1.2.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
2188
+
dependencies:
2189
+
'@floating-ui/react-dom': 2.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
2190
+
'@radix-ui/react-arrow': 1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
2191
+
'@radix-ui/react-compose-refs': 1.1.1(react@19.0.0)
2192
+
'@radix-ui/react-context': 1.1.1(react@19.0.0)
2193
+
'@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
2194
+
'@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0)
2195
+
'@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0)
2196
+
'@radix-ui/react-use-rect': 1.1.0(react@19.0.0)
2197
+
'@radix-ui/react-use-size': 1.1.0(react@19.0.0)
2198
+
'@radix-ui/rect': 1.1.0
2199
+
react: 19.0.0
2200
+
react-dom: 19.0.0(react@19.0.0)
2201
+
2202
+
'@radix-ui/react-portal@1.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
2203
+
dependencies:
2204
+
'@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
2205
+
'@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0)
2206
+
react: 19.0.0
2207
+
react-dom: 19.0.0(react@19.0.0)
2208
+
2209
+
'@radix-ui/react-presence@1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
2210
+
dependencies:
2211
+
'@radix-ui/react-compose-refs': 1.1.1(react@19.0.0)
2212
+
'@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0)
2213
+
react: 19.0.0
2214
+
react-dom: 19.0.0(react@19.0.0)
2215
+
2216
+
'@radix-ui/react-primitive@2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
2217
+
dependencies:
2218
+
'@radix-ui/react-slot': 1.1.1(react@19.0.0)
2219
+
react: 19.0.0
2220
+
react-dom: 19.0.0(react@19.0.0)
2221
+
2222
+
'@radix-ui/react-separator@1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
2223
+
dependencies:
2224
+
'@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
2225
+
react: 19.0.0
2226
+
react-dom: 19.0.0(react@19.0.0)
2227
+
2228
+
'@radix-ui/react-slot@1.1.1(react@19.0.0)':
2229
+
dependencies:
2230
+
'@radix-ui/react-compose-refs': 1.1.1(react@19.0.0)
2231
+
react: 19.0.0
2232
+
2233
+
'@radix-ui/react-tooltip@1.1.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
2234
+
dependencies:
2235
+
'@radix-ui/primitive': 1.1.1
2236
+
'@radix-ui/react-compose-refs': 1.1.1(react@19.0.0)
2237
+
'@radix-ui/react-context': 1.1.1(react@19.0.0)
2238
+
'@radix-ui/react-dismissable-layer': 1.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
2239
+
'@radix-ui/react-id': 1.1.0(react@19.0.0)
2240
+
'@radix-ui/react-popper': 1.2.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
2241
+
'@radix-ui/react-portal': 1.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
2242
+
'@radix-ui/react-presence': 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
2243
+
'@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
2244
+
'@radix-ui/react-slot': 1.1.1(react@19.0.0)
2245
+
'@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0)
2246
+
'@radix-ui/react-visually-hidden': 1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
2247
+
react: 19.0.0
2248
+
react-dom: 19.0.0(react@19.0.0)
2249
+
2250
+
'@radix-ui/react-use-callback-ref@1.1.0(react@19.0.0)':
2251
+
dependencies:
2252
+
react: 19.0.0
2253
+
2254
+
'@radix-ui/react-use-controllable-state@1.1.0(react@19.0.0)':
2255
+
dependencies:
2256
+
'@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0)
2257
+
react: 19.0.0
2258
+
2259
+
'@radix-ui/react-use-escape-keydown@1.1.0(react@19.0.0)':
2260
+
dependencies:
2261
+
'@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0)
2262
+
react: 19.0.0
2263
+
2264
+
'@radix-ui/react-use-layout-effect@1.1.0(react@19.0.0)':
2265
+
dependencies:
2266
+
react: 19.0.0
2267
+
2268
+
'@radix-ui/react-use-rect@1.1.0(react@19.0.0)':
2269
+
dependencies:
2270
+
'@radix-ui/rect': 1.1.0
2271
+
react: 19.0.0
2272
+
2273
+
'@radix-ui/react-use-size@1.1.0(react@19.0.0)':
2274
+
dependencies:
2275
+
'@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0)
2276
+
react: 19.0.0
2277
+
2278
+
'@radix-ui/react-visually-hidden@1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
2279
+
dependencies:
2280
+
'@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
2281
+
react: 19.0.0
2282
+
react-dom: 19.0.0(react@19.0.0)
2283
+
2284
+
'@radix-ui/rect@1.1.0': {}
2285
+
1354
2286
'@rollup/pluginutils@4.2.1':
1355
2287
dependencies:
1356
2288
estree-walker: 2.0.2
···
1413
2345
'@rollup/rollup-win32-x64-msvc@4.29.0':
1414
2346
optional: true
1415
2347
2348
+
'@tanstack/history@1.90.0': {}
2349
+
2350
+
'@tanstack/react-router@1.91.3(@tanstack/router-generator@1.87.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
2351
+
dependencies:
2352
+
'@tanstack/history': 1.90.0
2353
+
'@tanstack/react-store': 0.6.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
2354
+
jsesc: 3.1.0
2355
+
react: 19.0.0
2356
+
react-dom: 19.0.0(react@19.0.0)
2357
+
tiny-invariant: 1.3.3
2358
+
tiny-warning: 1.0.3
2359
+
optionalDependencies:
2360
+
'@tanstack/router-generator': 1.87.7
2361
+
2362
+
'@tanstack/react-store@0.6.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
2363
+
dependencies:
2364
+
'@tanstack/store': 0.6.0
2365
+
react: 19.0.0
2366
+
react-dom: 19.0.0(react@19.0.0)
2367
+
use-sync-external-store: 1.4.0(react@19.0.0)
2368
+
2369
+
'@tanstack/router-devtools@1.91.3(@tanstack/react-router@1.91.3(@tanstack/router-generator@1.87.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(csstype@3.1.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
2370
+
dependencies:
2371
+
'@tanstack/react-router': 1.91.3(@tanstack/router-generator@1.87.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
2372
+
clsx: 2.1.1
2373
+
goober: 2.1.16(csstype@3.1.3)
2374
+
react: 19.0.0
2375
+
react-dom: 19.0.0(react@19.0.0)
2376
+
transitivePeerDependencies:
2377
+
- csstype
2378
+
2379
+
'@tanstack/router-generator@1.87.7':
2380
+
dependencies:
2381
+
'@tanstack/virtual-file-routes': 1.87.6
2382
+
prettier: 3.4.2
2383
+
tsx: 4.19.2
2384
+
zod: 3.24.1
2385
+
2386
+
'@tanstack/router-plugin@1.91.1(vite@6.0.5(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.6.1))':
2387
+
dependencies:
2388
+
'@babel/core': 7.26.0
2389
+
'@babel/generator': 7.26.3
2390
+
'@babel/parser': 7.26.3
2391
+
'@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0)
2392
+
'@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.0)
2393
+
'@babel/template': 7.25.9
2394
+
'@babel/traverse': 7.26.4
2395
+
'@babel/types': 7.26.3
2396
+
'@tanstack/router-generator': 1.87.7
2397
+
'@tanstack/virtual-file-routes': 1.87.6
2398
+
'@types/babel__core': 7.20.5
2399
+
'@types/babel__generator': 7.6.8
2400
+
'@types/babel__template': 7.4.4
2401
+
'@types/babel__traverse': 7.20.6
2402
+
babel-dead-code-elimination: 1.0.8
2403
+
chokidar: 3.6.0
2404
+
unplugin: 1.16.0
2405
+
zod: 3.24.1
2406
+
optionalDependencies:
2407
+
vite: 6.0.5(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.6.1)
2408
+
transitivePeerDependencies:
2409
+
- supports-color
2410
+
2411
+
'@tanstack/store@0.6.0': {}
2412
+
2413
+
'@tanstack/virtual-file-routes@1.87.6': {}
2414
+
2415
+
'@types/babel__core@7.20.5':
2416
+
dependencies:
2417
+
'@babel/parser': 7.26.3
2418
+
'@babel/types': 7.26.3
2419
+
'@types/babel__generator': 7.6.8
2420
+
'@types/babel__template': 7.4.4
2421
+
'@types/babel__traverse': 7.20.6
2422
+
2423
+
'@types/babel__generator@7.6.8':
2424
+
dependencies:
2425
+
'@babel/types': 7.26.3
2426
+
2427
+
'@types/babel__template@7.4.4':
2428
+
dependencies:
2429
+
'@babel/parser': 7.26.3
2430
+
'@babel/types': 7.26.3
2431
+
2432
+
'@types/babel__traverse@7.20.6':
2433
+
dependencies:
2434
+
'@babel/types': 7.26.3
2435
+
1416
2436
'@types/estree@1.0.6': {}
1417
2437
1418
2438
'@types/node@22.10.2':
1419
2439
dependencies:
1420
2440
undici-types: 6.20.0
2441
+
2442
+
acorn@8.14.0: {}
1421
2443
1422
2444
ansi-regex@5.0.1: {}
1423
2445
···
1437
2459
picomatch: 2.3.1
1438
2460
1439
2461
arg@5.0.2: {}
2462
+
2463
+
aria-hidden@1.2.4:
2464
+
dependencies:
2465
+
tslib: 2.8.1
1440
2466
1441
2467
autoprefixer@10.4.20(postcss@8.4.49):
1442
2468
dependencies:
···
1448
2474
postcss: 8.4.49
1449
2475
postcss-value-parser: 4.2.0
1450
2476
2477
+
babel-dead-code-elimination@1.0.8:
2478
+
dependencies:
2479
+
'@babel/core': 7.26.0
2480
+
'@babel/parser': 7.26.3
2481
+
'@babel/traverse': 7.26.4
2482
+
'@babel/types': 7.26.3
2483
+
transitivePeerDependencies:
2484
+
- supports-color
2485
+
1451
2486
babel-plugin-transform-hook-names@1.0.2(@babel/core@7.26.0):
1452
2487
dependencies:
1453
2488
'@babel/core': 7.26.0
···
1523
2558
1524
2559
cssesc@3.0.0: {}
1525
2560
2561
+
csstype@3.1.3: {}
2562
+
1526
2563
debug@4.4.0:
1527
2564
dependencies:
1528
2565
ms: 2.1.3
2566
+
2567
+
detect-node-es@1.1.0: {}
1529
2568
1530
2569
didyoumean@1.2.2: {}
1531
2570
···
1559
2598
1560
2599
entities@4.5.0: {}
1561
2600
2601
+
esbuild@0.23.1:
2602
+
optionalDependencies:
2603
+
'@esbuild/aix-ppc64': 0.23.1
2604
+
'@esbuild/android-arm': 0.23.1
2605
+
'@esbuild/android-arm64': 0.23.1
2606
+
'@esbuild/android-x64': 0.23.1
2607
+
'@esbuild/darwin-arm64': 0.23.1
2608
+
'@esbuild/darwin-x64': 0.23.1
2609
+
'@esbuild/freebsd-arm64': 0.23.1
2610
+
'@esbuild/freebsd-x64': 0.23.1
2611
+
'@esbuild/linux-arm': 0.23.1
2612
+
'@esbuild/linux-arm64': 0.23.1
2613
+
'@esbuild/linux-ia32': 0.23.1
2614
+
'@esbuild/linux-loong64': 0.23.1
2615
+
'@esbuild/linux-mips64el': 0.23.1
2616
+
'@esbuild/linux-ppc64': 0.23.1
2617
+
'@esbuild/linux-riscv64': 0.23.1
2618
+
'@esbuild/linux-s390x': 0.23.1
2619
+
'@esbuild/linux-x64': 0.23.1
2620
+
'@esbuild/netbsd-x64': 0.23.1
2621
+
'@esbuild/openbsd-arm64': 0.23.1
2622
+
'@esbuild/openbsd-x64': 0.23.1
2623
+
'@esbuild/sunos-x64': 0.23.1
2624
+
'@esbuild/win32-arm64': 0.23.1
2625
+
'@esbuild/win32-ia32': 0.23.1
2626
+
'@esbuild/win32-x64': 0.23.1
2627
+
1562
2628
esbuild@0.24.0:
1563
2629
optionalDependencies:
1564
2630
'@esbuild/aix-ppc64': 0.24.0
···
1620
2686
1621
2687
gensync@1.0.0-beta.2: {}
1622
2688
2689
+
get-nonce@1.0.1: {}
2690
+
2691
+
get-tsconfig@4.8.1:
2692
+
dependencies:
2693
+
resolve-pkg-maps: 1.0.0
2694
+
1623
2695
glob-parent@5.1.2:
1624
2696
dependencies:
1625
2697
is-glob: 4.0.3
···
1638
2710
path-scurry: 1.11.1
1639
2711
1640
2712
globals@11.12.0: {}
2713
+
2714
+
goober@2.1.16(csstype@3.1.3):
2715
+
dependencies:
2716
+
csstype: 3.1.3
1641
2717
1642
2718
hasown@2.0.2:
1643
2719
dependencies:
···
1722
2798
1723
2799
nanoid@3.3.8: {}
1724
2800
2801
+
nanoid@5.0.9: {}
2802
+
1725
2803
node-html-parser@6.1.13:
1726
2804
dependencies:
1727
2805
css-select: 5.1.0
···
1798
2876
source-map-js: 1.2.1
1799
2877
1800
2878
preact@10.25.3: {}
2879
+
2880
+
prettier@3.4.2: {}
1801
2881
1802
2882
queue-microtask@1.2.3: {}
1803
2883
2884
+
react-dom@19.0.0(react@19.0.0):
2885
+
dependencies:
2886
+
react: 19.0.0
2887
+
scheduler: 0.25.0
2888
+
2889
+
react-remove-scroll-bar@2.3.8(react@19.0.0):
2890
+
dependencies:
2891
+
react: 19.0.0
2892
+
react-style-singleton: 2.2.3(react@19.0.0)
2893
+
tslib: 2.8.1
2894
+
2895
+
react-remove-scroll@2.6.2(react@19.0.0):
2896
+
dependencies:
2897
+
react: 19.0.0
2898
+
react-remove-scroll-bar: 2.3.8(react@19.0.0)
2899
+
react-style-singleton: 2.2.3(react@19.0.0)
2900
+
tslib: 2.8.1
2901
+
use-callback-ref: 1.3.3(react@19.0.0)
2902
+
use-sidecar: 1.1.3(react@19.0.0)
2903
+
2904
+
react-style-singleton@2.2.3(react@19.0.0):
2905
+
dependencies:
2906
+
get-nonce: 1.0.1
2907
+
react: 19.0.0
2908
+
tslib: 2.8.1
2909
+
1804
2910
react@19.0.0: {}
1805
2911
1806
2912
read-cache@1.0.0:
···
1810
2916
readdirp@3.6.0:
1811
2917
dependencies:
1812
2918
picomatch: 2.3.1
2919
+
2920
+
resolve-pkg-maps@1.0.0: {}
1813
2921
1814
2922
resolve@1.22.10:
1815
2923
dependencies:
···
1848
2956
dependencies:
1849
2957
queue-microtask: 1.2.3
1850
2958
2959
+
scheduler@0.25.0: {}
2960
+
1851
2961
semver@6.3.1: {}
1852
2962
1853
2963
shebang-command@2.0.0:
···
1857
2967
shebang-regex@3.0.0: {}
1858
2968
1859
2969
signal-exit@4.1.0: {}
2970
+
2971
+
simple-icons@13.21.0: {}
1860
2972
1861
2973
source-map-js@1.2.1: {}
1862
2974
···
1936
3048
thenify@3.3.1:
1937
3049
dependencies:
1938
3050
any-promise: 1.3.0
3051
+
3052
+
tiny-invariant@1.3.3: {}
3053
+
3054
+
tiny-warning@1.0.3: {}
1939
3055
1940
3056
to-regex-range@5.0.1:
1941
3057
dependencies:
···
1943
3059
1944
3060
ts-interface-checker@0.1.13: {}
1945
3061
3062
+
tslib@2.8.1: {}
3063
+
3064
+
tsx@4.19.2:
3065
+
dependencies:
3066
+
esbuild: 0.23.1
3067
+
get-tsconfig: 4.8.1
3068
+
optionalDependencies:
3069
+
fsevents: 2.3.3
3070
+
1946
3071
typescript@5.6.3: {}
1947
3072
1948
3073
undici-types@6.20.0: {}
1949
3074
3075
+
unplugin@1.16.0:
3076
+
dependencies:
3077
+
acorn: 8.14.0
3078
+
webpack-virtual-modules: 0.6.2
3079
+
1950
3080
update-browserslist-db@1.1.1(browserslist@4.24.3):
1951
3081
dependencies:
1952
3082
browserslist: 4.24.3
1953
3083
escalade: 3.2.0
1954
3084
picocolors: 1.1.1
1955
3085
3086
+
use-callback-ref@1.3.3(react@19.0.0):
3087
+
dependencies:
3088
+
react: 19.0.0
3089
+
tslib: 2.8.1
3090
+
3091
+
use-sidecar@1.1.3(react@19.0.0):
3092
+
dependencies:
3093
+
detect-node-es: 1.1.0
3094
+
react: 19.0.0
3095
+
tslib: 2.8.1
3096
+
3097
+
use-sync-external-store@1.4.0(react@19.0.0):
3098
+
dependencies:
3099
+
react: 19.0.0
3100
+
1956
3101
util-deprecate@1.0.2: {}
1957
3102
1958
-
vite@6.0.5(@types/node@22.10.2)(jiti@1.21.7)(yaml@2.6.1):
3103
+
vite@6.0.5(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.6.1):
1959
3104
dependencies:
1960
3105
esbuild: 0.24.0
1961
3106
postcss: 8.4.49
···
1964
3109
'@types/node': 22.10.2
1965
3110
fsevents: 2.3.3
1966
3111
jiti: 1.21.7
3112
+
tsx: 4.19.2
1967
3113
yaml: 2.6.1
3114
+
3115
+
webpack-virtual-modules@0.6.2: {}
1968
3116
1969
3117
which@2.0.2:
1970
3118
dependencies:
···
1985
3133
yallist@3.1.1: {}
1986
3134
1987
3135
yaml@2.6.1: {}
3136
+
3137
+
zod@3.24.1: {}
-25
src/app.css
-25
src/app.css
···
1
-
#app {
2
-
max-width: 1280px;
3
-
margin: 0 auto;
4
-
padding: 2rem;
5
-
text-align: center;
6
-
}
7
-
8
-
.logo {
9
-
height: 6em;
10
-
padding: 1.5em;
11
-
}
12
-
.logo:hover {
13
-
filter: drop-shadow(0 0 2em #646cffaa);
14
-
}
15
-
.logo.preact:hover {
16
-
filter: drop-shadow(0 0 2em #673ab8aa);
17
-
}
18
-
19
-
.card {
20
-
padding: 2em;
21
-
}
22
-
23
-
.read-the-docs {
24
-
color: #888;
25
-
}
+15
-40
src/app.tsx
+15
-40
src/app.tsx
···
1
-
import { useState } from 'preact/hooks'
2
-
import preactLogo from './assets/preact.svg'
3
-
import viteLogo from '/vite.svg'
4
-
import './app.css'
1
+
import { RouterProvider, createRouter } from "@tanstack/react-router";
5
2
6
-
export function App() {
7
-
const [count, setCount] = useState(0)
3
+
// Import the generated route tree
4
+
import { routeTree } from "./routeTree.gen";
8
5
9
-
return (
10
-
<>
11
-
<div>
12
-
<a href="https://vite.dev" target="_blank">
13
-
<img src={viteLogo} class="logo" alt="Vite logo" />
14
-
</a>
15
-
<a href="https://preactjs.com" target="_blank">
16
-
<img src={preactLogo} class="logo preact" alt="Preact logo" />
17
-
</a>
18
-
</div>
19
-
<h1>Vite + Preact</h1>
20
-
<div class="card">
21
-
<button onClick={() => setCount((count) => count + 1)}>
22
-
count is {count}
23
-
</button>
24
-
<p>
25
-
Edit <code>src/app.tsx</code> and save to test HMR
26
-
</p>
27
-
</div>
28
-
<p>
29
-
Check out{' '}
30
-
<a
31
-
href="https://preactjs.com/guide/v10/getting-started#create-a-vite-powered-preact-app"
32
-
target="_blank"
33
-
>
34
-
create-preact
35
-
</a>
36
-
, the official Preact + Vite starter
37
-
</p>
38
-
<p class="read-the-docs">
39
-
Click on the Vite and Preact logos to learn more
40
-
</p>
41
-
</>
42
-
)
6
+
// Create a new router instance
7
+
const router = createRouter({ routeTree });
8
+
9
+
// Register the router instance for type safety
10
+
declare module "@tanstack/react-router" {
11
+
interface Register {
12
+
router: typeof router;
13
+
}
14
+
}
15
+
16
+
export function App() {
17
+
return <RouterProvider router={router} />;
43
18
}
+103
src/components/repoIcons.tsx
+103
src/components/repoIcons.tsx
···
1
+
import {
2
+
ClipboardPaste,
3
+
File,
4
+
MessageSquare,
5
+
Pen,
6
+
ShieldQuestionIcon,
7
+
Star,
8
+
ThumbsUp,
9
+
Waves,
10
+
} from "lucide-react";
11
+
12
+
import {
13
+
siBluesky,
14
+
siLinkfire,
15
+
siMediafire,
16
+
SimpleIcon,
17
+
siReddit,
18
+
} from "simple-icons";
19
+
20
+
interface IconMapping {
21
+
// The icon to display, a url to an image or a component (Lucide icon)
22
+
icon: string | React.ReactNode;
23
+
// The label to display on icon hover
24
+
label: string;
25
+
}
26
+
27
+
function svgB64ify(svg: string) {
28
+
return "data:image/svg+xml;base64," + btoa(svg);
29
+
}
30
+
31
+
const iconMappings: Record<string, IconMapping> = {
32
+
"app.bsky": { icon: svgB64ify(siBluesky.svg), label: "Bluesky" },
33
+
"blue.zio.atfile": {
34
+
icon: <File />,
35
+
label: "Atfile",
36
+
},
37
+
"com.shinolabs.pinksea": {
38
+
icon: <Waves />,
39
+
label: "Pinksea",
40
+
},
41
+
"com.whtwnd.blog.entry": { icon: <Pen />, label: "Blog" },
42
+
"fyi.unravel.frontpage": {
43
+
icon: svgB64ify(siReddit.svg),
44
+
label: "Frontpage",
45
+
},
46
+
"events.smokesignal": {
47
+
icon: svgB64ify(siMediafire.svg),
48
+
label: "Smokesignal",
49
+
},
50
+
"link.pastesphere": { icon: <ClipboardPaste />, label: "Pastesphere" },
51
+
"my.skylights": { icon: <Star />, label: "Skylights" },
52
+
"social.psky": { icon: <MessageSquare />, label: "Psky" },
53
+
"xyz.statusphere": { icon: <ThumbsUp />, label: "Statusphere example app" },
54
+
};
55
+
56
+
function getIconForCollection(collection: string) {
57
+
// Find matching key in iconMappings
58
+
const matchingKey = Object.keys(iconMappings).find((key) =>
59
+
collection.includes(key),
60
+
);
61
+
return matchingKey ? iconMappings[matchingKey] : null;
62
+
}
63
+
64
+
function RepoIcons({ collections }: { collections: string[] }) {
65
+
let uniqueTypes = Array.from(
66
+
collections
67
+
.map((collection) => ({
68
+
id: collection,
69
+
Icon: getIconForCollection(collection)?.icon ?? <ShieldQuestionIcon />,
70
+
displayName: getIconForCollection(collection)?.label ?? "Unknown",
71
+
}))
72
+
.reduce((acc, current) => {
73
+
if (
74
+
!Array.from(acc.values()).some(
75
+
(item) => item.displayName === current.displayName,
76
+
)
77
+
) {
78
+
acc.set(current.displayName, current);
79
+
}
80
+
return acc;
81
+
}, new Map())
82
+
.values(),
83
+
);
84
+
// remove all unknowns
85
+
uniqueTypes = uniqueTypes.filter(
86
+
({ displayName }) => displayName !== "Unknown",
87
+
);
88
+
89
+
console.log(uniqueTypes);
90
+
return uniqueTypes.map(({ id, Icon, displayName }) => (
91
+
<div key={id}>
92
+
<div className="w-8 h-8 p-1 mr-2 rounded-full bg-neutral-500 text-white">
93
+
{typeof Icon === "string" ? (
94
+
<img src={Icon} alt={displayName} />
95
+
) : (
96
+
<>{Icon}</>
97
+
)}
98
+
</div>
99
+
</div>
100
+
));
101
+
}
102
+
103
+
export default RepoIcons;
+35
src/components/smartSearchBar.tsx
+35
src/components/smartSearchBar.tsx
···
1
+
import { Input } from "@/components/ui/input";
2
+
import { useState } from "react";
3
+
import { ArrowRight, Search } from "lucide-react";
4
+
import { useNavigate } from "@tanstack/react-router";
5
+
6
+
export function SmartSearchBar() {
7
+
const navigate = useNavigate();
8
+
const [input, setInput] = useState("");
9
+
10
+
const handleSubmit = (e: React.FormEvent) => {
11
+
e.preventDefault();
12
+
if (input.trim()) {
13
+
navigate({ to: `/at/${input}` });
14
+
// Or if you have a route defined with params:
15
+
// navigate({ to: '/at/$id', params: { id: input } });
16
+
}
17
+
};
18
+
19
+
return (
20
+
<form onSubmit={handleSubmit} className="relative w-full max-w-sm">
21
+
<Search className="absolute left-2 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
22
+
<Input
23
+
type="text"
24
+
placeholder="Search..."
25
+
value={input}
26
+
onChange={(e) => setInput(e.currentTarget.value)}
27
+
className="pl-8"
28
+
/>
29
+
<ArrowRight
30
+
className="absolute right-2 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground"
31
+
onClick={handleSubmit}
32
+
/>
33
+
</form>
34
+
);
35
+
}
+41
src/components/themeSwitcher.tsx
+41
src/components/themeSwitcher.tsx
···
1
+
"use client";
2
+
import { useTheme } from "@/providers/themeProvider";
3
+
import { useEffect, useState } from "react";
4
+
import { IconButton } from "./ui/iconButton";
5
+
import { Circle, Moon, Sun } from "lucide-react";
6
+
7
+
const other = (theme: string) => {
8
+
if (theme === "dark") {
9
+
return "light";
10
+
} else {
11
+
if (theme === "system") {
12
+
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)");
13
+
return systemTheme.matches ? "light" : "dark";
14
+
} else {
15
+
return "dark";
16
+
}
17
+
}
18
+
};
19
+
20
+
export const ColorToggle = () => {
21
+
const { theme, toggleTheme } = useTheme();
22
+
const [mounted, setMounted] = useState(false);
23
+
useEffect(() => {
24
+
setMounted(true);
25
+
}, []);
26
+
const DarkLightIcon = () => {
27
+
if (!mounted) return <Circle />;
28
+
return theme === "dark" ? <Sun /> : <Moon />;
29
+
};
30
+
return (
31
+
// tailwindcss button
32
+
<IconButton
33
+
className="flex items-center justify-center w-10 h-10 p-3 rounded-full bg-gray-200 dark:bg-gray-800 cursor-pointer hover:bg-gray-300 dark:hover:bg-gray-700"
34
+
aria-label="button"
35
+
Icon={DarkLightIcon}
36
+
onClick={() => {
37
+
toggleTheme();
38
+
}}
39
+
/>
40
+
);
41
+
};
+27
src/components/ui/iconButton.tsx
+27
src/components/ui/iconButton.tsx
···
1
+
import clsx from "clsx";
2
+
import { IconType } from "react-icons/lib";
3
+
interface IconButtonProps extends React.HTMLAttributes<HTMLButtonElement> {
4
+
className?: string;
5
+
Icon: IconType;
6
+
onClick?: () => void;
7
+
ariaLabel?: string;
8
+
disabled?: boolean;
9
+
}
10
+
11
+
export const IconButton = (props: IconButtonProps) => {
12
+
return (
13
+
// tailwindcss button
14
+
<button
15
+
className={clsx(
16
+
props.className,
17
+
"flex items-center justify-center w-10 h-10 p-3 rounded-full transition-colors duration-150 bg-gray-200 dark:bg-gray-800 cursor-pointer hover:bg-gray-300 dark:hover:bg-gray-700",
18
+
"disabled:cursor-default disabled:bg-gray-200 disabled:dark:bg-gray-800",
19
+
)}
20
+
disabled={props.disabled}
21
+
onClick={props.onClick}
22
+
aria-label={props.ariaLabel}
23
+
>
24
+
<props.Icon />
25
+
</button>
26
+
);
27
+
};
+22
src/components/ui/input.tsx
+22
src/components/ui/input.tsx
···
1
+
import * as React from "react"
2
+
3
+
import { cn } from "@/lib/utils"
4
+
5
+
const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
6
+
({ className, type, ...props }, ref) => {
7
+
return (
8
+
<input
9
+
type={type}
10
+
className={cn(
11
+
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
12
+
className
13
+
)}
14
+
ref={ref}
15
+
{...props}
16
+
/>
17
+
)
18
+
}
19
+
)
20
+
Input.displayName = "Input"
21
+
22
+
export { Input }
+29
src/components/ui/separator.tsx
+29
src/components/ui/separator.tsx
···
1
+
import * as React from "react"
2
+
import * as SeparatorPrimitive from "@radix-ui/react-separator"
3
+
4
+
import { cn } from "@/lib/utils"
5
+
6
+
const Separator = React.forwardRef<
7
+
React.ElementRef<typeof SeparatorPrimitive.Root>,
8
+
React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>
9
+
>(
10
+
(
11
+
{ className, orientation = "horizontal", decorative = true, ...props },
12
+
ref
13
+
) => (
14
+
<SeparatorPrimitive.Root
15
+
ref={ref}
16
+
decorative={decorative}
17
+
orientation={orientation}
18
+
className={cn(
19
+
"shrink-0 bg-border",
20
+
orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
21
+
className
22
+
)}
23
+
{...props}
24
+
/>
25
+
)
26
+
)
27
+
Separator.displayName = SeparatorPrimitive.Root.displayName
28
+
29
+
export { Separator }
+140
src/components/ui/sheet.tsx
+140
src/components/ui/sheet.tsx
···
1
+
"use client"
2
+
3
+
import * as React from "react"
4
+
import * as SheetPrimitive from "@radix-ui/react-dialog"
5
+
import { cva, type VariantProps } from "class-variance-authority"
6
+
import { X } from "lucide-react"
7
+
8
+
import { cn } from "@/lib/utils"
9
+
10
+
const Sheet = SheetPrimitive.Root
11
+
12
+
const SheetTrigger = SheetPrimitive.Trigger
13
+
14
+
const SheetClose = SheetPrimitive.Close
15
+
16
+
const SheetPortal = SheetPrimitive.Portal
17
+
18
+
const SheetOverlay = React.forwardRef<
19
+
React.ElementRef<typeof SheetPrimitive.Overlay>,
20
+
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
21
+
>(({ className, ...props }, ref) => (
22
+
<SheetPrimitive.Overlay
23
+
className={cn(
24
+
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
25
+
className
26
+
)}
27
+
{...props}
28
+
ref={ref}
29
+
/>
30
+
))
31
+
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName
32
+
33
+
const sheetVariants = cva(
34
+
"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
35
+
{
36
+
variants: {
37
+
side: {
38
+
top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
39
+
bottom:
40
+
"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
41
+
left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
42
+
right:
43
+
"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
44
+
},
45
+
},
46
+
defaultVariants: {
47
+
side: "right",
48
+
},
49
+
}
50
+
)
51
+
52
+
interface SheetContentProps
53
+
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
54
+
VariantProps<typeof sheetVariants> {}
55
+
56
+
const SheetContent = React.forwardRef<
57
+
React.ElementRef<typeof SheetPrimitive.Content>,
58
+
SheetContentProps
59
+
>(({ side = "right", className, children, ...props }, ref) => (
60
+
<SheetPortal>
61
+
<SheetOverlay />
62
+
<SheetPrimitive.Content
63
+
ref={ref}
64
+
className={cn(sheetVariants({ side }), className)}
65
+
{...props}
66
+
>
67
+
{children}
68
+
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
69
+
<X className="h-4 w-4" />
70
+
<span className="sr-only">Close</span>
71
+
</SheetPrimitive.Close>
72
+
</SheetPrimitive.Content>
73
+
</SheetPortal>
74
+
))
75
+
SheetContent.displayName = SheetPrimitive.Content.displayName
76
+
77
+
const SheetHeader = ({
78
+
className,
79
+
...props
80
+
}: React.HTMLAttributes<HTMLDivElement>) => (
81
+
<div
82
+
className={cn(
83
+
"flex flex-col space-y-2 text-center sm:text-left",
84
+
className
85
+
)}
86
+
{...props}
87
+
/>
88
+
)
89
+
SheetHeader.displayName = "SheetHeader"
90
+
91
+
const SheetFooter = ({
92
+
className,
93
+
...props
94
+
}: React.HTMLAttributes<HTMLDivElement>) => (
95
+
<div
96
+
className={cn(
97
+
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
98
+
className
99
+
)}
100
+
{...props}
101
+
/>
102
+
)
103
+
SheetFooter.displayName = "SheetFooter"
104
+
105
+
const SheetTitle = React.forwardRef<
106
+
React.ElementRef<typeof SheetPrimitive.Title>,
107
+
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
108
+
>(({ className, ...props }, ref) => (
109
+
<SheetPrimitive.Title
110
+
ref={ref}
111
+
className={cn("text-lg font-semibold text-foreground", className)}
112
+
{...props}
113
+
/>
114
+
))
115
+
SheetTitle.displayName = SheetPrimitive.Title.displayName
116
+
117
+
const SheetDescription = React.forwardRef<
118
+
React.ElementRef<typeof SheetPrimitive.Description>,
119
+
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
120
+
>(({ className, ...props }, ref) => (
121
+
<SheetPrimitive.Description
122
+
ref={ref}
123
+
className={cn("text-sm text-muted-foreground", className)}
124
+
{...props}
125
+
/>
126
+
))
127
+
SheetDescription.displayName = SheetPrimitive.Description.displayName
128
+
129
+
export {
130
+
Sheet,
131
+
SheetPortal,
132
+
SheetOverlay,
133
+
SheetTrigger,
134
+
SheetClose,
135
+
SheetContent,
136
+
SheetHeader,
137
+
SheetFooter,
138
+
SheetTitle,
139
+
SheetDescription,
140
+
}
+15
src/components/ui/skeleton.tsx
+15
src/components/ui/skeleton.tsx
···
1
+
import { cn } from "@/lib/utils"
2
+
3
+
function Skeleton({
4
+
className,
5
+
...props
6
+
}: React.HTMLAttributes<HTMLDivElement>) {
7
+
return (
8
+
<div
9
+
className={cn("animate-pulse rounded-md bg-muted", className)}
10
+
{...props}
11
+
/>
12
+
)
13
+
}
14
+
15
+
export { Skeleton }
+28
src/components/ui/tooltip.tsx
+28
src/components/ui/tooltip.tsx
···
1
+
import * as React from "react"
2
+
import * as TooltipPrimitive from "@radix-ui/react-tooltip"
3
+
4
+
import { cn } from "@/lib/utils"
5
+
6
+
const TooltipProvider = TooltipPrimitive.Provider
7
+
8
+
const Tooltip = TooltipPrimitive.Root
9
+
10
+
const TooltipTrigger = TooltipPrimitive.Trigger
11
+
12
+
const TooltipContent = React.forwardRef<
13
+
React.ElementRef<typeof TooltipPrimitive.Content>,
14
+
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
15
+
>(({ className, sideOffset = 4, ...props }, ref) => (
16
+
<TooltipPrimitive.Content
17
+
ref={ref}
18
+
sideOffset={sideOffset}
19
+
className={cn(
20
+
"z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
21
+
className
22
+
)}
23
+
{...props}
24
+
/>
25
+
))
26
+
TooltipContent.displayName = TooltipPrimitive.Content.displayName
27
+
28
+
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
+19
src/hooks/use-mobile.tsx
+19
src/hooks/use-mobile.tsx
···
1
+
import * as React from "react"
2
+
3
+
const MOBILE_BREAKPOINT = 768
4
+
5
+
export function useIsMobile() {
6
+
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
7
+
8
+
React.useEffect(() => {
9
+
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
10
+
const onChange = () => {
11
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
12
+
}
13
+
mql.addEventListener("change", onChange)
14
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
15
+
return () => mql.removeEventListener("change", onChange)
16
+
}, [])
17
+
18
+
return !!isMobile
19
+
}
+19
-2
src/index.css
+19
-2
src/index.css
···
1
1
@tailwind base;
2
2
@tailwind components;
3
3
@tailwind utilities;
4
+
4
5
@layer base {
5
6
:root {
6
7
--background: 0 0% 100%;
···
27
28
--chart-3: 197 37% 24%;
28
29
--chart-4: 43 74% 66%;
29
30
--chart-5: 27 87% 67%;
30
-
--radius: 0.5rem
31
+
--radius: 0.5rem;
32
+
--sidebar-background: 0 0% 98%;
33
+
--sidebar-foreground: 240 5.3% 26.1%;
34
+
--sidebar-primary: 240 5.9% 10%;
35
+
--sidebar-primary-foreground: 0 0% 98%;
36
+
--sidebar-accent: 240 4.8% 95.9%;
37
+
--sidebar-accent-foreground: 240 5.9% 10%;
38
+
--sidebar-border: 220 13% 91%;
39
+
--sidebar-ring: 217.2 91.2% 59.8%;
31
40
}
32
41
.dark {
33
42
--background: 0 0% 3.9%;
···
53
62
--chart-2: 160 60% 45%;
54
63
--chart-3: 30 80% 55%;
55
64
--chart-4: 280 65% 60%;
56
-
--chart-5: 340 75% 55%
65
+
--chart-5: 340 75% 55%;
66
+
--sidebar-background: 240 5.9% 10%;
67
+
--sidebar-foreground: 240 4.8% 95.9%;
68
+
--sidebar-primary: 224.3 76.3% 48%;
69
+
--sidebar-primary-foreground: 0 0% 100%;
70
+
--sidebar-accent: 240 3.7% 15.9%;
71
+
--sidebar-accent-foreground: 240 4.8% 95.9%;
72
+
--sidebar-border: 240 3.7% 15.9%;
73
+
--sidebar-ring: 217.2 91.2% 59.8%;
57
74
}
58
75
}
59
76
@layer base {
+4
-4
src/main.tsx
+4
-4
src/main.tsx
···
1
-
import { render } from 'preact'
2
-
import './index.css'
3
-
import { App } from './app.tsx'
1
+
import { render } from "preact";
2
+
import { App } from "./app.tsx";
3
+
import "./index.css";
4
4
5
-
render(<App />, document.getElementById('app')!)
5
+
render(<App />, document.getElementById("app")!);
+24
src/providers/qtprovider.tsx
+24
src/providers/qtprovider.tsx
···
1
+
import { XRPC, CredentialManager } from "@atcute/client";
2
+
import React from "preact/compat";
3
+
4
+
export const QtContext = React.createContext<QtClient | null>(null);
5
+
6
+
export function useXrpc(): XRPC {
7
+
const client = React.useContext(QtContext);
8
+
if (!client) {
9
+
throw new Error("useXrpc must be used within a QtProvider");
10
+
}
11
+
return client.rpc;
12
+
}
13
+
14
+
export class QtClient {
15
+
manager: CredentialManager;
16
+
rpc: XRPC;
17
+
constructor(service: URL = new URL("https://bsky.social")) {
18
+
this.manager = new CredentialManager({ service: service.toString() });
19
+
this.rpc = new XRPC({ handler: this.manager });
20
+
}
21
+
getXrpcClient() {
22
+
return this.rpc;
23
+
}
24
+
}
+52
src/providers/themeProvider.tsx
+52
src/providers/themeProvider.tsx
···
1
+
import React, { createContext, useContext, useEffect, useState } from "react";
2
+
3
+
type Theme = "dark" | "light";
4
+
5
+
type ThemeContextType = {
6
+
theme: Theme;
7
+
toggleTheme: () => void;
8
+
};
9
+
10
+
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
11
+
12
+
export function ThemeProvider({ children }: { children: React.ReactNode }) {
13
+
// Initialize with undefined to prevent hydration mismatch
14
+
const [theme, setTheme] = useState<Theme | undefined>(undefined);
15
+
16
+
useEffect(() => {
17
+
// Get initial theme on mount
18
+
const root = window.document.documentElement;
19
+
const initialColorValue = root.className as Theme;
20
+
setTheme(initialColorValue);
21
+
}, []);
22
+
23
+
useEffect(() => {
24
+
if (theme) {
25
+
// Update class and localStorage when theme changes
26
+
const root = window.document.documentElement;
27
+
root.className = theme;
28
+
localStorage.setItem("theme", theme);
29
+
}
30
+
}, [theme]);
31
+
32
+
const toggleTheme = () => {
33
+
setTheme((prev) => (prev === "light" ? "dark" : "light"));
34
+
};
35
+
36
+
// Only render children once theme is set
37
+
if (theme === undefined) return null;
38
+
39
+
return (
40
+
<ThemeContext.Provider value={{ theme, toggleTheme }}>
41
+
{children}
42
+
</ThemeContext.Provider>
43
+
);
44
+
}
45
+
46
+
export function useTheme() {
47
+
const context = useContext(ThemeContext);
48
+
if (context === undefined) {
49
+
throw new Error("useTheme must be used within a ThemeProvider");
50
+
}
51
+
return context;
52
+
}
+239
src/routeTree.gen.ts
+239
src/routeTree.gen.ts
···
1
+
/* eslint-disable */
2
+
3
+
// @ts-nocheck
4
+
5
+
// noinspection JSUnusedGlobalSymbols
6
+
7
+
// This file was automatically generated by TanStack Router.
8
+
// You should NOT make any changes in this file as it will be overwritten.
9
+
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
10
+
11
+
import { createFileRoute } from '@tanstack/react-router'
12
+
13
+
// Import Routes
14
+
15
+
import { Route as rootRoute } from './routes/__root'
16
+
17
+
// Create Virtual Routes
18
+
19
+
const AboutLazyImport = createFileRoute('/about')()
20
+
const IndexLazyImport = createFileRoute('/')()
21
+
const AtHandleLazyImport = createFileRoute('/at/$handle')()
22
+
const AtHandleCollectionLazyImport = createFileRoute(
23
+
'/at/$handle/$collection',
24
+
)()
25
+
const AtHandleCollectionRkeyLazyImport = createFileRoute(
26
+
'/at/$handle/$collection/$rkey',
27
+
)()
28
+
29
+
// Create/Update Routes
30
+
31
+
const AboutLazyRoute = AboutLazyImport.update({
32
+
id: '/about',
33
+
path: '/about',
34
+
getParentRoute: () => rootRoute,
35
+
} as any).lazy(() => import('./routes/about.lazy').then((d) => d.Route))
36
+
37
+
const IndexLazyRoute = IndexLazyImport.update({
38
+
id: '/',
39
+
path: '/',
40
+
getParentRoute: () => rootRoute,
41
+
} as any).lazy(() => import('./routes/index.lazy').then((d) => d.Route))
42
+
43
+
const AtHandleLazyRoute = AtHandleLazyImport.update({
44
+
id: '/at/$handle',
45
+
path: '/at/$handle',
46
+
getParentRoute: () => rootRoute,
47
+
} as any).lazy(() => import('./routes/at/$handle.lazy').then((d) => d.Route))
48
+
49
+
const AtHandleCollectionLazyRoute = AtHandleCollectionLazyImport.update({
50
+
id: '/$collection',
51
+
path: '/$collection',
52
+
getParentRoute: () => AtHandleLazyRoute,
53
+
} as any).lazy(() =>
54
+
import('./routes/at/$handle.$collection.lazy').then((d) => d.Route),
55
+
)
56
+
57
+
const AtHandleCollectionRkeyLazyRoute = AtHandleCollectionRkeyLazyImport.update(
58
+
{
59
+
id: '/$rkey',
60
+
path: '/$rkey',
61
+
getParentRoute: () => AtHandleCollectionLazyRoute,
62
+
} as any,
63
+
).lazy(() =>
64
+
import('./routes/at/$handle.$collection.$rkey.lazy').then((d) => d.Route),
65
+
)
66
+
67
+
// Populate the FileRoutesByPath interface
68
+
69
+
declare module '@tanstack/react-router' {
70
+
interface FileRoutesByPath {
71
+
'/': {
72
+
id: '/'
73
+
path: '/'
74
+
fullPath: '/'
75
+
preLoaderRoute: typeof IndexLazyImport
76
+
parentRoute: typeof rootRoute
77
+
}
78
+
'/about': {
79
+
id: '/about'
80
+
path: '/about'
81
+
fullPath: '/about'
82
+
preLoaderRoute: typeof AboutLazyImport
83
+
parentRoute: typeof rootRoute
84
+
}
85
+
'/at/$handle': {
86
+
id: '/at/$handle'
87
+
path: '/at/$handle'
88
+
fullPath: '/at/$handle'
89
+
preLoaderRoute: typeof AtHandleLazyImport
90
+
parentRoute: typeof rootRoute
91
+
}
92
+
'/at/$handle/$collection': {
93
+
id: '/at/$handle/$collection'
94
+
path: '/$collection'
95
+
fullPath: '/at/$handle/$collection'
96
+
preLoaderRoute: typeof AtHandleCollectionLazyImport
97
+
parentRoute: typeof AtHandleLazyImport
98
+
}
99
+
'/at/$handle/$collection/$rkey': {
100
+
id: '/at/$handle/$collection/$rkey'
101
+
path: '/$rkey'
102
+
fullPath: '/at/$handle/$collection/$rkey'
103
+
preLoaderRoute: typeof AtHandleCollectionRkeyLazyImport
104
+
parentRoute: typeof AtHandleCollectionLazyImport
105
+
}
106
+
}
107
+
}
108
+
109
+
// Create and export the route tree
110
+
111
+
interface AtHandleCollectionLazyRouteChildren {
112
+
AtHandleCollectionRkeyLazyRoute: typeof AtHandleCollectionRkeyLazyRoute
113
+
}
114
+
115
+
const AtHandleCollectionLazyRouteChildren: AtHandleCollectionLazyRouteChildren =
116
+
{
117
+
AtHandleCollectionRkeyLazyRoute: AtHandleCollectionRkeyLazyRoute,
118
+
}
119
+
120
+
const AtHandleCollectionLazyRouteWithChildren =
121
+
AtHandleCollectionLazyRoute._addFileChildren(
122
+
AtHandleCollectionLazyRouteChildren,
123
+
)
124
+
125
+
interface AtHandleLazyRouteChildren {
126
+
AtHandleCollectionLazyRoute: typeof AtHandleCollectionLazyRouteWithChildren
127
+
}
128
+
129
+
const AtHandleLazyRouteChildren: AtHandleLazyRouteChildren = {
130
+
AtHandleCollectionLazyRoute: AtHandleCollectionLazyRouteWithChildren,
131
+
}
132
+
133
+
const AtHandleLazyRouteWithChildren = AtHandleLazyRoute._addFileChildren(
134
+
AtHandleLazyRouteChildren,
135
+
)
136
+
137
+
export interface FileRoutesByFullPath {
138
+
'/': typeof IndexLazyRoute
139
+
'/about': typeof AboutLazyRoute
140
+
'/at/$handle': typeof AtHandleLazyRouteWithChildren
141
+
'/at/$handle/$collection': typeof AtHandleCollectionLazyRouteWithChildren
142
+
'/at/$handle/$collection/$rkey': typeof AtHandleCollectionRkeyLazyRoute
143
+
}
144
+
145
+
export interface FileRoutesByTo {
146
+
'/': typeof IndexLazyRoute
147
+
'/about': typeof AboutLazyRoute
148
+
'/at/$handle': typeof AtHandleLazyRouteWithChildren
149
+
'/at/$handle/$collection': typeof AtHandleCollectionLazyRouteWithChildren
150
+
'/at/$handle/$collection/$rkey': typeof AtHandleCollectionRkeyLazyRoute
151
+
}
152
+
153
+
export interface FileRoutesById {
154
+
__root__: typeof rootRoute
155
+
'/': typeof IndexLazyRoute
156
+
'/about': typeof AboutLazyRoute
157
+
'/at/$handle': typeof AtHandleLazyRouteWithChildren
158
+
'/at/$handle/$collection': typeof AtHandleCollectionLazyRouteWithChildren
159
+
'/at/$handle/$collection/$rkey': typeof AtHandleCollectionRkeyLazyRoute
160
+
}
161
+
162
+
export interface FileRouteTypes {
163
+
fileRoutesByFullPath: FileRoutesByFullPath
164
+
fullPaths:
165
+
| '/'
166
+
| '/about'
167
+
| '/at/$handle'
168
+
| '/at/$handle/$collection'
169
+
| '/at/$handle/$collection/$rkey'
170
+
fileRoutesByTo: FileRoutesByTo
171
+
to:
172
+
| '/'
173
+
| '/about'
174
+
| '/at/$handle'
175
+
| '/at/$handle/$collection'
176
+
| '/at/$handle/$collection/$rkey'
177
+
id:
178
+
| '__root__'
179
+
| '/'
180
+
| '/about'
181
+
| '/at/$handle'
182
+
| '/at/$handle/$collection'
183
+
| '/at/$handle/$collection/$rkey'
184
+
fileRoutesById: FileRoutesById
185
+
}
186
+
187
+
export interface RootRouteChildren {
188
+
IndexLazyRoute: typeof IndexLazyRoute
189
+
AboutLazyRoute: typeof AboutLazyRoute
190
+
AtHandleLazyRoute: typeof AtHandleLazyRouteWithChildren
191
+
}
192
+
193
+
const rootRouteChildren: RootRouteChildren = {
194
+
IndexLazyRoute: IndexLazyRoute,
195
+
AboutLazyRoute: AboutLazyRoute,
196
+
AtHandleLazyRoute: AtHandleLazyRouteWithChildren,
197
+
}
198
+
199
+
export const routeTree = rootRoute
200
+
._addFileChildren(rootRouteChildren)
201
+
._addFileTypes<FileRouteTypes>()
202
+
203
+
/* ROUTE_MANIFEST_START
204
+
{
205
+
"routes": {
206
+
"__root__": {
207
+
"filePath": "__root.tsx",
208
+
"children": [
209
+
"/",
210
+
"/about",
211
+
"/at/$handle"
212
+
]
213
+
},
214
+
"/": {
215
+
"filePath": "index.lazy.tsx"
216
+
},
217
+
"/about": {
218
+
"filePath": "about.lazy.tsx"
219
+
},
220
+
"/at/$handle": {
221
+
"filePath": "at/$handle.lazy.tsx",
222
+
"children": [
223
+
"/at/$handle/$collection"
224
+
]
225
+
},
226
+
"/at/$handle/$collection": {
227
+
"filePath": "at/$handle.$collection.lazy.tsx",
228
+
"parent": "/at/$handle",
229
+
"children": [
230
+
"/at/$handle/$collection/$rkey"
231
+
]
232
+
},
233
+
"/at/$handle/$collection/$rkey": {
234
+
"filePath": "at/$handle.$collection.$rkey.lazy.tsx",
235
+
"parent": "/at/$handle/$collection"
236
+
}
237
+
}
238
+
}
239
+
ROUTE_MANIFEST_END */
+23
src/routes/__root.tsx
+23
src/routes/__root.tsx
···
1
+
import { AppSidebar } from "@/components/sidebar";
2
+
import { SidebarProvider } from "@/components/ui/sidebar";
3
+
import { QtClient, QtContext } from "@/providers/qtprovider";
4
+
import { ThemeProvider } from "@/providers/themeProvider";
5
+
import { createRootRoute, Link, Outlet } from "@tanstack/react-router";
6
+
import { TanStackRouterDevtools } from "@tanstack/router-devtools";
7
+
8
+
// It's the layout component
9
+
export const Route = createRootRoute({
10
+
component: () => (
11
+
<>
12
+
<ThemeProvider>
13
+
<QtContext.Provider value={new QtClient()}>
14
+
<SidebarProvider>
15
+
<AppSidebar />
16
+
<Outlet />
17
+
</SidebarProvider>
18
+
</QtContext.Provider>
19
+
</ThemeProvider>
20
+
<TanStackRouterDevtools />
21
+
</>
22
+
),
23
+
});
+9
src/routes/about.lazy.tsx
+9
src/routes/about.lazy.tsx
+9
src/routes/at/$handle.$collection.$rkey.lazy.tsx
+9
src/routes/at/$handle.$collection.$rkey.lazy.tsx
+9
src/routes/at/$handle.$collection.lazy.tsx
+9
src/routes/at/$handle.$collection.lazy.tsx
+172
src/routes/at/$handle.lazy.tsx
+172
src/routes/at/$handle.lazy.tsx
···
1
+
import RepoIcons from "@/components/repoIcons";
2
+
import { QtClient, useXrpc } from "@/providers/qtprovider";
3
+
import "@atcute/bluesky/lexicons";
4
+
import {
5
+
AppBskyActorGetProfile,
6
+
ComAtprotoRepoDescribeRepo,
7
+
} from "@atcute/client/lexicons";
8
+
import {
9
+
IdentityMetadata,
10
+
resolveFromIdentity,
11
+
resolveHandle,
12
+
} from "@atcute/oauth-browser-client";
13
+
import { createLazyFileRoute } from "@tanstack/react-router";
14
+
import { AtSign } from "lucide-react";
15
+
import { useState, useEffect } from "preact/compat";
16
+
17
+
interface RepoData {
18
+
data?: ComAtprotoRepoDescribeRepo.Output;
19
+
blueSkyData?: AppBskyActorGetProfile.Output | null;
20
+
identity?: IdentityMetadata;
21
+
isLoading: boolean;
22
+
error: Error | null;
23
+
}
24
+
25
+
function useRepoData(handle: string): RepoData {
26
+
const xrpc = useXrpc();
27
+
const [state, setState] = useState<RepoData>({
28
+
data: undefined,
29
+
isLoading: true,
30
+
error: null,
31
+
});
32
+
33
+
useEffect(() => {
34
+
const abortController = new AbortController();
35
+
36
+
async function fetchRepoData() {
37
+
try {
38
+
setState((prev) => ({ ...prev, isLoading: true }));
39
+
40
+
const id = await resolveFromIdentity(handle);
41
+
// we dont use the main authenticated client here
42
+
const rpc = new QtClient(id.identity.pds);
43
+
// get the PDS
44
+
const response = await rpc
45
+
.getXrpcClient()
46
+
.get("com.atproto.repo.describeRepo", {
47
+
params: { repo: id.identity.id },
48
+
signal: abortController.signal,
49
+
});
50
+
// can we get bsky data?
51
+
if (response.data.collections.includes("app.bsky.actor.profile")) {
52
+
// reuse client dumbass
53
+
const bskyData = await new QtClient(
54
+
new URL("https://public.api.bsky.app"),
55
+
)
56
+
.getXrpcClient()
57
+
.get("app.bsky.actor.getProfile", {
58
+
params: { actor: id.identity.id },
59
+
});
60
+
61
+
setState({
62
+
blueSkyData: bskyData.data,
63
+
data: response.data,
64
+
identity: id.identity,
65
+
isLoading: false,
66
+
error: null,
67
+
});
68
+
} else {
69
+
setState({
70
+
blueSkyData: null,
71
+
data: response.data,
72
+
identity: id.identity,
73
+
isLoading: false,
74
+
error: null,
75
+
});
76
+
}
77
+
// todo: actual errors
78
+
} catch (err: any) {
79
+
if (err.name === "AbortError") return;
80
+
81
+
setState({
82
+
data: undefined,
83
+
isLoading: false,
84
+
error: err instanceof Error ? err : new Error("An error occurred"),
85
+
});
86
+
}
87
+
}
88
+
89
+
fetchRepoData();
90
+
91
+
return () => {
92
+
abortController.abort();
93
+
};
94
+
}, [handle, xrpc]);
95
+
96
+
return state;
97
+
}
98
+
99
+
export const Route = createLazyFileRoute("/at/$handle")({
100
+
component: RouteComponent,
101
+
});
102
+
103
+
function RouteComponent() {
104
+
const { handle } = Route.useParams();
105
+
const { blueSkyData, data, identity, isLoading, error } = useRepoData(handle);
106
+
107
+
if (isLoading) {
108
+
return <div>Loading...</div>;
109
+
}
110
+
111
+
if (error) {
112
+
return <div>Error: {error.message}</div>;
113
+
}
114
+
115
+
return (
116
+
<div className="flex flex-row justify-center w-full min-h-screen">
117
+
<div className="max-w-2xl w-screen p-4 md:mt-16 space-y-2">
118
+
{blueSkyData ? (
119
+
blueSkyData?.banner ? (
120
+
<div className="relative mb-12 md:mb-16">
121
+
<img
122
+
src={blueSkyData?.banner}
123
+
className="w-full rounded-lg scale-[108%] lg:scale-125 -z-10 border"
124
+
/>
125
+
<img
126
+
src={blueSkyData?.avatar}
127
+
className="absolute -bottom-12 md:-bottom-16 w-24 lg:w-32 aspect-square rounded-full border"
128
+
/>
129
+
</div>
130
+
) : (
131
+
<img src={blueSkyData?.avatar} className="w-32 h-32 rounded-full" />
132
+
)
133
+
) : (
134
+
<div className="w-32 h-32 bg-neutral-500 rounded-full grid place-items-center">
135
+
<AtSign className="w-16 h-16" />
136
+
</div>
137
+
)}
138
+
<h1 className="text-2xl md:text-3xl font-bold">
139
+
{blueSkyData?.displayName}{" "}
140
+
<span className="text-muted-foreground font-normal">
141
+
@{data?.handle}
142
+
{data?.handleIsCorrect ? "" : " (invalid handle)"}
143
+
</span>
144
+
</h1>
145
+
146
+
{data?.collections && (
147
+
<div className="flex flex-row pb-2">
148
+
<RepoIcons collections={data?.collections} />
149
+
</div>
150
+
)}
151
+
<code>{data?.did}</code>
152
+
<br />
153
+
154
+
<div>
155
+
PDS: {identity?.pds.hostname.includes("bsky.network") && "🍄"}{" "}
156
+
{identity?.pds.hostname}
157
+
</div>
158
+
159
+
<div>
160
+
<h2 className="text-xl font-bold">Collections</h2>
161
+
<ul>
162
+
{data?.collections.map((c) => (
163
+
<li key={c} className="text-blue-500">
164
+
<a href={`/at/${handle}/${c}`}>{c}</a>
165
+
</li>
166
+
))}
167
+
</ul>
168
+
</div>
169
+
</div>
170
+
</div>
171
+
);
172
+
}
+166
src/routes/index.lazy.tsx
+166
src/routes/index.lazy.tsx
···
1
+
import RepoIcons from "@/components/repoIcons";
2
+
import { QtClient, useXrpc } from "@/providers/qtprovider";
3
+
import "@atcute/bluesky/lexicons";
4
+
import {
5
+
AppBskyActorGetProfile,
6
+
ComAtprotoRepoDescribeRepo,
7
+
} from "@atcute/client/lexicons";
8
+
import {
9
+
IdentityMetadata,
10
+
resolveFromIdentity,
11
+
resolveHandle,
12
+
} from "@atcute/oauth-browser-client";
13
+
import { createLazyFileRoute } from "@tanstack/react-router";
14
+
import { AtSign } from "lucide-react";
15
+
import { useState, useEffect } from "preact/compat";
16
+
17
+
interface RepoData {
18
+
data?: ComAtprotoRepoDescribeRepo.Output;
19
+
blueSkyData?: AppBskyActorGetProfile.Output | null;
20
+
identity?: IdentityMetadata;
21
+
isLoading: boolean;
22
+
error: Error | null;
23
+
}
24
+
25
+
function useRepoData(handle: string): RepoData {
26
+
const xrpc = useXrpc();
27
+
const [state, setState] = useState<RepoData>({
28
+
data: undefined,
29
+
isLoading: true,
30
+
error: null,
31
+
});
32
+
33
+
useEffect(() => {
34
+
const abortController = new AbortController();
35
+
36
+
async function fetchRepoData() {
37
+
try {
38
+
setState((prev) => ({ ...prev, isLoading: true }));
39
+
40
+
const id = await resolveFromIdentity(handle);
41
+
// we dont use the main authenticated client here
42
+
const rpc = new QtClient(id.identity.pds);
43
+
// get the PDS
44
+
const response = await rpc
45
+
.getXrpcClient()
46
+
.get("com.atproto.repo.describeRepo", {
47
+
params: { repo: id.identity.id },
48
+
signal: abortController.signal,
49
+
});
50
+
// can we get bsky data?
51
+
if (response.data.collections.includes("app.bsky.actor.profile")) {
52
+
// reuse client dumbass
53
+
const bskyData = await new QtClient(
54
+
new URL("https://public.api.bsky.app"),
55
+
)
56
+
.getXrpcClient()
57
+
.get("app.bsky.actor.getProfile", {
58
+
params: { actor: id.identity.id },
59
+
});
60
+
61
+
setState({
62
+
blueSkyData: bskyData.data,
63
+
data: response.data,
64
+
identity: id.identity,
65
+
isLoading: false,
66
+
error: null,
67
+
});
68
+
} else {
69
+
setState({
70
+
blueSkyData: null,
71
+
data: response.data,
72
+
identity: id.identity,
73
+
isLoading: false,
74
+
error: null,
75
+
});
76
+
}
77
+
// todo: actual errors
78
+
} catch (err: any) {
79
+
if (err.name === "AbortError") return;
80
+
81
+
setState({
82
+
data: undefined,
83
+
isLoading: false,
84
+
error: err instanceof Error ? err : new Error("An error occurred"),
85
+
});
86
+
}
87
+
}
88
+
89
+
fetchRepoData();
90
+
91
+
return () => {
92
+
abortController.abort();
93
+
};
94
+
}, [handle, xrpc]);
95
+
96
+
return state;
97
+
}
98
+
99
+
export const Route = createLazyFileRoute("/")({
100
+
component: Index,
101
+
});
102
+
103
+
function Index() {
104
+
const { blueSkyData, data, identity, isLoading, error } =
105
+
useRepoData("danabra.mov");
106
+
107
+
if (isLoading) {
108
+
return <div>Loading...</div>;
109
+
}
110
+
111
+
if (error) {
112
+
return <div>Error: {error.message}</div>;
113
+
}
114
+
115
+
return (
116
+
<div className="flex flex-row justify-center w-full min-h-screen">
117
+
<div className="max-w-2xl w-screen p-4 md:mt-16 space-y-2">
118
+
{blueSkyData ? (
119
+
blueSkyData?.banner ? (
120
+
<div className="relative mb-12 md:mb-16">
121
+
<img
122
+
src={blueSkyData?.banner}
123
+
className="w-full rounded-lg scale-[108%] lg:scale-125 -z-10 border"
124
+
/>
125
+
<img
126
+
src={blueSkyData?.avatar}
127
+
className="absolute -bottom-12 md:-bottom-16 w-24 lg:w-32 aspect-square rounded-full border"
128
+
/>
129
+
</div>
130
+
) : (
131
+
<img src={blueSkyData?.avatar} className="w-32 h-32 rounded-full" />
132
+
)
133
+
) : (
134
+
<div className="w-32 h-32 bg-neutral-500 rounded-full grid place-items-center">
135
+
<AtSign className="w-16 h-16" />
136
+
</div>
137
+
)}
138
+
<h1 className="text-2xl md:text-3xl font-bold">
139
+
{blueSkyData?.displayName}{" "}
140
+
<span className="text-muted-foreground font-normal">
141
+
@{data?.handle}
142
+
{data?.handleIsCorrect ? "" : " (invalid handle)"}
143
+
</span>
144
+
</h1>
145
+
146
+
{data?.collections && (
147
+
<div className="flex flex-row pb-2">
148
+
<RepoIcons collections={data?.collections} />
149
+
</div>
150
+
)}
151
+
<code>{data?.did}</code>
152
+
<br />
153
+
154
+
<div>
155
+
PDS: {identity?.pds.hostname.includes("bsky.network") && "🍄"}{" "}
156
+
{identity?.pds.hostname}
157
+
</div>
158
+
159
+
<div>
160
+
<h2 className="text-xl font-bold">Collections</h2>
161
+
<ul>{data?.collections.map((c) => <li key={c}>{c}</li>)}</ul>
162
+
</div>
163
+
</div>
164
+
</div>
165
+
);
166
+
}
+10
tailwind.config.js
+10
tailwind.config.js
···
49
49
'3': 'hsl(var(--chart-3))',
50
50
'4': 'hsl(var(--chart-4))',
51
51
'5': 'hsl(var(--chart-5))'
52
+
},
53
+
sidebar: {
54
+
DEFAULT: 'hsl(var(--sidebar-background))',
55
+
foreground: 'hsl(var(--sidebar-foreground))',
56
+
primary: 'hsl(var(--sidebar-primary))',
57
+
'primary-foreground': 'hsl(var(--sidebar-primary-foreground))',
58
+
accent: 'hsl(var(--sidebar-accent))',
59
+
'accent-foreground': 'hsl(var(--sidebar-accent-foreground))',
60
+
border: 'hsl(var(--sidebar-border))',
61
+
ring: 'hsl(var(--sidebar-ring))'
52
62
}
53
63
}
54
64
}
+1
tsconfig.json
+1
tsconfig.json
+2
-1
vite.config.ts
+2
-1
vite.config.ts
···
1
1
import path from "path";
2
2
import { defineConfig } from "vite";
3
3
import preact from "@preact/preset-vite";
4
+
import { TanStackRouterVite } from "@tanstack/router-plugin/vite";
4
5
5
6
// https://vite.dev/config/
6
7
export default defineConfig({
7
-
plugins: [preact()],
8
+
plugins: [TanStackRouterVite(), preact()],
8
9
resolve: {
9
10
alias: {
10
11
"@": path.resolve(__dirname, "./src"),