+22
.tangled/workflows/deploy.yml
+22
.tangled/workflows/deploy.yml
···
1
+
## need this for commit idk what else to change
2
+
3
+
when:
4
+
- event: ["push"]
5
+
branch: ["main"]
6
+
7
+
engine: "nixery"
8
+
9
+
clone:
10
+
skip: true
11
+
12
+
dependencies:
13
+
nixpkgs:
14
+
- curl
15
+
16
+
steps:
17
+
- name: "Trigger Deploy"
18
+
command: |
19
+
curl -X POST \
20
+
-H "Authorization: Bearer $SCANS_HOST_API_KEY" \
21
+
-H "Authorization: Bearer $SCANS_HOST_API_KEY" \
22
+
https://free.scan.blue/api/v1/sites/jy35AeguTwaqDy_3ufq09/deploy?wait=true
+25
0001-ok.patch
+25
0001-ok.patch
···
1
+
From baf405c82fb23f9274a35384286bac2b901d45af Mon Sep 17 00:00:00 2001
2
+
From: scanash00 <scan@scanash.com>
3
+
Date: Tue, 30 Dec 2025 22:12:13 -0900
4
+
Subject: [PATCH] add ?wait=true
5
+
6
+
---
7
+
.tangled/workflows/deploy.yml | 3 ++-
8
+
1 file changed, 2 insertions(+), 1 deletion(-)
9
+
10
+
diff --git a/.tangled/workflows/deploy.yml b/.tangled/workflows/deploy.yml
11
+
index a44c51b..b7edfea 100644
12
+
--- a/.tangled/workflows/deploy.yml
13
+
+++ b/.tangled/workflows/deploy.yml
14
+
@@ -16,4 +16,5 @@ steps:
15
+
command: |
16
+
curl -X POST \
17
+
-H "Authorization: Bearer $SCANS_HOST_API_KEY" \
18
+
- https://free.scan.blue/api/v1/sites/jy35AeguTwaqDy_3ufq09/deploy
19
+
\ No newline at end of file
20
+
+ -H "Authorization: Bearer $SCANS_HOST_API_KEY" \
21
+
+ https://free.scan.blue/api/v1/sites/YOUR_SITE_ID/deploy?wait=true
22
+
\ No newline at end of file
23
+
--
24
+
2.50.1 (Apple Git-155)
25
+
+12
-12
package.json
+12
-12
package.json
···
9
9
"serve": "vite preview"
10
10
},
11
11
"devDependencies": {
12
-
"@iconify-json/lucide": "^1.2.81",
12
+
"@iconify-json/lucide": "^1.2.82",
13
13
"@iconify/tailwind4": "^1.2.0",
14
14
"@tailwindcss/vite": "^4.1.18",
15
15
"prettier": "^3.7.4",
···
17
17
"prettier-plugin-tailwindcss": "^0.7.2",
18
18
"tailwindcss": "^4.1.18",
19
19
"typescript": "^5.9.3",
20
-
"vite": "^7.2.7",
20
+
"vite": "^7.3.0",
21
21
"vite-plugin-solid": "^2.11.10"
22
22
},
23
23
"dependencies": {
24
24
"@atcute/atproto": "^3.1.9",
25
25
"@atcute/bluesky": "^3.2.14",
26
-
"@atcute/client": "^4.1.1",
26
+
"@atcute/client": "^4.1.2",
27
27
"@atcute/crypto": "^2.3.0",
28
-
"@atcute/did-plc": "^0.2.0",
28
+
"@atcute/did-plc": "^0.3.1",
29
29
"@atcute/identity": "^1.1.3",
30
-
"@atcute/identity-resolver": "^1.2.0",
30
+
"@atcute/identity-resolver": "^1.2.1",
31
31
"@atcute/leaflet": "^1.0.14",
32
-
"@atcute/lexicon-doc": "^2.0.5",
32
+
"@atcute/lexicon-doc": "^2.0.6",
33
33
"@atcute/lexicon-resolver": "^0.1.5",
34
-
"@atcute/lexicons": "^1.2.5",
34
+
"@atcute/lexicons": "^1.2.6",
35
35
"@atcute/multibase": "^1.1.6",
36
36
"@atcute/oauth-browser-client": "^2.0.3",
37
-
"@atcute/repo": "^0.1.0",
37
+
"@atcute/repo": "^0.1.1",
38
38
"@atcute/tangled": "^1.0.13",
39
-
"@atcute/tid": "^1.0.3",
40
-
"@codemirror/commands": "^6.10.0",
39
+
"@atcute/tid": "^1.1.0",
40
+
"@codemirror/commands": "^6.10.1",
41
41
"@codemirror/lang-json": "^6.0.2",
42
42
"@codemirror/lint": "^6.9.2",
43
-
"@codemirror/state": "^6.5.2",
44
-
"@codemirror/view": "^6.39.4",
43
+
"@codemirror/state": "^6.5.3",
44
+
"@codemirror/view": "^6.39.7",
45
45
"@fsegurai/codemirror-theme-basic-dark": "^6.2.3",
46
46
"@fsegurai/codemirror-theme-basic-light": "^6.2.3",
47
47
"@mary/exif-rm": "jsr:^0.2.2",
+410
-365
pnpm-lock.yaml
+410
-365
pnpm-lock.yaml
···
15
15
specifier: ^3.2.14
16
16
version: 3.2.14
17
17
'@atcute/client':
18
-
specifier: ^4.1.1
19
-
version: 4.1.1
18
+
specifier: ^4.1.2
19
+
version: 4.1.2
20
20
'@atcute/crypto':
21
21
specifier: ^2.3.0
22
22
version: 2.3.0
23
23
'@atcute/did-plc':
24
-
specifier: ^0.2.0
25
-
version: 0.2.0
24
+
specifier: ^0.3.1
25
+
version: 0.3.1
26
26
'@atcute/identity':
27
27
specifier: ^1.1.3
28
28
version: 1.1.3
29
29
'@atcute/identity-resolver':
30
-
specifier: ^1.2.0
31
-
version: 1.2.0(@atcute/identity@1.1.3)
30
+
specifier: ^1.2.1
31
+
version: 1.2.1(@atcute/identity@1.1.3)
32
32
'@atcute/leaflet':
33
33
specifier: ^1.0.14
34
34
version: 1.0.14
35
35
'@atcute/lexicon-doc':
36
-
specifier: ^2.0.5
37
-
version: 2.0.5
36
+
specifier: ^2.0.6
37
+
version: 2.0.6
38
38
'@atcute/lexicon-resolver':
39
39
specifier: ^0.1.5
40
-
version: 0.1.5(@atcute/identity-resolver@1.2.0(@atcute/identity@1.1.3))(@atcute/identity@1.1.3)
40
+
version: 0.1.5(@atcute/identity-resolver@1.2.1(@atcute/identity@1.1.3))(@atcute/identity@1.1.3)
41
41
'@atcute/lexicons':
42
-
specifier: ^1.2.5
43
-
version: 1.2.5
42
+
specifier: ^1.2.6
43
+
version: 1.2.6
44
44
'@atcute/multibase':
45
45
specifier: ^1.1.6
46
46
version: 1.1.6
···
48
48
specifier: ^2.0.3
49
49
version: 2.0.3(@atcute/identity@1.1.3)
50
50
'@atcute/repo':
51
-
specifier: ^0.1.0
52
-
version: 0.1.0
51
+
specifier: ^0.1.1
52
+
version: 0.1.1
53
53
'@atcute/tangled':
54
54
specifier: ^1.0.13
55
55
version: 1.0.13
56
56
'@atcute/tid':
57
-
specifier: ^1.0.3
58
-
version: 1.0.3
57
+
specifier: ^1.1.0
58
+
version: 1.1.0
59
59
'@codemirror/commands':
60
-
specifier: ^6.10.0
61
-
version: 6.10.0
60
+
specifier: ^6.10.1
61
+
version: 6.10.1
62
62
'@codemirror/lang-json':
63
63
specifier: ^6.0.2
64
64
version: 6.0.2
···
66
66
specifier: ^6.9.2
67
67
version: 6.9.2
68
68
'@codemirror/state':
69
-
specifier: ^6.5.2
70
-
version: 6.5.2
69
+
specifier: ^6.5.3
70
+
version: 6.5.3
71
71
'@codemirror/view':
72
-
specifier: ^6.39.4
73
-
version: 6.39.4
72
+
specifier: ^6.39.7
73
+
version: 6.39.7
74
74
'@fsegurai/codemirror-theme-basic-dark':
75
75
specifier: ^6.2.3
76
-
version: 6.2.3(@codemirror/language@6.11.3)(@codemirror/state@6.5.2)(@codemirror/view@6.39.4)(@lezer/highlight@1.2.3)
76
+
version: 6.2.3(@codemirror/language@6.12.1)(@codemirror/state@6.5.3)(@codemirror/view@6.39.7)(@lezer/highlight@1.2.3)
77
77
'@fsegurai/codemirror-theme-basic-light':
78
78
specifier: ^6.2.3
79
-
version: 6.2.3(@codemirror/language@6.11.3)(@codemirror/state@6.5.2)(@codemirror/view@6.39.4)(@lezer/highlight@1.2.3)
79
+
version: 6.2.3(@codemirror/language@6.12.1)(@codemirror/state@6.5.3)(@codemirror/view@6.39.7)(@lezer/highlight@1.2.3)
80
80
'@mary/exif-rm':
81
81
specifier: jsr:^0.2.2
82
82
version: '@jsr/mary__exif-rm@0.2.2'
···
97
97
version: 1.9.10
98
98
devDependencies:
99
99
'@iconify-json/lucide':
100
-
specifier: ^1.2.81
101
-
version: 1.2.81
100
+
specifier: ^1.2.82
101
+
version: 1.2.82
102
102
'@iconify/tailwind4':
103
103
specifier: ^1.2.0
104
104
version: 1.2.0(tailwindcss@4.1.18)
105
105
'@tailwindcss/vite':
106
106
specifier: ^4.1.18
107
-
version: 4.1.18(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2))
107
+
version: 4.1.18(vite@7.3.0(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2))
108
108
prettier:
109
109
specifier: ^3.7.4
110
110
version: 3.7.4
···
121
121
specifier: ^5.9.3
122
122
version: 5.9.3
123
123
vite:
124
-
specifier: ^7.2.7
125
-
version: 7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)
124
+
specifier: ^7.3.0
125
+
version: 7.3.0(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)
126
126
vite-plugin-solid:
127
127
specifier: ^2.11.10
128
-
version: 2.11.10(solid-js@1.9.10)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2))
128
+
version: 2.11.10(solid-js@1.9.10)(vite@7.3.0(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2))
129
129
130
130
packages:
131
131
···
147
147
'@atcute/cbor@2.2.8':
148
148
resolution: {integrity: sha512-UzOAN9BuN6JCXgn0ryV8qZuRJUDrNqrbLd6EFM8jc6RYssjRyGRxNy6RZ1NU/07Hd8Tq/0pz8+nQiMu5Zai5uw==}
149
149
150
-
'@atcute/cid@2.2.6':
151
-
resolution: {integrity: sha512-bTAHHbJ24p+E//V4KCS4xdmd39o211jJswvqQOevj7vk+5IYcgDLx1ryZWZ1sEPOo9x875li/kj5gpKL14RDwQ==}
150
+
'@atcute/cid@2.3.0':
151
+
resolution: {integrity: sha512-1SRdkTuMs/l5arQ+7Ag0F7JAueZqtzYE0d2gmbkuzi8EPweNU1kYlQs0CE4dSd81YF8PMDTOQty0K2ATq9CW9g==}
152
152
153
-
'@atcute/client@4.1.1':
154
-
resolution: {integrity: sha512-FROCbTTCeL5u4tO/n72jDEKyKqjdlXMB56Ehve3W/gnnLGCYWvN42sS7tvL1Mgu6sbO3yZwsXKDrmM2No4XpjA==}
153
+
'@atcute/client@4.1.2':
154
+
resolution: {integrity: sha512-DOJ0hpdBA4QVl4SGUeOUyz5FfYhdjRW1h0XIH9YDgNTipeA0tnUbRs8hWh9Nb7nyn6zMKzO5RpaWyWWWSx9Yxw==}
155
155
156
156
'@atcute/crypto@2.3.0':
157
157
resolution: {integrity: sha512-w5pkJKCjbNMQu+F4JRHbR3ROQyhi1wbn+GSC6WDQamcYHkZmEZk1/eoI354bIQOOfkEM6aFLv718iskrkon4GQ==}
158
158
159
-
'@atcute/did-plc@0.2.0':
160
-
resolution: {integrity: sha512-1sGek8GRM/Ph7nLVRREm8FqM7g4shGckItvdVwJcRbUa8Rh0zOsXQa0QyYWAC0k40BhkqO9FwKXhJEaXCmF5oQ==}
159
+
'@atcute/did-plc@0.3.1':
160
+
resolution: {integrity: sha512-KsuVdRtaaIPMmlcCDcxZzLg6OWm7rajczquhIHfA3s57+c34PFQbdY4Lsc2BvDwZ0fUjmbwzvQI3Zio2VcZa7w==}
161
161
162
-
'@atcute/identity-resolver@1.2.0':
163
-
resolution: {integrity: sha512-5UbSJfdV3JIkF8ksXz7g4nKBWasf2wROvzM66cfvTIWydWFO6/oS1KZd+zo9Eokje5Scf5+jsY9ZfgVARLepXg==}
162
+
'@atcute/identity-resolver@1.2.1':
163
+
resolution: {integrity: sha512-LqWFFf8D8bqW8l0zUV9oZxcXYZ8+uQTZfjURoxH1TLmtmZFSXredtQHsY70k/iSMNDPxWHJXebdlKxJm5ioNIg==}
164
164
peerDependencies:
165
165
'@atcute/identity': ^1.0.0
166
166
···
170
170
'@atcute/leaflet@1.0.14':
171
171
resolution: {integrity: sha512-TWbtB7b73GChBaYwfd7aWFyGVObZ/DqrRtwkpWGm1GO8zZmQ9eJyKDUnXim7NOAs2hmKQ1u2wk2AM4AYzkF5Gg==}
172
172
173
-
'@atcute/lexicon-doc@2.0.5':
174
-
resolution: {integrity: sha512-fNCp94ehGjWFZMIqP6pWD1F9MOJogNCyqsaMVZluPSIclZ+lDL528iXB56aW4u0eSiD6Y9WJB1OI/lElG39cSA==}
173
+
'@atcute/lexicon-doc@2.0.6':
174
+
resolution: {integrity: sha512-iDYJkuom+tIw3zIvU1ggCEVFfReXKfOUtIhpY2kEg2kQeSfMB75F+8k1QOpeAQBetyWYmjsHqBuSUX9oQS6L1Q==}
175
175
176
176
'@atcute/lexicon-resolver@0.1.5':
177
177
resolution: {integrity: sha512-0bx1/zdMQPuxvRcHW6ykAxRxktC2rEZLoAVSFoLSWDAA92Tf09F9QPK5wgXSF4MNODm1dvzMEdWSMIvlg8sr3A==}
···
179
179
'@atcute/identity': ^1.1.0
180
180
'@atcute/identity-resolver': ^1.1.3
181
181
182
-
'@atcute/lexicons@1.2.5':
183
-
resolution: {integrity: sha512-9yO9WdgxW8jZ7SbzUycH710z+JmsQ9W9n5S6i6eghYju32kkluFmgBeS47r8e8p2+Dv4DemS7o/3SUGsX9FR5Q==}
182
+
'@atcute/lexicons@1.2.6':
183
+
resolution: {integrity: sha512-s76UQd8D+XmHIzrjD9CJ9SOOeeLPHc+sMmcj7UFakAW/dDFXc579fcRdRfuUKvXBL5v1Gs2VgDdlh/IvvQZAwA==}
184
184
185
-
'@atcute/mst@0.1.0':
186
-
resolution: {integrity: sha512-h+iDToKEnBpigk2DOHjSqY63vJtjYKUIztqu1CZ0P+I54wV2SrgoqAXAT1xrW6A1Iup8cjTv+U2H5WVG4KxPLw==}
185
+
'@atcute/mst@0.1.1':
186
+
resolution: {integrity: sha512-NZ/lZ68GOjmAgBSeGf6WHyKM5wo1Hhc7PNt9uwsViswGPMNEEKNj9cw+0YGziXee/Qbnvc+CKqbRSPwruhXFQg==}
187
187
188
188
'@atcute/multibase@1.1.6':
189
189
resolution: {integrity: sha512-HBxuCgYLKPPxETV0Rot4VP9e24vKl8JdzGCZOVsDaOXJgbRZoRIF67Lp0H/OgnJeH/Xpva8Z5ReoTNJE5dn3kg==}
···
191
191
'@atcute/oauth-browser-client@2.0.3':
192
192
resolution: {integrity: sha512-rzUjwhjE4LRRKdQnCFQag/zXRZMEAB1hhBoLfnoQuHwWbmDUCL7fzwC3jRhDPp3om8XaYNDj8a/iqRip0wRqoQ==}
193
193
194
-
'@atcute/repo@0.1.0':
195
-
resolution: {integrity: sha512-INiYAuma8dydBu7cqd2WVpcXh3mzhIepYBUqFWAK5MqMulPRLTRCc/9GW3G9pxYrOdlvLCVamG2Jf8XK0nuFEw==}
194
+
'@atcute/repo@0.1.1':
195
+
resolution: {integrity: sha512-P5aWjt3bvcquUkUmGPslF0naAfLGRHse5Qdz9/RJYrFuoH0iiEMyRnW6M+3ksOe20GPsMnbq71WbzzFkRFPBtg==}
196
196
197
197
'@atcute/tangled@1.0.13':
198
198
resolution: {integrity: sha512-K95jmjDXl/f1FFzOJkk07ibNbFsPmn64sdrMACxQmUibO9WcfSjzjZLPXuH6WHFnCNtIBG3x1FQ7ndQgLoZAmw==}
199
199
200
-
'@atcute/tid@1.0.3':
201
-
resolution: {integrity: sha512-wfMJx1IMdnu0CZgWl0uR4JO2s6PGT1YPhpytD4ZHzEYKKQVuqV6Eb/7vieaVo1eYNMp2FrY67FZObeR7utRl2w==}
200
+
'@atcute/tid@1.1.0':
201
+
resolution: {integrity: sha512-U/YKL9BsBi/bcVXaIwdUBfglnjFxRfqoPd2f1uLsEIDQk1EyxepwdDQYOQ5t/aQctmtywl7lQn6KESQNG+mdfg==}
202
+
203
+
'@atcute/time-ms@1.0.0':
204
+
resolution: {integrity: sha512-iWEOlMBcO3ktB+zQPC2kXka9H/798we+IWq2sjhb+hQJNNfcJrwejzvNi/68Q3jKo/hdfwZjRU9iF8U6D32/2Q==}
202
205
203
206
'@atcute/uint8array@1.0.6':
204
207
resolution: {integrity: sha512-ucfRBQc7BFT8n9eCyGOzDHEMKF/nZwhS2pPao4Xtab1ML3HdFYcX2DM1tadCzas85QTGxHe5urnUAAcNKGRi9A==}
···
206
209
'@atcute/util-fetch@1.0.4':
207
210
resolution: {integrity: sha512-sIU9Qk0dE8PLEXSfhy+gIJV+HpiiknMytCI2SqLlqd0vgZUtEKI/EQfP+23LHWvP+CLCzVDOa6cpH045OlmNBg==}
208
211
212
+
'@atcute/util-text@0.0.1':
213
+
resolution: {integrity: sha512-t1KZqvn0AYy+h2KcJyHnKF9aEqfRfMUmyY8j1ELtAEIgqN9CxINAjxnoRCJIFUlvWzb+oY3uElQL/Vyk3yss0g==}
214
+
209
215
'@atcute/varint@1.0.3':
210
216
resolution: {integrity: sha512-fdvMPyBB+McDT+Ai5e9RwEbwYV4yjZ60S2Dn5PTjGqUyxvoCH1z42viuheDZRUDkmfQehXJTZ5az7dSozVNtog==}
211
217
···
297
303
'@codemirror/autocomplete@6.20.0':
298
304
resolution: {integrity: sha512-bOwvTOIJcG5FVo5gUUupiwYh8MioPLQ4UcqbcRf7UQ98X90tCa9E1kZ3Z7tqwpZxYyOvh1YTYbmZE9RTfTp5hg==}
299
305
300
-
'@codemirror/commands@6.10.0':
301
-
resolution: {integrity: sha512-2xUIc5mHXQzT16JnyOFkh8PvfeXuIut3pslWGfsGOhxP/lpgRm9HOl/mpzLErgt5mXDovqA0d11P21gofRLb9w==}
306
+
'@codemirror/commands@6.10.1':
307
+
resolution: {integrity: sha512-uWDWFypNdQmz2y1LaNJzK7fL7TYKLeUAU0npEC685OKTF3KcQ2Vu3klIM78D7I6wGhktme0lh3CuQLv0ZCrD9Q==}
302
308
303
309
'@codemirror/lang-json@6.0.2':
304
310
resolution: {integrity: sha512-x2OtO+AvwEHrEwR0FyyPtfDUiloG3rnVTSZV1W8UteaLL8/MajQd8DpvUb2YVzC+/T18aSDv0H9mu+xw0EStoQ==}
305
311
306
-
'@codemirror/language@6.11.3':
307
-
resolution: {integrity: sha512-9HBM2XnwDj7fnu0551HkGdrUrrqmYq/WC5iv6nbY2WdicXdGbhR/gfbZOH73Aqj4351alY1+aoG9rCNfiwS1RA==}
312
+
'@codemirror/language@6.12.1':
313
+
resolution: {integrity: sha512-Fa6xkSiuGKc8XC8Cn96T+TQHYj4ZZ7RdFmXA3i9xe/3hLHfwPZdM+dqfX0Cp0zQklBKhVD8Yzc8LS45rkqcwpQ==}
308
314
309
315
'@codemirror/lint@6.9.2':
310
316
resolution: {integrity: sha512-sv3DylBiIyi+xKwRCJAAsBZZZWo82shJ/RTMymLabAdtbkV5cSKwWDeCgtUq3v8flTaXS2y1kKkICuRYtUswyQ==}
···
312
318
'@codemirror/search@6.5.11':
313
319
resolution: {integrity: sha512-KmWepDE6jUdL6n8cAAqIpRmLPBZ5ZKnicE8oGU/s3QrAVID+0VhLFrzUucVKHG5035/BSykhExDL/Xm7dHthiA==}
314
320
315
-
'@codemirror/state@6.5.2':
316
-
resolution: {integrity: sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==}
321
+
'@codemirror/state@6.5.3':
322
+
resolution: {integrity: sha512-MerMzJzlXogk2fxWFU1nKp36bY5orBG59HnPiz0G9nLRebWa0zXuv2siH6PLIHBvv5TH8CkQRqjBs0MlxCZu+A==}
317
323
318
-
'@codemirror/view@6.39.4':
319
-
resolution: {integrity: sha512-xMF6OfEAUVY5Waega4juo1QGACfNkNF+aJLqpd8oUJz96ms2zbfQ9Gh35/tI3y8akEV31FruKfj7hBnIU/nkqA==}
324
+
'@codemirror/view@6.39.7':
325
+
resolution: {integrity: sha512-3Vif9hnNHJnl2YgOtkR/wzGzhYcQ8gy3LGdUhkLUU8xSBbgsTxrE8he/CMTpeINm5TgxLe2FmzvF6IYQL/BSAg==}
320
326
321
327
'@cyberalien/svg-utils@1.0.11':
322
328
resolution: {integrity: sha512-qEE9mnyI+avfGT3emKuRs3ucYkITeaV0Xi7VlYN41f+uGnZBecQP3jwz/AF437H9J4Q7qPClHKm4NiTYpNE6hA==}
···
327
333
cpu: [ppc64]
328
334
os: [aix]
329
335
330
-
'@esbuild/aix-ppc64@0.25.12':
331
-
resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==}
336
+
'@esbuild/aix-ppc64@0.27.2':
337
+
resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==}
332
338
engines: {node: '>=18'}
333
339
cpu: [ppc64]
334
340
os: [aix]
···
339
345
cpu: [arm64]
340
346
os: [android]
341
347
342
-
'@esbuild/android-arm64@0.25.12':
343
-
resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==}
348
+
'@esbuild/android-arm64@0.27.2':
349
+
resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==}
344
350
engines: {node: '>=18'}
345
351
cpu: [arm64]
346
352
os: [android]
···
351
357
cpu: [arm]
352
358
os: [android]
353
359
354
-
'@esbuild/android-arm@0.25.12':
355
-
resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==}
360
+
'@esbuild/android-arm@0.27.2':
361
+
resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==}
356
362
engines: {node: '>=18'}
357
363
cpu: [arm]
358
364
os: [android]
···
363
369
cpu: [x64]
364
370
os: [android]
365
371
366
-
'@esbuild/android-x64@0.25.12':
367
-
resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==}
372
+
'@esbuild/android-x64@0.27.2':
373
+
resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==}
368
374
engines: {node: '>=18'}
369
375
cpu: [x64]
370
376
os: [android]
···
375
381
cpu: [arm64]
376
382
os: [darwin]
377
383
378
-
'@esbuild/darwin-arm64@0.25.12':
379
-
resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==}
384
+
'@esbuild/darwin-arm64@0.27.2':
385
+
resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==}
380
386
engines: {node: '>=18'}
381
387
cpu: [arm64]
382
388
os: [darwin]
···
387
393
cpu: [x64]
388
394
os: [darwin]
389
395
390
-
'@esbuild/darwin-x64@0.25.12':
391
-
resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==}
396
+
'@esbuild/darwin-x64@0.27.2':
397
+
resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==}
392
398
engines: {node: '>=18'}
393
399
cpu: [x64]
394
400
os: [darwin]
···
399
405
cpu: [arm64]
400
406
os: [freebsd]
401
407
402
-
'@esbuild/freebsd-arm64@0.25.12':
403
-
resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==}
408
+
'@esbuild/freebsd-arm64@0.27.2':
409
+
resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==}
404
410
engines: {node: '>=18'}
405
411
cpu: [arm64]
406
412
os: [freebsd]
···
411
417
cpu: [x64]
412
418
os: [freebsd]
413
419
414
-
'@esbuild/freebsd-x64@0.25.12':
415
-
resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==}
420
+
'@esbuild/freebsd-x64@0.27.2':
421
+
resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==}
416
422
engines: {node: '>=18'}
417
423
cpu: [x64]
418
424
os: [freebsd]
···
423
429
cpu: [arm64]
424
430
os: [linux]
425
431
426
-
'@esbuild/linux-arm64@0.25.12':
427
-
resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==}
432
+
'@esbuild/linux-arm64@0.27.2':
433
+
resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==}
428
434
engines: {node: '>=18'}
429
435
cpu: [arm64]
430
436
os: [linux]
···
435
441
cpu: [arm]
436
442
os: [linux]
437
443
438
-
'@esbuild/linux-arm@0.25.12':
439
-
resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==}
444
+
'@esbuild/linux-arm@0.27.2':
445
+
resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==}
440
446
engines: {node: '>=18'}
441
447
cpu: [arm]
442
448
os: [linux]
···
447
453
cpu: [ia32]
448
454
os: [linux]
449
455
450
-
'@esbuild/linux-ia32@0.25.12':
451
-
resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==}
456
+
'@esbuild/linux-ia32@0.27.2':
457
+
resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==}
452
458
engines: {node: '>=18'}
453
459
cpu: [ia32]
454
460
os: [linux]
···
459
465
cpu: [loong64]
460
466
os: [linux]
461
467
462
-
'@esbuild/linux-loong64@0.25.12':
463
-
resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==}
468
+
'@esbuild/linux-loong64@0.27.2':
469
+
resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==}
464
470
engines: {node: '>=18'}
465
471
cpu: [loong64]
466
472
os: [linux]
···
471
477
cpu: [mips64el]
472
478
os: [linux]
473
479
474
-
'@esbuild/linux-mips64el@0.25.12':
475
-
resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==}
480
+
'@esbuild/linux-mips64el@0.27.2':
481
+
resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==}
476
482
engines: {node: '>=18'}
477
483
cpu: [mips64el]
478
484
os: [linux]
···
483
489
cpu: [ppc64]
484
490
os: [linux]
485
491
486
-
'@esbuild/linux-ppc64@0.25.12':
487
-
resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==}
492
+
'@esbuild/linux-ppc64@0.27.2':
493
+
resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==}
488
494
engines: {node: '>=18'}
489
495
cpu: [ppc64]
490
496
os: [linux]
···
495
501
cpu: [riscv64]
496
502
os: [linux]
497
503
498
-
'@esbuild/linux-riscv64@0.25.12':
499
-
resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==}
504
+
'@esbuild/linux-riscv64@0.27.2':
505
+
resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==}
500
506
engines: {node: '>=18'}
501
507
cpu: [riscv64]
502
508
os: [linux]
···
507
513
cpu: [s390x]
508
514
os: [linux]
509
515
510
-
'@esbuild/linux-s390x@0.25.12':
511
-
resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==}
516
+
'@esbuild/linux-s390x@0.27.2':
517
+
resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==}
512
518
engines: {node: '>=18'}
513
519
cpu: [s390x]
514
520
os: [linux]
···
519
525
cpu: [x64]
520
526
os: [linux]
521
527
522
-
'@esbuild/linux-x64@0.25.12':
523
-
resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==}
528
+
'@esbuild/linux-x64@0.27.2':
529
+
resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==}
524
530
engines: {node: '>=18'}
525
531
cpu: [x64]
526
532
os: [linux]
527
533
528
-
'@esbuild/netbsd-arm64@0.25.12':
529
-
resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==}
534
+
'@esbuild/netbsd-arm64@0.27.2':
535
+
resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==}
530
536
engines: {node: '>=18'}
531
537
cpu: [arm64]
532
538
os: [netbsd]
···
537
543
cpu: [x64]
538
544
os: [netbsd]
539
545
540
-
'@esbuild/netbsd-x64@0.25.12':
541
-
resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==}
546
+
'@esbuild/netbsd-x64@0.27.2':
547
+
resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==}
542
548
engines: {node: '>=18'}
543
549
cpu: [x64]
544
550
os: [netbsd]
···
549
555
cpu: [arm64]
550
556
os: [openbsd]
551
557
552
-
'@esbuild/openbsd-arm64@0.25.12':
553
-
resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==}
558
+
'@esbuild/openbsd-arm64@0.27.2':
559
+
resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==}
554
560
engines: {node: '>=18'}
555
561
cpu: [arm64]
556
562
os: [openbsd]
···
561
567
cpu: [x64]
562
568
os: [openbsd]
563
569
564
-
'@esbuild/openbsd-x64@0.25.12':
565
-
resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==}
570
+
'@esbuild/openbsd-x64@0.27.2':
571
+
resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==}
566
572
engines: {node: '>=18'}
567
573
cpu: [x64]
568
574
os: [openbsd]
569
575
570
-
'@esbuild/openharmony-arm64@0.25.12':
571
-
resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==}
576
+
'@esbuild/openharmony-arm64@0.27.2':
577
+
resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==}
572
578
engines: {node: '>=18'}
573
579
cpu: [arm64]
574
580
os: [openharmony]
···
579
585
cpu: [x64]
580
586
os: [sunos]
581
587
582
-
'@esbuild/sunos-x64@0.25.12':
583
-
resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==}
588
+
'@esbuild/sunos-x64@0.27.2':
589
+
resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==}
584
590
engines: {node: '>=18'}
585
591
cpu: [x64]
586
592
os: [sunos]
···
591
597
cpu: [arm64]
592
598
os: [win32]
593
599
594
-
'@esbuild/win32-arm64@0.25.12':
595
-
resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==}
600
+
'@esbuild/win32-arm64@0.27.2':
601
+
resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==}
596
602
engines: {node: '>=18'}
597
603
cpu: [arm64]
598
604
os: [win32]
···
603
609
cpu: [ia32]
604
610
os: [win32]
605
611
606
-
'@esbuild/win32-ia32@0.25.12':
607
-
resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==}
612
+
'@esbuild/win32-ia32@0.27.2':
613
+
resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==}
608
614
engines: {node: '>=18'}
609
615
cpu: [ia32]
610
616
os: [win32]
···
615
621
cpu: [x64]
616
622
os: [win32]
617
623
618
-
'@esbuild/win32-x64@0.25.12':
619
-
resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==}
624
+
'@esbuild/win32-x64@0.27.2':
625
+
resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==}
620
626
engines: {node: '>=18'}
621
627
cpu: [x64]
622
628
os: [win32]
···
637
643
'@codemirror/view': ^6.0.0
638
644
'@lezer/highlight': ^1.0.0
639
645
640
-
'@iconify-json/lucide@1.2.81':
641
-
resolution: {integrity: sha512-6Kz/+SEuD5bkg0KImi0yFem9l6njKp4e1qF1LpQbgRfk7ngsJR/qjlB4y5rM8N1iKiDR/p19cqhmwZxyCWek+w==}
646
+
'@iconify-json/lucide@1.2.82':
647
+
resolution: {integrity: sha512-fHZWegspOZonl5GNTvOkHsjnTMdSslFh3EzpzUtRyLxO8bOonqk2OTU3hCl0k4VXzViMjqpRK3X1sotnuBXkFA==}
642
648
643
649
'@iconify/tailwind4@1.2.0':
644
650
resolution: {integrity: sha512-+t7XqfojOB0zzZdd8gV7IQZGq1AaIHTlsxMVzagxYR0hAlJCLUD63o3iSlNKRMH3ZR7gZ8y5c9dJ7J431avRbA==}
645
651
peerDependencies:
646
652
tailwindcss: '>= 4.0.0'
647
653
648
-
'@iconify/tools@5.0.0':
649
-
resolution: {integrity: sha512-GY/FsuNdWA/FbkLqgQ8b1PHFkNvjMeSFWaVJdLldYGHBp0lZ64HJlcS0qzLfglacHTd8zYdfQjF74RxGqyGMgw==}
654
+
'@iconify/tools@5.0.1':
655
+
resolution: {integrity: sha512-/znhBN9WIpJd9UtKhyEDfRKwNo8rrOy8dShF8bwSZ1i27ukTSHjeS6bmVK4tTYBYriwFhBf70JT6g8GIRwFvbw==}
650
656
651
657
'@iconify/types@2.0.0':
652
658
resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
···
673
679
'@jsr/mary__exif-rm@0.2.2':
674
680
resolution: {integrity: sha512-+ZpLaC+1CyqWhH608Sqd6/yTG0pOlokn2tCXha7s1SMQ+GLKo4Nn/PskTeeP9Pt+6gNYSu6ednoSlRvXb2ZGxg==, tarball: https://npm.jsr.io/~/11/@jsr/mary__exif-rm/0.2.2.tgz}
675
681
676
-
'@lezer/common@1.4.0':
677
-
resolution: {integrity: sha512-DVeMRoGrgn/k45oQNu189BoW4SZwgZFzJ1+1TV5j2NJ/KFC83oa/enRqZSGshyeMk5cPWMhsKs9nx+8o0unwGg==}
682
+
'@lezer/common@1.5.0':
683
+
resolution: {integrity: sha512-PNGcolp9hr4PJdXR4ix7XtixDrClScvtSCYW3rQG106oVMOOI+jFb+0+J3mbeL/53g1Zd6s0kJzaw6Ri68GmAA==}
678
684
679
685
'@lezer/highlight@1.2.3':
680
686
resolution: {integrity: sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g==}
···
691
697
'@noble/secp256k1@3.0.0':
692
698
resolution: {integrity: sha512-NJBaR352KyIvj3t6sgT/+7xrNyF9Xk9QlLSIqUGVUYlsnDTAUqY8LOmwpcgEx4AMJXRITQ5XEVHD+mMaPfr3mg==}
693
699
694
-
'@rollup/rollup-android-arm-eabi@4.53.3':
695
-
resolution: {integrity: sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==}
700
+
'@rollup/rollup-android-arm-eabi@4.54.0':
701
+
resolution: {integrity: sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng==}
696
702
cpu: [arm]
697
703
os: [android]
698
704
699
-
'@rollup/rollup-android-arm64@4.53.3':
700
-
resolution: {integrity: sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==}
705
+
'@rollup/rollup-android-arm64@4.54.0':
706
+
resolution: {integrity: sha512-Skx39Uv+u7H224Af+bDgNinitlmHyQX1K/atIA32JP3JQw6hVODX5tkbi2zof/E69M1qH2UoN3Xdxgs90mmNYw==}
701
707
cpu: [arm64]
702
708
os: [android]
703
709
704
-
'@rollup/rollup-darwin-arm64@4.53.3':
705
-
resolution: {integrity: sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==}
710
+
'@rollup/rollup-darwin-arm64@4.54.0':
711
+
resolution: {integrity: sha512-k43D4qta/+6Fq+nCDhhv9yP2HdeKeP56QrUUTW7E6PhZP1US6NDqpJj4MY0jBHlJivVJD5P8NxrjuobZBJTCRw==}
706
712
cpu: [arm64]
707
713
os: [darwin]
708
714
709
-
'@rollup/rollup-darwin-x64@4.53.3':
710
-
resolution: {integrity: sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==}
715
+
'@rollup/rollup-darwin-x64@4.54.0':
716
+
resolution: {integrity: sha512-cOo7biqwkpawslEfox5Vs8/qj83M/aZCSSNIWpVzfU2CYHa2G3P1UN5WF01RdTHSgCkri7XOlTdtk17BezlV3A==}
711
717
cpu: [x64]
712
718
os: [darwin]
713
719
714
-
'@rollup/rollup-freebsd-arm64@4.53.3':
715
-
resolution: {integrity: sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==}
720
+
'@rollup/rollup-freebsd-arm64@4.54.0':
721
+
resolution: {integrity: sha512-miSvuFkmvFbgJ1BevMa4CPCFt5MPGw094knM64W9I0giUIMMmRYcGW/JWZDriaw/k1kOBtsWh1z6nIFV1vPNtA==}
716
722
cpu: [arm64]
717
723
os: [freebsd]
718
724
719
-
'@rollup/rollup-freebsd-x64@4.53.3':
720
-
resolution: {integrity: sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==}
725
+
'@rollup/rollup-freebsd-x64@4.54.0':
726
+
resolution: {integrity: sha512-KGXIs55+b/ZfZsq9aR026tmr/+7tq6VG6MsnrvF4H8VhwflTIuYh+LFUlIsRdQSgrgmtM3fVATzEAj4hBQlaqQ==}
721
727
cpu: [x64]
722
728
os: [freebsd]
723
729
724
-
'@rollup/rollup-linux-arm-gnueabihf@4.53.3':
725
-
resolution: {integrity: sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==}
730
+
'@rollup/rollup-linux-arm-gnueabihf@4.54.0':
731
+
resolution: {integrity: sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==}
726
732
cpu: [arm]
727
733
os: [linux]
728
734
729
-
'@rollup/rollup-linux-arm-musleabihf@4.53.3':
730
-
resolution: {integrity: sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==}
735
+
'@rollup/rollup-linux-arm-musleabihf@4.54.0':
736
+
resolution: {integrity: sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==}
731
737
cpu: [arm]
732
738
os: [linux]
733
739
734
-
'@rollup/rollup-linux-arm64-gnu@4.53.3':
735
-
resolution: {integrity: sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==}
740
+
'@rollup/rollup-linux-arm64-gnu@4.54.0':
741
+
resolution: {integrity: sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==}
736
742
cpu: [arm64]
737
743
os: [linux]
738
744
739
-
'@rollup/rollup-linux-arm64-musl@4.53.3':
740
-
resolution: {integrity: sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==}
745
+
'@rollup/rollup-linux-arm64-musl@4.54.0':
746
+
resolution: {integrity: sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==}
741
747
cpu: [arm64]
742
748
os: [linux]
743
749
744
-
'@rollup/rollup-linux-loong64-gnu@4.53.3':
745
-
resolution: {integrity: sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==}
750
+
'@rollup/rollup-linux-loong64-gnu@4.54.0':
751
+
resolution: {integrity: sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==}
746
752
cpu: [loong64]
747
753
os: [linux]
748
754
749
-
'@rollup/rollup-linux-ppc64-gnu@4.53.3':
750
-
resolution: {integrity: sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==}
755
+
'@rollup/rollup-linux-ppc64-gnu@4.54.0':
756
+
resolution: {integrity: sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==}
751
757
cpu: [ppc64]
752
758
os: [linux]
753
759
754
-
'@rollup/rollup-linux-riscv64-gnu@4.53.3':
755
-
resolution: {integrity: sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==}
760
+
'@rollup/rollup-linux-riscv64-gnu@4.54.0':
761
+
resolution: {integrity: sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==}
756
762
cpu: [riscv64]
757
763
os: [linux]
758
764
759
-
'@rollup/rollup-linux-riscv64-musl@4.53.3':
760
-
resolution: {integrity: sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==}
765
+
'@rollup/rollup-linux-riscv64-musl@4.54.0':
766
+
resolution: {integrity: sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==}
761
767
cpu: [riscv64]
762
768
os: [linux]
763
769
764
-
'@rollup/rollup-linux-s390x-gnu@4.53.3':
765
-
resolution: {integrity: sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==}
770
+
'@rollup/rollup-linux-s390x-gnu@4.54.0':
771
+
resolution: {integrity: sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==}
766
772
cpu: [s390x]
767
773
os: [linux]
768
774
769
-
'@rollup/rollup-linux-x64-gnu@4.53.3':
770
-
resolution: {integrity: sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==}
775
+
'@rollup/rollup-linux-x64-gnu@4.54.0':
776
+
resolution: {integrity: sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==}
771
777
cpu: [x64]
772
778
os: [linux]
773
779
774
-
'@rollup/rollup-linux-x64-musl@4.53.3':
775
-
resolution: {integrity: sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==}
780
+
'@rollup/rollup-linux-x64-musl@4.54.0':
781
+
resolution: {integrity: sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==}
776
782
cpu: [x64]
777
783
os: [linux]
778
784
779
-
'@rollup/rollup-openharmony-arm64@4.53.3':
780
-
resolution: {integrity: sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==}
785
+
'@rollup/rollup-openharmony-arm64@4.54.0':
786
+
resolution: {integrity: sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==}
781
787
cpu: [arm64]
782
788
os: [openharmony]
783
789
784
-
'@rollup/rollup-win32-arm64-msvc@4.53.3':
785
-
resolution: {integrity: sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==}
790
+
'@rollup/rollup-win32-arm64-msvc@4.54.0':
791
+
resolution: {integrity: sha512-c2V0W1bsKIKfbLMBu/WGBz6Yci8nJ/ZJdheE0EwB73N3MvHYKiKGs3mVilX4Gs70eGeDaMqEob25Tw2Gb9Nqyw==}
786
792
cpu: [arm64]
787
793
os: [win32]
788
794
789
-
'@rollup/rollup-win32-ia32-msvc@4.53.3':
790
-
resolution: {integrity: sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==}
795
+
'@rollup/rollup-win32-ia32-msvc@4.54.0':
796
+
resolution: {integrity: sha512-woEHgqQqDCkAzrDhvDipnSirm5vxUXtSKDYTVpZG3nUdW/VVB5VdCYA2iReSj/u3yCZzXID4kuKG7OynPnB3WQ==}
791
797
cpu: [ia32]
792
798
os: [win32]
793
799
794
-
'@rollup/rollup-win32-x64-gnu@4.53.3':
795
-
resolution: {integrity: sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==}
800
+
'@rollup/rollup-win32-x64-gnu@4.54.0':
801
+
resolution: {integrity: sha512-dzAc53LOuFvHwbCEOS0rPbXp6SIhAf2txMP5p6mGyOXXw5mWY8NGGbPMPrs4P1WItkfApDathBj/NzMLUZ9rtQ==}
796
802
cpu: [x64]
797
803
os: [win32]
798
804
799
-
'@rollup/rollup-win32-x64-msvc@4.53.3':
800
-
resolution: {integrity: sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==}
805
+
'@rollup/rollup-win32-x64-msvc@4.54.0':
806
+
resolution: {integrity: sha512-hYT5d3YNdSh3mbCU1gwQyPgQd3T2ne0A3KG8KSBdav5TiBg6eInVmV+TeR5uHufiIgSFg0XsOWGW5/RhNcSvPg==}
801
807
cpu: [x64]
802
808
os: [win32]
803
809
···
814
820
peerDependencies:
815
821
solid-js: ^1.8.6
816
822
817
-
'@standard-schema/spec@1.0.0':
818
-
resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==}
823
+
'@standard-schema/spec@1.1.0':
824
+
resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
819
825
820
826
'@tailwindcss/node@4.1.18':
821
827
resolution: {integrity: sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==}
···
922
928
'@types/estree@1.0.8':
923
929
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
924
930
931
+
'@types/node@22.19.3':
932
+
resolution: {integrity: sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==}
933
+
925
934
'@types/node@24.10.1':
926
935
resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==}
927
936
···
944
953
solid-js:
945
954
optional: true
946
955
947
-
baseline-browser-mapping@2.9.7:
948
-
resolution: {integrity: sha512-k9xFKplee6KIio3IDbwj+uaCLpqzOwakOgmqzPezM0sFJlFKcg30vk2wOiAJtkTSfx0SSQDSe8q+mWA/fSH5Zg==}
956
+
baseline-browser-mapping@2.9.11:
957
+
resolution: {integrity: sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==}
949
958
hasBin: true
950
959
951
960
boolbase@1.0.0:
···
956
965
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
957
966
hasBin: true
958
967
959
-
caniuse-lite@1.0.30001760:
960
-
resolution: {integrity: sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==}
968
+
caniuse-lite@1.0.30001761:
969
+
resolution: {integrity: sha512-JF9ptu1vP2coz98+5051jZ4PwQgd2ni8A+gYSN7EA7dPKIMf0pDlSUxhdmVOaV3/fYK5uWBkgSXJaRLr4+3A6g==}
961
970
962
971
codemirror@6.0.2:
963
972
resolution: {integrity: sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==}
···
1043
1052
engines: {node: '>=18'}
1044
1053
hasBin: true
1045
1054
1046
-
esbuild@0.25.12:
1047
-
resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==}
1055
+
esbuild@0.27.2:
1056
+
resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==}
1048
1057
engines: {node: '>=18'}
1049
1058
hasBin: true
1050
1059
···
1195
1204
mlly@1.8.0:
1196
1205
resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==}
1197
1206
1198
-
modern-tar@0.7.2:
1199
-
resolution: {integrity: sha512-TGG1ZRk1TAQ3neuZwahAHke3rKsSlro+ooMYtjh9sl2gGPVMLMuWiHgwC7im9T5bSM566RSo2Dko56ETgEvZcA==}
1207
+
modern-tar@0.7.3:
1208
+
resolution: {integrity: sha512-4W79zekKGyYU4JXVmB78DOscMFaJth2gGhgfTl2alWE4rNe3nf4N2pqenQ0rEtIewrnD79M687Ouba3YGTLOvg==}
1200
1209
engines: {node: '>=18.0.0'}
1201
1210
1202
1211
ms@2.1.3:
···
1214
1223
nanoid@5.1.6:
1215
1224
resolution: {integrity: sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==}
1216
1225
engines: {node: ^18 || >=20}
1226
+
hasBin: true
1227
+
1228
+
node-gyp-build@4.8.4:
1229
+
resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==}
1217
1230
hasBin: true
1218
1231
1219
1232
node-releases@2.0.27:
···
1318
1331
resolve-pkg-maps@1.0.0:
1319
1332
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
1320
1333
1321
-
rollup@4.53.3:
1322
-
resolution: {integrity: sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==}
1334
+
rollup@4.54.0:
1335
+
resolution: {integrity: sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw==}
1323
1336
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
1324
1337
hasBin: true
1325
1338
···
1388
1401
ufo@1.6.1:
1389
1402
resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==}
1390
1403
1404
+
undici-types@6.21.0:
1405
+
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
1406
+
1391
1407
undici-types@7.16.0:
1392
1408
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
1393
1409
1394
-
update-browserslist-db@1.2.2:
1395
-
resolution: {integrity: sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==}
1410
+
unicode-segmenter@0.14.4:
1411
+
resolution: {integrity: sha512-pR5VCiCrLrKOL6FRW61jnk9+wyMtKKowq+jyFY9oc6uHbWKhDL4yVRiI4YZPksGMK72Pahh8m0cn/0JvbDDyJg==}
1412
+
1413
+
update-browserslist-db@1.2.3:
1414
+
resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==}
1396
1415
hasBin: true
1397
1416
peerDependencies:
1398
1417
browserslist: '>= 4.21.0'
···
1407
1426
'@testing-library/jest-dom':
1408
1427
optional: true
1409
1428
1410
-
vite@7.2.7:
1411
-
resolution: {integrity: sha512-ITcnkFeR3+fI8P1wMgItjGrR10170d8auB4EpMLPqmx6uxElH3a/hHGQabSHKdqd4FXWO1nFIp9rRn7JQ34ACQ==}
1429
+
vite@7.3.0:
1430
+
resolution: {integrity: sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==}
1412
1431
engines: {node: ^20.19.0 || >=22.12.0}
1413
1432
hasBin: true
1414
1433
peerDependencies:
···
1474
1493
1475
1494
'@atcute/atproto@3.1.9':
1476
1495
dependencies:
1477
-
'@atcute/lexicons': 1.2.5
1496
+
'@atcute/lexicons': 1.2.6
1478
1497
1479
1498
'@atcute/bluesky@3.2.14':
1480
1499
dependencies:
1481
1500
'@atcute/atproto': 3.1.9
1482
-
'@atcute/lexicons': 1.2.5
1501
+
'@atcute/lexicons': 1.2.6
1483
1502
1484
1503
'@atcute/car@3.1.3':
1485
1504
dependencies:
1486
1505
'@atcute/cbor': 2.2.8
1487
-
'@atcute/cid': 2.2.6
1506
+
'@atcute/cid': 2.3.0
1488
1507
'@atcute/uint8array': 1.0.6
1489
1508
'@atcute/varint': 1.0.3
1490
1509
yocto-queue: 1.2.2
···
1492
1511
'@atcute/car@5.0.0':
1493
1512
dependencies:
1494
1513
'@atcute/cbor': 2.2.8
1495
-
'@atcute/cid': 2.2.6
1514
+
'@atcute/cid': 2.3.0
1496
1515
'@atcute/uint8array': 1.0.6
1497
1516
'@atcute/varint': 1.0.3
1498
1517
1499
1518
'@atcute/cbor@2.2.8':
1500
1519
dependencies:
1501
-
'@atcute/cid': 2.2.6
1520
+
'@atcute/cid': 2.3.0
1502
1521
'@atcute/multibase': 1.1.6
1503
1522
'@atcute/uint8array': 1.0.6
1504
1523
1505
-
'@atcute/cid@2.2.6':
1524
+
'@atcute/cid@2.3.0':
1506
1525
dependencies:
1507
1526
'@atcute/multibase': 1.1.6
1508
1527
'@atcute/uint8array': 1.0.6
1509
1528
1510
-
'@atcute/client@4.1.1':
1529
+
'@atcute/client@4.1.2':
1511
1530
dependencies:
1512
1531
'@atcute/identity': 1.1.3
1513
-
'@atcute/lexicons': 1.2.5
1532
+
'@atcute/lexicons': 1.2.6
1514
1533
1515
1534
'@atcute/crypto@2.3.0':
1516
1535
dependencies:
···
1518
1537
'@atcute/uint8array': 1.0.6
1519
1538
'@noble/secp256k1': 3.0.0
1520
1539
1521
-
'@atcute/did-plc@0.2.0':
1540
+
'@atcute/did-plc@0.3.1':
1522
1541
dependencies:
1523
1542
'@atcute/cbor': 2.2.8
1524
-
'@atcute/cid': 2.2.6
1543
+
'@atcute/cid': 2.3.0
1525
1544
'@atcute/crypto': 2.3.0
1526
1545
'@atcute/identity': 1.1.3
1527
-
'@atcute/lexicons': 1.2.5
1546
+
'@atcute/lexicons': 1.2.6
1528
1547
'@atcute/multibase': 1.1.6
1529
1548
'@atcute/uint8array': 1.0.6
1549
+
'@atcute/util-fetch': 1.0.4
1530
1550
'@badrap/valita': 0.4.6
1531
1551
1532
-
'@atcute/identity-resolver@1.2.0(@atcute/identity@1.1.3)':
1552
+
'@atcute/identity-resolver@1.2.1(@atcute/identity@1.1.3)':
1533
1553
dependencies:
1534
1554
'@atcute/identity': 1.1.3
1535
-
'@atcute/lexicons': 1.2.5
1555
+
'@atcute/lexicons': 1.2.6
1536
1556
'@atcute/util-fetch': 1.0.4
1537
1557
'@badrap/valita': 0.4.6
1538
1558
1539
1559
'@atcute/identity@1.1.3':
1540
1560
dependencies:
1541
-
'@atcute/lexicons': 1.2.5
1561
+
'@atcute/lexicons': 1.2.6
1542
1562
'@badrap/valita': 0.4.6
1543
1563
1544
1564
'@atcute/leaflet@1.0.14':
1545
1565
dependencies:
1546
1566
'@atcute/atproto': 3.1.9
1547
-
'@atcute/lexicons': 1.2.5
1567
+
'@atcute/lexicons': 1.2.6
1548
1568
1549
-
'@atcute/lexicon-doc@2.0.5':
1569
+
'@atcute/lexicon-doc@2.0.6':
1550
1570
dependencies:
1551
1571
'@atcute/identity': 1.1.3
1552
-
'@atcute/lexicons': 1.2.5
1572
+
'@atcute/lexicons': 1.2.6
1573
+
'@atcute/uint8array': 1.0.6
1574
+
'@atcute/util-text': 0.0.1
1553
1575
'@badrap/valita': 0.4.6
1554
1576
1555
-
'@atcute/lexicon-resolver@0.1.5(@atcute/identity-resolver@1.2.0(@atcute/identity@1.1.3))(@atcute/identity@1.1.3)':
1577
+
'@atcute/lexicon-resolver@0.1.5(@atcute/identity-resolver@1.2.1(@atcute/identity@1.1.3))(@atcute/identity@1.1.3)':
1556
1578
dependencies:
1557
1579
'@atcute/crypto': 2.3.0
1558
1580
'@atcute/identity': 1.1.3
1559
-
'@atcute/identity-resolver': 1.2.0(@atcute/identity@1.1.3)
1560
-
'@atcute/lexicon-doc': 2.0.5
1561
-
'@atcute/lexicons': 1.2.5
1562
-
'@atcute/repo': 0.1.0
1581
+
'@atcute/identity-resolver': 1.2.1(@atcute/identity@1.1.3)
1582
+
'@atcute/lexicon-doc': 2.0.6
1583
+
'@atcute/lexicons': 1.2.6
1584
+
'@atcute/repo': 0.1.1
1563
1585
'@atcute/util-fetch': 1.0.4
1564
1586
'@badrap/valita': 0.4.6
1565
1587
1566
-
'@atcute/lexicons@1.2.5':
1588
+
'@atcute/lexicons@1.2.6':
1567
1589
dependencies:
1568
-
'@standard-schema/spec': 1.0.0
1590
+
'@atcute/uint8array': 1.0.6
1591
+
'@atcute/util-text': 0.0.1
1592
+
'@standard-schema/spec': 1.1.0
1569
1593
esm-env: 1.2.2
1570
1594
1571
-
'@atcute/mst@0.1.0':
1595
+
'@atcute/mst@0.1.1':
1572
1596
dependencies:
1573
1597
'@atcute/cbor': 2.2.8
1574
-
'@atcute/cid': 2.2.6
1598
+
'@atcute/cid': 2.3.0
1575
1599
'@atcute/uint8array': 1.0.6
1576
1600
1577
1601
'@atcute/multibase@1.1.6':
···
1580
1604
1581
1605
'@atcute/oauth-browser-client@2.0.3(@atcute/identity@1.1.3)':
1582
1606
dependencies:
1583
-
'@atcute/client': 4.1.1
1584
-
'@atcute/identity-resolver': 1.2.0(@atcute/identity@1.1.3)
1585
-
'@atcute/lexicons': 1.2.5
1607
+
'@atcute/client': 4.1.2
1608
+
'@atcute/identity-resolver': 1.2.1(@atcute/identity@1.1.3)
1609
+
'@atcute/lexicons': 1.2.6
1586
1610
'@atcute/multibase': 1.1.6
1587
1611
'@atcute/uint8array': 1.0.6
1588
1612
nanoid: 5.1.6
1589
1613
transitivePeerDependencies:
1590
1614
- '@atcute/identity'
1591
1615
1592
-
'@atcute/repo@0.1.0':
1616
+
'@atcute/repo@0.1.1':
1593
1617
dependencies:
1594
1618
'@atcute/car': 5.0.0
1595
1619
'@atcute/cbor': 2.2.8
1596
-
'@atcute/cid': 2.2.6
1620
+
'@atcute/cid': 2.3.0
1597
1621
'@atcute/crypto': 2.3.0
1598
-
'@atcute/lexicons': 1.2.5
1599
-
'@atcute/mst': 0.1.0
1622
+
'@atcute/lexicons': 1.2.6
1623
+
'@atcute/mst': 0.1.1
1600
1624
'@atcute/uint8array': 1.0.6
1601
1625
1602
1626
'@atcute/tangled@1.0.13':
1603
1627
dependencies:
1604
1628
'@atcute/atproto': 3.1.9
1605
-
'@atcute/lexicons': 1.2.5
1629
+
'@atcute/lexicons': 1.2.6
1606
1630
1607
-
'@atcute/tid@1.0.3': {}
1631
+
'@atcute/tid@1.1.0':
1632
+
dependencies:
1633
+
'@atcute/time-ms': 1.0.0
1634
+
1635
+
'@atcute/time-ms@1.0.0':
1636
+
dependencies:
1637
+
'@types/node': 22.19.3
1638
+
node-gyp-build: 4.8.4
1608
1639
1609
1640
'@atcute/uint8array@1.0.6': {}
1610
1641
1611
1642
'@atcute/util-fetch@1.0.4':
1612
1643
dependencies:
1613
1644
'@badrap/valita': 0.4.6
1645
+
1646
+
'@atcute/util-text@0.0.1':
1647
+
dependencies:
1648
+
unicode-segmenter: 0.14.4
1614
1649
1615
1650
'@atcute/varint@1.0.3': {}
1616
1651
···
1729
1764
1730
1765
'@codemirror/autocomplete@6.20.0':
1731
1766
dependencies:
1732
-
'@codemirror/language': 6.11.3
1733
-
'@codemirror/state': 6.5.2
1734
-
'@codemirror/view': 6.39.4
1735
-
'@lezer/common': 1.4.0
1767
+
'@codemirror/language': 6.12.1
1768
+
'@codemirror/state': 6.5.3
1769
+
'@codemirror/view': 6.39.7
1770
+
'@lezer/common': 1.5.0
1736
1771
1737
-
'@codemirror/commands@6.10.0':
1772
+
'@codemirror/commands@6.10.1':
1738
1773
dependencies:
1739
-
'@codemirror/language': 6.11.3
1740
-
'@codemirror/state': 6.5.2
1741
-
'@codemirror/view': 6.39.4
1742
-
'@lezer/common': 1.4.0
1774
+
'@codemirror/language': 6.12.1
1775
+
'@codemirror/state': 6.5.3
1776
+
'@codemirror/view': 6.39.7
1777
+
'@lezer/common': 1.5.0
1743
1778
1744
1779
'@codemirror/lang-json@6.0.2':
1745
1780
dependencies:
1746
-
'@codemirror/language': 6.11.3
1781
+
'@codemirror/language': 6.12.1
1747
1782
'@lezer/json': 1.0.3
1748
1783
1749
-
'@codemirror/language@6.11.3':
1784
+
'@codemirror/language@6.12.1':
1750
1785
dependencies:
1751
-
'@codemirror/state': 6.5.2
1752
-
'@codemirror/view': 6.39.4
1753
-
'@lezer/common': 1.4.0
1786
+
'@codemirror/state': 6.5.3
1787
+
'@codemirror/view': 6.39.7
1788
+
'@lezer/common': 1.5.0
1754
1789
'@lezer/highlight': 1.2.3
1755
1790
'@lezer/lr': 1.4.5
1756
1791
style-mod: 4.1.3
1757
1792
1758
1793
'@codemirror/lint@6.9.2':
1759
1794
dependencies:
1760
-
'@codemirror/state': 6.5.2
1761
-
'@codemirror/view': 6.39.4
1795
+
'@codemirror/state': 6.5.3
1796
+
'@codemirror/view': 6.39.7
1762
1797
crelt: 1.0.6
1763
1798
1764
1799
'@codemirror/search@6.5.11':
1765
1800
dependencies:
1766
-
'@codemirror/state': 6.5.2
1767
-
'@codemirror/view': 6.39.4
1801
+
'@codemirror/state': 6.5.3
1802
+
'@codemirror/view': 6.39.7
1768
1803
crelt: 1.0.6
1769
1804
1770
-
'@codemirror/state@6.5.2':
1805
+
'@codemirror/state@6.5.3':
1771
1806
dependencies:
1772
1807
'@marijn/find-cluster-break': 1.0.2
1773
1808
1774
-
'@codemirror/view@6.39.4':
1809
+
'@codemirror/view@6.39.7':
1775
1810
dependencies:
1776
-
'@codemirror/state': 6.5.2
1811
+
'@codemirror/state': 6.5.3
1777
1812
crelt: 1.0.6
1778
1813
style-mod: 4.1.3
1779
1814
w3c-keyname: 2.2.8
···
1785
1820
'@esbuild/aix-ppc64@0.23.1':
1786
1821
optional: true
1787
1822
1788
-
'@esbuild/aix-ppc64@0.25.12':
1823
+
'@esbuild/aix-ppc64@0.27.2':
1789
1824
optional: true
1790
1825
1791
1826
'@esbuild/android-arm64@0.23.1':
1792
1827
optional: true
1793
1828
1794
-
'@esbuild/android-arm64@0.25.12':
1829
+
'@esbuild/android-arm64@0.27.2':
1795
1830
optional: true
1796
1831
1797
1832
'@esbuild/android-arm@0.23.1':
1798
1833
optional: true
1799
1834
1800
-
'@esbuild/android-arm@0.25.12':
1835
+
'@esbuild/android-arm@0.27.2':
1801
1836
optional: true
1802
1837
1803
1838
'@esbuild/android-x64@0.23.1':
1804
1839
optional: true
1805
1840
1806
-
'@esbuild/android-x64@0.25.12':
1841
+
'@esbuild/android-x64@0.27.2':
1807
1842
optional: true
1808
1843
1809
1844
'@esbuild/darwin-arm64@0.23.1':
1810
1845
optional: true
1811
1846
1812
-
'@esbuild/darwin-arm64@0.25.12':
1847
+
'@esbuild/darwin-arm64@0.27.2':
1813
1848
optional: true
1814
1849
1815
1850
'@esbuild/darwin-x64@0.23.1':
1816
1851
optional: true
1817
1852
1818
-
'@esbuild/darwin-x64@0.25.12':
1853
+
'@esbuild/darwin-x64@0.27.2':
1819
1854
optional: true
1820
1855
1821
1856
'@esbuild/freebsd-arm64@0.23.1':
1822
1857
optional: true
1823
1858
1824
-
'@esbuild/freebsd-arm64@0.25.12':
1859
+
'@esbuild/freebsd-arm64@0.27.2':
1825
1860
optional: true
1826
1861
1827
1862
'@esbuild/freebsd-x64@0.23.1':
1828
1863
optional: true
1829
1864
1830
-
'@esbuild/freebsd-x64@0.25.12':
1865
+
'@esbuild/freebsd-x64@0.27.2':
1831
1866
optional: true
1832
1867
1833
1868
'@esbuild/linux-arm64@0.23.1':
1834
1869
optional: true
1835
1870
1836
-
'@esbuild/linux-arm64@0.25.12':
1871
+
'@esbuild/linux-arm64@0.27.2':
1837
1872
optional: true
1838
1873
1839
1874
'@esbuild/linux-arm@0.23.1':
1840
1875
optional: true
1841
1876
1842
-
'@esbuild/linux-arm@0.25.12':
1877
+
'@esbuild/linux-arm@0.27.2':
1843
1878
optional: true
1844
1879
1845
1880
'@esbuild/linux-ia32@0.23.1':
1846
1881
optional: true
1847
1882
1848
-
'@esbuild/linux-ia32@0.25.12':
1883
+
'@esbuild/linux-ia32@0.27.2':
1849
1884
optional: true
1850
1885
1851
1886
'@esbuild/linux-loong64@0.23.1':
1852
1887
optional: true
1853
1888
1854
-
'@esbuild/linux-loong64@0.25.12':
1889
+
'@esbuild/linux-loong64@0.27.2':
1855
1890
optional: true
1856
1891
1857
1892
'@esbuild/linux-mips64el@0.23.1':
1858
1893
optional: true
1859
1894
1860
-
'@esbuild/linux-mips64el@0.25.12':
1895
+
'@esbuild/linux-mips64el@0.27.2':
1861
1896
optional: true
1862
1897
1863
1898
'@esbuild/linux-ppc64@0.23.1':
1864
1899
optional: true
1865
1900
1866
-
'@esbuild/linux-ppc64@0.25.12':
1901
+
'@esbuild/linux-ppc64@0.27.2':
1867
1902
optional: true
1868
1903
1869
1904
'@esbuild/linux-riscv64@0.23.1':
1870
1905
optional: true
1871
1906
1872
-
'@esbuild/linux-riscv64@0.25.12':
1907
+
'@esbuild/linux-riscv64@0.27.2':
1873
1908
optional: true
1874
1909
1875
1910
'@esbuild/linux-s390x@0.23.1':
1876
1911
optional: true
1877
1912
1878
-
'@esbuild/linux-s390x@0.25.12':
1913
+
'@esbuild/linux-s390x@0.27.2':
1879
1914
optional: true
1880
1915
1881
1916
'@esbuild/linux-x64@0.23.1':
1882
1917
optional: true
1883
1918
1884
-
'@esbuild/linux-x64@0.25.12':
1919
+
'@esbuild/linux-x64@0.27.2':
1885
1920
optional: true
1886
1921
1887
-
'@esbuild/netbsd-arm64@0.25.12':
1922
+
'@esbuild/netbsd-arm64@0.27.2':
1888
1923
optional: true
1889
1924
1890
1925
'@esbuild/netbsd-x64@0.23.1':
1891
1926
optional: true
1892
1927
1893
-
'@esbuild/netbsd-x64@0.25.12':
1928
+
'@esbuild/netbsd-x64@0.27.2':
1894
1929
optional: true
1895
1930
1896
1931
'@esbuild/openbsd-arm64@0.23.1':
1897
1932
optional: true
1898
1933
1899
-
'@esbuild/openbsd-arm64@0.25.12':
1934
+
'@esbuild/openbsd-arm64@0.27.2':
1900
1935
optional: true
1901
1936
1902
1937
'@esbuild/openbsd-x64@0.23.1':
1903
1938
optional: true
1904
1939
1905
-
'@esbuild/openbsd-x64@0.25.12':
1940
+
'@esbuild/openbsd-x64@0.27.2':
1906
1941
optional: true
1907
1942
1908
-
'@esbuild/openharmony-arm64@0.25.12':
1943
+
'@esbuild/openharmony-arm64@0.27.2':
1909
1944
optional: true
1910
1945
1911
1946
'@esbuild/sunos-x64@0.23.1':
1912
1947
optional: true
1913
1948
1914
-
'@esbuild/sunos-x64@0.25.12':
1949
+
'@esbuild/sunos-x64@0.27.2':
1915
1950
optional: true
1916
1951
1917
1952
'@esbuild/win32-arm64@0.23.1':
1918
1953
optional: true
1919
1954
1920
-
'@esbuild/win32-arm64@0.25.12':
1955
+
'@esbuild/win32-arm64@0.27.2':
1921
1956
optional: true
1922
1957
1923
1958
'@esbuild/win32-ia32@0.23.1':
1924
1959
optional: true
1925
1960
1926
-
'@esbuild/win32-ia32@0.25.12':
1961
+
'@esbuild/win32-ia32@0.27.2':
1927
1962
optional: true
1928
1963
1929
1964
'@esbuild/win32-x64@0.23.1':
1930
1965
optional: true
1931
1966
1932
-
'@esbuild/win32-x64@0.25.12':
1967
+
'@esbuild/win32-x64@0.27.2':
1933
1968
optional: true
1934
1969
1935
-
'@fsegurai/codemirror-theme-basic-dark@6.2.3(@codemirror/language@6.11.3)(@codemirror/state@6.5.2)(@codemirror/view@6.39.4)(@lezer/highlight@1.2.3)':
1970
+
'@fsegurai/codemirror-theme-basic-dark@6.2.3(@codemirror/language@6.12.1)(@codemirror/state@6.5.3)(@codemirror/view@6.39.7)(@lezer/highlight@1.2.3)':
1936
1971
dependencies:
1937
-
'@codemirror/language': 6.11.3
1938
-
'@codemirror/state': 6.5.2
1939
-
'@codemirror/view': 6.39.4
1972
+
'@codemirror/language': 6.12.1
1973
+
'@codemirror/state': 6.5.3
1974
+
'@codemirror/view': 6.39.7
1940
1975
'@lezer/highlight': 1.2.3
1941
1976
1942
-
'@fsegurai/codemirror-theme-basic-light@6.2.3(@codemirror/language@6.11.3)(@codemirror/state@6.5.2)(@codemirror/view@6.39.4)(@lezer/highlight@1.2.3)':
1977
+
'@fsegurai/codemirror-theme-basic-light@6.2.3(@codemirror/language@6.12.1)(@codemirror/state@6.5.3)(@codemirror/view@6.39.7)(@lezer/highlight@1.2.3)':
1943
1978
dependencies:
1944
-
'@codemirror/language': 6.11.3
1945
-
'@codemirror/state': 6.5.2
1946
-
'@codemirror/view': 6.39.4
1979
+
'@codemirror/language': 6.12.1
1980
+
'@codemirror/state': 6.5.3
1981
+
'@codemirror/view': 6.39.7
1947
1982
'@lezer/highlight': 1.2.3
1948
1983
1949
-
'@iconify-json/lucide@1.2.81':
1984
+
'@iconify-json/lucide@1.2.82':
1950
1985
dependencies:
1951
1986
'@iconify/types': 2.0.0
1952
1987
1953
1988
'@iconify/tailwind4@1.2.0(tailwindcss@4.1.18)':
1954
1989
dependencies:
1955
-
'@iconify/tools': 5.0.0
1990
+
'@iconify/tools': 5.0.1
1956
1991
'@iconify/types': 2.0.0
1957
1992
'@iconify/utils': 3.1.0
1958
1993
tailwindcss: 4.1.18
1959
1994
1960
-
'@iconify/tools@5.0.0':
1995
+
'@iconify/tools@5.0.1':
1961
1996
dependencies:
1962
1997
'@cyberalien/svg-utils': 1.0.11
1963
1998
'@iconify/types': 2.0.0
1964
1999
'@iconify/utils': 3.1.0
1965
2000
fflate: 0.8.2
1966
-
modern-tar: 0.7.2
2001
+
modern-tar: 0.7.3
1967
2002
pathe: 2.0.3
1968
2003
svgo: 4.0.0
1969
2004
···
1996
2031
1997
2032
'@jsr/mary__exif-rm@0.2.2': {}
1998
2033
1999
-
'@lezer/common@1.4.0': {}
2034
+
'@lezer/common@1.5.0': {}
2000
2035
2001
2036
'@lezer/highlight@1.2.3':
2002
2037
dependencies:
2003
-
'@lezer/common': 1.4.0
2038
+
'@lezer/common': 1.5.0
2004
2039
2005
2040
'@lezer/json@1.0.3':
2006
2041
dependencies:
2007
-
'@lezer/common': 1.4.0
2042
+
'@lezer/common': 1.5.0
2008
2043
'@lezer/highlight': 1.2.3
2009
2044
'@lezer/lr': 1.4.5
2010
2045
2011
2046
'@lezer/lr@1.4.5':
2012
2047
dependencies:
2013
-
'@lezer/common': 1.4.0
2048
+
'@lezer/common': 1.5.0
2014
2049
2015
2050
'@marijn/find-cluster-break@1.0.2': {}
2016
2051
2017
2052
'@noble/secp256k1@3.0.0': {}
2018
2053
2019
-
'@rollup/rollup-android-arm-eabi@4.53.3':
2054
+
'@rollup/rollup-android-arm-eabi@4.54.0':
2020
2055
optional: true
2021
2056
2022
-
'@rollup/rollup-android-arm64@4.53.3':
2057
+
'@rollup/rollup-android-arm64@4.54.0':
2023
2058
optional: true
2024
2059
2025
-
'@rollup/rollup-darwin-arm64@4.53.3':
2060
+
'@rollup/rollup-darwin-arm64@4.54.0':
2026
2061
optional: true
2027
2062
2028
-
'@rollup/rollup-darwin-x64@4.53.3':
2063
+
'@rollup/rollup-darwin-x64@4.54.0':
2029
2064
optional: true
2030
2065
2031
-
'@rollup/rollup-freebsd-arm64@4.53.3':
2066
+
'@rollup/rollup-freebsd-arm64@4.54.0':
2032
2067
optional: true
2033
2068
2034
-
'@rollup/rollup-freebsd-x64@4.53.3':
2069
+
'@rollup/rollup-freebsd-x64@4.54.0':
2035
2070
optional: true
2036
2071
2037
-
'@rollup/rollup-linux-arm-gnueabihf@4.53.3':
2072
+
'@rollup/rollup-linux-arm-gnueabihf@4.54.0':
2038
2073
optional: true
2039
2074
2040
-
'@rollup/rollup-linux-arm-musleabihf@4.53.3':
2075
+
'@rollup/rollup-linux-arm-musleabihf@4.54.0':
2041
2076
optional: true
2042
2077
2043
-
'@rollup/rollup-linux-arm64-gnu@4.53.3':
2078
+
'@rollup/rollup-linux-arm64-gnu@4.54.0':
2044
2079
optional: true
2045
2080
2046
-
'@rollup/rollup-linux-arm64-musl@4.53.3':
2081
+
'@rollup/rollup-linux-arm64-musl@4.54.0':
2047
2082
optional: true
2048
2083
2049
-
'@rollup/rollup-linux-loong64-gnu@4.53.3':
2084
+
'@rollup/rollup-linux-loong64-gnu@4.54.0':
2050
2085
optional: true
2051
2086
2052
-
'@rollup/rollup-linux-ppc64-gnu@4.53.3':
2087
+
'@rollup/rollup-linux-ppc64-gnu@4.54.0':
2053
2088
optional: true
2054
2089
2055
-
'@rollup/rollup-linux-riscv64-gnu@4.53.3':
2090
+
'@rollup/rollup-linux-riscv64-gnu@4.54.0':
2056
2091
optional: true
2057
2092
2058
-
'@rollup/rollup-linux-riscv64-musl@4.53.3':
2093
+
'@rollup/rollup-linux-riscv64-musl@4.54.0':
2059
2094
optional: true
2060
2095
2061
-
'@rollup/rollup-linux-s390x-gnu@4.53.3':
2096
+
'@rollup/rollup-linux-s390x-gnu@4.54.0':
2062
2097
optional: true
2063
2098
2064
-
'@rollup/rollup-linux-x64-gnu@4.53.3':
2099
+
'@rollup/rollup-linux-x64-gnu@4.54.0':
2065
2100
optional: true
2066
2101
2067
-
'@rollup/rollup-linux-x64-musl@4.53.3':
2102
+
'@rollup/rollup-linux-x64-musl@4.54.0':
2068
2103
optional: true
2069
2104
2070
-
'@rollup/rollup-openharmony-arm64@4.53.3':
2105
+
'@rollup/rollup-openharmony-arm64@4.54.0':
2071
2106
optional: true
2072
2107
2073
-
'@rollup/rollup-win32-arm64-msvc@4.53.3':
2108
+
'@rollup/rollup-win32-arm64-msvc@4.54.0':
2074
2109
optional: true
2075
2110
2076
-
'@rollup/rollup-win32-ia32-msvc@4.53.3':
2111
+
'@rollup/rollup-win32-ia32-msvc@4.54.0':
2077
2112
optional: true
2078
2113
2079
-
'@rollup/rollup-win32-x64-gnu@4.53.3':
2114
+
'@rollup/rollup-win32-x64-gnu@4.54.0':
2080
2115
optional: true
2081
2116
2082
-
'@rollup/rollup-win32-x64-msvc@4.53.3':
2117
+
'@rollup/rollup-win32-x64-msvc@4.54.0':
2083
2118
optional: true
2084
2119
2085
2120
'@skyware/firehose@0.5.2':
···
2096
2131
dependencies:
2097
2132
solid-js: 1.9.10
2098
2133
2099
-
'@standard-schema/spec@1.0.0': {}
2134
+
'@standard-schema/spec@1.1.0': {}
2100
2135
2101
2136
'@tailwindcss/node@4.1.18':
2102
2137
dependencies:
···
2159
2194
'@tailwindcss/oxide-win32-arm64-msvc': 4.1.18
2160
2195
'@tailwindcss/oxide-win32-x64-msvc': 4.1.18
2161
2196
2162
-
'@tailwindcss/vite@4.1.18(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2))':
2197
+
'@tailwindcss/vite@4.1.18(vite@7.3.0(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2))':
2163
2198
dependencies:
2164
2199
'@tailwindcss/node': 4.1.18
2165
2200
'@tailwindcss/oxide': 4.1.18
2166
2201
tailwindcss: 4.1.18
2167
-
vite: 7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)
2202
+
vite: 7.3.0(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)
2168
2203
2169
2204
'@types/babel__core@7.20.5':
2170
2205
dependencies:
···
2188
2223
'@babel/types': 7.28.5
2189
2224
2190
2225
'@types/estree@1.0.8': {}
2226
+
2227
+
'@types/node@22.19.3':
2228
+
dependencies:
2229
+
undici-types: 6.21.0
2191
2230
2192
2231
'@types/node@24.10.1':
2193
2232
dependencies:
···
2212
2251
optionalDependencies:
2213
2252
solid-js: 1.9.10
2214
2253
2215
-
baseline-browser-mapping@2.9.7: {}
2254
+
baseline-browser-mapping@2.9.11: {}
2216
2255
2217
2256
boolbase@1.0.0: {}
2218
2257
2219
2258
browserslist@4.28.1:
2220
2259
dependencies:
2221
-
baseline-browser-mapping: 2.9.7
2222
-
caniuse-lite: 1.0.30001760
2260
+
baseline-browser-mapping: 2.9.11
2261
+
caniuse-lite: 1.0.30001761
2223
2262
electron-to-chromium: 1.5.267
2224
2263
node-releases: 2.0.27
2225
-
update-browserslist-db: 1.2.2(browserslist@4.28.1)
2264
+
update-browserslist-db: 1.2.3(browserslist@4.28.1)
2226
2265
2227
-
caniuse-lite@1.0.30001760: {}
2266
+
caniuse-lite@1.0.30001761: {}
2228
2267
2229
2268
codemirror@6.0.2:
2230
2269
dependencies:
2231
2270
'@codemirror/autocomplete': 6.20.0
2232
-
'@codemirror/commands': 6.10.0
2233
-
'@codemirror/language': 6.11.3
2271
+
'@codemirror/commands': 6.10.1
2272
+
'@codemirror/language': 6.12.1
2234
2273
'@codemirror/lint': 6.9.2
2235
2274
'@codemirror/search': 6.5.11
2236
-
'@codemirror/state': 6.5.2
2237
-
'@codemirror/view': 6.39.4
2275
+
'@codemirror/state': 6.5.3
2276
+
'@codemirror/view': 6.39.7
2238
2277
2239
2278
commander@11.1.0: {}
2240
2279
···
2333
2372
'@esbuild/win32-x64': 0.23.1
2334
2373
optional: true
2335
2374
2336
-
esbuild@0.25.12:
2375
+
esbuild@0.27.2:
2337
2376
optionalDependencies:
2338
-
'@esbuild/aix-ppc64': 0.25.12
2339
-
'@esbuild/android-arm': 0.25.12
2340
-
'@esbuild/android-arm64': 0.25.12
2341
-
'@esbuild/android-x64': 0.25.12
2342
-
'@esbuild/darwin-arm64': 0.25.12
2343
-
'@esbuild/darwin-x64': 0.25.12
2344
-
'@esbuild/freebsd-arm64': 0.25.12
2345
-
'@esbuild/freebsd-x64': 0.25.12
2346
-
'@esbuild/linux-arm': 0.25.12
2347
-
'@esbuild/linux-arm64': 0.25.12
2348
-
'@esbuild/linux-ia32': 0.25.12
2349
-
'@esbuild/linux-loong64': 0.25.12
2350
-
'@esbuild/linux-mips64el': 0.25.12
2351
-
'@esbuild/linux-ppc64': 0.25.12
2352
-
'@esbuild/linux-riscv64': 0.25.12
2353
-
'@esbuild/linux-s390x': 0.25.12
2354
-
'@esbuild/linux-x64': 0.25.12
2355
-
'@esbuild/netbsd-arm64': 0.25.12
2356
-
'@esbuild/netbsd-x64': 0.25.12
2357
-
'@esbuild/openbsd-arm64': 0.25.12
2358
-
'@esbuild/openbsd-x64': 0.25.12
2359
-
'@esbuild/openharmony-arm64': 0.25.12
2360
-
'@esbuild/sunos-x64': 0.25.12
2361
-
'@esbuild/win32-arm64': 0.25.12
2362
-
'@esbuild/win32-ia32': 0.25.12
2363
-
'@esbuild/win32-x64': 0.25.12
2377
+
'@esbuild/aix-ppc64': 0.27.2
2378
+
'@esbuild/android-arm': 0.27.2
2379
+
'@esbuild/android-arm64': 0.27.2
2380
+
'@esbuild/android-x64': 0.27.2
2381
+
'@esbuild/darwin-arm64': 0.27.2
2382
+
'@esbuild/darwin-x64': 0.27.2
2383
+
'@esbuild/freebsd-arm64': 0.27.2
2384
+
'@esbuild/freebsd-x64': 0.27.2
2385
+
'@esbuild/linux-arm': 0.27.2
2386
+
'@esbuild/linux-arm64': 0.27.2
2387
+
'@esbuild/linux-ia32': 0.27.2
2388
+
'@esbuild/linux-loong64': 0.27.2
2389
+
'@esbuild/linux-mips64el': 0.27.2
2390
+
'@esbuild/linux-ppc64': 0.27.2
2391
+
'@esbuild/linux-riscv64': 0.27.2
2392
+
'@esbuild/linux-s390x': 0.27.2
2393
+
'@esbuild/linux-x64': 0.27.2
2394
+
'@esbuild/netbsd-arm64': 0.27.2
2395
+
'@esbuild/netbsd-x64': 0.27.2
2396
+
'@esbuild/openbsd-arm64': 0.27.2
2397
+
'@esbuild/openbsd-x64': 0.27.2
2398
+
'@esbuild/openharmony-arm64': 0.27.2
2399
+
'@esbuild/sunos-x64': 0.27.2
2400
+
'@esbuild/win32-arm64': 0.27.2
2401
+
'@esbuild/win32-ia32': 0.27.2
2402
+
'@esbuild/win32-x64': 0.27.2
2364
2403
2365
2404
escalade@3.2.0: {}
2366
2405
···
2468
2507
pkg-types: 1.3.1
2469
2508
ufo: 1.6.1
2470
2509
2471
-
modern-tar@0.7.2: {}
2510
+
modern-tar@0.7.3: {}
2472
2511
2473
2512
ms@2.1.3: {}
2474
2513
···
2477
2516
nanoid@3.3.11: {}
2478
2517
2479
2518
nanoid@5.1.6: {}
2519
+
2520
+
node-gyp-build@4.8.4: {}
2480
2521
2481
2522
node-releases@2.0.27: {}
2482
2523
···
2524
2565
resolve-pkg-maps@1.0.0:
2525
2566
optional: true
2526
2567
2527
-
rollup@4.53.3:
2568
+
rollup@4.54.0:
2528
2569
dependencies:
2529
2570
'@types/estree': 1.0.8
2530
2571
optionalDependencies:
2531
-
'@rollup/rollup-android-arm-eabi': 4.53.3
2532
-
'@rollup/rollup-android-arm64': 4.53.3
2533
-
'@rollup/rollup-darwin-arm64': 4.53.3
2534
-
'@rollup/rollup-darwin-x64': 4.53.3
2535
-
'@rollup/rollup-freebsd-arm64': 4.53.3
2536
-
'@rollup/rollup-freebsd-x64': 4.53.3
2537
-
'@rollup/rollup-linux-arm-gnueabihf': 4.53.3
2538
-
'@rollup/rollup-linux-arm-musleabihf': 4.53.3
2539
-
'@rollup/rollup-linux-arm64-gnu': 4.53.3
2540
-
'@rollup/rollup-linux-arm64-musl': 4.53.3
2541
-
'@rollup/rollup-linux-loong64-gnu': 4.53.3
2542
-
'@rollup/rollup-linux-ppc64-gnu': 4.53.3
2543
-
'@rollup/rollup-linux-riscv64-gnu': 4.53.3
2544
-
'@rollup/rollup-linux-riscv64-musl': 4.53.3
2545
-
'@rollup/rollup-linux-s390x-gnu': 4.53.3
2546
-
'@rollup/rollup-linux-x64-gnu': 4.53.3
2547
-
'@rollup/rollup-linux-x64-musl': 4.53.3
2548
-
'@rollup/rollup-openharmony-arm64': 4.53.3
2549
-
'@rollup/rollup-win32-arm64-msvc': 4.53.3
2550
-
'@rollup/rollup-win32-ia32-msvc': 4.53.3
2551
-
'@rollup/rollup-win32-x64-gnu': 4.53.3
2552
-
'@rollup/rollup-win32-x64-msvc': 4.53.3
2572
+
'@rollup/rollup-android-arm-eabi': 4.54.0
2573
+
'@rollup/rollup-android-arm64': 4.54.0
2574
+
'@rollup/rollup-darwin-arm64': 4.54.0
2575
+
'@rollup/rollup-darwin-x64': 4.54.0
2576
+
'@rollup/rollup-freebsd-arm64': 4.54.0
2577
+
'@rollup/rollup-freebsd-x64': 4.54.0
2578
+
'@rollup/rollup-linux-arm-gnueabihf': 4.54.0
2579
+
'@rollup/rollup-linux-arm-musleabihf': 4.54.0
2580
+
'@rollup/rollup-linux-arm64-gnu': 4.54.0
2581
+
'@rollup/rollup-linux-arm64-musl': 4.54.0
2582
+
'@rollup/rollup-linux-loong64-gnu': 4.54.0
2583
+
'@rollup/rollup-linux-ppc64-gnu': 4.54.0
2584
+
'@rollup/rollup-linux-riscv64-gnu': 4.54.0
2585
+
'@rollup/rollup-linux-riscv64-musl': 4.54.0
2586
+
'@rollup/rollup-linux-s390x-gnu': 4.54.0
2587
+
'@rollup/rollup-linux-x64-gnu': 4.54.0
2588
+
'@rollup/rollup-linux-x64-musl': 4.54.0
2589
+
'@rollup/rollup-openharmony-arm64': 4.54.0
2590
+
'@rollup/rollup-win32-arm64-msvc': 4.54.0
2591
+
'@rollup/rollup-win32-ia32-msvc': 4.54.0
2592
+
'@rollup/rollup-win32-x64-gnu': 4.54.0
2593
+
'@rollup/rollup-win32-x64-msvc': 4.54.0
2553
2594
fsevents: 2.3.3
2554
2595
2555
2596
sax@1.4.3: {}
···
2614
2655
2615
2656
ufo@1.6.1: {}
2616
2657
2658
+
undici-types@6.21.0: {}
2659
+
2617
2660
undici-types@7.16.0:
2618
2661
optional: true
2619
2662
2620
-
update-browserslist-db@1.2.2(browserslist@4.28.1):
2663
+
unicode-segmenter@0.14.4: {}
2664
+
2665
+
update-browserslist-db@1.2.3(browserslist@4.28.1):
2621
2666
dependencies:
2622
2667
browserslist: 4.28.1
2623
2668
escalade: 3.2.0
2624
2669
picocolors: 1.1.1
2625
2670
2626
-
vite-plugin-solid@2.11.10(solid-js@1.9.10)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)):
2671
+
vite-plugin-solid@2.11.10(solid-js@1.9.10)(vite@7.3.0(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)):
2627
2672
dependencies:
2628
2673
'@babel/core': 7.28.5
2629
2674
'@types/babel__core': 7.20.5
···
2631
2676
merge-anything: 5.1.7
2632
2677
solid-js: 1.9.10
2633
2678
solid-refresh: 0.6.3(solid-js@1.9.10)
2634
-
vite: 7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)
2635
-
vitefu: 1.1.1(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2))
2679
+
vite: 7.3.0(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)
2680
+
vitefu: 1.1.1(vite@7.3.0(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2))
2636
2681
transitivePeerDependencies:
2637
2682
- supports-color
2638
2683
2639
-
vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2):
2684
+
vite@7.3.0(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2):
2640
2685
dependencies:
2641
-
esbuild: 0.25.12
2686
+
esbuild: 0.27.2
2642
2687
fdir: 6.5.0(picomatch@4.0.3)
2643
2688
picomatch: 4.0.3
2644
2689
postcss: 8.5.6
2645
-
rollup: 4.53.3
2690
+
rollup: 4.54.0
2646
2691
tinyglobby: 0.2.15
2647
2692
optionalDependencies:
2648
2693
'@types/node': 24.10.1
···
2651
2696
lightningcss: 1.30.2
2652
2697
tsx: 4.19.2
2653
2698
2654
-
vitefu@1.1.1(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)):
2699
+
vitefu@1.1.1(vite@7.3.0(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)):
2655
2700
optionalDependencies:
2656
-
vite: 7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)
2701
+
vite: 7.3.0(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)
2657
2702
2658
2703
w3c-keyname@2.2.8: {}
2659
2704
+1
-1
src/auth/account.tsx
+1
-1
src/auth/account.tsx
···
140
140
>
141
141
<span class="truncate">{sessions[did]?.handle || did}</span>
142
142
<Show when={did === agent()?.sub && sessions[did].signedIn}>
143
-
<span class="iconify lucide--check shrink-0 text-green-500 dark:text-green-400"></span>
143
+
<span class="iconify lucide--circle-check shrink-0 text-blue-500 dark:text-blue-400"></span>
144
144
</Show>
145
145
<Show when={!sessions[did].signedIn}>
146
146
<span class="iconify lucide--circle-alert shrink-0 text-red-500 dark:text-red-400"></span>
+1
-1
src/auth/login.tsx
+1
-1
src/auth/login.tsx
···
49
49
<label for="username" class="hidden">
50
50
Add account
51
51
</label>
52
-
<div class="dark:bg-dark-100 dark:inset-shadow-dark-200 flex grow items-center gap-2 rounded-lg border-[0.5px] border-neutral-300 bg-white px-2 inset-shadow-xs focus-within:outline-[1px] focus-within:outline-neutral-600 dark:border-neutral-600 dark:focus-within:outline-neutral-400">
52
+
<div class="dark:bg-dark-100 flex grow items-center gap-2 rounded-lg bg-white px-2 outline-1 outline-neutral-200 focus-within:outline-[1.5px] focus-within:outline-neutral-600 dark:outline-neutral-600 dark:focus-within:outline-neutral-400">
53
53
<label
54
54
for="username"
55
55
class="iconify lucide--user-round-plus shrink-0 text-neutral-500 dark:text-neutral-400"
+117
-173
src/components/backlinks.tsx
+117
-173
src/components/backlinks.tsx
···
1
1
import * as TID from "@atcute/tid";
2
2
import { createResource, createSignal, For, onMount, Show } from "solid-js";
3
-
import {
4
-
getAllBacklinks,
5
-
getDidBacklinks,
6
-
getRecordBacklinks,
7
-
LinksWithDids,
8
-
LinksWithRecords,
9
-
} from "../utils/api.js";
3
+
import { getAllBacklinks, getRecordBacklinks, LinksWithRecords } from "../utils/api.js";
10
4
import { localDateFromTimestamp } from "../utils/date.js";
11
5
import { Button } from "./button.jsx";
12
6
13
-
type Backlink = {
7
+
type BacklinksProps = {
8
+
target: string;
9
+
collection: string;
10
+
path: string;
11
+
};
12
+
13
+
type BacklinkEntry = {
14
+
collection: string;
14
15
path: string;
15
16
counts: { distinct_dids: number; records: number };
16
17
};
17
18
18
-
const linksBySource = (links: Record<string, any>) => {
19
-
let out: Record<string, Backlink[]> = {};
19
+
const flattenLinks = (links: Record<string, any>): BacklinkEntry[] => {
20
+
const entries: BacklinkEntry[] = [];
20
21
Object.keys(links)
21
22
.toSorted()
22
23
.forEach((collection) => {
···
24
25
Object.keys(paths)
25
26
.toSorted()
26
27
.forEach((path) => {
27
-
if (paths[path].records === 0) return;
28
-
if (out[collection]) out[collection].push({ path, counts: paths[path] });
29
-
else out[collection] = [{ path, counts: paths[path] }];
28
+
if (paths[path].records > 0) {
29
+
entries.push({ collection, path, counts: paths[path] });
30
+
}
30
31
});
31
32
});
32
-
return out;
33
+
return entries;
33
34
};
34
35
35
-
const Backlinks = (props: { target: string }) => {
36
-
const fetchBacklinks = async () => {
37
-
const res = await getAllBacklinks(props.target);
38
-
return linksBySource(res.links);
39
-
};
36
+
const BacklinkRecords = (props: BacklinksProps & { cursor?: string }) => {
37
+
const [links, setLinks] = createSignal<LinksWithRecords>();
38
+
const [more, setMore] = createSignal(false);
40
39
41
-
const [response] = createResource(fetchBacklinks);
42
-
43
-
const [show, setShow] = createSignal<{
44
-
collection: string;
45
-
path: string;
46
-
showDids: boolean;
47
-
} | null>();
40
+
onMount(async () => {
41
+
const res = await getRecordBacklinks(props.target, props.collection, props.path, props.cursor);
42
+
setLinks(res);
43
+
});
48
44
49
45
return (
50
-
<div class="flex w-full flex-col gap-1 text-sm wrap-anywhere">
51
-
<Show
52
-
when={response() && Object.keys(response()!).length}
53
-
fallback={<p>No backlinks found.</p>}
54
-
>
55
-
<For each={Object.keys(response()!)}>
56
-
{(collection) => (
57
-
<div>
58
-
<div class="flex items-center gap-1">
59
-
<span class="iconify lucide--book-text shrink-0"></span>
60
-
{collection}
61
-
</div>
62
-
<For each={response()![collection]}>
63
-
{({ path, counts }) => (
64
-
<div class="ml-4.5">
65
-
<div class="flex items-center gap-1">
66
-
<span class="iconify lucide--route shrink-0"></span>
67
-
{path.slice(1)}
68
-
</div>
69
-
<div class="ml-4.5">
70
-
<p>
71
-
<button
72
-
class="text-blue-400 hover:underline active:underline"
73
-
onclick={() =>
74
-
(
75
-
show()?.collection === collection &&
76
-
show()?.path === path &&
77
-
!show()?.showDids
78
-
) ?
79
-
setShow(null)
80
-
: setShow({ collection, path, showDids: false })
81
-
}
82
-
>
83
-
{counts.records} record{counts.records < 2 ? "" : "s"}
84
-
</button>
85
-
{" from "}
86
-
<button
87
-
class="text-blue-400 hover:underline active:underline"
88
-
onclick={() =>
89
-
(
90
-
show()?.collection === collection &&
91
-
show()?.path === path &&
92
-
show()?.showDids
93
-
) ?
94
-
setShow(null)
95
-
: setShow({ collection, path, showDids: true })
96
-
}
97
-
>
98
-
{counts.distinct_dids} DID
99
-
{counts.distinct_dids < 2 ? "" : "s"}
100
-
</button>
101
-
</p>
102
-
<Show when={show()?.collection === collection && show()?.path === path}>
103
-
<Show when={show()?.showDids}>
104
-
<p class="w-full font-semibold">Distinct identities</p>
105
-
<BacklinkItems
106
-
target={props.target}
107
-
collection={collection}
108
-
path={path}
109
-
dids={true}
110
-
/>
111
-
</Show>
112
-
<Show when={!show()?.showDids}>
113
-
<p class="w-full font-semibold">Records</p>
114
-
<BacklinkItems
115
-
target={props.target}
116
-
collection={collection}
117
-
path={path}
118
-
dids={false}
119
-
/>
120
-
</Show>
121
-
</Show>
122
-
</div>
123
-
</div>
124
-
)}
125
-
</For>
46
+
<Show when={links()} fallback={<p class="px-3 py-2 text-neutral-500">Loadingโฆ</p>}>
47
+
<For each={links()!.linking_records}>
48
+
{({ did, collection, rkey }) => {
49
+
const timestamp =
50
+
TID.validate(rkey) ? localDateFromTimestamp(TID.parse(rkey).timestamp / 1000) : null;
51
+
return (
52
+
<a
53
+
href={`/at://${did}/${collection}/${rkey}`}
54
+
class="grid grid-cols-[auto_1fr_auto] items-center gap-x-1 px-2 py-1.5 font-mono text-xs select-none hover:bg-neutral-200/50 active:bg-neutral-200/50 sm:gap-x-3 sm:px-3 dark:hover:bg-neutral-700/50 dark:active:bg-neutral-700/50"
55
+
>
56
+
<span class="text-blue-500 dark:text-blue-400">{rkey}</span>
57
+
<span class="truncate text-neutral-700 dark:text-neutral-300" title={did}>
58
+
{did}
59
+
</span>
60
+
<span class="text-neutral-500 tabular-nums dark:text-neutral-400">
61
+
{timestamp ?? ""}
62
+
</span>
63
+
</a>
64
+
);
65
+
}}
66
+
</For>
67
+
<Show when={links()?.cursor}>
68
+
<Show
69
+
when={more()}
70
+
fallback={
71
+
<div class="p-2">
72
+
<Button
73
+
onClick={() => setMore(true)}
74
+
class="dark:hover:bg-dark-200 dark:shadow-dark-700 dark:active:bg-dark-100 box-border flex h-7 w-full items-center justify-center gap-1 rounded border-[0.5px] border-neutral-300 bg-neutral-50 px-2 py-1.5 text-xs shadow-xs select-none hover:bg-neutral-100 active:bg-neutral-200 dark:border-neutral-700 dark:bg-neutral-800"
75
+
>
76
+
Load More
77
+
</Button>
126
78
</div>
127
-
)}
128
-
</For>
79
+
}
80
+
>
81
+
<BacklinkRecords
82
+
target={props.target}
83
+
collection={props.collection}
84
+
path={props.path}
85
+
cursor={links()!.cursor}
86
+
/>
87
+
</Show>
129
88
</Show>
130
-
</div>
89
+
</Show>
131
90
);
132
91
};
133
92
134
-
// switching on !!did everywhere is pretty annoying, this could probably be two components
135
-
// but i don't want to duplicate or think about how to extract the paging logic
136
-
const BacklinkItems = ({
137
-
target,
138
-
collection,
139
-
path,
140
-
dids,
141
-
cursor,
142
-
}: {
143
-
target: string;
144
-
collection: string;
145
-
path: string;
146
-
dids: boolean;
147
-
cursor?: string;
148
-
}) => {
149
-
const [links, setLinks] = createSignal<LinksWithDids | LinksWithRecords>();
150
-
const [more, setMore] = createSignal<boolean>(false);
151
-
152
-
onMount(async () => {
153
-
const links = await (dids ? getDidBacklinks : getRecordBacklinks)(
154
-
target,
155
-
collection,
156
-
path,
157
-
cursor,
158
-
);
159
-
setLinks(links);
93
+
const Backlinks = (props: { target: string }) => {
94
+
const [response] = createResource(async () => {
95
+
const res = await getAllBacklinks(props.target);
96
+
return flattenLinks(res.links);
160
97
});
161
98
162
-
// TODO: could pass the `total` into this component, which can be checked against each call to this endpoint to find if it's stale.
163
-
// also hmm 'total' is misleading/wrong on that api
164
-
165
99
return (
166
-
<Show when={links()} fallback={<p>Loading…</p>}>
167
-
<Show when={dids}>
168
-
<For each={(links() as LinksWithDids).linking_dids}>
169
-
{(did) => (
170
-
<a
171
-
href={`/at://${did}`}
172
-
class="relative flex w-full font-mono text-blue-400 hover:underline active:underline"
173
-
>
174
-
{did}
175
-
</a>
100
+
<div class="flex w-full flex-col gap-3 text-sm">
101
+
<Show when={response()} fallback={<p class="text-neutral-500">Loadingโฆ</p>}>
102
+
<Show when={response()!.length === 0}>
103
+
<p class="text-neutral-500">No backlinks found.</p>
104
+
</Show>
105
+
<For each={response()}>
106
+
{(entry) => (
107
+
<BacklinkSection
108
+
target={props.target}
109
+
collection={entry.collection}
110
+
path={entry.path}
111
+
counts={entry.counts}
112
+
/>
176
113
)}
177
114
</For>
178
115
</Show>
179
-
<Show when={!dids}>
180
-
<For each={(links() as LinksWithRecords).linking_records}>
181
-
{({ did, collection, rkey }) => (
182
-
<p class="relative flex w-full items-center gap-1 font-mono">
183
-
<a
184
-
href={`/at://${did}/${collection}/${rkey}`}
185
-
class="text-blue-400 hover:underline active:underline"
186
-
>
187
-
{rkey}
188
-
</a>
189
-
<span class="text-xs text-neutral-500 dark:text-neutral-400">
190
-
{TID.validate(rkey) ?
191
-
localDateFromTimestamp(TID.parse(rkey).timestamp / 1000)
192
-
: undefined}
193
-
</span>
194
-
</p>
195
-
)}
196
-
</For>
197
-
</Show>
198
-
<Show when={links()?.cursor}>
199
-
<Show when={more()} fallback={<Button onClick={() => setMore(true)}>Load More</Button>}>
200
-
<BacklinkItems
201
-
target={target}
202
-
collection={collection}
203
-
path={path}
204
-
dids={dids}
205
-
cursor={links()!.cursor}
116
+
</div>
117
+
);
118
+
};
119
+
120
+
const BacklinkSection = (
121
+
props: BacklinksProps & { counts: { distinct_dids: number; records: number } },
122
+
) => {
123
+
const [expanded, setExpanded] = createSignal(false);
124
+
125
+
return (
126
+
<div class="overflow-hidden rounded-lg border border-neutral-200 dark:border-neutral-700">
127
+
<button
128
+
class="flex w-full items-center justify-between gap-3 px-3 py-2 text-left hover:bg-neutral-50 dark:hover:bg-neutral-800/50"
129
+
onClick={() => setExpanded(!expanded())}
130
+
>
131
+
<div class="flex min-w-0 flex-1 flex-col">
132
+
<span class="w-full truncate">{props.collection}</span>
133
+
<span class="w-full text-xs wrap-break-word text-neutral-500 dark:text-neutral-400">
134
+
{props.path.slice(1)}
135
+
</span>
136
+
</div>
137
+
<div class="flex shrink-0 items-center gap-2 text-neutral-700 dark:text-neutral-300">
138
+
<span class="text-xs">
139
+
{props.counts.records} from {props.counts.distinct_dids} repo
140
+
{props.counts.distinct_dids > 1 ? "s" : ""}
141
+
</span>
142
+
<span
143
+
class="iconify lucide--chevron-down transition-transform"
144
+
classList={{ "rotate-180": expanded() }}
206
145
/>
207
-
</Show>
146
+
</div>
147
+
</button>
148
+
<Show when={expanded()}>
149
+
<div class="border-t border-neutral-200 bg-neutral-50/50 dark:border-neutral-700 dark:bg-neutral-800/30">
150
+
<BacklinkRecords target={props.target} collection={props.collection} path={props.path} />
151
+
</div>
208
152
</Show>
209
-
</Show>
153
+
</div>
210
154
);
211
155
};
212
156
+90
src/components/create/confirm-submit.tsx
+90
src/components/create/confirm-submit.tsx
···
1
+
import { createSignal, Show } from "solid-js";
2
+
import { Button } from "../button.jsx";
3
+
4
+
export const ConfirmSubmit = (props: {
5
+
isCreate: boolean;
6
+
onConfirm: (validate: boolean | undefined, recreate: boolean) => void;
7
+
onClose: () => void;
8
+
}) => {
9
+
const [validate, setValidate] = createSignal<boolean | undefined>(undefined);
10
+
const [recreate, setRecreate] = createSignal(false);
11
+
12
+
const getValidateLabel = () => {
13
+
return (
14
+
validate() === true ? "True"
15
+
: validate() === false ? "False"
16
+
: "Unset"
17
+
);
18
+
};
19
+
20
+
const cycleValidate = () => {
21
+
setValidate(
22
+
validate() === undefined ? true
23
+
: validate() === true ? false
24
+
: undefined,
25
+
);
26
+
};
27
+
28
+
return (
29
+
<div class="dark:bg-dark-300 dark:shadow-dark-700 absolute top-70 left-[50%] w-[24rem] -translate-x-1/2 rounded-lg border-[0.5px] border-neutral-300 bg-neutral-50 p-4 shadow-md transition-opacity duration-200 dark:border-neutral-700 starting:opacity-0">
30
+
<div class="flex flex-col gap-3 text-sm">
31
+
<h2 class="font-semibold">{props.isCreate ? "Create" : "Edit"} record</h2>
32
+
<div class="flex flex-col gap-1.5">
33
+
<div class="flex items-center gap-2">
34
+
<button
35
+
type="button"
36
+
class="-ml-2 flex min-w-30 items-center gap-1.5 rounded-lg px-2 py-1 text-xs hover:bg-neutral-200/50 dark:hover:bg-neutral-700"
37
+
onClick={cycleValidate}
38
+
>
39
+
<span
40
+
classList={{
41
+
iconify: true,
42
+
"lucide--square-check text-green-500 dark:text-green-400": validate() === true,
43
+
"lucide--square-x text-red-500 dark:text-red-400": validate() === false,
44
+
"lucide--square text-neutral-500 dark:text-neutral-400": validate() === undefined,
45
+
}}
46
+
></span>
47
+
<span>Validate: {getValidateLabel()}</span>
48
+
</button>
49
+
</div>
50
+
<p class="text-xs text-neutral-600 dark:text-neutral-400">
51
+
Set to 'false' to skip lexicon schema validation by the PDS, 'true' to require it, or
52
+
leave unset to validate only for known lexicons.
53
+
</p>
54
+
</div>
55
+
<Show when={!props.isCreate}>
56
+
<div class="flex flex-col gap-1.5">
57
+
<div class="flex items-center gap-2">
58
+
<button
59
+
type="button"
60
+
class="-ml-2 flex items-center gap-1.5 rounded-lg px-2 py-1 text-xs hover:bg-neutral-200/50 dark:hover:bg-neutral-700"
61
+
onClick={() => setRecreate(!recreate())}
62
+
>
63
+
<span
64
+
classList={{
65
+
iconify: true,
66
+
"lucide--square-check text-green-500 dark:text-green-400": recreate(),
67
+
"lucide--square text-neutral-500 dark:text-neutral-400": !recreate(),
68
+
}}
69
+
></span>
70
+
<span>Recreate</span>
71
+
</button>
72
+
</div>
73
+
<p class="text-xs text-neutral-600 dark:text-neutral-400">
74
+
Delete the existing record and create a new one with the same record key.
75
+
</p>
76
+
</div>
77
+
</Show>
78
+
<div class="flex justify-between gap-2">
79
+
<Button onClick={props.onClose}>Cancel</Button>
80
+
<Button
81
+
onClick={() => props.onConfirm(validate(), recreate())}
82
+
class="dark:shadow-dark-700 min-w-12 rounded-lg bg-blue-500 px-2 py-1.5 text-xs text-white shadow-xs select-none hover:bg-blue-600 active:bg-blue-700 dark:bg-blue-600 dark:hover:bg-blue-500 dark:active:bg-blue-400"
83
+
>
84
+
{props.isCreate ? "Create" : "Edit"}
85
+
</Button>
86
+
</div>
87
+
</div>
88
+
</div>
89
+
);
90
+
};
+29
-48
src/components/create/index.tsx
+29
-48
src/components/create/index.tsx
···
20
20
import { addNotification, removeNotification } from "../notification.jsx";
21
21
import { TextInput } from "../text-input.jsx";
22
22
import Tooltip from "../tooltip.jsx";
23
+
import { ConfirmSubmit } from "./confirm-submit";
23
24
import { FileUpload } from "./file-upload";
24
25
import { HandleInput } from "./handle-input";
25
26
import { MenuItem } from "./menu-item";
···
37
38
const [openUpload, setOpenUpload] = createSignal(false);
38
39
const [openInsertMenu, setOpenInsertMenu] = createSignal(false);
39
40
const [openHandleDialog, setOpenHandleDialog] = createSignal(false);
40
-
const [validate, setValidate] = createSignal<boolean | undefined>(undefined);
41
+
const [openConfirmDialog, setOpenConfirmDialog] = createSignal(false);
41
42
const [isMaximized, setIsMaximized] = createSignal(false);
42
43
const [isMinimized, setIsMinimized] = createSignal(false);
43
44
const [collectionError, setCollectionError] = createSignal("");
···
96
97
};
97
98
};
98
99
99
-
const getValidateIcon = () => {
100
-
return (
101
-
validate() === true ? "lucide--circle-check"
102
-
: validate() === false ? "lucide--circle-x"
103
-
: "lucide--circle"
104
-
);
105
-
};
106
-
107
-
const getValidateLabel = () => {
108
-
return (
109
-
validate() === true ? "True"
110
-
: validate() === false ? "False"
111
-
: "Unset"
112
-
);
113
-
};
114
-
115
100
createEffect(() => {
116
101
if (openDialog()) {
117
-
setValidate(undefined);
118
102
setCollectionError("");
119
103
setRkeyError("");
120
104
}
121
105
});
122
106
123
-
const createRecord = async (formData: FormData) => {
107
+
const createRecord = async (validate: boolean | undefined) => {
108
+
const formData = new FormData(formRef);
124
109
const repo = formData.get("repo")?.toString();
125
110
if (!repo) return;
126
111
const rpc = new Client({ handler: new OAuthUserAgent(await getSession(repo as Did)) });
···
139
124
collection: collection ? collection.toString() : record.$type,
140
125
rkey: rkey?.toString().length ? rkey?.toString() : undefined,
141
126
record: record,
142
-
validate: validate(),
127
+
validate: validate,
143
128
},
144
129
});
145
130
if (!res.ok) {
146
131
setNotice(`${res.data.error}: ${res.data.message}`);
147
132
return;
148
133
}
134
+
setOpenConfirmDialog(false);
149
135
setOpenDialog(false);
150
136
const id = addNotification({
151
137
message: "Record created",
···
155
141
navigate(`/${res.data.uri}`);
156
142
};
157
143
158
-
const editRecord = async (recreate?: boolean) => {
144
+
const editRecord = async (validate: boolean | undefined, recreate: boolean) => {
159
145
const record = editorInstance.view.state.doc.toString();
160
146
if (!record) return;
161
147
const rpc = new Client({ handler: agent()! });
···
165
151
const res = await rpc.post("com.atproto.repo.applyWrites", {
166
152
input: {
167
153
repo: agent()!.sub,
168
-
validate: validate(),
154
+
validate: validate,
169
155
writes: [
170
156
{
171
157
collection: params.collection as `${string}.${string}.${string}`,
···
189
175
const res = await rpc.post("com.atproto.repo.applyWrites", {
190
176
input: {
191
177
repo: agent()!.sub,
192
-
validate: validate(),
178
+
validate: validate,
193
179
writes: [
194
180
{
195
181
collection: params.collection as `${string}.${string}.${string}`,
···
205
191
return;
206
192
}
207
193
}
194
+
setOpenConfirmDialog(false);
208
195
setOpenDialog(false);
209
196
const id = addNotification({
210
197
message: "Record edited",
···
418
405
>
419
406
<HandleInput onClose={() => setOpenHandleDialog(false)} />
420
407
</Modal>
408
+
<Modal
409
+
open={openConfirmDialog()}
410
+
onClose={() => setOpenConfirmDialog(false)}
411
+
closeOnClick={false}
412
+
>
413
+
<ConfirmSubmit
414
+
isCreate={props.create}
415
+
onConfirm={(validate, recreate) => {
416
+
if (props.create) {
417
+
createRecord(validate);
418
+
} else {
419
+
editRecord(validate, recreate);
420
+
}
421
+
}}
422
+
onClose={() => setOpenConfirmDialog(false)}
423
+
/>
424
+
</Modal>
421
425
<div class="flex items-center justify-end gap-2">
422
-
<button
423
-
type="button"
424
-
class="flex items-center gap-1 rounded-sm p-1.5 text-xs hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
425
-
onClick={() =>
426
-
setValidate(
427
-
validate() === true ? false
428
-
: validate() === false ? undefined
429
-
: true,
430
-
)
431
-
}
432
-
>
433
-
<Tooltip text={getValidateLabel()}>
434
-
<span class={`iconify ${getValidateIcon()}`}></span>
435
-
</Tooltip>
436
-
<span>Validate</span>
437
-
</button>
438
-
<Show when={!props.create && hasUserScope("create") && hasUserScope("delete")}>
439
-
<Button onClick={() => editRecord(true)}>Recreate</Button>
440
-
</Show>
441
-
<Button
442
-
onClick={() =>
443
-
props.create ? createRecord(new FormData(formRef)) : editRecord()
444
-
}
445
-
>
446
-
{props.create ? "Create" : "Edit"}
426
+
<Button onClick={() => setOpenConfirmDialog(true)}>
427
+
{props.create ? "Create..." : "Edit..."}
447
428
</Button>
448
429
</div>
449
430
</div>
+7
-2
src/components/dropdown.tsx
+7
-2
src/components/dropdown.tsx
···
75
75
export const ActionMenu = (props: {
76
76
label: string;
77
77
icon: string;
78
-
onClick: JSX.EventHandlerUnion<HTMLButtonElement, MouseEvent>;
78
+
onClick: () => void;
79
79
}) => {
80
+
const ctx = useContext(MenuContext);
81
+
80
82
return (
81
83
<button
82
-
onClick={props.onClick}
84
+
onClick={() => {
85
+
props.onClick();
86
+
ctx?.setShowMenu(false);
87
+
}}
83
88
class="flex items-center gap-2 rounded-md p-1.5 whitespace-nowrap hover:bg-neutral-200/50 active:bg-neutral-200 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
84
89
>
85
90
<Show when={props.icon}>
+1
src/components/editor.tsx
+1
src/components/editor.tsx
+70
-56
src/components/json.tsx
+70
-56
src/components/json.tsx
···
1
1
import { isCid, isDid, isNsid, isResourceUri, Nsid } from "@atcute/lexicons/syntax";
2
2
import { A, useNavigate, useParams } from "@solidjs/router";
3
-
import { createEffect, createSignal, ErrorBoundary, For, on, Show } from "solid-js";
3
+
import {
4
+
createContext,
5
+
createEffect,
6
+
createSignal,
7
+
ErrorBoundary,
8
+
For,
9
+
on,
10
+
Show,
11
+
useContext,
12
+
} from "solid-js";
4
13
import { resolveLexiconAuthority } from "../utils/api";
5
14
import { hideMedia } from "../views/settings";
6
15
import { pds } from "./navbar";
7
16
import { addNotification, removeNotification } from "./notification";
8
17
import VideoPlayer from "./video-player";
9
18
19
+
interface JSONContext {
20
+
repo: string;
21
+
truncate?: boolean;
22
+
parentIsBlob?: boolean;
23
+
}
24
+
25
+
const JSONCtx = createContext<JSONContext>();
26
+
const useJSONCtx = () => useContext(JSONCtx)!;
27
+
10
28
interface AtBlob {
11
29
$type: string;
12
30
ref: { $link: string };
13
31
mimeType: string;
14
32
}
15
33
16
-
const JSONString = (props: {
17
-
data: string;
18
-
isType?: boolean;
19
-
isLink?: boolean;
20
-
parentIsBlob?: boolean;
21
-
}) => {
34
+
const isURL =
35
+
URL.canParse ??
36
+
((url, base) => {
37
+
try {
38
+
new URL(url, base);
39
+
return true;
40
+
} catch {
41
+
return false;
42
+
}
43
+
});
44
+
45
+
const JSONString = (props: { data: string; isType?: boolean; isLink?: boolean }) => {
46
+
const ctx = useJSONCtx();
22
47
const navigate = useNavigate();
23
48
const params = useParams();
24
49
25
-
const isURL =
26
-
URL.canParse ??
27
-
((url, base) => {
28
-
try {
29
-
new URL(url, base);
30
-
return true;
31
-
} catch {
32
-
return false;
33
-
}
34
-
});
35
-
36
50
const handleClick = async (lex: string) => {
37
51
try {
38
52
const [nsid, anchor] = lex.split("#");
···
50
64
}
51
65
};
52
66
67
+
const MAX_LENGTH = 200;
68
+
const isTruncated = () => ctx.truncate && props.data.length > MAX_LENGTH;
69
+
const displayData = () => (isTruncated() ? props.data.slice(0, MAX_LENGTH) : props.data);
70
+
const remainingChars = () => props.data.length - MAX_LENGTH;
71
+
53
72
return (
54
73
<span>
55
74
"
56
-
<For each={props.data.split(/(\s)/)}>
75
+
<For each={displayData().split(/(\s)/)}>
57
76
{(part) => (
58
77
<>
59
78
{isResourceUri(part) ?
···
72
91
>
73
92
{part}
74
93
</button>
75
-
: isCid(part) && props.isLink && props.parentIsBlob && params.repo ?
94
+
: isCid(part) && props.isLink && ctx.parentIsBlob && params.repo ?
76
95
<A
77
96
class="text-blue-400 hover:underline active:underline"
78
97
rel="noopener"
···
93
112
</>
94
113
)}
95
114
</For>
115
+
<Show when={isTruncated()}>
116
+
<span>โฆ</span>
117
+
</Show>
96
118
"
119
+
<Show when={isTruncated()}>
120
+
<span class="ml-1 text-neutral-500 dark:text-neutral-400">
121
+
(+{remainingChars().toLocaleString()})
122
+
</span>
123
+
</Show>
97
124
</span>
98
125
);
99
126
};
···
110
137
return <span>null</span>;
111
138
};
112
139
113
-
const JSONObject = (props: {
114
-
data: { [x: string]: JSONType };
115
-
repo: string;
116
-
parentIsBlob?: boolean;
117
-
}) => {
140
+
const JSONObject = (props: { data: { [x: string]: JSONType } }) => {
141
+
const ctx = useJSONCtx();
118
142
const params = useParams();
119
143
const [hide, setHide] = createSignal(
120
144
localStorage.hideMedia === "true" || params.rkey === undefined,
···
136
160
);
137
161
138
162
const isBlob = props.data.$type === "blob";
139
-
const isBlobContext = isBlob || props.parentIsBlob;
163
+
const isBlobContext = isBlob || ctx.parentIsBlob;
140
164
141
165
const Obj = ({ key, value }: { key: string; value: JSONType }) => {
142
166
const [show, setShow] = createSignal(true);
···
169
193
"self-center": value !== Object(value),
170
194
"pl-[calc(2ch-0.5px)] border-l-[0.5px] border-neutral-500/50 dark:border-neutral-400/50 has-hover:group-hover/indent:border-neutral-700 transition-colors dark:has-hover:group-hover/indent:border-neutral-300":
171
195
value === Object(value),
172
-
"invisible h-0": !show(),
196
+
"invisible h-0 overflow-hidden": !show(),
173
197
}}
174
198
>
175
-
<JSONValue
176
-
data={value}
177
-
repo={props.repo}
178
-
isType={key === "$type"}
179
-
isLink={key === "$link"}
180
-
parentIsBlob={isBlobContext}
181
-
/>
199
+
<JSONCtx.Provider value={{ ...ctx, parentIsBlob: isBlobContext }}>
200
+
<JSONValueInner data={value} isType={key === "$type"} isLink={key === "$link"} />
201
+
</JSONCtx.Provider>
182
202
</span>
183
203
</span>
184
204
);
···
200
220
<Show when={blob.mimeType.startsWith("image/")}>
201
221
<img
202
222
class="h-auto max-h-48 max-w-48 object-contain sm:max-h-64 sm:max-w-64"
203
-
src={`https://${pds()}/xrpc/com.atproto.sync.getBlob?did=${props.repo}&cid=${blob.ref.$link}`}
223
+
src={`https://${pds()}/xrpc/com.atproto.sync.getBlob?did=${ctx.repo}&cid=${blob.ref.$link}`}
204
224
onLoad={() => setMediaLoaded(true)}
205
225
/>
206
226
</Show>
207
227
<Show when={blob.mimeType === "video/mp4"}>
208
228
<ErrorBoundary fallback={() => <span>Failed to load video</span>}>
209
229
<VideoPlayer
210
-
did={props.repo}
230
+
did={ctx.repo}
211
231
cid={blob.ref.$link}
212
232
onLoad={() => setMediaLoaded(true)}
213
233
/>
···
241
261
return rawObj;
242
262
};
243
263
244
-
const JSONArray = (props: { data: JSONType[]; repo: string; parentIsBlob?: boolean }) => {
264
+
const JSONArray = (props: { data: JSONType[] }) => {
245
265
return (
246
266
<For each={props.data}>
247
267
{(value, index) => (
···
252
272
}}
253
273
>
254
274
<span class="ml-[1ch] w-full">
255
-
<JSONValue data={value} repo={props.repo} parentIsBlob={props.parentIsBlob} />
275
+
<JSONValueInner data={value} />
256
276
</span>
257
277
</span>
258
278
)}
···
260
280
);
261
281
};
262
282
263
-
export const JSONValue = (props: {
264
-
data: JSONType;
265
-
repo: string;
266
-
isType?: boolean;
267
-
isLink?: boolean;
268
-
parentIsBlob?: boolean;
269
-
}) => {
283
+
const JSONValueInner = (props: { data: JSONType; isType?: boolean; isLink?: boolean }) => {
270
284
const data = props.data;
271
285
if (typeof data === "string")
272
-
return (
273
-
<JSONString
274
-
data={data}
275
-
isType={props.isType}
276
-
isLink={props.isLink}
277
-
parentIsBlob={props.parentIsBlob}
278
-
/>
279
-
);
286
+
return <JSONString data={data} isType={props.isType} isLink={props.isLink} />;
280
287
if (typeof data === "number") return <JSONNumber data={data} />;
281
288
if (typeof data === "boolean") return <JSONBoolean data={data} />;
282
289
if (data === null) return <JSONNull />;
283
-
if (Array.isArray(data))
284
-
return <JSONArray data={data} repo={props.repo} parentIsBlob={props.parentIsBlob} />;
285
-
return <JSONObject data={data} repo={props.repo} parentIsBlob={props.parentIsBlob} />;
290
+
if (Array.isArray(data)) return <JSONArray data={data} />;
291
+
return <JSONObject data={data} />;
292
+
};
293
+
294
+
export const JSONValue = (props: { data: JSONType; repo: string; truncate?: boolean }) => {
295
+
return (
296
+
<JSONCtx.Provider value={{ repo: props.repo, truncate: props.truncate }}>
297
+
<JSONValueInner data={props.data} />
298
+
</JSONCtx.Provider>
299
+
);
286
300
};
287
301
288
302
export type JSONType = string | number | boolean | null | { [x: string]: JSONType } | JSONType[];
+5
-5
src/components/search.tsx
+5
-5
src/components/search.tsx
···
188
188
<label for="input" class="hidden">
189
189
PDS URL, AT URI, NSID, DID, or handle
190
190
</label>
191
-
<div class="dark:bg-dark-100 dark:inset-shadow-dark-200 flex items-center gap-2 rounded-lg border-[0.5px] border-neutral-300 bg-white px-2 inset-shadow-xs focus-within:outline-[1px] focus-within:outline-neutral-600 dark:border-neutral-600 dark:focus-within:outline-neutral-400">
191
+
<div class="dark:bg-dark-100 flex items-center gap-2 rounded-lg bg-white px-2 outline-1 outline-neutral-200 focus-within:outline-[1.5px] focus-within:outline-neutral-600 dark:outline-neutral-600 dark:focus-within:outline-neutral-400">
192
192
<label
193
193
for="input"
194
194
class="iconify lucide--search text-neutral-500 dark:text-neutral-400"
···
312
312
src={actor.avatar?.replace("img/avatar/", "img/avatar_thumbnail/")}
313
313
class="size-9 rounded-full"
314
314
/>
315
-
<div class="flex flex-col">
315
+
<div class="flex min-w-0 flex-col">
316
316
<Show when={actor.displayName}>
317
-
<span class="text-sm font-medium">{actor.displayName}</span>
317
+
<span class="truncate text-sm font-medium">{actor.displayName}</span>
318
318
</Show>
319
-
<span class="text-xs text-neutral-600 dark:text-neutral-400">
319
+
<span class="truncate text-xs text-neutral-600 dark:text-neutral-400">
320
320
@{actor.handle}
321
321
</span>
322
322
</div>
···
382
382
class="flex items-center rounded-md p-1 hover:bg-neutral-100 active:bg-neutral-200 dark:hover:bg-neutral-600 dark:active:bg-neutral-500"
383
383
onClick={() => setOpenList(true)}
384
384
>
385
-
<span class="iconify lucide--help-circle"></span>
385
+
<span class="iconify lucide--help-circle text-neutral-600 dark:text-neutral-300"></span>
386
386
</button>
387
387
</>
388
388
);
+2
-2
src/components/sticky.tsx
+2
-2
src/components/sticky.tsx
···
29
29
/>
30
30
31
31
<div
32
-
class="sticky top-2 z-10 flex w-full flex-col items-center justify-center gap-2 rounded-lg p-3 transition-colors"
32
+
class="sticky top-2 z-10 flex w-full flex-col items-center justify-center gap-2 rounded-lg border-[0.5px] p-3 transition-colors"
33
33
classList={{
34
-
"bg-neutral-50 dark:bg-dark-300 border-[0.5px] border-neutral-300 dark:border-neutral-700 shadow-md":
34
+
"bg-neutral-50 dark:bg-dark-300 border-neutral-300 dark:border-neutral-700 shadow-md":
35
35
filterStuck(),
36
36
"bg-transparent border-transparent shadow-none": !filterStuck(),
37
37
}}
+1
-1
src/components/text-input.tsx
+1
-1
src/components/text-input.tsx
···
25
25
disabled={props.disabled}
26
26
required={props.required}
27
27
class={
28
-
"dark:bg-dark-100 dark:inset-shadow-dark-200 rounded-lg border-[0.5px] border-neutral-300 bg-white px-2 py-1 inset-shadow-xs select-none placeholder:text-sm focus:outline-[1px] focus:outline-neutral-600 dark:border-neutral-600 dark:focus:outline-neutral-400 " +
28
+
"dark:bg-dark-100 rounded-lg bg-white px-2 py-1 outline-1 outline-neutral-200 select-none placeholder:text-sm focus:outline-[1.5px] focus:outline-neutral-600 dark:outline-neutral-600 dark:focus:outline-neutral-400 " +
29
29
props.class
30
30
}
31
31
onInput={props.onInput}
+11
-2
src/layout.tsx
+11
-2
src/layout.tsx
···
118
118
});
119
119
120
120
return (
121
-
<div id="main" class="mx-auto mb-8 flex max-w-lg flex-col items-center p-4">
121
+
<div id="main" class="mx-auto mb-8 flex max-w-lg flex-col items-center p-3">
122
122
<MetaProvider>
123
123
<Show when={location.pathname !== "/"}>
124
124
<Meta name="robots" content="noindex, nofollow" />
···
151
151
<DropdownMenu icon="lucide--menu text-lg" buttonClass="rounded-lg p-1.5">
152
152
<NavMenu href="/jetstream" label="Jetstream" icon="lucide--radio-tower" />
153
153
<NavMenu href="/firehose" label="Firehose" icon="lucide--droplet" />
154
-
<NavMenu href="/labels" label="Labels" icon="lucide--tags" />
154
+
<NavMenu href="/labels" label="Labels" icon="lucide--tag" />
155
155
<NavMenu href="/settings" label="Settings" icon="lucide--settings" />
156
156
<MenuSeparator />
157
157
<NavMenu
···
192
192
</Show>
193
193
</div>
194
194
<NotificationContainer />
195
+
<Show
196
+
when={localStorage.plcDirectory && localStorage.plcDirectory !== "https://plc.directory"}
197
+
>
198
+
<div class="dark:bg-dark-500 fixed right-0 bottom-0 left-0 z-10 flex items-center justify-center bg-neutral-100 px-3 py-1 text-xs">
199
+
<span>
200
+
PLC directory: <span class="font-medium">{localStorage.plcDirectory}</span>
201
+
</span>
202
+
</div>
203
+
</Show>
195
204
</div>
196
205
);
197
206
};
-17
src/utils/api.ts
-17
src/utils/api.ts
···
133
133
linking_records: Array<{ did: string; collection: string; rkey: string }>;
134
134
};
135
135
136
-
type LinksWithDids = {
137
-
cursor: string;
138
-
total: number;
139
-
linking_dids: Array<string>;
140
-
};
141
-
142
136
const getConstellation = async (
143
137
endpoint: string,
144
138
target: string,
···
175
169
): Promise<LinksWithRecords> =>
176
170
getConstellation("/links", target, collection, path, cursor, limit || 100);
177
171
178
-
const getDidBacklinks = (
179
-
target: string,
180
-
collection: string,
181
-
path: string,
182
-
cursor?: string,
183
-
limit?: number,
184
-
): Promise<LinksWithDids> =>
185
-
getConstellation("/links/distinct-dids", target, collection, path, cursor, limit || 100);
186
-
187
172
export {
188
173
didDocCache,
189
174
getAllBacklinks,
190
-
getDidBacklinks,
191
175
getPDS,
192
176
getRecordBacklinks,
193
177
labelerCache,
···
198
182
resolvePDS,
199
183
validateHandle,
200
184
type LinkData,
201
-
type LinksWithDids,
202
185
type LinksWithRecords,
203
186
};
+24
src/utils/route-cache.ts
+24
src/utils/route-cache.ts
···
1
+
import { createStore } from "solid-js/store";
2
+
3
+
export interface CollectionCacheEntry {
4
+
records: unknown[];
5
+
cursor: string | undefined;
6
+
scrollY: number;
7
+
reverse: boolean;
8
+
}
9
+
10
+
type RouteCache = Record<string, CollectionCacheEntry>;
11
+
12
+
const [routeCache, setRouteCache] = createStore<RouteCache>({});
13
+
14
+
export const getCollectionCache = (key: string): CollectionCacheEntry | undefined => {
15
+
return routeCache[key];
16
+
};
17
+
18
+
export const setCollectionCache = (key: string, entry: CollectionCacheEntry): void => {
19
+
setRouteCache(key, entry);
20
+
};
21
+
22
+
export const clearCollectionCache = (key: string): void => {
23
+
setRouteCache(key, undefined!);
24
+
};
+5
-4
src/views/blob.tsx
+5
-4
src/views/blob.tsx
···
30
30
return (
31
31
<div class="flex flex-col items-center gap-2">
32
32
<Show when={blobs() || response()}>
33
-
<div class="flex w-full flex-col gap-0.5 font-mono text-xs wrap-anywhere">
33
+
<div class="flex w-full flex-col gap-0.5 pb-20 font-mono text-xs sm:text-sm">
34
34
<For each={blobs()}>
35
35
{(cid) => (
36
36
<a
37
37
href={`${props.pds}/xrpc/com.atproto.sync.getBlob?did=${props.repo}&cid=${cid}`}
38
38
target="_blank"
39
-
class="w-fit rounded px-0.5 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
39
+
class="truncate rounded px-0.5 text-left text-blue-400 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
40
+
dir="rtl"
40
41
>
41
-
<span class="text-blue-400">{cid}</span>
42
+
{cid}
42
43
</a>
43
44
)}
44
45
</For>
45
46
</div>
46
47
</Show>
47
-
<div class="dark:bg-dark-500 fixed bottom-0 z-5 flex w-screen justify-center bg-neutral-100 py-2">
48
+
<div class="dark:bg-dark-500 fixed bottom-0 z-5 flex w-screen justify-center bg-neutral-100 pt-2 pb-4">
48
49
<div class="flex flex-col items-center gap-1 pb-2">
49
50
<p>
50
51
{blobs()?.length} blob{(blobs()?.length ?? 0 > 1) ? "s" : ""}
+78
-23
src/views/collection.tsx
+78
-23
src/views/collection.tsx
···
2
2
import { Client, simpleFetchHandler } from "@atcute/client";
3
3
import { $type, ActorIdentifier, InferXRPCBodyOutput } from "@atcute/lexicons";
4
4
import * as TID from "@atcute/tid";
5
-
import { A, useParams } from "@solidjs/router";
6
-
import { createEffect, createMemo, createResource, createSignal, For, Show } from "solid-js";
5
+
import { A, useBeforeLeave, useParams } from "@solidjs/router";
6
+
import {
7
+
createEffect,
8
+
createMemo,
9
+
createResource,
10
+
createSignal,
11
+
For,
12
+
onMount,
13
+
Show,
14
+
} from "solid-js";
7
15
import { createStore } from "solid-js/store";
8
16
import { hasUserScope } from "../auth/scope-utils";
9
17
import { agent } from "../auth/state";
···
14
22
import { StickyOverlay } from "../components/sticky.jsx";
15
23
import { TextInput } from "../components/text-input.jsx";
16
24
import Tooltip from "../components/tooltip.jsx";
25
+
import { isTouchDevice } from "../layout.jsx";
17
26
import { resolvePDS } from "../utils/api.js";
18
27
import { localDateFromTimestamp } from "../utils/date.js";
28
+
import {
29
+
clearCollectionCache,
30
+
getCollectionCache,
31
+
setCollectionCache,
32
+
} from "../utils/route-cache.js";
19
33
20
34
interface AtprotoRecord {
21
35
rkey: string;
···
42
56
43
57
return (
44
58
<span
45
-
class="relative flex w-full min-w-0 items-baseline rounded px-0.5 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
59
+
class="relative flex w-full min-w-0 items-baseline rounded p-0.5 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
46
60
ref={rkeyRef}
47
-
onmouseover={() => setHover(true)}
48
-
onmouseleave={() => setHover(false)}
61
+
onmouseover={() => !isTouchDevice && setHover(true)}
62
+
onmouseleave={() => !isTouchDevice && setHover(false)}
49
63
>
50
64
<span class="flex items-baseline truncate">
51
-
<span class="shrink-0 text-sm text-blue-400 sm:text-base">{props.record.rkey}</span>
65
+
<span class="shrink-0 text-sm text-blue-400">{props.record.rkey}</span>
52
66
<span class="ml-1 truncate text-xs text-neutral-500 dark:text-neutral-400" dir="rtl">
53
67
{props.record.cid}
54
68
</span>
···
66
80
<JSONValue
67
81
data={props.record.record.value as JSONType}
68
82
repo={props.record.record.uri.split("/")[2]}
83
+
truncate
69
84
/>
70
85
</span>
71
86
</Show>
···
83
98
const [reverse, setReverse] = createSignal(false);
84
99
const [recreate, setRecreate] = createSignal(false);
85
100
const [openDelete, setOpenDelete] = createSignal(false);
101
+
const [restoredFromCache, setRestoredFromCache] = createSignal(false);
86
102
const did = params.repo;
87
103
let pds: string;
88
104
let rpc: Client;
89
105
106
+
const cacheKey = () => `${params.pds}/${params.repo}/${params.collection}`;
107
+
108
+
onMount(() => {
109
+
const cached = getCollectionCache(cacheKey());
110
+
if (cached) {
111
+
setRecords(cached.records as AtprotoRecord[]);
112
+
setCursor(cached.cursor);
113
+
setReverse(cached.reverse);
114
+
setRestoredFromCache(true);
115
+
requestAnimationFrame(() => {
116
+
window.scrollTo(0, cached.scrollY);
117
+
});
118
+
}
119
+
});
120
+
121
+
useBeforeLeave((e) => {
122
+
const recordPathPrefix = `/at://${did}/${params.collection}/`;
123
+
const isNavigatingToRecord = typeof e.to === "string" && e.to.startsWith(recordPathPrefix);
124
+
125
+
if (isNavigatingToRecord && records.length > 0) {
126
+
setCollectionCache(cacheKey(), {
127
+
records: [...records],
128
+
cursor: cursor(),
129
+
scrollY: window.scrollY,
130
+
reverse: reverse(),
131
+
});
132
+
} else {
133
+
clearCollectionCache(cacheKey());
134
+
}
135
+
});
136
+
90
137
const fetchRecords = async () => {
138
+
if (restoredFromCache() && records.length > 0 && !cursor()) {
139
+
setRestoredFromCache(false);
140
+
return records;
141
+
}
142
+
if (restoredFromCache()) setRestoredFromCache(false);
143
+
91
144
if (!pds) pds = await resolvePDS(did!);
92
145
if (!rpc) rpc = new Client({ handler: simpleFetchHandler({ service: pds }) });
93
146
const res = await rpc.get("com.atproto.repo.listRecords", {
···
166
219
setCursor(undefined);
167
220
setOpenDelete(false);
168
221
setRecreate(false);
222
+
clearCollectionCache(cacheKey());
169
223
refetch();
170
224
};
171
225
···
210
264
setLastSelected(undefined);
211
265
setBatchDelete(!batchDelete());
212
266
}}
213
-
class="flex items-center rounded-md p-1 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
267
+
class="flex items-center rounded-md p-1.5 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
214
268
>
215
269
<span
216
-
class={`iconify text-lg ${batchDelete() ? "lucide--circle-x" : "lucide--trash-2"} `}
270
+
class={`iconify ${batchDelete() ? "lucide--circle-x" : "lucide--trash-2"} `}
217
271
></span>
218
272
</button>
219
273
}
···
224
278
children={
225
279
<button
226
280
onclick={() => selectAll()}
227
-
class="flex items-center rounded-md p-1 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
281
+
class="flex items-center rounded-md p-1.5 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
228
282
>
229
-
<span class="iconify lucide--copy-check text-lg"></span>
283
+
<span class="iconify lucide--copy-check"></span>
230
284
</button>
231
285
}
232
286
/>
···
239
293
setRecreate(true);
240
294
setOpenDelete(true);
241
295
}}
242
-
class="flex items-center rounded-md p-1 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
296
+
class="flex items-center rounded-md p-1.5 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
243
297
>
244
-
<span class="iconify lucide--recycle text-lg text-green-500 dark:text-green-400"></span>
298
+
<span class="iconify lucide--recycle text-green-500 dark:text-green-400"></span>
245
299
</button>
246
300
}
247
301
/>
···
254
308
setRecreate(false);
255
309
setOpenDelete(true);
256
310
}}
257
-
class="flex items-center rounded-md p-1 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
311
+
class="flex items-center rounded-md p-1.5 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
258
312
>
259
-
<span class="iconify lucide--trash-2 text-lg text-red-500 dark:text-red-400"></span>
313
+
<span class="iconify lucide--trash-2 text-red-500 dark:text-red-400"></span>
260
314
</button>
261
315
}
262
316
/>
···
280
334
</div>
281
335
</Modal>
282
336
</Show>
337
+
<TextInput
338
+
name="Filter"
339
+
placeholder="Filter by substring"
340
+
onInput={(e) => setFilter(e.currentTarget.value)}
341
+
class="grow"
342
+
/>
283
343
<Tooltip text="Jetstream">
284
344
<A
285
345
href={`/jetstream?collections=${params.collection}&dids=${params.repo}`}
286
-
class="flex items-center rounded-md p-1 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
346
+
class="flex items-center rounded-md p-1.5 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
287
347
>
288
-
<span class="iconify lucide--radio-tower text-lg"></span>
348
+
<span class="iconify lucide--radio-tower"></span>
289
349
</A>
290
350
</Tooltip>
291
-
<TextInput
292
-
name="Filter"
293
-
placeholder="Filter by substring"
294
-
onInput={(e) => setFilter(e.currentTarget.value)}
295
-
class="grow"
296
-
/>
297
351
</div>
298
352
<Show when={records.length > 1}>
299
353
<div class="flex items-center justify-between gap-x-2">
···
302
356
setReverse(!reverse());
303
357
setRecords([]);
304
358
setCursor(undefined);
359
+
clearCollectionCache(cacheKey());
305
360
refetch();
306
361
}}
307
362
>
···
349
404
</label>
350
405
</Show>
351
406
<Show when={!batchDelete()}>
352
-
<A href={`/at://${did}/${params.collection}/${record.rkey}`}>
407
+
<A href={`/at://${did}/${params.collection}/${record.rkey}`} class="select-none">
353
408
<RecordLink record={record} />
354
409
</A>
355
410
</Show>
+9
-9
src/views/home.tsx
+9
-9
src/views/home.tsx
···
1
1
export const Home = () => {
2
2
return (
3
3
<div class="flex w-full flex-col gap-3 wrap-break-word">
4
-
<div class="flex flex-col gap-0.5">
4
+
<div class="flex flex-col gap-1">
5
5
<div>
6
6
<span class="text-xl font-semibold">AT Protocol Explorer</span>
7
7
</div>
···
16
16
</span>
17
17
</div>
18
18
<div class="flex items-center gap-1">
19
-
<div class="iconify lucide--user-round" />
20
-
<span>Login to manage records in your repository.</span>
21
-
</div>
22
-
<div class="flex items-center gap-1">
23
-
<div class="iconify lucide--radio-tower" />
24
-
<span>Jetstream and firehose streaming.</span>
25
-
</div>
26
-
<div class="flex items-center gap-1">
27
19
<div class="iconify lucide--link" />
28
20
<span>
29
21
Backlinks support with{" "}
···
36
28
</a>
37
29
.
38
30
</span>
31
+
</div>
32
+
<div class="flex items-center gap-1">
33
+
<div class="iconify lucide--user-round" />
34
+
<span>Login to manage records in your repository.</span>
35
+
</div>
36
+
<div class="flex items-center gap-1">
37
+
<div class="iconify lucide--radio-tower" />
38
+
<span>Jetstream and firehose streaming.</span>
39
39
</div>
40
40
<div class="flex items-center gap-1">
41
41
<div class="iconify lucide--tag" />
+1
-1
src/views/labels.tsx
+1
-1
src/views/labels.tsx
···
228
228
rows={2}
229
229
value={searchParams.uriPatterns ?? "*"}
230
230
placeholder="at://did:web:example.com/app.bsky.feed.post/*"
231
-
class="dark:bg-dark-100 dark:inset-shadow-dark-200 grow rounded-lg border-[0.5px] border-neutral-300 bg-white px-2 py-1.5 text-sm inset-shadow-xs focus:outline-[1px] focus:outline-neutral-600 dark:border-neutral-600 dark:focus:outline-neutral-400"
231
+
class="dark:bg-dark-100 grow rounded-lg bg-white px-2 py-1.5 text-sm outline-1 outline-neutral-200 focus:outline-[1.5px] focus:outline-neutral-600 dark:outline-neutral-600 dark:focus:outline-neutral-400"
232
232
/>
233
233
</label>
234
234
</div>
+11
-20
src/views/logs.tsx
+11
-20
src/views/logs.tsx
···
55
55
}
56
56
});
57
57
58
-
const FilterButton = (props: { icon: string; event: PlcEvent; label: string }) => {
58
+
const FilterButton = (props: { event: PlcEvent; label: string }) => {
59
59
const isActive = () => activePlcEvent() === props.event;
60
60
const toggleFilter = () => setActivePlcEvent(isActive() ? undefined : props.event);
61
61
62
62
return (
63
63
<button
64
64
classList={{
65
-
"flex items-center gap-1 sm:gap-1.5 rounded-lg px-3 py-2 sm:px-2 sm:py-1.5 text-base sm:text-sm transition-colors": true,
66
-
"bg-neutral-700 text-white dark:bg-neutral-200 dark:text-neutral-900": isActive(),
65
+
"font-medium rounded-lg px-2 py-1.5 text-xs sm:text-sm transition-colors": true,
66
+
"bg-neutral-700 text-white dark:bg-neutral-300 dark:text-neutral-900": isActive(),
67
67
"bg-neutral-200 text-neutral-700 hover:bg-neutral-300 dark:bg-neutral-700 dark:text-neutral-300 dark:hover:bg-neutral-600":
68
68
!isActive(),
69
69
}}
70
70
onclick={toggleFilter}
71
71
>
72
-
<span class={props.icon}></span>
73
-
<span class="hidden font-medium sm:inline">{props.label}</span>
72
+
{props.label}
74
73
</button>
75
74
);
76
75
};
···
255
254
<div class="iconify lucide--filter" />
256
255
<p class="font-medium">Filter by type</p>
257
256
</div>
258
-
<div class="flex flex-wrap gap-1 sm:gap-2">
259
-
<FilterButton icon="iconify lucide--at-sign" event="handle" label="Alias" />
260
-
<FilterButton icon="iconify lucide--hard-drive" event="service" label="Service" />
261
-
<FilterButton
262
-
icon="iconify lucide--shield-check"
263
-
event="verification_method"
264
-
label="Verification"
265
-
/>
266
-
<FilterButton
267
-
icon="iconify lucide--key-round"
268
-
event="rotation_key"
269
-
label="Rotation Key"
270
-
/>
257
+
<div class="flex flex-wrap gap-1">
258
+
<FilterButton event="handle" label="Alias" />
259
+
<FilterButton event="service" label="Service" />
260
+
<FilterButton event="verification_method" label="Verification" />
261
+
<FilterButton event="rotation_key" label="Rotation Key" />
271
262
</div>
272
263
</div>
273
264
<div class="flex items-center gap-1.5 text-sm font-medium">
274
265
<Show when={validLog() === true}>
275
-
<span class="iconify lucide--check-circle-2 text-green-500 dark:text-green-400"></span>
266
+
<span class="iconify lucide--check text-green-600 dark:text-green-400"></span>
276
267
<span>Valid log</span>
277
268
</Show>
278
269
<Show when={validLog() === false}>
279
-
<span class="iconify lucide--x-circle text-red-500 dark:text-red-400"></span>
270
+
<span class="iconify lucide--x text-red-500 dark:text-red-400"></span>
280
271
<span>Log validation failed</span>
281
272
</Show>
282
273
<Show when={validLog() === undefined}>
+55
-37
src/views/pds.tsx
+55
-37
src/views/pds.tsx
···
5
5
import { A, useLocation, useParams } from "@solidjs/router";
6
6
import { createResource, createSignal, For, Show } from "solid-js";
7
7
import { Button } from "../components/button";
8
-
import { CopyMenu, DropdownMenu, MenuProvider, NavMenu } from "../components/dropdown";
9
8
import { Modal } from "../components/modal";
10
9
import { setPDS } from "../components/navbar";
11
10
import Tooltip from "../components/tooltip";
11
+
import { resolveDidDoc } from "../utils/api";
12
12
import { localDateFromTimestamp } from "../utils/date";
13
13
14
14
const LIMIT = 1000;
···
54
54
55
55
const RepoCard = (repo: ComAtprotoSyncListRepos.Repo) => {
56
56
const [openInfo, setOpenInfo] = createSignal(false);
57
+
const [handle, setHandle] = createSignal<string>();
58
+
59
+
const fetchHandle = async () => {
60
+
try {
61
+
const doc = await resolveDidDoc(repo.did);
62
+
const aka = doc.alsoKnownAs?.find((a) => a.startsWith("at://"));
63
+
if (aka) setHandle(aka.replace("at://", ""));
64
+
} catch {}
65
+
};
57
66
58
67
return (
59
68
<div class="flex items-center gap-0.5">
···
69
78
</Tooltip>
70
79
</Show>
71
80
<button
72
-
onclick={() => setOpenInfo(true)}
81
+
onclick={() => {
82
+
setOpenInfo(true);
83
+
if (!handle()) fetchHandle();
84
+
}}
73
85
class="flex items-center rounded-md p-1.5 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
74
86
>
75
-
<span class="iconify lucide--info"></span>
87
+
<span class="iconify lucide--info text-neutral-600 dark:text-neutral-400"></span>
76
88
</button>
77
89
<Modal open={openInfo()} onClose={() => setOpenInfo(false)}>
78
90
<div class="dark:bg-dark-300 dark:shadow-dark-700 absolute top-70 left-[50%] w-max max-w-[90vw] -translate-x-1/2 rounded-lg border-[0.5px] border-neutral-300 bg-white p-3 shadow-md transition-opacity duration-200 sm:max-w-xl dark:border-neutral-700 starting:opacity-0">
···
86
98
</button>
87
99
</div>
88
100
<div class="grid grid-cols-[auto_1fr] items-baseline gap-x-1 gap-y-0.5 text-sm">
101
+
<span class="font-medium">Handle:</span>
102
+
<span class="text-neutral-700 dark:text-neutral-300">{handle()}</span>
89
103
<span class="font-medium">Head:</span>
90
104
<span class="wrap-anywhere text-neutral-700 dark:text-neutral-300">{repo.head}</span>
91
105
···
122
136
);
123
137
};
124
138
125
-
const Tab = (props: { tab: "repos" | "info"; label: string }) => (
139
+
const Tab = (props: { tab: "repos" | "info" | "firehose"; label: string }) => (
126
140
<A
127
141
classList={{
128
-
"border-b-2": true,
129
-
"border-transparent hover:border-neutral-400 dark:hover:border-neutral-600":
142
+
"border-b-2 font-medium": true,
143
+
"border-transparent dark:text-neutral-300/80 text-neutral-600 hover:border-neutral-600 dark:hover:border-neutral-300/80":
130
144
(!!location.hash && location.hash !== `#${props.tab}`) ||
131
145
(!location.hash && props.tab !== "repos"),
132
146
}}
133
-
href={`/${params.pds}#${props.tab}`}
147
+
href={
148
+
props.tab === "firehose" ?
149
+
`/firehose?instance=wss://${params.pds}`
150
+
: `/${params.pds}#${props.tab}`
151
+
}
134
152
>
135
153
{props.label}
136
154
</A>
···
138
156
139
157
return (
140
158
<Show when={repos() || response()}>
141
-
<div class="flex w-full flex-col">
142
-
<div class="dark:shadow-dark-700 dark:bg-dark-300 mb-2 flex w-full justify-between rounded-lg border-[0.5px] border-neutral-300 bg-neutral-50 p-2 text-sm shadow-xs dark:border-neutral-700">
143
-
<div class="ml-1 flex items-center gap-3">
144
-
<Tab tab="repos" label="Repositories" />
145
-
<Tab tab="info" label="Info" />
146
-
</div>
147
-
<MenuProvider>
148
-
<DropdownMenu icon="lucide--ellipsis-vertical" buttonClass="rounded-sm p-1.5">
149
-
<CopyMenu content={params.pds!} label="Copy PDS" icon="lucide--copy" />
150
-
<NavMenu
151
-
href={`/firehose?instance=wss://${params.pds}`}
152
-
label="Firehose"
153
-
icon="lucide--radio-tower"
154
-
/>
155
-
</DropdownMenu>
156
-
</MenuProvider>
159
+
<div class="flex w-full flex-col px-2">
160
+
<div class="mb-3 flex gap-4 text-sm sm:text-base">
161
+
<Tab tab="repos" label="Repositories" />
162
+
<Tab tab="info" label="Info" />
163
+
<Tab tab="firehose" label="Firehose" />
157
164
</div>
158
-
<div class="flex flex-col gap-1 px-2">
159
-
<Show when={!location.hash || location.hash === "#repos"}>
160
-
<div class="flex flex-col divide-y-[0.5px] divide-neutral-300 dark:divide-neutral-700">
161
-
<For each={repos()}>{(repo) => <RepoCard {...repo} />}</For>
162
-
</div>
163
-
</Show>
165
+
<Show when={!location.hash || location.hash === "#repos"}>
166
+
<div class="flex flex-col divide-y-[0.5px] divide-neutral-300 pb-20 dark:divide-neutral-700">
167
+
<For each={repos()}>{(repo) => <RepoCard {...repo} />}</For>
168
+
</div>
169
+
</Show>
170
+
<div class="flex flex-col gap-2">
164
171
<Show when={location.hash === "#info"}>
165
172
<Show when={version()}>
166
173
{(version) => (
167
-
<div class="flex items-baseline gap-x-1">
174
+
<div class="flex flex-col">
168
175
<span class="font-semibold">Version</span>
169
-
<span class="truncate text-sm">{version()}</span>
176
+
<span class="text-sm text-neutral-700 dark:text-neutral-300">{version()}</span>
170
177
</div>
171
178
)}
172
179
</Show>
173
180
<Show when={serverInfos()}>
174
181
{(server) => (
175
182
<>
176
-
<div class="flex items-baseline gap-x-1">
183
+
<div class="flex flex-col">
177
184
<span class="font-semibold">DID</span>
178
-
<span class="truncate text-sm">{server().did}</span>
185
+
<span class="text-sm">{server().did}</span>
179
186
</div>
180
-
<Show when={server().inviteCodeRequired}>
187
+
<div class="flex items-center gap-1">
181
188
<span class="font-semibold">Invite Code Required</span>
182
-
</Show>
189
+
<span
190
+
classList={{
191
+
"iconify lucide--check text-green-500 dark:text-green-400":
192
+
server().inviteCodeRequired === true,
193
+
"iconify lucide--x text-red-500 dark:text-red-400":
194
+
!server().inviteCodeRequired,
195
+
}}
196
+
></span>
197
+
</div>
183
198
<Show when={server().phoneVerificationRequired}>
184
-
<span class="font-semibold">Phone Verification Required</span>
199
+
<div class="flex items-center gap-1">
200
+
<span class="font-semibold">Phone Verification Required</span>
201
+
<span class="iconify lucide--check text-green-500 dark:text-green-400"></span>
202
+
</div>
185
203
</Show>
186
204
<Show when={server().availableUserDomains.length}>
187
205
<div class="flex flex-col">
···
232
250
</div>
233
251
</div>
234
252
<Show when={!location.hash || location.hash === "#repos"}>
235
-
<div class="dark:bg-dark-500 fixed bottom-0 z-5 flex w-screen justify-center bg-neutral-100 py-2">
253
+
<div class="dark:bg-dark-500 fixed bottom-0 z-5 flex w-screen justify-center bg-neutral-100 pt-2 pb-4">
236
254
<div class="flex flex-col items-center gap-1 pb-2">
237
255
<p>{repos()?.length} loaded</p>
238
256
<Show when={!response.loading && cursor()}>
+7
-18
src/views/record.tsx
+7
-18
src/views/record.tsx
···
363
363
<div class="flex items-center gap-0.5">
364
364
<A
365
365
classList={{
366
-
"border-b-2": true,
367
-
"border-transparent hover:border-neutral-400 dark:hover:border-neutral-600":
366
+
"border-b-2 font-medium": true,
367
+
"border-transparent text-neutral-600 dark:text-neutral-300/80 hover:border-neutral-600 dark:hover:border-neutral-300/80":
368
368
!isActive(),
369
369
}}
370
370
href={`/at://${did}/${params.collection}/${params.rkey}#${props.tab}`}
···
381
381
return (
382
382
<Show when={record()} keyed>
383
383
<div class="flex w-full flex-col items-center">
384
-
<div class="dark:shadow-dark-700 dark:bg-dark-300 mb-3 flex w-full justify-between rounded-lg border-[0.5px] border-neutral-300 bg-neutral-50 p-2 text-sm shadow-xs dark:border-neutral-700">
385
-
<div class="ml-1 flex items-center gap-3">
384
+
<div class="mb-3 flex w-full justify-between px-2 text-sm sm:text-base">
385
+
<div class="flex items-center gap-4">
386
386
<RecordTab tab="record" label="Record" />
387
387
<RecordTab tab="schema" label="Schema" />
388
388
<RecordTab tab="backlinks" label="Backlinks" />
···
490
490
<Show when={location.hash === "#info"}>
491
491
<div class="flex w-full flex-col gap-2 px-2 text-sm">
492
492
<div>
493
-
<div class="flex items-center gap-1">
494
-
<span class="iconify lucide--at-sign"></span>
495
-
<p class="font-semibold">AT URI</p>
496
-
</div>
493
+
<p class="font-semibold">AT URI</p>
497
494
<div class="truncate text-xs">{record()?.uri}</div>
498
495
</div>
499
496
<Show when={record()?.cid}>
500
497
<div>
501
-
<div class="flex items-center gap-1">
502
-
<span class="iconify lucide--box"></span>
503
-
<p class="font-semibold">CID</p>
504
-
</div>
498
+
<p class="font-semibold">CID</p>
505
499
<div class="truncate text-left text-xs" dir="rtl">
506
500
{record()?.cid}
507
501
</div>
···
509
503
</Show>
510
504
<div>
511
505
<div class="flex items-center gap-1">
512
-
<span class="iconify lucide--lock-keyhole"></span>
513
506
<p class="font-semibold">Record verification</p>
514
507
<span
515
508
classList={{
···
526
519
</div>
527
520
<div>
528
521
<div class="flex items-center gap-1">
529
-
<span class="iconify lucide--file-check"></span>
530
522
<p class="font-semibold">Schema validation</p>
531
523
<span
532
524
classList={{
···
556
548
</div>
557
549
<Show when={lexiconUri()}>
558
550
<div>
559
-
<div class="flex items-center gap-1">
560
-
<span class="iconify lucide--scroll-text"></span>
561
-
<p class="font-semibold">Lexicon schema</p>
562
-
</div>
551
+
<p class="font-semibold">Lexicon schema</p>
563
552
<div class="truncate text-xs">
564
553
<A
565
554
href={`/${lexiconUri()}`}
+76
-88
src/views/repo.tsx
+76
-88
src/views/repo.tsx
···
88
88
return (
89
89
<A
90
90
classList={{
91
-
"border-b-2": true,
92
-
"border-transparent hover:border-neutral-400 dark:hover:border-neutral-600": !isActive(),
91
+
"border-b-2 font-medium": true,
92
+
"border-transparent text-neutral-600 dark:text-neutral-300/80 hover:border-neutral-600 dark:hover:border-neutral-300/80":
93
+
!isActive(),
93
94
}}
94
95
href={`/at://${params.repo}#${props.tab}`}
95
96
>
···
211
212
let loaded = 0;
212
213
213
214
const reader = response.body?.getReader();
214
-
const chunks: Uint8Array[] = [];
215
+
const chunks: BlobPart[] = [];
215
216
216
217
if (reader) {
217
218
while (true) {
···
275
276
return (
276
277
<Show when={repo()}>
277
278
<div class="flex w-full flex-col gap-3 wrap-break-word">
278
-
<div class="dark:shadow-dark-700 dark:bg-dark-300 flex justify-between rounded-lg border-[0.5px] border-neutral-300 bg-neutral-50 p-2 text-sm shadow-xs dark:border-neutral-700">
279
-
<div class="ml-1 flex items-center gap-2 text-xs sm:gap-4 sm:text-sm">
279
+
<div class="flex justify-between px-2 text-sm sm:text-base">
280
+
<div class="flex items-center gap-3 sm:gap-4">
280
281
<Show when={!error()}>
281
282
<RepoTab tab="collections" label="Collections" />
282
283
</Show>
···
289
290
</Show>
290
291
<RepoTab tab="backlinks" label="Backlinks" />
291
292
</div>
292
-
<div class="flex gap-0.5">
293
+
<div class="flex gap-1">
293
294
<Show when={error() && error() !== "Missing PDS"}>
294
295
<div class="flex items-center gap-1 text-red-500 dark:text-red-400">
295
296
<span class="iconify lucide--alert-triangle"></span>
296
297
<span>{error()}</span>
297
298
</div>
298
299
</Show>
299
-
<Show when={!error() && (!location.hash || location.hash.startsWith("#collections"))}>
300
-
<Tooltip text="Filter collections">
301
-
<button
302
-
class="flex items-center rounded-sm p-1.5 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
303
-
onClick={() => setShowFilter(!showFilter())}
304
-
>
305
-
<span class="iconify lucide--filter"></span>
306
-
</button>
307
-
</Tooltip>
308
-
</Show>
309
300
<MenuProvider>
310
301
<DropdownMenu icon="lucide--ellipsis-vertical" buttonClass="rounded-sm p-1.5">
302
+
<Show
303
+
when={!error() && (!location.hash || location.hash.startsWith("#collections"))}
304
+
>
305
+
<ActionMenu
306
+
label="Filter collections"
307
+
icon="lucide--filter"
308
+
onClick={() => setShowFilter(!showFilter())}
309
+
/>
310
+
</Show>
311
311
<CopyMenu content={params.repo!} label="Copy DID" icon="lucide--copy" />
312
312
<NavMenu
313
313
href={`/jetstream?dids=${params.repo}`}
···
323
323
</Show>
324
324
<Show when={error()?.length === 0 || error() === undefined}>
325
325
<ActionMenu
326
-
label="Export Repo"
326
+
label="Export repo"
327
327
icon={downloading() ? "lucide--loader-circle animate-spin" : "lucide--download"}
328
328
onClick={() => downloadRepo()}
329
329
/>
···
336
336
: `https://${did.split("did:web:")[1]}/.well-known/did.json`
337
337
}
338
338
newTab
339
-
label="DID Document"
339
+
label="DID document"
340
340
icon="lucide--external-link"
341
341
/>
342
342
<Show when={did.startsWith("did:plc")}>
343
343
<NavMenu
344
344
href={`${localStorage.plcDirectory ?? "https://plc.directory"}/${did}/log/audit`}
345
345
newTab
346
-
label="Audit Log"
346
+
label="Audit log"
347
347
icon="lucide--external-link"
348
348
/>
349
349
</Show>
···
406
406
<div class="flex flex-col text-sm wrap-anywhere" classList={{ "-mt-1": !showFilter() }}>
407
407
<Show
408
408
when={Object.keys(nsids() ?? {}).length != 0}
409
-
fallback={<span class="text-center text-base mt-3">No collections found.</span>}
409
+
fallback={<span class="mt-3 text-center text-base">No collections found.</span>}
410
410
>
411
411
<For
412
412
each={Object.keys(nsids() ?? {}).filter((authority) =>
···
486
486
<div class="flex flex-col gap-3 wrap-anywhere">
487
487
{/* ID Section */}
488
488
<div>
489
-
<div class="flex items-center gap-1">
490
-
<div class="iconify lucide--id-card" />
491
-
<p class="font-semibold">ID</p>
489
+
<div class="font-semibold">DID</div>
490
+
<div class="text-sm text-neutral-700 dark:text-neutral-300">
491
+
{didDocument().id}
492
492
</div>
493
-
<div class="text-sm">{didDocument().id}</div>
494
493
</div>
495
494
496
495
{/* Aliases Section */}
497
496
<div>
498
-
<div class="flex items-center gap-1">
499
-
<div class="iconify lucide--at-sign" />
500
-
<p class="font-semibold">Aliases</p>
501
-
</div>
502
-
<div class="flex flex-col gap-0.5">
503
-
<For each={didDocument().alsoKnownAs}>
504
-
{(alias) => (
505
-
<div class="flex items-center gap-1 text-sm">
506
-
<span>{alias}</span>
507
-
<Show when={alias.startsWith("at://")}>
508
-
<Tooltip
509
-
text={
510
-
validHandles[alias] === true ? "Valid handle"
511
-
: validHandles[alias] === undefined ?
512
-
"Validating"
513
-
: "Invalid handle"
514
-
}
515
-
>
516
-
<span
517
-
classList={{
518
-
"iconify lucide--circle-check text-green-600 dark:text-green-400":
519
-
validHandles[alias] === true,
520
-
"iconify lucide--circle-x text-red-500 dark:text-red-400":
521
-
validHandles[alias] === false,
522
-
"iconify lucide--loader-circle animate-spin":
523
-
validHandles[alias] === undefined,
524
-
}}
525
-
></span>
526
-
</Tooltip>
527
-
</Show>
528
-
</div>
529
-
)}
530
-
</For>
531
-
</div>
497
+
<p class="font-semibold">Aliases</p>
498
+
<For each={didDocument().alsoKnownAs}>
499
+
{(alias) => (
500
+
<div class="flex items-center gap-1 text-sm text-neutral-700 dark:text-neutral-300">
501
+
<span>{alias}</span>
502
+
<Show when={alias.startsWith("at://")}>
503
+
<Tooltip
504
+
text={
505
+
validHandles[alias] === true ? "Valid handle"
506
+
: validHandles[alias] === undefined ?
507
+
"Validating"
508
+
: "Invalid handle"
509
+
}
510
+
>
511
+
<span
512
+
classList={{
513
+
"iconify lucide--check text-green-600 dark:text-green-400":
514
+
validHandles[alias] === true,
515
+
"iconify lucide--x text-red-500 dark:text-red-400":
516
+
validHandles[alias] === false,
517
+
"iconify lucide--loader-circle animate-spin":
518
+
validHandles[alias] === undefined,
519
+
}}
520
+
></span>
521
+
</Tooltip>
522
+
</Show>
523
+
</div>
524
+
)}
525
+
</For>
532
526
</div>
533
527
534
528
{/* Services Section */}
535
529
<div>
536
-
<div class="flex items-center gap-1">
537
-
<div class="iconify lucide--hard-drive" />
538
-
<p class="font-semibold">Services</p>
539
-
</div>
540
-
<div class="flex flex-col gap-0.5">
530
+
<p class="font-semibold">Services</p>
531
+
<div class="flex flex-col gap-1">
541
532
<For each={didDocument().service}>
542
533
{(service) => (
543
-
<div class="text-sm">
544
-
<div class="font-medium text-neutral-700 dark:text-neutral-300">
545
-
#{service.id.split("#")[1]}
546
-
</div>
534
+
<div class="grid grid-cols-[auto_1fr] items-center gap-x-1 text-sm text-neutral-700 dark:text-neutral-300">
535
+
<span class="iconify lucide--hash"></span>
536
+
<span>{service.id.split("#")[1]}</span>
537
+
<span></span>
547
538
<a
548
-
class="underline hover:text-blue-400"
539
+
class="w-fit underline hover:text-blue-400"
549
540
href={service.serviceEndpoint.toString()}
550
541
target="_blank"
551
542
rel="noopener"
···
560
551
561
552
{/* Verification Methods Section */}
562
553
<div>
563
-
<div class="flex items-center gap-1">
564
-
<div class="iconify lucide--shield-check" />
565
-
<p class="font-semibold">Verification Methods</p>
566
-
</div>
567
-
<div class="flex flex-col gap-0.5">
554
+
<p class="font-semibold">Verification Methods</p>
555
+
<div class="flex flex-col gap-1">
568
556
<For each={didDocument().verificationMethod}>
569
557
{(verif) => (
570
558
<Show when={verif.publicKeyMultibase}>
571
559
{(key) => (
572
-
<div class="text-sm">
573
-
<div class="flex items-baseline gap-1">
574
-
<span class="font-medium text-neutral-700 dark:text-neutral-300">
575
-
#{verif.id.split("#")[1]}
576
-
</span>
577
-
<span class="rounded bg-neutral-200 px-1 py-0.5 text-xs text-neutral-800 dark:bg-neutral-700 dark:text-neutral-300">
578
-
{detectKeyType(key())}
579
-
</span>
560
+
<div class="grid grid-cols-[auto_1fr] items-center gap-x-1 text-sm text-neutral-700 dark:text-neutral-300">
561
+
<span class="iconify lucide--hash"></span>
562
+
<div class="flex items-center gap-2">
563
+
<span>{verif.id.split("#")[1]}</span>
564
+
<div class="flex items-center gap-1 text-neutral-500 dark:text-neutral-400">
565
+
<span class="iconify lucide--key-round"></span>
566
+
<span>{detectKeyType(key())}</span>
567
+
</div>
580
568
</div>
569
+
<span></span>
581
570
<div class="font-mono break-all">{key()}</div>
582
571
</div>
583
572
)}
···
590
579
{/* Rotation Keys Section */}
591
580
<Show when={rotationKeys().length > 0}>
592
581
<div>
593
-
<div class="flex items-center gap-1">
594
-
<div class="iconify lucide--key-round" />
595
-
<p class="font-semibold">Rotation Keys</p>
596
-
</div>
597
-
<div class="flex flex-col gap-0.5">
582
+
<p class="font-semibold">Rotation Keys</p>
583
+
<div class="flex flex-col gap-1">
598
584
<For each={rotationKeys()}>
599
585
{(key) => (
600
-
<div class="text-sm">
601
-
<span class="rounded bg-neutral-200 px-1 py-0.5 text-xs text-neutral-800 dark:bg-neutral-700 dark:text-neutral-300">
586
+
<div class="grid grid-cols-[auto_1fr] items-center gap-x-1 text-sm text-neutral-700 dark:text-neutral-300">
587
+
<span class="iconify lucide--key-round text-neutral-500 dark:text-neutral-400"></span>
588
+
<span class="text-neutral-500 dark:text-neutral-400">
602
589
{detectDidKeyType(key)}
603
590
</span>
591
+
<span></span>
604
592
<div class="font-mono break-all">{key.replace("did:key:", "")}</div>
605
593
</div>
606
594
)}
+8
-8
src/views/stream.tsx
+8
-8
src/views/stream.tsx
···
143
143
144
144
return (
145
145
<div class="flex w-full flex-col items-center">
146
-
<div class="flex gap-2 text-sm">
146
+
<div class="mb-1 flex gap-4 font-medium">
147
147
<A
148
-
class="flex items-center gap-1 border-b-2 p-1"
149
-
inactiveClass="border-transparent hover:border-neutral-400 dark:hover:border-neutral-600"
148
+
class="flex items-center gap-1 border-b-2"
149
+
inactiveClass="border-transparent text-neutral-600 dark:text-neutral-400 hover:border-neutral-400 dark:hover:border-neutral-600"
150
150
href="/jetstream"
151
151
>
152
152
Jetstream
153
153
</A>
154
154
<A
155
-
class="flex items-center gap-1 border-b-2 p-1"
156
-
inactiveClass="border-transparent hover:border-neutral-400 dark:hover:border-neutral-600"
155
+
class="flex items-center gap-1 border-b-2"
156
+
inactiveClass="border-transparent text-neutral-600 dark:text-neutral-400 hover:border-neutral-400 dark:hover:border-neutral-600"
157
157
href="/firehose"
158
158
>
159
159
Firehose
160
160
</A>
161
161
</div>
162
162
<StickyOverlay>
163
-
<form ref={formRef} class="flex w-full flex-col gap-1 text-sm">
163
+
<form ref={formRef} class="flex w-full flex-col gap-1.5 text-sm">
164
164
<Show when={!connected()}>
165
165
<label class="flex items-center justify-end gap-x-1">
166
166
<span class="min-w-20">Instance</span>
···
183
183
spellcheck={false}
184
184
placeholder="Comma-separated list of collections"
185
185
value={searchParams.collections ?? ""}
186
-
class="dark:bg-dark-100 dark:inset-shadow-dark-200 grow rounded-lg border-[0.5px] border-neutral-300 bg-white px-2 py-1 inset-shadow-xs focus:outline-[1px] focus:outline-neutral-600 dark:border-neutral-600 dark:focus:outline-neutral-400"
186
+
class="dark:bg-dark-100 grow rounded-lg bg-white px-2 py-1 outline-1 outline-neutral-200 focus:outline-[1.5px] focus:outline-neutral-600 dark:outline-neutral-600 dark:focus:outline-neutral-400"
187
187
/>
188
188
</label>
189
189
</Show>
···
195
195
spellcheck={false}
196
196
placeholder="Comma-separated list of DIDs"
197
197
value={searchParams.dids ?? ""}
198
-
class="dark:bg-dark-100 dark:inset-shadow-dark-200 grow rounded-lg border-[0.5px] border-neutral-300 bg-white px-2 py-1 inset-shadow-xs focus:outline-[1px] focus:outline-neutral-600 dark:border-neutral-600 dark:focus:outline-neutral-400"
198
+
class="dark:bg-dark-100 grow rounded-lg bg-white px-2 py-1 outline-1 outline-neutral-200 focus:outline-[1.5px] focus:outline-neutral-600 dark:outline-neutral-600 dark:focus:outline-neutral-400"
199
199
/>
200
200
</label>
201
201
</Show>