+170
-28
README.md
+170
-28
README.md
···
1
-
# Astro Starter Kit: Minimal
1
+
# ATproto Personal Website Template
2
+
3
+
A modern personal website template powered by Astro, Tailwind CSS, and the ATproto protocol. This template allows you to create a personal website that displays content from your ATproto repository, including Bluesky posts, custom lexicon types, and more.
4
+
5
+
## Features
6
+
7
+
- **Type-safe ATproto Integration**: Full TypeScript support for ATproto records and custom lexicon
8
+
- **Component-driven Rendering**: Only render content types that have dedicated components
9
+
- **Feed Support**: Display content from custom Bluesky feeds
10
+
- **Custom Lexicon Support**: Easy to add new content types with custom components
11
+
- **Theme Customization**: Configurable colors, fonts, and styling
12
+
- **Performance Optimized**: Caching and efficient data fetching
13
+
- **Responsive Design**: Works on all device sizes
14
+
- **Dark Mode Support**: Built-in dark/light theme switching
15
+
16
+
## Supported Content Types
17
+
18
+
- **Bluesky Posts**: Standard Bluesky posts with text, images, and embeds
19
+
- **Whitewind Blog Posts**: Blog posts with titles, content, and tags
20
+
- **Leaflet Publications**: Publications with categories and rich content
21
+
- **Grain Image Galleries**: Image galleries with descriptions and captions
22
+
23
+
## Quick Start
24
+
25
+
1. **Clone the template**:
26
+
```bash
27
+
git clone <your-repo-url>
28
+
cd your-website
29
+
```
30
+
31
+
2. **Install dependencies**:
32
+
```bash
33
+
npm install
34
+
```
35
+
36
+
3. **Configure your environment**:
37
+
```bash
38
+
cp env.example .env
39
+
```
40
+
41
+
Edit `.env` with your configuration:
42
+
```env
43
+
ATPROTO_DID=did:plc:your-did-here
44
+
SITE_TITLE=My Personal Website
45
+
SITE_AUTHOR=Your Name
46
+
```
47
+
48
+
4. **Start development server**:
49
+
```bash
50
+
npm run dev
51
+
```
52
+
53
+
## Configuration
54
+
55
+
### Environment Variables
56
+
57
+
| Variable | Description | Default |
58
+
|----------|-------------|---------|
59
+
| `ATPROTO_DID` | Your ATproto DID | Required |
60
+
| `ATPROTO_PDS_URL` | PDS server URL | `https://bsky.social` |
61
+
| `SITE_TITLE` | Website title | `My Personal Website` |
62
+
| `SITE_DESCRIPTION` | Website description | `A personal website powered by ATproto` |
63
+
| `SITE_AUTHOR` | Your name | `Your Name` |
64
+
| `SITE_URL` | Your website URL | `https://example.com` |
65
+
| `THEME_PRIMARY_COLOR` | Primary color | `#3b82f6` |
66
+
| `THEME_SECONDARY_COLOR` | Secondary color | `#64748b` |
67
+
| `THEME_ACCENT_COLOR` | Accent color | `#f59e0b` |
68
+
| `THEME_FONT_FAMILY` | Font family | `Inter, system-ui, sans-serif` |
69
+
| `CONTENT_DEFAULT_FEED_LIMIT` | Default feed limit | `20` |
70
+
| `CONTENT_CACHE_TTL` | Cache TTL (ms) | `300000` |
71
+
72
+
## Usage
73
+
74
+
### Adding Content Components
75
+
76
+
The template uses a component registry system. To add a new content type:
2
77
3
-
```sh
4
-
npm create astro@latest -- --template minimal
78
+
1. **Define the type** in `src/lib/types/atproto.ts`:
79
+
```typescript
80
+
export interface MyCustomType extends CustomLexiconRecord {
81
+
$type: 'app.bsky.actor.profile#myCustomType';
82
+
title: string;
83
+
content: string;
84
+
}
85
+
```
86
+
87
+
2. **Create a component** in `src/components/content/`:
88
+
```astro
89
+
---
90
+
interface Props {
91
+
title: string;
92
+
content: string;
93
+
}
94
+
const { title, content } = Astro.props;
95
+
---
96
+
97
+
<article class="...">
98
+
<h2>{title}</h2>
99
+
<div>{content}</div>
100
+
</article>
101
+
```
102
+
103
+
3. **Register the component** in `src/lib/components/register.ts`:
104
+
```typescript
105
+
registerComponent('app.bsky.actor.profile#myCustomType', MyCustomComponent);
106
+
```
107
+
108
+
### Using Feed Components
109
+
110
+
Display content from a Bluesky feed:
111
+
112
+
```astro
113
+
<BlueskyFeed
114
+
feedUri="at://did:plc:.../app.bsky.feed.generator/..."
115
+
limit={10}
116
+
showAuthor={true}
117
+
showTimestamp={true}
118
+
/>
5
119
```
6
120
7
-
> 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun!
121
+
Display content from your repository:
8
122
9
-
## 🚀 Project Structure
123
+
```astro
124
+
<ContentFeed
125
+
did="did:plc:your-did"
126
+
limit={20}
127
+
showAuthor={false}
128
+
showTimestamp={true}
129
+
/>
130
+
```
10
131
11
-
Inside of your Astro project, you'll see the following folders and files:
132
+
## Project Structure
12
133
13
-
```text
14
-
/
15
-
├── public/
16
-
├── src/
17
-
│ └── pages/
18
-
│ └── index.astro
19
-
└── package.json
134
+
```
135
+
src/
136
+
├── lib/
137
+
│ ├── atproto/ # ATproto API integration
138
+
│ ├── components/ # Component registry
139
+
│ ├── config/ # Site configuration
140
+
│ └── types/ # TypeScript definitions
141
+
├── components/
142
+
│ ├── content/ # Content rendering components
143
+
│ ├── layout/ # Layout components
144
+
│ └── ui/ # UI components
145
+
├── pages/ # Astro pages
146
+
└── styles/ # Global styles
20
147
```
21
148
22
-
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
149
+
## Deployment
150
+
151
+
### Cloudflare Pages
152
+
153
+
1. Connect your repository to Cloudflare Pages
154
+
2. Set build command: `npm run build`
155
+
3. Set build output directory: `dist`
156
+
4. Add environment variables in Cloudflare Pages settings
157
+
158
+
### Other Platforms
23
159
24
-
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
160
+
The site can be deployed to any static hosting platform that supports Astro:
161
+
- Vercel
162
+
- Netlify
163
+
- GitHub Pages
164
+
- etc.
25
165
26
-
Any static assets, like images, can be placed in the `public/` directory.
166
+
## Custom Lexicon
167
+
168
+
To publish custom lexicon for others to use:
27
169
28
-
## 🧞 Commands
170
+
1. Define your lexicon schema following the ATproto specification
171
+
2. Publish to your PDS or a public repository
172
+
3. Create components for rendering your custom types
173
+
4. Document the lexicon for other developers
29
174
30
-
All commands are run from the root of the project, from a terminal:
175
+
## Contributing
31
176
32
-
| Command | Action |
33
-
| :------------------------ | :----------------------------------------------- |
34
-
| `npm install` | Installs dependencies |
35
-
| `npm run dev` | Starts local dev server at `localhost:4321` |
36
-
| `npm run build` | Build your production site to `./dist/` |
37
-
| `npm run preview` | Preview your build locally, before deploying |
38
-
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
39
-
| `npm run astro -- --help` | Get help using the Astro CLI |
177
+
1. Fork the repository
178
+
2. Create a feature branch
179
+
3. Make your changes
180
+
4. Add tests if applicable
181
+
5. Submit a pull request
40
182
41
-
## 👀 Want to learn more?
183
+
## License
42
184
43
-
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
185
+
MIT License - see LICENSE file for details.
+7
-1
astro.config.mjs
+7
-1
astro.config.mjs
+20
env.example
+20
env.example
···
1
+
# ATproto Configuration
2
+
ATPROTO_HANDLE=your-handle.bsky.social
3
+
ATPROTO_DID=did:plc:your-did-here
4
+
ATPROTO_PDS_URL=https://bsky.social
5
+
6
+
# Site Configuration
7
+
SITE_TITLE=My Personal Website
8
+
SITE_DESCRIPTION=A personal website powered by ATproto
9
+
SITE_AUTHOR=Your Name
10
+
SITE_URL=https://your-domain.com
11
+
12
+
# Theme Configuration
13
+
THEME_PRIMARY_COLOR=#3b82f6
14
+
THEME_SECONDARY_COLOR=#64748b
15
+
THEME_ACCENT_COLOR=#f59e0b
16
+
THEME_FONT_FAMILY=Inter, system-ui, sans-serif
17
+
18
+
# Content Configuration
19
+
CONTENT_DEFAULT_FEED_LIMIT=20
20
+
CONTENT_CACHE_TTL=300000
+1918
-6
package-lock.json
+1918
-6
package-lock.json
···
8
8
"name": "attempt2-home",
9
9
"version": "0.0.1",
10
10
"dependencies": {
11
-
"astro": "^5.12.8"
11
+
"@astrojs/check": "^0.9.4",
12
+
"@atproto/api": "^0.16.2",
13
+
"@atproto/xrpc": "^0.7.1",
14
+
"@tailwindcss/typography": "^0.5.16",
15
+
"@tailwindcss/vite": "^4.1.11",
16
+
"@types/node": "^24.2.0",
17
+
"astro": "^5.12.8",
18
+
"dotenv": "^17.2.1",
19
+
"tailwindcss": "^4.1.11",
20
+
"typescript": "^5.9.2"
21
+
}
22
+
},
23
+
"node_modules/@ampproject/remapping": {
24
+
"version": "2.3.0",
25
+
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
26
+
"integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
27
+
"license": "Apache-2.0",
28
+
"dependencies": {
29
+
"@jridgewell/gen-mapping": "^0.3.5",
30
+
"@jridgewell/trace-mapping": "^0.3.24"
31
+
},
32
+
"engines": {
33
+
"node": ">=6.0.0"
34
+
}
35
+
},
36
+
"node_modules/@astrojs/check": {
37
+
"version": "0.9.4",
38
+
"resolved": "https://registry.npmjs.org/@astrojs/check/-/check-0.9.4.tgz",
39
+
"integrity": "sha512-IOheHwCtpUfvogHHsvu0AbeRZEnjJg3MopdLddkJE70mULItS/Vh37BHcI00mcOJcH1vhD3odbpvWokpxam7xA==",
40
+
"license": "MIT",
41
+
"dependencies": {
42
+
"@astrojs/language-server": "^2.15.0",
43
+
"chokidar": "^4.0.1",
44
+
"kleur": "^4.1.5",
45
+
"yargs": "^17.7.2"
46
+
},
47
+
"bin": {
48
+
"astro-check": "dist/bin.js"
49
+
},
50
+
"peerDependencies": {
51
+
"typescript": "^5.0.0"
12
52
}
13
53
},
14
54
"node_modules/@astrojs/compiler": {
···
23
63
"integrity": "sha512-7dwEVigz9vUWDw3nRwLQ/yH/xYovlUA0ZD86xoeKEBmkz9O6iELG1yri67PgAPW6VLL/xInA4t7H0CK6VmtkKQ==",
24
64
"license": "MIT"
25
65
},
66
+
"node_modules/@astrojs/language-server": {
67
+
"version": "2.15.4",
68
+
"resolved": "https://registry.npmjs.org/@astrojs/language-server/-/language-server-2.15.4.tgz",
69
+
"integrity": "sha512-JivzASqTPR2bao9BWsSc/woPHH7OGSGc9aMxXL4U6egVTqBycB3ZHdBJPuOCVtcGLrzdWTosAqVPz1BVoxE0+A==",
70
+
"license": "MIT",
71
+
"dependencies": {
72
+
"@astrojs/compiler": "^2.10.3",
73
+
"@astrojs/yaml2ts": "^0.2.2",
74
+
"@jridgewell/sourcemap-codec": "^1.4.15",
75
+
"@volar/kit": "~2.4.7",
76
+
"@volar/language-core": "~2.4.7",
77
+
"@volar/language-server": "~2.4.7",
78
+
"@volar/language-service": "~2.4.7",
79
+
"fast-glob": "^3.2.12",
80
+
"muggle-string": "^0.4.1",
81
+
"volar-service-css": "0.0.62",
82
+
"volar-service-emmet": "0.0.62",
83
+
"volar-service-html": "0.0.62",
84
+
"volar-service-prettier": "0.0.62",
85
+
"volar-service-typescript": "0.0.62",
86
+
"volar-service-typescript-twoslash-queries": "0.0.62",
87
+
"volar-service-yaml": "0.0.62",
88
+
"vscode-html-languageservice": "^5.2.0",
89
+
"vscode-uri": "^3.0.8"
90
+
},
91
+
"bin": {
92
+
"astro-ls": "bin/nodeServer.js"
93
+
},
94
+
"peerDependencies": {
95
+
"prettier": "^3.0.0",
96
+
"prettier-plugin-astro": ">=0.11.0"
97
+
},
98
+
"peerDependenciesMeta": {
99
+
"prettier": {
100
+
"optional": true
101
+
},
102
+
"prettier-plugin-astro": {
103
+
"optional": true
104
+
}
105
+
}
106
+
},
26
107
"node_modules/@astrojs/markdown-remark": {
27
108
"version": "6.3.5",
28
109
"resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-6.3.5.tgz",
···
82
163
"node": "18.20.8 || ^20.3.0 || >=22.0.0"
83
164
}
84
165
},
166
+
"node_modules/@astrojs/yaml2ts": {
167
+
"version": "0.2.2",
168
+
"resolved": "https://registry.npmjs.org/@astrojs/yaml2ts/-/yaml2ts-0.2.2.tgz",
169
+
"integrity": "sha512-GOfvSr5Nqy2z5XiwqTouBBpy5FyI6DEe+/g/Mk5am9SjILN1S5fOEvYK0GuWHg98yS/dobP4m8qyqw/URW35fQ==",
170
+
"license": "MIT",
171
+
"dependencies": {
172
+
"yaml": "^2.5.0"
173
+
}
174
+
},
175
+
"node_modules/@atproto/api": {
176
+
"version": "0.16.2",
177
+
"resolved": "https://registry.npmjs.org/@atproto/api/-/api-0.16.2.tgz",
178
+
"integrity": "sha512-sSTg31J8ws8DNaoiizp+/uJideRxRaJsq+Nyl8rnSxGw0w3oCvoeRU19iRWh2t0jZEmiRJAGkveGu23NKmPYEQ==",
179
+
"license": "MIT",
180
+
"dependencies": {
181
+
"@atproto/common-web": "^0.4.2",
182
+
"@atproto/lexicon": "^0.4.12",
183
+
"@atproto/syntax": "^0.4.0",
184
+
"@atproto/xrpc": "^0.7.1",
185
+
"await-lock": "^2.2.2",
186
+
"multiformats": "^9.9.0",
187
+
"tlds": "^1.234.0",
188
+
"zod": "^3.23.8"
189
+
}
190
+
},
191
+
"node_modules/@atproto/common-web": {
192
+
"version": "0.4.2",
193
+
"resolved": "https://registry.npmjs.org/@atproto/common-web/-/common-web-0.4.2.tgz",
194
+
"integrity": "sha512-vrXwGNoFGogodjQvJDxAeP3QbGtawgZute2ed1XdRO0wMixLk3qewtikZm06H259QDJVu6voKC5mubml+WgQUw==",
195
+
"license": "MIT",
196
+
"dependencies": {
197
+
"graphemer": "^1.4.0",
198
+
"multiformats": "^9.9.0",
199
+
"uint8arrays": "3.0.0",
200
+
"zod": "^3.23.8"
201
+
}
202
+
},
203
+
"node_modules/@atproto/lexicon": {
204
+
"version": "0.4.12",
205
+
"resolved": "https://registry.npmjs.org/@atproto/lexicon/-/lexicon-0.4.12.tgz",
206
+
"integrity": "sha512-fcEvEQ1GpQYF5igZ4IZjPWEoWVpsEF22L9RexxLS3ptfySXLflEyH384e7HITzO/73McDeaJx3lqHIuqn9ulnw==",
207
+
"license": "MIT",
208
+
"dependencies": {
209
+
"@atproto/common-web": "^0.4.2",
210
+
"@atproto/syntax": "^0.4.0",
211
+
"iso-datestring-validator": "^2.2.2",
212
+
"multiformats": "^9.9.0",
213
+
"zod": "^3.23.8"
214
+
}
215
+
},
216
+
"node_modules/@atproto/syntax": {
217
+
"version": "0.4.0",
218
+
"resolved": "https://registry.npmjs.org/@atproto/syntax/-/syntax-0.4.0.tgz",
219
+
"integrity": "sha512-b9y5ceHS8YKOfP3mdKmwAx5yVj9294UN7FG2XzP6V5aKUdFazEYRnR9m5n5ZQFKa3GNvz7de9guZCJ/sUTcOAA==",
220
+
"license": "MIT"
221
+
},
222
+
"node_modules/@atproto/xrpc": {
223
+
"version": "0.7.1",
224
+
"resolved": "https://registry.npmjs.org/@atproto/xrpc/-/xrpc-0.7.1.tgz",
225
+
"integrity": "sha512-ANHEzlskYlMEdH18m+Itp3a8d0pEJao2qoDybDoMupTnoeNkya4VKIaOgAi6ERQnqatBBZyn9asW+7rJmSt/8g==",
226
+
"license": "MIT",
227
+
"dependencies": {
228
+
"@atproto/lexicon": "^0.4.12",
229
+
"zod": "^3.23.8"
230
+
}
231
+
},
85
232
"node_modules/@babel/helper-string-parser": {
86
233
"version": "7.27.1",
87
234
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
···
138
285
"cross-fetch": "^3.0.4",
139
286
"fontkit": "^2.0.2"
140
287
}
288
+
},
289
+
"node_modules/@emmetio/abbreviation": {
290
+
"version": "2.3.3",
291
+
"resolved": "https://registry.npmjs.org/@emmetio/abbreviation/-/abbreviation-2.3.3.tgz",
292
+
"integrity": "sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA==",
293
+
"license": "MIT",
294
+
"dependencies": {
295
+
"@emmetio/scanner": "^1.0.4"
296
+
}
297
+
},
298
+
"node_modules/@emmetio/css-abbreviation": {
299
+
"version": "2.1.8",
300
+
"resolved": "https://registry.npmjs.org/@emmetio/css-abbreviation/-/css-abbreviation-2.1.8.tgz",
301
+
"integrity": "sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw==",
302
+
"license": "MIT",
303
+
"dependencies": {
304
+
"@emmetio/scanner": "^1.0.4"
305
+
}
306
+
},
307
+
"node_modules/@emmetio/css-parser": {
308
+
"version": "0.4.0",
309
+
"resolved": "https://registry.npmjs.org/@emmetio/css-parser/-/css-parser-0.4.0.tgz",
310
+
"integrity": "sha512-z7wkxRSZgrQHXVzObGkXG+Vmj3uRlpM11oCZ9pbaz0nFejvCDmAiNDpY75+wgXOcffKpj4rzGtwGaZxfJKsJxw==",
311
+
"license": "MIT",
312
+
"dependencies": {
313
+
"@emmetio/stream-reader": "^2.2.0",
314
+
"@emmetio/stream-reader-utils": "^0.1.0"
315
+
}
316
+
},
317
+
"node_modules/@emmetio/html-matcher": {
318
+
"version": "1.3.0",
319
+
"resolved": "https://registry.npmjs.org/@emmetio/html-matcher/-/html-matcher-1.3.0.tgz",
320
+
"integrity": "sha512-NTbsvppE5eVyBMuyGfVu2CRrLvo7J4YHb6t9sBFLyY03WYhXET37qA4zOYUjBWFCRHO7pS1B9khERtY0f5JXPQ==",
321
+
"license": "ISC",
322
+
"dependencies": {
323
+
"@emmetio/scanner": "^1.0.0"
324
+
}
325
+
},
326
+
"node_modules/@emmetio/scanner": {
327
+
"version": "1.0.4",
328
+
"resolved": "https://registry.npmjs.org/@emmetio/scanner/-/scanner-1.0.4.tgz",
329
+
"integrity": "sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA==",
330
+
"license": "MIT"
331
+
},
332
+
"node_modules/@emmetio/stream-reader": {
333
+
"version": "2.2.0",
334
+
"resolved": "https://registry.npmjs.org/@emmetio/stream-reader/-/stream-reader-2.2.0.tgz",
335
+
"integrity": "sha512-fXVXEyFA5Yv3M3n8sUGT7+fvecGrZP4k6FnWWMSZVQf69kAq0LLpaBQLGcPR30m3zMmKYhECP4k/ZkzvhEW5kw==",
336
+
"license": "MIT"
337
+
},
338
+
"node_modules/@emmetio/stream-reader-utils": {
339
+
"version": "0.1.0",
340
+
"resolved": "https://registry.npmjs.org/@emmetio/stream-reader-utils/-/stream-reader-utils-0.1.0.tgz",
341
+
"integrity": "sha512-ZsZ2I9Vzso3Ho/pjZFsmmZ++FWeEd/txqybHTm4OgaZzdS8V9V/YYWQwg5TC38Z7uLWUV1vavpLLbjJtKubR1A==",
342
+
"license": "MIT"
141
343
},
142
344
"node_modules/@emnapi/runtime": {
143
345
"version": "1.4.5",
···
926
1128
"url": "https://opencollective.com/libvips"
927
1129
}
928
1130
},
1131
+
"node_modules/@isaacs/fs-minipass": {
1132
+
"version": "4.0.1",
1133
+
"resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
1134
+
"integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==",
1135
+
"license": "ISC",
1136
+
"dependencies": {
1137
+
"minipass": "^7.0.4"
1138
+
},
1139
+
"engines": {
1140
+
"node": ">=18.0.0"
1141
+
}
1142
+
},
1143
+
"node_modules/@jridgewell/gen-mapping": {
1144
+
"version": "0.3.12",
1145
+
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz",
1146
+
"integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==",
1147
+
"license": "MIT",
1148
+
"dependencies": {
1149
+
"@jridgewell/sourcemap-codec": "^1.5.0",
1150
+
"@jridgewell/trace-mapping": "^0.3.24"
1151
+
}
1152
+
},
1153
+
"node_modules/@jridgewell/resolve-uri": {
1154
+
"version": "3.1.2",
1155
+
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
1156
+
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
1157
+
"license": "MIT",
1158
+
"engines": {
1159
+
"node": ">=6.0.0"
1160
+
}
1161
+
},
929
1162
"node_modules/@jridgewell/sourcemap-codec": {
930
1163
"version": "1.5.4",
931
1164
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz",
932
1165
"integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==",
933
1166
"license": "MIT"
934
1167
},
1168
+
"node_modules/@jridgewell/trace-mapping": {
1169
+
"version": "0.3.29",
1170
+
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz",
1171
+
"integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==",
1172
+
"license": "MIT",
1173
+
"dependencies": {
1174
+
"@jridgewell/resolve-uri": "^3.1.0",
1175
+
"@jridgewell/sourcemap-codec": "^1.4.14"
1176
+
}
1177
+
},
1178
+
"node_modules/@nodelib/fs.scandir": {
1179
+
"version": "2.1.5",
1180
+
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
1181
+
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
1182
+
"license": "MIT",
1183
+
"dependencies": {
1184
+
"@nodelib/fs.stat": "2.0.5",
1185
+
"run-parallel": "^1.1.9"
1186
+
},
1187
+
"engines": {
1188
+
"node": ">= 8"
1189
+
}
1190
+
},
1191
+
"node_modules/@nodelib/fs.stat": {
1192
+
"version": "2.0.5",
1193
+
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
1194
+
"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
1195
+
"license": "MIT",
1196
+
"engines": {
1197
+
"node": ">= 8"
1198
+
}
1199
+
},
1200
+
"node_modules/@nodelib/fs.walk": {
1201
+
"version": "1.2.8",
1202
+
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
1203
+
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
1204
+
"license": "MIT",
1205
+
"dependencies": {
1206
+
"@nodelib/fs.scandir": "2.1.5",
1207
+
"fastq": "^1.6.0"
1208
+
},
1209
+
"engines": {
1210
+
"node": ">= 8"
1211
+
}
1212
+
},
935
1213
"node_modules/@oslojs/encoding": {
936
1214
"version": "1.1.0",
937
1215
"resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz",
···
1302
1580
"tslib": "^2.8.0"
1303
1581
}
1304
1582
},
1583
+
"node_modules/@tailwindcss/node": {
1584
+
"version": "4.1.11",
1585
+
"resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.11.tgz",
1586
+
"integrity": "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q==",
1587
+
"license": "MIT",
1588
+
"dependencies": {
1589
+
"@ampproject/remapping": "^2.3.0",
1590
+
"enhanced-resolve": "^5.18.1",
1591
+
"jiti": "^2.4.2",
1592
+
"lightningcss": "1.30.1",
1593
+
"magic-string": "^0.30.17",
1594
+
"source-map-js": "^1.2.1",
1595
+
"tailwindcss": "4.1.11"
1596
+
}
1597
+
},
1598
+
"node_modules/@tailwindcss/oxide": {
1599
+
"version": "4.1.11",
1600
+
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.11.tgz",
1601
+
"integrity": "sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg==",
1602
+
"hasInstallScript": true,
1603
+
"license": "MIT",
1604
+
"dependencies": {
1605
+
"detect-libc": "^2.0.4",
1606
+
"tar": "^7.4.3"
1607
+
},
1608
+
"engines": {
1609
+
"node": ">= 10"
1610
+
},
1611
+
"optionalDependencies": {
1612
+
"@tailwindcss/oxide-android-arm64": "4.1.11",
1613
+
"@tailwindcss/oxide-darwin-arm64": "4.1.11",
1614
+
"@tailwindcss/oxide-darwin-x64": "4.1.11",
1615
+
"@tailwindcss/oxide-freebsd-x64": "4.1.11",
1616
+
"@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.11",
1617
+
"@tailwindcss/oxide-linux-arm64-gnu": "4.1.11",
1618
+
"@tailwindcss/oxide-linux-arm64-musl": "4.1.11",
1619
+
"@tailwindcss/oxide-linux-x64-gnu": "4.1.11",
1620
+
"@tailwindcss/oxide-linux-x64-musl": "4.1.11",
1621
+
"@tailwindcss/oxide-wasm32-wasi": "4.1.11",
1622
+
"@tailwindcss/oxide-win32-arm64-msvc": "4.1.11",
1623
+
"@tailwindcss/oxide-win32-x64-msvc": "4.1.11"
1624
+
}
1625
+
},
1626
+
"node_modules/@tailwindcss/oxide-android-arm64": {
1627
+
"version": "4.1.11",
1628
+
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.11.tgz",
1629
+
"integrity": "sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg==",
1630
+
"cpu": [
1631
+
"arm64"
1632
+
],
1633
+
"license": "MIT",
1634
+
"optional": true,
1635
+
"os": [
1636
+
"android"
1637
+
],
1638
+
"engines": {
1639
+
"node": ">= 10"
1640
+
}
1641
+
},
1642
+
"node_modules/@tailwindcss/oxide-darwin-arm64": {
1643
+
"version": "4.1.11",
1644
+
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.11.tgz",
1645
+
"integrity": "sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ==",
1646
+
"cpu": [
1647
+
"arm64"
1648
+
],
1649
+
"license": "MIT",
1650
+
"optional": true,
1651
+
"os": [
1652
+
"darwin"
1653
+
],
1654
+
"engines": {
1655
+
"node": ">= 10"
1656
+
}
1657
+
},
1658
+
"node_modules/@tailwindcss/oxide-darwin-x64": {
1659
+
"version": "4.1.11",
1660
+
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.11.tgz",
1661
+
"integrity": "sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw==",
1662
+
"cpu": [
1663
+
"x64"
1664
+
],
1665
+
"license": "MIT",
1666
+
"optional": true,
1667
+
"os": [
1668
+
"darwin"
1669
+
],
1670
+
"engines": {
1671
+
"node": ">= 10"
1672
+
}
1673
+
},
1674
+
"node_modules/@tailwindcss/oxide-freebsd-x64": {
1675
+
"version": "4.1.11",
1676
+
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.11.tgz",
1677
+
"integrity": "sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA==",
1678
+
"cpu": [
1679
+
"x64"
1680
+
],
1681
+
"license": "MIT",
1682
+
"optional": true,
1683
+
"os": [
1684
+
"freebsd"
1685
+
],
1686
+
"engines": {
1687
+
"node": ">= 10"
1688
+
}
1689
+
},
1690
+
"node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
1691
+
"version": "4.1.11",
1692
+
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.11.tgz",
1693
+
"integrity": "sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg==",
1694
+
"cpu": [
1695
+
"arm"
1696
+
],
1697
+
"license": "MIT",
1698
+
"optional": true,
1699
+
"os": [
1700
+
"linux"
1701
+
],
1702
+
"engines": {
1703
+
"node": ">= 10"
1704
+
}
1705
+
},
1706
+
"node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
1707
+
"version": "4.1.11",
1708
+
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.11.tgz",
1709
+
"integrity": "sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ==",
1710
+
"cpu": [
1711
+
"arm64"
1712
+
],
1713
+
"license": "MIT",
1714
+
"optional": true,
1715
+
"os": [
1716
+
"linux"
1717
+
],
1718
+
"engines": {
1719
+
"node": ">= 10"
1720
+
}
1721
+
},
1722
+
"node_modules/@tailwindcss/oxide-linux-arm64-musl": {
1723
+
"version": "4.1.11",
1724
+
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.11.tgz",
1725
+
"integrity": "sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ==",
1726
+
"cpu": [
1727
+
"arm64"
1728
+
],
1729
+
"license": "MIT",
1730
+
"optional": true,
1731
+
"os": [
1732
+
"linux"
1733
+
],
1734
+
"engines": {
1735
+
"node": ">= 10"
1736
+
}
1737
+
},
1738
+
"node_modules/@tailwindcss/oxide-linux-x64-gnu": {
1739
+
"version": "4.1.11",
1740
+
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.11.tgz",
1741
+
"integrity": "sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg==",
1742
+
"cpu": [
1743
+
"x64"
1744
+
],
1745
+
"license": "MIT",
1746
+
"optional": true,
1747
+
"os": [
1748
+
"linux"
1749
+
],
1750
+
"engines": {
1751
+
"node": ">= 10"
1752
+
}
1753
+
},
1754
+
"node_modules/@tailwindcss/oxide-linux-x64-musl": {
1755
+
"version": "4.1.11",
1756
+
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.11.tgz",
1757
+
"integrity": "sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q==",
1758
+
"cpu": [
1759
+
"x64"
1760
+
],
1761
+
"license": "MIT",
1762
+
"optional": true,
1763
+
"os": [
1764
+
"linux"
1765
+
],
1766
+
"engines": {
1767
+
"node": ">= 10"
1768
+
}
1769
+
},
1770
+
"node_modules/@tailwindcss/oxide-wasm32-wasi": {
1771
+
"version": "4.1.11",
1772
+
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.11.tgz",
1773
+
"integrity": "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g==",
1774
+
"bundleDependencies": [
1775
+
"@napi-rs/wasm-runtime",
1776
+
"@emnapi/core",
1777
+
"@emnapi/runtime",
1778
+
"@tybys/wasm-util",
1779
+
"@emnapi/wasi-threads",
1780
+
"tslib"
1781
+
],
1782
+
"cpu": [
1783
+
"wasm32"
1784
+
],
1785
+
"license": "MIT",
1786
+
"optional": true,
1787
+
"dependencies": {
1788
+
"@emnapi/core": "^1.4.3",
1789
+
"@emnapi/runtime": "^1.4.3",
1790
+
"@emnapi/wasi-threads": "^1.0.2",
1791
+
"@napi-rs/wasm-runtime": "^0.2.11",
1792
+
"@tybys/wasm-util": "^0.9.0",
1793
+
"tslib": "^2.8.0"
1794
+
},
1795
+
"engines": {
1796
+
"node": ">=14.0.0"
1797
+
}
1798
+
},
1799
+
"node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
1800
+
"version": "4.1.11",
1801
+
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.11.tgz",
1802
+
"integrity": "sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w==",
1803
+
"cpu": [
1804
+
"arm64"
1805
+
],
1806
+
"license": "MIT",
1807
+
"optional": true,
1808
+
"os": [
1809
+
"win32"
1810
+
],
1811
+
"engines": {
1812
+
"node": ">= 10"
1813
+
}
1814
+
},
1815
+
"node_modules/@tailwindcss/oxide-win32-x64-msvc": {
1816
+
"version": "4.1.11",
1817
+
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.11.tgz",
1818
+
"integrity": "sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg==",
1819
+
"cpu": [
1820
+
"x64"
1821
+
],
1822
+
"license": "MIT",
1823
+
"optional": true,
1824
+
"os": [
1825
+
"win32"
1826
+
],
1827
+
"engines": {
1828
+
"node": ">= 10"
1829
+
}
1830
+
},
1831
+
"node_modules/@tailwindcss/typography": {
1832
+
"version": "0.5.16",
1833
+
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.16.tgz",
1834
+
"integrity": "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==",
1835
+
"license": "MIT",
1836
+
"dependencies": {
1837
+
"lodash.castarray": "^4.4.0",
1838
+
"lodash.isplainobject": "^4.0.6",
1839
+
"lodash.merge": "^4.6.2",
1840
+
"postcss-selector-parser": "6.0.10"
1841
+
},
1842
+
"peerDependencies": {
1843
+
"tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1"
1844
+
}
1845
+
},
1846
+
"node_modules/@tailwindcss/vite": {
1847
+
"version": "4.1.11",
1848
+
"resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.11.tgz",
1849
+
"integrity": "sha512-RHYhrR3hku0MJFRV+fN2gNbDNEh3dwKvY8XJvTxCSXeMOsCRSr+uKvDWQcbizrHgjML6ZmTE5OwMrl5wKcujCw==",
1850
+
"license": "MIT",
1851
+
"dependencies": {
1852
+
"@tailwindcss/node": "4.1.11",
1853
+
"@tailwindcss/oxide": "4.1.11",
1854
+
"tailwindcss": "4.1.11"
1855
+
},
1856
+
"peerDependencies": {
1857
+
"vite": "^5.2.0 || ^6 || ^7"
1858
+
}
1859
+
},
1305
1860
"node_modules/@types/debug": {
1306
1861
"version": "4.1.12",
1307
1862
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
···
1380
1935
"integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
1381
1936
"license": "ISC"
1382
1937
},
1938
+
"node_modules/@volar/kit": {
1939
+
"version": "2.4.22",
1940
+
"resolved": "https://registry.npmjs.org/@volar/kit/-/kit-2.4.22.tgz",
1941
+
"integrity": "sha512-o2LhNb2PLCUJ6v2XSqN7m+pJt+SE0QW1U2E52jnS8yZ03ohcGOOuFJdH1VlZgCBk0RlwO4xp0OaDoTtyTvMTrw==",
1942
+
"license": "MIT",
1943
+
"dependencies": {
1944
+
"@volar/language-service": "2.4.22",
1945
+
"@volar/typescript": "2.4.22",
1946
+
"typesafe-path": "^0.2.2",
1947
+
"vscode-languageserver-textdocument": "^1.0.11",
1948
+
"vscode-uri": "^3.0.8"
1949
+
},
1950
+
"peerDependencies": {
1951
+
"typescript": "*"
1952
+
}
1953
+
},
1954
+
"node_modules/@volar/language-core": {
1955
+
"version": "2.4.22",
1956
+
"resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.22.tgz",
1957
+
"integrity": "sha512-gp4M7Di5KgNyIyO903wTClYBavRt6UyFNpc5LWfyZr1lBsTUY+QrVZfmbNF2aCyfklBOVk9YC4p+zkwoyT7ECg==",
1958
+
"license": "MIT",
1959
+
"dependencies": {
1960
+
"@volar/source-map": "2.4.22"
1961
+
}
1962
+
},
1963
+
"node_modules/@volar/language-server": {
1964
+
"version": "2.4.22",
1965
+
"resolved": "https://registry.npmjs.org/@volar/language-server/-/language-server-2.4.22.tgz",
1966
+
"integrity": "sha512-THIGWcQsEJKZU7SjVKPcy4MIamX4qpusKErj33ru7fi2WcD+FmFjYY/F2LIk/C15xEcb34JT1uZBlbO2dfzYSQ==",
1967
+
"license": "MIT",
1968
+
"dependencies": {
1969
+
"@volar/language-core": "2.4.22",
1970
+
"@volar/language-service": "2.4.22",
1971
+
"@volar/typescript": "2.4.22",
1972
+
"path-browserify": "^1.0.1",
1973
+
"request-light": "^0.7.0",
1974
+
"vscode-languageserver": "^9.0.1",
1975
+
"vscode-languageserver-protocol": "^3.17.5",
1976
+
"vscode-languageserver-textdocument": "^1.0.11",
1977
+
"vscode-uri": "^3.0.8"
1978
+
}
1979
+
},
1980
+
"node_modules/@volar/language-service": {
1981
+
"version": "2.4.22",
1982
+
"resolved": "https://registry.npmjs.org/@volar/language-service/-/language-service-2.4.22.tgz",
1983
+
"integrity": "sha512-8TmvOf/6uqaJMBVQIP9kgVpRzMrqLI3nCmWuSIPAldlmwjZTOiN17GA4AL4sTFJUg61xCSyMQWbProNFQ88yew==",
1984
+
"license": "MIT",
1985
+
"dependencies": {
1986
+
"@volar/language-core": "2.4.22",
1987
+
"vscode-languageserver-protocol": "^3.17.5",
1988
+
"vscode-languageserver-textdocument": "^1.0.11",
1989
+
"vscode-uri": "^3.0.8"
1990
+
}
1991
+
},
1992
+
"node_modules/@volar/source-map": {
1993
+
"version": "2.4.22",
1994
+
"resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.22.tgz",
1995
+
"integrity": "sha512-L2nVr/1vei0xKRgO2tYVXtJYd09HTRjaZi418e85Q+QdbbqA8h7bBjfNyPPSsjnrOO4l4kaAo78c8SQUAdHvgA==",
1996
+
"license": "MIT"
1997
+
},
1998
+
"node_modules/@volar/typescript": {
1999
+
"version": "2.4.22",
2000
+
"resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.22.tgz",
2001
+
"integrity": "sha512-6ZczlJW1/GWTrNnkmZxJp4qyBt/SGVlcTuCWpI5zLrdPdCZsj66Aff9ZsfFaT3TyjG8zVYgBMYPuCm/eRkpcpQ==",
2002
+
"license": "MIT",
2003
+
"dependencies": {
2004
+
"@volar/language-core": "2.4.22",
2005
+
"path-browserify": "^1.0.1",
2006
+
"vscode-uri": "^3.0.8"
2007
+
}
2008
+
},
2009
+
"node_modules/@vscode/emmet-helper": {
2010
+
"version": "2.11.0",
2011
+
"resolved": "https://registry.npmjs.org/@vscode/emmet-helper/-/emmet-helper-2.11.0.tgz",
2012
+
"integrity": "sha512-QLxjQR3imPZPQltfbWRnHU6JecWTF1QSWhx3GAKQpslx7y3Dp6sIIXhKjiUJ/BR9FX8PVthjr9PD6pNwOJfAzw==",
2013
+
"license": "MIT",
2014
+
"dependencies": {
2015
+
"emmet": "^2.4.3",
2016
+
"jsonc-parser": "^2.3.0",
2017
+
"vscode-languageserver-textdocument": "^1.0.1",
2018
+
"vscode-languageserver-types": "^3.15.1",
2019
+
"vscode-uri": "^3.0.8"
2020
+
}
2021
+
},
2022
+
"node_modules/@vscode/l10n": {
2023
+
"version": "0.0.18",
2024
+
"resolved": "https://registry.npmjs.org/@vscode/l10n/-/l10n-0.0.18.tgz",
2025
+
"integrity": "sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==",
2026
+
"license": "MIT"
2027
+
},
1383
2028
"node_modules/acorn": {
1384
2029
"version": "8.15.0",
1385
2030
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
···
1392
2037
"node": ">=0.4.0"
1393
2038
}
1394
2039
},
2040
+
"node_modules/ajv": {
2041
+
"version": "8.17.1",
2042
+
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
2043
+
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
2044
+
"license": "MIT",
2045
+
"dependencies": {
2046
+
"fast-deep-equal": "^3.1.3",
2047
+
"fast-uri": "^3.0.1",
2048
+
"json-schema-traverse": "^1.0.0",
2049
+
"require-from-string": "^2.0.2"
2050
+
},
2051
+
"funding": {
2052
+
"type": "github",
2053
+
"url": "https://github.com/sponsors/epoberezkin"
2054
+
}
2055
+
},
1395
2056
"node_modules/ansi-align": {
1396
2057
"version": "3.0.1",
1397
2058
"resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz",
···
1601
2262
"sharp": "^0.33.3"
1602
2263
}
1603
2264
},
2265
+
"node_modules/await-lock": {
2266
+
"version": "2.2.2",
2267
+
"resolved": "https://registry.npmjs.org/await-lock/-/await-lock-2.2.2.tgz",
2268
+
"integrity": "sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw==",
2269
+
"license": "MIT"
2270
+
},
1604
2271
"node_modules/axobject-query": {
1605
2272
"version": "4.1.0",
1606
2273
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
···
1688
2355
"url": "https://github.com/sponsors/sindresorhus"
1689
2356
}
1690
2357
},
2358
+
"node_modules/braces": {
2359
+
"version": "3.0.3",
2360
+
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
2361
+
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
2362
+
"license": "MIT",
2363
+
"dependencies": {
2364
+
"fill-range": "^7.1.1"
2365
+
},
2366
+
"engines": {
2367
+
"node": ">=8"
2368
+
}
2369
+
},
1691
2370
"node_modules/brotli": {
1692
2371
"version": "1.3.3",
1693
2372
"resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz",
···
1776
2455
"url": "https://paulmillr.com/funding/"
1777
2456
}
1778
2457
},
2458
+
"node_modules/chownr": {
2459
+
"version": "3.0.0",
2460
+
"resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
2461
+
"integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==",
2462
+
"license": "BlueOak-1.0.0",
2463
+
"engines": {
2464
+
"node": ">=18"
2465
+
}
2466
+
},
1779
2467
"node_modules/ci-info": {
1780
2468
"version": "4.3.0",
1781
2469
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz",
···
1803
2491
"url": "https://github.com/sponsors/sindresorhus"
1804
2492
}
1805
2493
},
2494
+
"node_modules/cliui": {
2495
+
"version": "8.0.1",
2496
+
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
2497
+
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
2498
+
"license": "ISC",
2499
+
"dependencies": {
2500
+
"string-width": "^4.2.0",
2501
+
"strip-ansi": "^6.0.1",
2502
+
"wrap-ansi": "^7.0.0"
2503
+
},
2504
+
"engines": {
2505
+
"node": ">=12"
2506
+
}
2507
+
},
2508
+
"node_modules/cliui/node_modules/ansi-regex": {
2509
+
"version": "5.0.1",
2510
+
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
2511
+
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
2512
+
"license": "MIT",
2513
+
"engines": {
2514
+
"node": ">=8"
2515
+
}
2516
+
},
2517
+
"node_modules/cliui/node_modules/ansi-styles": {
2518
+
"version": "4.3.0",
2519
+
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
2520
+
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
2521
+
"license": "MIT",
2522
+
"dependencies": {
2523
+
"color-convert": "^2.0.1"
2524
+
},
2525
+
"engines": {
2526
+
"node": ">=8"
2527
+
},
2528
+
"funding": {
2529
+
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
2530
+
}
2531
+
},
2532
+
"node_modules/cliui/node_modules/emoji-regex": {
2533
+
"version": "8.0.0",
2534
+
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
2535
+
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
2536
+
"license": "MIT"
2537
+
},
2538
+
"node_modules/cliui/node_modules/string-width": {
2539
+
"version": "4.2.3",
2540
+
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
2541
+
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
2542
+
"license": "MIT",
2543
+
"dependencies": {
2544
+
"emoji-regex": "^8.0.0",
2545
+
"is-fullwidth-code-point": "^3.0.0",
2546
+
"strip-ansi": "^6.0.1"
2547
+
},
2548
+
"engines": {
2549
+
"node": ">=8"
2550
+
}
2551
+
},
2552
+
"node_modules/cliui/node_modules/strip-ansi": {
2553
+
"version": "6.0.1",
2554
+
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
2555
+
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
2556
+
"license": "MIT",
2557
+
"dependencies": {
2558
+
"ansi-regex": "^5.0.1"
2559
+
},
2560
+
"engines": {
2561
+
"node": ">=8"
2562
+
}
2563
+
},
2564
+
"node_modules/cliui/node_modules/wrap-ansi": {
2565
+
"version": "7.0.0",
2566
+
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
2567
+
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
2568
+
"license": "MIT",
2569
+
"dependencies": {
2570
+
"ansi-styles": "^4.0.0",
2571
+
"string-width": "^4.1.0",
2572
+
"strip-ansi": "^6.0.0"
2573
+
},
2574
+
"engines": {
2575
+
"node": ">=10"
2576
+
},
2577
+
"funding": {
2578
+
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
2579
+
}
2580
+
},
1806
2581
"node_modules/clone": {
1807
2582
"version": "2.1.2",
1808
2583
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
···
1840
2615
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
1841
2616
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
1842
2617
"license": "MIT",
1843
-
"optional": true,
1844
2618
"dependencies": {
1845
2619
"color-name": "~1.1.4"
1846
2620
},
···
1852
2626
"version": "1.1.4",
1853
2627
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
1854
2628
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
1855
-
"license": "MIT",
1856
-
"optional": true
2629
+
"license": "MIT"
1857
2630
},
1858
2631
"node_modules/color-string": {
1859
2632
"version": "1.9.1",
···
1996
2769
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
1997
2770
"integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
1998
2771
"license": "Apache-2.0",
1999
-
"optional": true,
2000
2772
"engines": {
2001
2773
"node": ">=8"
2002
2774
}
···
2053
2825
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
2054
2826
"license": "MIT"
2055
2827
},
2828
+
"node_modules/dotenv": {
2829
+
"version": "17.2.1",
2830
+
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.1.tgz",
2831
+
"integrity": "sha512-kQhDYKZecqnM0fCnzI5eIv5L4cAe/iRI+HqMbO/hbRdTAeXDG+M9FjipUxNfbARuEg4iHIbhnhs78BCHNbSxEQ==",
2832
+
"license": "BSD-2-Clause",
2833
+
"engines": {
2834
+
"node": ">=12"
2835
+
},
2836
+
"funding": {
2837
+
"url": "https://dotenvx.com"
2838
+
}
2839
+
},
2056
2840
"node_modules/dset": {
2057
2841
"version": "3.1.4",
2058
2842
"resolved": "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz",
···
2062
2846
"node": ">=4"
2063
2847
}
2064
2848
},
2849
+
"node_modules/emmet": {
2850
+
"version": "2.4.11",
2851
+
"resolved": "https://registry.npmjs.org/emmet/-/emmet-2.4.11.tgz",
2852
+
"integrity": "sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ==",
2853
+
"license": "MIT",
2854
+
"workspaces": [
2855
+
"./packages/scanner",
2856
+
"./packages/abbreviation",
2857
+
"./packages/css-abbreviation",
2858
+
"./"
2859
+
],
2860
+
"dependencies": {
2861
+
"@emmetio/abbreviation": "^2.3.3",
2862
+
"@emmetio/css-abbreviation": "^2.1.8"
2863
+
}
2864
+
},
2065
2865
"node_modules/emoji-regex": {
2066
2866
"version": "10.4.0",
2067
2867
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz",
2068
2868
"integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==",
2069
2869
"license": "MIT"
2070
2870
},
2871
+
"node_modules/enhanced-resolve": {
2872
+
"version": "5.18.2",
2873
+
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz",
2874
+
"integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==",
2875
+
"license": "MIT",
2876
+
"dependencies": {
2877
+
"graceful-fs": "^4.2.4",
2878
+
"tapable": "^2.2.0"
2879
+
},
2880
+
"engines": {
2881
+
"node": ">=10.13.0"
2882
+
}
2883
+
},
2071
2884
"node_modules/entities": {
2072
2885
"version": "6.0.1",
2073
2886
"resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
···
2127
2940
"@esbuild/win32-x64": "0.25.8"
2128
2941
}
2129
2942
},
2943
+
"node_modules/escalade": {
2944
+
"version": "3.2.0",
2945
+
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
2946
+
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
2947
+
"license": "MIT",
2948
+
"engines": {
2949
+
"node": ">=6"
2950
+
}
2951
+
},
2130
2952
"node_modules/escape-string-regexp": {
2131
2953
"version": "5.0.0",
2132
2954
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
···
2166
2988
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
2167
2989
"license": "MIT"
2168
2990
},
2991
+
"node_modules/fast-glob": {
2992
+
"version": "3.3.3",
2993
+
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
2994
+
"integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
2995
+
"license": "MIT",
2996
+
"dependencies": {
2997
+
"@nodelib/fs.stat": "^2.0.2",
2998
+
"@nodelib/fs.walk": "^1.2.3",
2999
+
"glob-parent": "^5.1.2",
3000
+
"merge2": "^1.3.0",
3001
+
"micromatch": "^4.0.8"
3002
+
},
3003
+
"engines": {
3004
+
"node": ">=8.6.0"
3005
+
}
3006
+
},
3007
+
"node_modules/fast-uri": {
3008
+
"version": "3.0.6",
3009
+
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz",
3010
+
"integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==",
3011
+
"funding": [
3012
+
{
3013
+
"type": "github",
3014
+
"url": "https://github.com/sponsors/fastify"
3015
+
},
3016
+
{
3017
+
"type": "opencollective",
3018
+
"url": "https://opencollective.com/fastify"
3019
+
}
3020
+
],
3021
+
"license": "BSD-3-Clause"
3022
+
},
3023
+
"node_modules/fastq": {
3024
+
"version": "1.19.1",
3025
+
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
3026
+
"integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
3027
+
"license": "ISC",
3028
+
"dependencies": {
3029
+
"reusify": "^1.0.4"
3030
+
}
3031
+
},
2169
3032
"node_modules/fdir": {
2170
3033
"version": "6.4.6",
2171
3034
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz",
···
2180
3043
}
2181
3044
}
2182
3045
},
3046
+
"node_modules/fill-range": {
3047
+
"version": "7.1.1",
3048
+
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
3049
+
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
3050
+
"license": "MIT",
3051
+
"dependencies": {
3052
+
"to-regex-range": "^5.0.1"
3053
+
},
3054
+
"engines": {
3055
+
"node": ">=8"
3056
+
}
3057
+
},
2183
3058
"node_modules/flattie": {
2184
3059
"version": "1.1.1",
2185
3060
"resolved": "https://registry.npmjs.org/flattie/-/flattie-1.1.1.tgz",
···
2230
3105
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
2231
3106
}
2232
3107
},
3108
+
"node_modules/get-caller-file": {
3109
+
"version": "2.0.5",
3110
+
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
3111
+
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
3112
+
"license": "ISC",
3113
+
"engines": {
3114
+
"node": "6.* || 8.* || >= 10.*"
3115
+
}
3116
+
},
2233
3117
"node_modules/get-east-asian-width": {
2234
3118
"version": "1.3.0",
2235
3119
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz",
···
2247
3131
"resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz",
2248
3132
"integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==",
2249
3133
"license": "ISC"
3134
+
},
3135
+
"node_modules/glob-parent": {
3136
+
"version": "5.1.2",
3137
+
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
3138
+
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
3139
+
"license": "ISC",
3140
+
"dependencies": {
3141
+
"is-glob": "^4.0.1"
3142
+
},
3143
+
"engines": {
3144
+
"node": ">= 6"
3145
+
}
3146
+
},
3147
+
"node_modules/graceful-fs": {
3148
+
"version": "4.2.11",
3149
+
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
3150
+
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
3151
+
"license": "ISC"
3152
+
},
3153
+
"node_modules/graphemer": {
3154
+
"version": "1.4.0",
3155
+
"resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
3156
+
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
3157
+
"license": "MIT"
2250
3158
},
2251
3159
"node_modules/h3": {
2252
3160
"version": "1.15.4",
···
2515
3423
"url": "https://github.com/sponsors/sindresorhus"
2516
3424
}
2517
3425
},
3426
+
"node_modules/is-extglob": {
3427
+
"version": "2.1.1",
3428
+
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
3429
+
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
3430
+
"license": "MIT",
3431
+
"engines": {
3432
+
"node": ">=0.10.0"
3433
+
}
3434
+
},
2518
3435
"node_modules/is-fullwidth-code-point": {
2519
3436
"version": "3.0.0",
2520
3437
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
···
2524
3441
"node": ">=8"
2525
3442
}
2526
3443
},
3444
+
"node_modules/is-glob": {
3445
+
"version": "4.0.3",
3446
+
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
3447
+
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
3448
+
"license": "MIT",
3449
+
"dependencies": {
3450
+
"is-extglob": "^2.1.1"
3451
+
},
3452
+
"engines": {
3453
+
"node": ">=0.10.0"
3454
+
}
3455
+
},
2527
3456
"node_modules/is-inside-container": {
2528
3457
"version": "1.0.0",
2529
3458
"resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
···
2542
3471
"url": "https://github.com/sponsors/sindresorhus"
2543
3472
}
2544
3473
},
3474
+
"node_modules/is-number": {
3475
+
"version": "7.0.0",
3476
+
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
3477
+
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
3478
+
"license": "MIT",
3479
+
"engines": {
3480
+
"node": ">=0.12.0"
3481
+
}
3482
+
},
2545
3483
"node_modules/is-plain-obj": {
2546
3484
"version": "4.1.0",
2547
3485
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
···
2569
3507
"url": "https://github.com/sponsors/sindresorhus"
2570
3508
}
2571
3509
},
3510
+
"node_modules/iso-datestring-validator": {
3511
+
"version": "2.2.2",
3512
+
"resolved": "https://registry.npmjs.org/iso-datestring-validator/-/iso-datestring-validator-2.2.2.tgz",
3513
+
"integrity": "sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==",
3514
+
"license": "MIT"
3515
+
},
3516
+
"node_modules/jiti": {
3517
+
"version": "2.5.1",
3518
+
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz",
3519
+
"integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==",
3520
+
"license": "MIT",
3521
+
"bin": {
3522
+
"jiti": "lib/jiti-cli.mjs"
3523
+
}
3524
+
},
2572
3525
"node_modules/js-yaml": {
2573
3526
"version": "4.1.0",
2574
3527
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
···
2581
3534
"js-yaml": "bin/js-yaml.js"
2582
3535
}
2583
3536
},
3537
+
"node_modules/json-schema-traverse": {
3538
+
"version": "1.0.0",
3539
+
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
3540
+
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
3541
+
"license": "MIT"
3542
+
},
3543
+
"node_modules/jsonc-parser": {
3544
+
"version": "2.3.1",
3545
+
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.3.1.tgz",
3546
+
"integrity": "sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==",
3547
+
"license": "MIT"
3548
+
},
2584
3549
"node_modules/kleur": {
2585
3550
"version": "4.1.5",
2586
3551
"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
···
2590
3555
"node": ">=6"
2591
3556
}
2592
3557
},
3558
+
"node_modules/lightningcss": {
3559
+
"version": "1.30.1",
3560
+
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz",
3561
+
"integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==",
3562
+
"license": "MPL-2.0",
3563
+
"dependencies": {
3564
+
"detect-libc": "^2.0.3"
3565
+
},
3566
+
"engines": {
3567
+
"node": ">= 12.0.0"
3568
+
},
3569
+
"funding": {
3570
+
"type": "opencollective",
3571
+
"url": "https://opencollective.com/parcel"
3572
+
},
3573
+
"optionalDependencies": {
3574
+
"lightningcss-darwin-arm64": "1.30.1",
3575
+
"lightningcss-darwin-x64": "1.30.1",
3576
+
"lightningcss-freebsd-x64": "1.30.1",
3577
+
"lightningcss-linux-arm-gnueabihf": "1.30.1",
3578
+
"lightningcss-linux-arm64-gnu": "1.30.1",
3579
+
"lightningcss-linux-arm64-musl": "1.30.1",
3580
+
"lightningcss-linux-x64-gnu": "1.30.1",
3581
+
"lightningcss-linux-x64-musl": "1.30.1",
3582
+
"lightningcss-win32-arm64-msvc": "1.30.1",
3583
+
"lightningcss-win32-x64-msvc": "1.30.1"
3584
+
}
3585
+
},
3586
+
"node_modules/lightningcss-darwin-arm64": {
3587
+
"version": "1.30.1",
3588
+
"resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz",
3589
+
"integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==",
3590
+
"cpu": [
3591
+
"arm64"
3592
+
],
3593
+
"license": "MPL-2.0",
3594
+
"optional": true,
3595
+
"os": [
3596
+
"darwin"
3597
+
],
3598
+
"engines": {
3599
+
"node": ">= 12.0.0"
3600
+
},
3601
+
"funding": {
3602
+
"type": "opencollective",
3603
+
"url": "https://opencollective.com/parcel"
3604
+
}
3605
+
},
3606
+
"node_modules/lightningcss-darwin-x64": {
3607
+
"version": "1.30.1",
3608
+
"resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz",
3609
+
"integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==",
3610
+
"cpu": [
3611
+
"x64"
3612
+
],
3613
+
"license": "MPL-2.0",
3614
+
"optional": true,
3615
+
"os": [
3616
+
"darwin"
3617
+
],
3618
+
"engines": {
3619
+
"node": ">= 12.0.0"
3620
+
},
3621
+
"funding": {
3622
+
"type": "opencollective",
3623
+
"url": "https://opencollective.com/parcel"
3624
+
}
3625
+
},
3626
+
"node_modules/lightningcss-freebsd-x64": {
3627
+
"version": "1.30.1",
3628
+
"resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz",
3629
+
"integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==",
3630
+
"cpu": [
3631
+
"x64"
3632
+
],
3633
+
"license": "MPL-2.0",
3634
+
"optional": true,
3635
+
"os": [
3636
+
"freebsd"
3637
+
],
3638
+
"engines": {
3639
+
"node": ">= 12.0.0"
3640
+
},
3641
+
"funding": {
3642
+
"type": "opencollective",
3643
+
"url": "https://opencollective.com/parcel"
3644
+
}
3645
+
},
3646
+
"node_modules/lightningcss-linux-arm-gnueabihf": {
3647
+
"version": "1.30.1",
3648
+
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz",
3649
+
"integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==",
3650
+
"cpu": [
3651
+
"arm"
3652
+
],
3653
+
"license": "MPL-2.0",
3654
+
"optional": true,
3655
+
"os": [
3656
+
"linux"
3657
+
],
3658
+
"engines": {
3659
+
"node": ">= 12.0.0"
3660
+
},
3661
+
"funding": {
3662
+
"type": "opencollective",
3663
+
"url": "https://opencollective.com/parcel"
3664
+
}
3665
+
},
3666
+
"node_modules/lightningcss-linux-arm64-gnu": {
3667
+
"version": "1.30.1",
3668
+
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz",
3669
+
"integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==",
3670
+
"cpu": [
3671
+
"arm64"
3672
+
],
3673
+
"license": "MPL-2.0",
3674
+
"optional": true,
3675
+
"os": [
3676
+
"linux"
3677
+
],
3678
+
"engines": {
3679
+
"node": ">= 12.0.0"
3680
+
},
3681
+
"funding": {
3682
+
"type": "opencollective",
3683
+
"url": "https://opencollective.com/parcel"
3684
+
}
3685
+
},
3686
+
"node_modules/lightningcss-linux-arm64-musl": {
3687
+
"version": "1.30.1",
3688
+
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz",
3689
+
"integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==",
3690
+
"cpu": [
3691
+
"arm64"
3692
+
],
3693
+
"license": "MPL-2.0",
3694
+
"optional": true,
3695
+
"os": [
3696
+
"linux"
3697
+
],
3698
+
"engines": {
3699
+
"node": ">= 12.0.0"
3700
+
},
3701
+
"funding": {
3702
+
"type": "opencollective",
3703
+
"url": "https://opencollective.com/parcel"
3704
+
}
3705
+
},
3706
+
"node_modules/lightningcss-linux-x64-gnu": {
3707
+
"version": "1.30.1",
3708
+
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz",
3709
+
"integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==",
3710
+
"cpu": [
3711
+
"x64"
3712
+
],
3713
+
"license": "MPL-2.0",
3714
+
"optional": true,
3715
+
"os": [
3716
+
"linux"
3717
+
],
3718
+
"engines": {
3719
+
"node": ">= 12.0.0"
3720
+
},
3721
+
"funding": {
3722
+
"type": "opencollective",
3723
+
"url": "https://opencollective.com/parcel"
3724
+
}
3725
+
},
3726
+
"node_modules/lightningcss-linux-x64-musl": {
3727
+
"version": "1.30.1",
3728
+
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz",
3729
+
"integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==",
3730
+
"cpu": [
3731
+
"x64"
3732
+
],
3733
+
"license": "MPL-2.0",
3734
+
"optional": true,
3735
+
"os": [
3736
+
"linux"
3737
+
],
3738
+
"engines": {
3739
+
"node": ">= 12.0.0"
3740
+
},
3741
+
"funding": {
3742
+
"type": "opencollective",
3743
+
"url": "https://opencollective.com/parcel"
3744
+
}
3745
+
},
3746
+
"node_modules/lightningcss-win32-arm64-msvc": {
3747
+
"version": "1.30.1",
3748
+
"resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz",
3749
+
"integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==",
3750
+
"cpu": [
3751
+
"arm64"
3752
+
],
3753
+
"license": "MPL-2.0",
3754
+
"optional": true,
3755
+
"os": [
3756
+
"win32"
3757
+
],
3758
+
"engines": {
3759
+
"node": ">= 12.0.0"
3760
+
},
3761
+
"funding": {
3762
+
"type": "opencollective",
3763
+
"url": "https://opencollective.com/parcel"
3764
+
}
3765
+
},
3766
+
"node_modules/lightningcss-win32-x64-msvc": {
3767
+
"version": "1.30.1",
3768
+
"resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz",
3769
+
"integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==",
3770
+
"cpu": [
3771
+
"x64"
3772
+
],
3773
+
"license": "MPL-2.0",
3774
+
"optional": true,
3775
+
"os": [
3776
+
"win32"
3777
+
],
3778
+
"engines": {
3779
+
"node": ">= 12.0.0"
3780
+
},
3781
+
"funding": {
3782
+
"type": "opencollective",
3783
+
"url": "https://opencollective.com/parcel"
3784
+
}
3785
+
},
3786
+
"node_modules/lodash": {
3787
+
"version": "4.17.21",
3788
+
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
3789
+
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
3790
+
"license": "MIT"
3791
+
},
3792
+
"node_modules/lodash.castarray": {
3793
+
"version": "4.4.0",
3794
+
"resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz",
3795
+
"integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==",
3796
+
"license": "MIT"
3797
+
},
3798
+
"node_modules/lodash.isplainobject": {
3799
+
"version": "4.0.6",
3800
+
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
3801
+
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
3802
+
"license": "MIT"
3803
+
},
3804
+
"node_modules/lodash.merge": {
3805
+
"version": "4.6.2",
3806
+
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
3807
+
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
3808
+
"license": "MIT"
3809
+
},
2593
3810
"node_modules/longest-streak": {
2594
3811
"version": "3.1.0",
2595
3812
"resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
···
2866
4083
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz",
2867
4084
"integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==",
2868
4085
"license": "CC0-1.0"
4086
+
},
4087
+
"node_modules/merge2": {
4088
+
"version": "1.4.1",
4089
+
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
4090
+
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
4091
+
"license": "MIT",
4092
+
"engines": {
4093
+
"node": ">= 8"
4094
+
}
2869
4095
},
2870
4096
"node_modules/micromark": {
2871
4097
"version": "4.0.2",
···
3430
4656
],
3431
4657
"license": "MIT"
3432
4658
},
4659
+
"node_modules/micromatch": {
4660
+
"version": "4.0.8",
4661
+
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
4662
+
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
4663
+
"license": "MIT",
4664
+
"dependencies": {
4665
+
"braces": "^3.0.3",
4666
+
"picomatch": "^2.3.1"
4667
+
},
4668
+
"engines": {
4669
+
"node": ">=8.6"
4670
+
}
4671
+
},
4672
+
"node_modules/micromatch/node_modules/picomatch": {
4673
+
"version": "2.3.1",
4674
+
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
4675
+
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
4676
+
"license": "MIT",
4677
+
"engines": {
4678
+
"node": ">=8.6"
4679
+
},
4680
+
"funding": {
4681
+
"url": "https://github.com/sponsors/jonschlinkert"
4682
+
}
4683
+
},
4684
+
"node_modules/minipass": {
4685
+
"version": "7.1.2",
4686
+
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
4687
+
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
4688
+
"license": "ISC",
4689
+
"engines": {
4690
+
"node": ">=16 || 14 >=14.17"
4691
+
}
4692
+
},
4693
+
"node_modules/minizlib": {
4694
+
"version": "3.0.2",
4695
+
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz",
4696
+
"integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==",
4697
+
"license": "MIT",
4698
+
"dependencies": {
4699
+
"minipass": "^7.1.2"
4700
+
},
4701
+
"engines": {
4702
+
"node": ">= 18"
4703
+
}
4704
+
},
4705
+
"node_modules/mkdirp": {
4706
+
"version": "3.0.1",
4707
+
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
4708
+
"integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
4709
+
"license": "MIT",
4710
+
"bin": {
4711
+
"mkdirp": "dist/cjs/src/bin.js"
4712
+
},
4713
+
"engines": {
4714
+
"node": ">=10"
4715
+
},
4716
+
"funding": {
4717
+
"url": "https://github.com/sponsors/isaacs"
4718
+
}
4719
+
},
3433
4720
"node_modules/mrmime": {
3434
4721
"version": "2.0.1",
3435
4722
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
···
3444
4731
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
3445
4732
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
3446
4733
"license": "MIT"
4734
+
},
4735
+
"node_modules/muggle-string": {
4736
+
"version": "0.4.1",
4737
+
"resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz",
4738
+
"integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==",
4739
+
"license": "MIT"
4740
+
},
4741
+
"node_modules/multiformats": {
4742
+
"version": "9.9.0",
4743
+
"resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz",
4744
+
"integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==",
4745
+
"license": "(Apache-2.0 AND MIT)"
3447
4746
},
3448
4747
"node_modules/nanoid": {
3449
4748
"version": "3.3.11",
···
3645
4944
"url": "https://github.com/inikulin/parse5?sponsor=1"
3646
4945
}
3647
4946
},
4947
+
"node_modules/path-browserify": {
4948
+
"version": "1.0.1",
4949
+
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
4950
+
"integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
4951
+
"license": "MIT"
4952
+
},
3648
4953
"node_modules/picocolors": {
3649
4954
"version": "1.1.1",
3650
4955
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
···
3691
4996
"node": "^10 || ^12 || >=14"
3692
4997
}
3693
4998
},
4999
+
"node_modules/postcss-selector-parser": {
5000
+
"version": "6.0.10",
5001
+
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
5002
+
"integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
5003
+
"license": "MIT",
5004
+
"dependencies": {
5005
+
"cssesc": "^3.0.0",
5006
+
"util-deprecate": "^1.0.2"
5007
+
},
5008
+
"engines": {
5009
+
"node": ">=4"
5010
+
}
5011
+
},
5012
+
"node_modules/prettier": {
5013
+
"version": "3.6.2",
5014
+
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
5015
+
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
5016
+
"license": "MIT",
5017
+
"optional": true,
5018
+
"peer": true,
5019
+
"bin": {
5020
+
"prettier": "bin/prettier.cjs"
5021
+
},
5022
+
"engines": {
5023
+
"node": ">=14"
5024
+
},
5025
+
"funding": {
5026
+
"url": "https://github.com/prettier/prettier?sponsor=1"
5027
+
}
5028
+
},
3694
5029
"node_modules/prismjs": {
3695
5030
"version": "1.30.0",
3696
5031
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz",
···
3731
5066
"type": "github",
3732
5067
"url": "https://github.com/sponsors/wooorm"
3733
5068
}
5069
+
},
5070
+
"node_modules/queue-microtask": {
5071
+
"version": "1.2.3",
5072
+
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
5073
+
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
5074
+
"funding": [
5075
+
{
5076
+
"type": "github",
5077
+
"url": "https://github.com/sponsors/feross"
5078
+
},
5079
+
{
5080
+
"type": "patreon",
5081
+
"url": "https://www.patreon.com/feross"
5082
+
},
5083
+
{
5084
+
"type": "consulting",
5085
+
"url": "https://feross.org/support"
5086
+
}
5087
+
],
5088
+
"license": "MIT"
3734
5089
},
3735
5090
"node_modules/radix3": {
3736
5091
"version": "1.1.2",
···
3917
5272
"url": "https://opencollective.com/unified"
3918
5273
}
3919
5274
},
5275
+
"node_modules/request-light": {
5276
+
"version": "0.7.0",
5277
+
"resolved": "https://registry.npmjs.org/request-light/-/request-light-0.7.0.tgz",
5278
+
"integrity": "sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q==",
5279
+
"license": "MIT"
5280
+
},
5281
+
"node_modules/require-directory": {
5282
+
"version": "2.1.1",
5283
+
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
5284
+
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
5285
+
"license": "MIT",
5286
+
"engines": {
5287
+
"node": ">=0.10.0"
5288
+
}
5289
+
},
5290
+
"node_modules/require-from-string": {
5291
+
"version": "2.0.2",
5292
+
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
5293
+
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
5294
+
"license": "MIT",
5295
+
"engines": {
5296
+
"node": ">=0.10.0"
5297
+
}
5298
+
},
3920
5299
"node_modules/restructure": {
3921
5300
"version": "3.0.2",
3922
5301
"resolved": "https://registry.npmjs.org/restructure/-/restructure-3.0.2.tgz",
···
3984
5363
"url": "https://opencollective.com/unified"
3985
5364
}
3986
5365
},
5366
+
"node_modules/reusify": {
5367
+
"version": "1.1.0",
5368
+
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
5369
+
"integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
5370
+
"license": "MIT",
5371
+
"engines": {
5372
+
"iojs": ">=1.0.0",
5373
+
"node": ">=0.10.0"
5374
+
}
5375
+
},
3987
5376
"node_modules/rollup": {
3988
5377
"version": "4.46.2",
3989
5378
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.46.2.tgz",
···
4023
5412
"fsevents": "~2.3.2"
4024
5413
}
4025
5414
},
5415
+
"node_modules/run-parallel": {
5416
+
"version": "1.2.0",
5417
+
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
5418
+
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
5419
+
"funding": [
5420
+
{
5421
+
"type": "github",
5422
+
"url": "https://github.com/sponsors/feross"
5423
+
},
5424
+
{
5425
+
"type": "patreon",
5426
+
"url": "https://www.patreon.com/feross"
5427
+
},
5428
+
{
5429
+
"type": "consulting",
5430
+
"url": "https://feross.org/support"
5431
+
}
5432
+
],
5433
+
"license": "MIT",
5434
+
"dependencies": {
5435
+
"queue-microtask": "^1.2.2"
5436
+
}
5437
+
},
4026
5438
"node_modules/semver": {
4027
5439
"version": "7.7.2",
4028
5440
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
···
4184
5596
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
4185
5597
}
4186
5598
},
5599
+
"node_modules/tailwindcss": {
5600
+
"version": "4.1.11",
5601
+
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.11.tgz",
5602
+
"integrity": "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==",
5603
+
"license": "MIT"
5604
+
},
5605
+
"node_modules/tapable": {
5606
+
"version": "2.2.2",
5607
+
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz",
5608
+
"integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==",
5609
+
"license": "MIT",
5610
+
"engines": {
5611
+
"node": ">=6"
5612
+
}
5613
+
},
5614
+
"node_modules/tar": {
5615
+
"version": "7.4.3",
5616
+
"resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz",
5617
+
"integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==",
5618
+
"license": "ISC",
5619
+
"dependencies": {
5620
+
"@isaacs/fs-minipass": "^4.0.0",
5621
+
"chownr": "^3.0.0",
5622
+
"minipass": "^7.1.2",
5623
+
"minizlib": "^3.0.1",
5624
+
"mkdirp": "^3.0.1",
5625
+
"yallist": "^5.0.0"
5626
+
},
5627
+
"engines": {
5628
+
"node": ">=18"
5629
+
}
5630
+
},
4187
5631
"node_modules/tiny-inflate": {
4188
5632
"version": "1.0.3",
4189
5633
"resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz",
···
4212
5656
"url": "https://github.com/sponsors/SuperchupuDev"
4213
5657
}
4214
5658
},
5659
+
"node_modules/tlds": {
5660
+
"version": "1.259.0",
5661
+
"resolved": "https://registry.npmjs.org/tlds/-/tlds-1.259.0.tgz",
5662
+
"integrity": "sha512-AldGGlDP0PNgwppe2quAvuBl18UcjuNtOnDuUkqhd6ipPqrYYBt3aTxK1QTsBVknk97lS2JcafWMghjGWFtunw==",
5663
+
"license": "MIT",
5664
+
"bin": {
5665
+
"tlds": "bin.js"
5666
+
}
5667
+
},
5668
+
"node_modules/to-regex-range": {
5669
+
"version": "5.0.1",
5670
+
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
5671
+
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
5672
+
"license": "MIT",
5673
+
"dependencies": {
5674
+
"is-number": "^7.0.0"
5675
+
},
5676
+
"engines": {
5677
+
"node": ">=8.0"
5678
+
}
5679
+
},
4215
5680
"node_modules/tr46": {
4216
5681
"version": "0.0.3",
4217
5682
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
···
4276
5741
"url": "https://github.com/sponsors/sindresorhus"
4277
5742
}
4278
5743
},
5744
+
"node_modules/typesafe-path": {
5745
+
"version": "0.2.2",
5746
+
"resolved": "https://registry.npmjs.org/typesafe-path/-/typesafe-path-0.2.2.tgz",
5747
+
"integrity": "sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA==",
5748
+
"license": "MIT"
5749
+
},
4279
5750
"node_modules/typescript": {
4280
5751
"version": "5.9.2",
4281
5752
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
4282
5753
"integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
4283
5754
"license": "Apache-2.0",
4284
-
"peer": true,
4285
5755
"bin": {
4286
5756
"tsc": "bin/tsc",
4287
5757
"tsserver": "bin/tsserver"
···
4290
5760
"node": ">=14.17"
4291
5761
}
4292
5762
},
5763
+
"node_modules/typescript-auto-import-cache": {
5764
+
"version": "0.3.6",
5765
+
"resolved": "https://registry.npmjs.org/typescript-auto-import-cache/-/typescript-auto-import-cache-0.3.6.tgz",
5766
+
"integrity": "sha512-RpuHXrknHdVdK7wv/8ug3Fr0WNsNi5l5aB8MYYuXhq2UH5lnEB1htJ1smhtD5VeCsGr2p8mUDtd83LCQDFVgjQ==",
5767
+
"license": "MIT",
5768
+
"dependencies": {
5769
+
"semver": "^7.3.8"
5770
+
}
5771
+
},
4293
5772
"node_modules/ufo": {
4294
5773
"version": "1.6.1",
4295
5774
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz",
4296
5775
"integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==",
4297
5776
"license": "MIT"
5777
+
},
5778
+
"node_modules/uint8arrays": {
5779
+
"version": "3.0.0",
5780
+
"resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.0.0.tgz",
5781
+
"integrity": "sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA==",
5782
+
"license": "MIT",
5783
+
"dependencies": {
5784
+
"multiformats": "^9.4.2"
5785
+
}
4298
5786
},
4299
5787
"node_modules/ultrahtml": {
4300
5788
"version": "1.6.0",
···
4579
6067
}
4580
6068
}
4581
6069
},
6070
+
"node_modules/util-deprecate": {
6071
+
"version": "1.0.2",
6072
+
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
6073
+
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
6074
+
"license": "MIT"
6075
+
},
4582
6076
"node_modules/vfile": {
4583
6077
"version": "6.0.3",
4584
6078
"resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz",
···
4714
6208
}
4715
6209
}
4716
6210
},
6211
+
"node_modules/volar-service-css": {
6212
+
"version": "0.0.62",
6213
+
"resolved": "https://registry.npmjs.org/volar-service-css/-/volar-service-css-0.0.62.tgz",
6214
+
"integrity": "sha512-JwNyKsH3F8PuzZYuqPf+2e+4CTU8YoyUHEHVnoXNlrLe7wy9U3biomZ56llN69Ris7TTy/+DEX41yVxQpM4qvg==",
6215
+
"license": "MIT",
6216
+
"dependencies": {
6217
+
"vscode-css-languageservice": "^6.3.0",
6218
+
"vscode-languageserver-textdocument": "^1.0.11",
6219
+
"vscode-uri": "^3.0.8"
6220
+
},
6221
+
"peerDependencies": {
6222
+
"@volar/language-service": "~2.4.0"
6223
+
},
6224
+
"peerDependenciesMeta": {
6225
+
"@volar/language-service": {
6226
+
"optional": true
6227
+
}
6228
+
}
6229
+
},
6230
+
"node_modules/volar-service-emmet": {
6231
+
"version": "0.0.62",
6232
+
"resolved": "https://registry.npmjs.org/volar-service-emmet/-/volar-service-emmet-0.0.62.tgz",
6233
+
"integrity": "sha512-U4dxWDBWz7Pi4plpbXf4J4Z/ss6kBO3TYrACxWNsE29abu75QzVS0paxDDhI6bhqpbDFXlpsDhZ9aXVFpnfGRQ==",
6234
+
"license": "MIT",
6235
+
"dependencies": {
6236
+
"@emmetio/css-parser": "^0.4.0",
6237
+
"@emmetio/html-matcher": "^1.3.0",
6238
+
"@vscode/emmet-helper": "^2.9.3",
6239
+
"vscode-uri": "^3.0.8"
6240
+
},
6241
+
"peerDependencies": {
6242
+
"@volar/language-service": "~2.4.0"
6243
+
},
6244
+
"peerDependenciesMeta": {
6245
+
"@volar/language-service": {
6246
+
"optional": true
6247
+
}
6248
+
}
6249
+
},
6250
+
"node_modules/volar-service-html": {
6251
+
"version": "0.0.62",
6252
+
"resolved": "https://registry.npmjs.org/volar-service-html/-/volar-service-html-0.0.62.tgz",
6253
+
"integrity": "sha512-Zw01aJsZRh4GTGUjveyfEzEqpULQUdQH79KNEiKVYHZyuGtdBRYCHlrus1sueSNMxwwkuF5WnOHfvBzafs8yyQ==",
6254
+
"license": "MIT",
6255
+
"dependencies": {
6256
+
"vscode-html-languageservice": "^5.3.0",
6257
+
"vscode-languageserver-textdocument": "^1.0.11",
6258
+
"vscode-uri": "^3.0.8"
6259
+
},
6260
+
"peerDependencies": {
6261
+
"@volar/language-service": "~2.4.0"
6262
+
},
6263
+
"peerDependenciesMeta": {
6264
+
"@volar/language-service": {
6265
+
"optional": true
6266
+
}
6267
+
}
6268
+
},
6269
+
"node_modules/volar-service-prettier": {
6270
+
"version": "0.0.62",
6271
+
"resolved": "https://registry.npmjs.org/volar-service-prettier/-/volar-service-prettier-0.0.62.tgz",
6272
+
"integrity": "sha512-h2yk1RqRTE+vkYZaI9KYuwpDfOQRrTEMvoHol0yW4GFKc75wWQRrb5n/5abDrzMPrkQbSip8JH2AXbvrRtYh4w==",
6273
+
"license": "MIT",
6274
+
"dependencies": {
6275
+
"vscode-uri": "^3.0.8"
6276
+
},
6277
+
"peerDependencies": {
6278
+
"@volar/language-service": "~2.4.0",
6279
+
"prettier": "^2.2 || ^3.0"
6280
+
},
6281
+
"peerDependenciesMeta": {
6282
+
"@volar/language-service": {
6283
+
"optional": true
6284
+
},
6285
+
"prettier": {
6286
+
"optional": true
6287
+
}
6288
+
}
6289
+
},
6290
+
"node_modules/volar-service-typescript": {
6291
+
"version": "0.0.62",
6292
+
"resolved": "https://registry.npmjs.org/volar-service-typescript/-/volar-service-typescript-0.0.62.tgz",
6293
+
"integrity": "sha512-p7MPi71q7KOsH0eAbZwPBiKPp9B2+qrdHAd6VY5oTo9BUXatsOAdakTm9Yf0DUj6uWBAaOT01BSeVOPwucMV1g==",
6294
+
"license": "MIT",
6295
+
"dependencies": {
6296
+
"path-browserify": "^1.0.1",
6297
+
"semver": "^7.6.2",
6298
+
"typescript-auto-import-cache": "^0.3.3",
6299
+
"vscode-languageserver-textdocument": "^1.0.11",
6300
+
"vscode-nls": "^5.2.0",
6301
+
"vscode-uri": "^3.0.8"
6302
+
},
6303
+
"peerDependencies": {
6304
+
"@volar/language-service": "~2.4.0"
6305
+
},
6306
+
"peerDependenciesMeta": {
6307
+
"@volar/language-service": {
6308
+
"optional": true
6309
+
}
6310
+
}
6311
+
},
6312
+
"node_modules/volar-service-typescript-twoslash-queries": {
6313
+
"version": "0.0.62",
6314
+
"resolved": "https://registry.npmjs.org/volar-service-typescript-twoslash-queries/-/volar-service-typescript-twoslash-queries-0.0.62.tgz",
6315
+
"integrity": "sha512-KxFt4zydyJYYI0kFAcWPTh4u0Ha36TASPZkAnNY784GtgajerUqM80nX/W1d0wVhmcOFfAxkVsf/Ed+tiYU7ng==",
6316
+
"license": "MIT",
6317
+
"dependencies": {
6318
+
"vscode-uri": "^3.0.8"
6319
+
},
6320
+
"peerDependencies": {
6321
+
"@volar/language-service": "~2.4.0"
6322
+
},
6323
+
"peerDependenciesMeta": {
6324
+
"@volar/language-service": {
6325
+
"optional": true
6326
+
}
6327
+
}
6328
+
},
6329
+
"node_modules/volar-service-yaml": {
6330
+
"version": "0.0.62",
6331
+
"resolved": "https://registry.npmjs.org/volar-service-yaml/-/volar-service-yaml-0.0.62.tgz",
6332
+
"integrity": "sha512-k7gvv7sk3wa+nGll3MaSKyjwQsJjIGCHFjVkl3wjaSP2nouKyn9aokGmqjrl39mi88Oy49giog2GkZH526wjig==",
6333
+
"license": "MIT",
6334
+
"dependencies": {
6335
+
"vscode-uri": "^3.0.8",
6336
+
"yaml-language-server": "~1.15.0"
6337
+
},
6338
+
"peerDependencies": {
6339
+
"@volar/language-service": "~2.4.0"
6340
+
},
6341
+
"peerDependenciesMeta": {
6342
+
"@volar/language-service": {
6343
+
"optional": true
6344
+
}
6345
+
}
6346
+
},
6347
+
"node_modules/vscode-css-languageservice": {
6348
+
"version": "6.3.7",
6349
+
"resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-6.3.7.tgz",
6350
+
"integrity": "sha512-5TmXHKllPzfkPhW4UE9sODV3E0bIOJPOk+EERKllf2SmAczjfTmYeq5txco+N3jpF8KIZ6loj/JptpHBQuVQRA==",
6351
+
"license": "MIT",
6352
+
"dependencies": {
6353
+
"@vscode/l10n": "^0.0.18",
6354
+
"vscode-languageserver-textdocument": "^1.0.12",
6355
+
"vscode-languageserver-types": "3.17.5",
6356
+
"vscode-uri": "^3.1.0"
6357
+
}
6358
+
},
6359
+
"node_modules/vscode-html-languageservice": {
6360
+
"version": "5.5.1",
6361
+
"resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-5.5.1.tgz",
6362
+
"integrity": "sha512-/ZdEtsZ3OiFSyL00kmmu7crFV9KwWR+MgpzjsxO60DQH7sIfHZM892C/E4iDd11EKocr+NYuvOA4Y7uc3QzLEA==",
6363
+
"license": "MIT",
6364
+
"dependencies": {
6365
+
"@vscode/l10n": "^0.0.18",
6366
+
"vscode-languageserver-textdocument": "^1.0.12",
6367
+
"vscode-languageserver-types": "^3.17.5",
6368
+
"vscode-uri": "^3.1.0"
6369
+
}
6370
+
},
6371
+
"node_modules/vscode-json-languageservice": {
6372
+
"version": "4.1.8",
6373
+
"resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-4.1.8.tgz",
6374
+
"integrity": "sha512-0vSpg6Xd9hfV+eZAaYN63xVVMOTmJ4GgHxXnkLCh+9RsQBkWKIghzLhW2B9ebfG+LQQg8uLtsQ2aUKjTgE+QOg==",
6375
+
"license": "MIT",
6376
+
"dependencies": {
6377
+
"jsonc-parser": "^3.0.0",
6378
+
"vscode-languageserver-textdocument": "^1.0.1",
6379
+
"vscode-languageserver-types": "^3.16.0",
6380
+
"vscode-nls": "^5.0.0",
6381
+
"vscode-uri": "^3.0.2"
6382
+
},
6383
+
"engines": {
6384
+
"npm": ">=7.0.0"
6385
+
}
6386
+
},
6387
+
"node_modules/vscode-json-languageservice/node_modules/jsonc-parser": {
6388
+
"version": "3.3.1",
6389
+
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz",
6390
+
"integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==",
6391
+
"license": "MIT"
6392
+
},
6393
+
"node_modules/vscode-jsonrpc": {
6394
+
"version": "8.2.0",
6395
+
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz",
6396
+
"integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==",
6397
+
"license": "MIT",
6398
+
"engines": {
6399
+
"node": ">=14.0.0"
6400
+
}
6401
+
},
6402
+
"node_modules/vscode-languageserver": {
6403
+
"version": "9.0.1",
6404
+
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz",
6405
+
"integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==",
6406
+
"license": "MIT",
6407
+
"dependencies": {
6408
+
"vscode-languageserver-protocol": "3.17.5"
6409
+
},
6410
+
"bin": {
6411
+
"installServerIntoExtension": "bin/installServerIntoExtension"
6412
+
}
6413
+
},
6414
+
"node_modules/vscode-languageserver-protocol": {
6415
+
"version": "3.17.5",
6416
+
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz",
6417
+
"integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==",
6418
+
"license": "MIT",
6419
+
"dependencies": {
6420
+
"vscode-jsonrpc": "8.2.0",
6421
+
"vscode-languageserver-types": "3.17.5"
6422
+
}
6423
+
},
6424
+
"node_modules/vscode-languageserver-textdocument": {
6425
+
"version": "1.0.12",
6426
+
"resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz",
6427
+
"integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==",
6428
+
"license": "MIT"
6429
+
},
6430
+
"node_modules/vscode-languageserver-types": {
6431
+
"version": "3.17.5",
6432
+
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz",
6433
+
"integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==",
6434
+
"license": "MIT"
6435
+
},
6436
+
"node_modules/vscode-nls": {
6437
+
"version": "5.2.0",
6438
+
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-5.2.0.tgz",
6439
+
"integrity": "sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==",
6440
+
"license": "MIT"
6441
+
},
6442
+
"node_modules/vscode-uri": {
6443
+
"version": "3.1.0",
6444
+
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz",
6445
+
"integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==",
6446
+
"license": "MIT"
6447
+
},
4717
6448
"node_modules/web-namespaces": {
4718
6449
"version": "2.0.1",
4719
6450
"resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz",
···
4787
6518
"integrity": "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==",
4788
6519
"license": "MIT"
4789
6520
},
6521
+
"node_modules/y18n": {
6522
+
"version": "5.0.8",
6523
+
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
6524
+
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
6525
+
"license": "ISC",
6526
+
"engines": {
6527
+
"node": ">=10"
6528
+
}
6529
+
},
6530
+
"node_modules/yallist": {
6531
+
"version": "5.0.0",
6532
+
"resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
6533
+
"integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
6534
+
"license": "BlueOak-1.0.0",
6535
+
"engines": {
6536
+
"node": ">=18"
6537
+
}
6538
+
},
6539
+
"node_modules/yaml": {
6540
+
"version": "2.8.1",
6541
+
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz",
6542
+
"integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==",
6543
+
"license": "ISC",
6544
+
"bin": {
6545
+
"yaml": "bin.mjs"
6546
+
},
6547
+
"engines": {
6548
+
"node": ">= 14.6"
6549
+
}
6550
+
},
6551
+
"node_modules/yaml-language-server": {
6552
+
"version": "1.15.0",
6553
+
"resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-1.15.0.tgz",
6554
+
"integrity": "sha512-N47AqBDCMQmh6mBLmI6oqxryHRzi33aPFPsJhYy3VTUGCdLHYjGh4FZzpUjRlphaADBBkDmnkM/++KNIOHi5Rw==",
6555
+
"license": "MIT",
6556
+
"dependencies": {
6557
+
"ajv": "^8.11.0",
6558
+
"lodash": "4.17.21",
6559
+
"request-light": "^0.5.7",
6560
+
"vscode-json-languageservice": "4.1.8",
6561
+
"vscode-languageserver": "^7.0.0",
6562
+
"vscode-languageserver-textdocument": "^1.0.1",
6563
+
"vscode-languageserver-types": "^3.16.0",
6564
+
"vscode-nls": "^5.0.0",
6565
+
"vscode-uri": "^3.0.2",
6566
+
"yaml": "2.2.2"
6567
+
},
6568
+
"bin": {
6569
+
"yaml-language-server": "bin/yaml-language-server"
6570
+
},
6571
+
"optionalDependencies": {
6572
+
"prettier": "2.8.7"
6573
+
}
6574
+
},
6575
+
"node_modules/yaml-language-server/node_modules/prettier": {
6576
+
"version": "2.8.7",
6577
+
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz",
6578
+
"integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==",
6579
+
"license": "MIT",
6580
+
"optional": true,
6581
+
"bin": {
6582
+
"prettier": "bin-prettier.js"
6583
+
},
6584
+
"engines": {
6585
+
"node": ">=10.13.0"
6586
+
},
6587
+
"funding": {
6588
+
"url": "https://github.com/prettier/prettier?sponsor=1"
6589
+
}
6590
+
},
6591
+
"node_modules/yaml-language-server/node_modules/request-light": {
6592
+
"version": "0.5.8",
6593
+
"resolved": "https://registry.npmjs.org/request-light/-/request-light-0.5.8.tgz",
6594
+
"integrity": "sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg==",
6595
+
"license": "MIT"
6596
+
},
6597
+
"node_modules/yaml-language-server/node_modules/vscode-jsonrpc": {
6598
+
"version": "6.0.0",
6599
+
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz",
6600
+
"integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==",
6601
+
"license": "MIT",
6602
+
"engines": {
6603
+
"node": ">=8.0.0 || >=10.0.0"
6604
+
}
6605
+
},
6606
+
"node_modules/yaml-language-server/node_modules/vscode-languageserver": {
6607
+
"version": "7.0.0",
6608
+
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-7.0.0.tgz",
6609
+
"integrity": "sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==",
6610
+
"license": "MIT",
6611
+
"dependencies": {
6612
+
"vscode-languageserver-protocol": "3.16.0"
6613
+
},
6614
+
"bin": {
6615
+
"installServerIntoExtension": "bin/installServerIntoExtension"
6616
+
}
6617
+
},
6618
+
"node_modules/yaml-language-server/node_modules/vscode-languageserver-protocol": {
6619
+
"version": "3.16.0",
6620
+
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz",
6621
+
"integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==",
6622
+
"license": "MIT",
6623
+
"dependencies": {
6624
+
"vscode-jsonrpc": "6.0.0",
6625
+
"vscode-languageserver-types": "3.16.0"
6626
+
}
6627
+
},
6628
+
"node_modules/yaml-language-server/node_modules/vscode-languageserver-types": {
6629
+
"version": "3.16.0",
6630
+
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz",
6631
+
"integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==",
6632
+
"license": "MIT"
6633
+
},
6634
+
"node_modules/yaml-language-server/node_modules/yaml": {
6635
+
"version": "2.2.2",
6636
+
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.2.tgz",
6637
+
"integrity": "sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA==",
6638
+
"license": "ISC",
6639
+
"engines": {
6640
+
"node": ">= 14"
6641
+
}
6642
+
},
6643
+
"node_modules/yargs": {
6644
+
"version": "17.7.2",
6645
+
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
6646
+
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
6647
+
"license": "MIT",
6648
+
"dependencies": {
6649
+
"cliui": "^8.0.1",
6650
+
"escalade": "^3.1.1",
6651
+
"get-caller-file": "^2.0.5",
6652
+
"require-directory": "^2.1.1",
6653
+
"string-width": "^4.2.3",
6654
+
"y18n": "^5.0.5",
6655
+
"yargs-parser": "^21.1.1"
6656
+
},
6657
+
"engines": {
6658
+
"node": ">=12"
6659
+
}
6660
+
},
4790
6661
"node_modules/yargs-parser": {
4791
6662
"version": "21.1.1",
4792
6663
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
···
4794
6665
"license": "ISC",
4795
6666
"engines": {
4796
6667
"node": ">=12"
6668
+
}
6669
+
},
6670
+
"node_modules/yargs/node_modules/ansi-regex": {
6671
+
"version": "5.0.1",
6672
+
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
6673
+
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
6674
+
"license": "MIT",
6675
+
"engines": {
6676
+
"node": ">=8"
6677
+
}
6678
+
},
6679
+
"node_modules/yargs/node_modules/emoji-regex": {
6680
+
"version": "8.0.0",
6681
+
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
6682
+
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
6683
+
"license": "MIT"
6684
+
},
6685
+
"node_modules/yargs/node_modules/string-width": {
6686
+
"version": "4.2.3",
6687
+
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
6688
+
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
6689
+
"license": "MIT",
6690
+
"dependencies": {
6691
+
"emoji-regex": "^8.0.0",
6692
+
"is-fullwidth-code-point": "^3.0.0",
6693
+
"strip-ansi": "^6.0.1"
6694
+
},
6695
+
"engines": {
6696
+
"node": ">=8"
6697
+
}
6698
+
},
6699
+
"node_modules/yargs/node_modules/strip-ansi": {
6700
+
"version": "6.0.1",
6701
+
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
6702
+
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
6703
+
"license": "MIT",
6704
+
"dependencies": {
6705
+
"ansi-regex": "^5.0.1"
6706
+
},
6707
+
"engines": {
6708
+
"node": ">=8"
4797
6709
}
4798
6710
},
4799
6711
"node_modules/yocto-queue": {
+11
-2
package.json
+11
-2
package.json
···
9
9
"astro": "astro"
10
10
},
11
11
"dependencies": {
12
-
"astro": "^5.12.8"
12
+
"@astrojs/check": "^0.9.4",
13
+
"@atproto/api": "^0.16.2",
14
+
"@atproto/xrpc": "^0.7.1",
15
+
"@tailwindcss/typography": "^0.5.16",
16
+
"@tailwindcss/vite": "^4.1.11",
17
+
"@types/node": "^24.2.0",
18
+
"astro": "^5.12.8",
19
+
"dotenv": "^17.2.1",
20
+
"tailwindcss": "^4.1.11",
21
+
"typescript": "^5.9.2"
13
22
}
14
-
}
23
+
}
+49
src/components/content/BlueskyFeed.astro
+49
src/components/content/BlueskyFeed.astro
···
1
+
---
2
+
import { AtprotoClient } from '../../lib/atproto/client';
3
+
import { loadConfig } from '../../lib/config/site';
4
+
import BlueskyPost from './BlueskyPost.astro';
5
+
6
+
interface Props {
7
+
feedUri: string;
8
+
limit?: number;
9
+
showAuthor?: boolean;
10
+
showTimestamp?: boolean;
11
+
}
12
+
13
+
const { feedUri, limit = 10, showAuthor = true, showTimestamp = true } = Astro.props;
14
+
15
+
const config = loadConfig();
16
+
const client = new AtprotoClient(config.atproto.pdsUrl);
17
+
18
+
// Fetch feed data with error handling
19
+
let blueskyPosts: any[] = [];
20
+
try {
21
+
const records = await client.getFeed(feedUri, limit);
22
+
const filteredRecords = client.filterSupportedRecords(records);
23
+
24
+
// Only render Bluesky posts
25
+
blueskyPosts = filteredRecords.filter(record =>
26
+
record.value && record.value.$type === 'app.bsky.feed.post'
27
+
);
28
+
} catch (error) {
29
+
console.error('Error fetching feed:', error);
30
+
blueskyPosts = [];
31
+
}
32
+
---
33
+
34
+
<div class="space-y-4">
35
+
{blueskyPosts.length > 0 ? (
36
+
blueskyPosts.map((record) => (
37
+
<BlueskyPost
38
+
post={record.value}
39
+
showAuthor={showAuthor}
40
+
showTimestamp={showTimestamp}
41
+
/>
42
+
))
43
+
) : (
44
+
<div class="text-center py-8 text-gray-500 dark:text-gray-400">
45
+
<p>No posts found in this feed.</p>
46
+
<p class="text-sm mt-2">This could be due to authentication requirements or the feed being empty.</p>
47
+
</div>
48
+
)}
49
+
</div>
+115
src/components/content/BlueskyPost.astro
+115
src/components/content/BlueskyPost.astro
···
1
+
---
2
+
import type { BlueskyPost } from '../../lib/types/atproto';
3
+
4
+
interface Props {
5
+
post: BlueskyPost;
6
+
showAuthor?: boolean;
7
+
showTimestamp?: boolean;
8
+
}
9
+
10
+
const { post, showAuthor = false, showTimestamp = true } = Astro.props;
11
+
12
+
// Validate post data
13
+
if (!post || !post.text) {
14
+
return null;
15
+
}
16
+
17
+
const formatDate = (dateString: string) => {
18
+
return new Date(dateString).toLocaleDateString('en-US', {
19
+
year: 'numeric',
20
+
month: 'short',
21
+
day: 'numeric',
22
+
});
23
+
};
24
+
25
+
// Helper function to get image URL from blob reference
26
+
const getImageUrl = (imageRef: string) => {
27
+
return `https://bsky.social/xrpc/com.atproto.sync.getBlob?did=did:plc:6ayddqghxhciedbaofoxkcbs&cid=${imageRef}`;
28
+
};
29
+
30
+
// Helper function to render images
31
+
const renderImages = (images: any[]) => {
32
+
if (!images || images.length === 0) return null;
33
+
34
+
return (
35
+
<div class={`grid gap-2 ${images.length === 1 ? 'grid-cols-1' : images.length === 2 ? 'grid-cols-2' : 'grid-cols-3'}`}>
36
+
{images.map((image: any) => {
37
+
const imageUrl = getImageUrl(image.image.ref.$link);
38
+
return (
39
+
<div class="relative">
40
+
<img
41
+
src={imageUrl}
42
+
alt={image.alt || 'Post image'}
43
+
class="rounded-lg w-full h-auto object-cover"
44
+
style={`aspect-ratio: ${image.aspectRatio?.width || 1} / ${image.aspectRatio?.height || 1}`}
45
+
/>
46
+
</div>
47
+
);
48
+
})}
49
+
</div>
50
+
);
51
+
};
52
+
---
53
+
54
+
<article class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4 mb-4">
55
+
{showAuthor && post.author && (
56
+
<div class="flex items-center mb-3">
57
+
<div class="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center text-white text-sm font-medium">
58
+
{post.author.displayName?.[0] || 'U'}
59
+
</div>
60
+
<div class="ml-3">
61
+
<div class="text-sm font-medium text-gray-900 dark:text-white">
62
+
{post.author.displayName || 'Unknown'}
63
+
</div>
64
+
<div class="text-xs text-gray-500 dark:text-gray-400">
65
+
@{post.author.handle || 'unknown'}
66
+
</div>
67
+
</div>
68
+
</div>
69
+
)}
70
+
71
+
<div class="text-gray-900 dark:text-white mb-3">
72
+
{post.text}
73
+
</div>
74
+
75
+
{post.embed && (
76
+
<div class="mb-3">
77
+
{/* Handle image embeds */}
78
+
{post.embed.$type === 'app.bsky.embed.images' && post.embed.images && (
79
+
renderImages(post.embed.images)
80
+
)}
81
+
82
+
{/* Handle external link embeds */}
83
+
{post.embed.$type === 'app.bsky.embed.external' && post.embed.external && (
84
+
<div class="border border-gray-200 dark:border-gray-700 rounded-lg p-3">
85
+
<div class="text-sm text-gray-600 dark:text-gray-400 mb-1">
86
+
{post.embed.external.uri}
87
+
</div>
88
+
<div class="text-sm font-medium text-gray-900 dark:text-white">
89
+
{post.embed.external.title}
90
+
</div>
91
+
{post.embed.external.description && (
92
+
<div class="text-sm text-gray-600 dark:text-gray-400 mt-1">
93
+
{post.embed.external.description}
94
+
</div>
95
+
)}
96
+
</div>
97
+
)}
98
+
99
+
{/* Handle record embeds (quotes/reposts) */}
100
+
{post.embed.$type === 'app.bsky.embed.record' && post.embed.record && (
101
+
<div class="border border-gray-200 dark:border-gray-700 rounded-lg p-3 bg-gray-50 dark:bg-gray-700">
102
+
<div class="text-sm text-gray-600 dark:text-gray-400">
103
+
Quoted post
104
+
</div>
105
+
</div>
106
+
)}
107
+
</div>
108
+
)}
109
+
110
+
{showTimestamp && post.createdAt && (
111
+
<div class="text-xs text-gray-500 dark:text-gray-400">
112
+
{formatDate(post.createdAt)}
113
+
</div>
114
+
)}
115
+
</article>
+144
src/components/content/ContentFeed.astro
+144
src/components/content/ContentFeed.astro
···
1
+
---
2
+
import { AtprotoClient } from '../../lib/atproto/client';
3
+
import { loadConfig } from '../../lib/config/site';
4
+
import type { AtprotoRecord } from '../../lib/types/atproto';
5
+
6
+
interface Props {
7
+
handle: string;
8
+
collection?: string;
9
+
limit?: number;
10
+
feedUri?: string;
11
+
showAuthor?: boolean;
12
+
showTimestamp?: boolean;
13
+
}
14
+
15
+
const {
16
+
handle,
17
+
collection = 'app.bsky.feed.post',
18
+
limit = 10,
19
+
feedUri,
20
+
showAuthor = true,
21
+
showTimestamp = true
22
+
} = Astro.props;
23
+
24
+
const config = loadConfig();
25
+
const client = new AtprotoClient(config.atproto.pdsUrl);
26
+
27
+
// Helper function to get image URL from blob reference
28
+
const getImageUrl = (imageRef: string) => {
29
+
return `https://bsky.social/xrpc/com.atproto.sync.getBlob?did=did:plc:6ayddqghxhciedbaofoxkcbs&cid=${imageRef}`;
30
+
};
31
+
32
+
// Helper function to format date
33
+
const formatDate = (dateString: string) => {
34
+
return new Date(dateString).toLocaleDateString('en-US', {
35
+
year: 'numeric',
36
+
month: 'short',
37
+
day: 'numeric',
38
+
});
39
+
};
40
+
41
+
// Fetch data based on whether it's a feed or collection with error handling
42
+
let records: AtprotoRecord[] = [];
43
+
try {
44
+
if (feedUri) {
45
+
records = await client.getFeed(feedUri, limit);
46
+
} else {
47
+
records = await client.getRecords(handle, collection, limit);
48
+
}
49
+
50
+
} catch (error) {
51
+
console.error('ContentFeed: Error fetching content:', error);
52
+
records = [];
53
+
}
54
+
---
55
+
56
+
<div class="space-y-6">
57
+
{records.length > 0 ? (
58
+
<div class="space-y-4">
59
+
{records.map((record) => {
60
+
if (record.value?.$type !== 'app.bsky.feed.post') return null;
61
+
62
+
const post = record.value;
63
+
return (
64
+
<article class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4 mb-4">
65
+
<div class="text-gray-900 dark:text-white mb-3">
66
+
{post.text}
67
+
</div>
68
+
69
+
{post.embed && (
70
+
<div class="mb-3">
71
+
{/* Handle image embeds */}
72
+
{post.embed.$type === 'app.bsky.embed.images' && post.embed.images && (
73
+
<div class={`grid gap-2 ${post.embed.images.length === 1 ? 'grid-cols-1' : post.embed.images.length === 2 ? 'grid-cols-2' : 'grid-cols-3'}`}>
74
+
{post.embed.images.map((image: any) => {
75
+
// Handle both string and BlobRef object formats
76
+
let imageRef;
77
+
if (typeof image.image?.ref === 'string') {
78
+
imageRef = image.image.ref;
79
+
} else if (image.image?.ref?.$link) {
80
+
imageRef = image.image.ref.$link;
81
+
} else if (image.image?.ref?.toString) {
82
+
// Handle BlobRef object
83
+
imageRef = image.image.ref.toString();
84
+
}
85
+
86
+
const imageUrl = imageRef ? getImageUrl(imageRef) : '';
87
+
return (
88
+
<div class="relative">
89
+
<img
90
+
src={imageUrl}
91
+
alt={image.alt || 'Post image'}
92
+
class="rounded-lg w-full h-auto object-cover"
93
+
style={`aspect-ratio: ${image.aspectRatio?.width || 1} / ${image.aspectRatio?.height || 1}`}
94
+
/>
95
+
</div>
96
+
);
97
+
})}
98
+
</div>
99
+
)}
100
+
101
+
{/* Handle external link embeds */}
102
+
{post.embed.$type === 'app.bsky.embed.external' && post.embed.external && (
103
+
<div class="border border-gray-200 dark:border-gray-700 rounded-lg p-3">
104
+
<div class="text-sm text-gray-600 dark:text-gray-400 mb-1">
105
+
{post.embed.external.uri}
106
+
</div>
107
+
<div class="text-sm font-medium text-gray-900 dark:text-white">
108
+
{post.embed.external.title}
109
+
</div>
110
+
{post.embed.external.description && (
111
+
<div class="text-sm text-gray-600 dark:text-gray-400 mt-1">
112
+
{post.embed.external.description}
113
+
</div>
114
+
)}
115
+
</div>
116
+
)}
117
+
118
+
{/* Handle record embeds (quotes/reposts) */}
119
+
{post.embed.$type === 'app.bsky.embed.record' && post.embed.record && (
120
+
<div class="border border-gray-200 dark:border-gray-700 rounded-lg p-3 bg-gray-50 dark:bg-gray-700">
121
+
<div class="text-sm text-gray-600 dark:text-gray-400">
122
+
Quoted post
123
+
</div>
124
+
</div>
125
+
)}
126
+
</div>
127
+
)}
128
+
129
+
{showTimestamp && post.createdAt && (
130
+
<div class="text-xs text-gray-500 dark:text-gray-400">
131
+
{formatDate(post.createdAt)}
132
+
</div>
133
+
)}
134
+
</article>
135
+
);
136
+
})}
137
+
</div>
138
+
) : (
139
+
<div class="text-center py-8 text-gray-500 dark:text-gray-400">
140
+
<p>No posts found.</p>
141
+
<p class="text-sm mt-2">Debug: Handle = {handle}, Records fetched = {records.length}</p>
142
+
</div>
143
+
)}
144
+
</div>
+68
src/components/content/GrainImageGallery.astro
+68
src/components/content/GrainImageGallery.astro
···
1
+
---
2
+
import type { GrainImageGallery } from '../../lib/types/atproto';
3
+
4
+
interface Props {
5
+
gallery: GrainImageGallery;
6
+
showDescription?: boolean;
7
+
showTimestamp?: boolean;
8
+
columns?: number;
9
+
}
10
+
11
+
const { gallery, showDescription = true, showTimestamp = true, columns = 3 } = Astro.props;
12
+
13
+
const formatDate = (dateString: string) => {
14
+
return new Date(dateString).toLocaleDateString('en-US', {
15
+
year: 'numeric',
16
+
month: 'long',
17
+
day: 'numeric',
18
+
});
19
+
};
20
+
21
+
const gridCols = {
22
+
1: 'grid-cols-1',
23
+
2: 'grid-cols-2',
24
+
3: 'grid-cols-3',
25
+
4: 'grid-cols-4',
26
+
5: 'grid-cols-5',
27
+
6: 'grid-cols-6',
28
+
}[columns] || 'grid-cols-3';
29
+
---
30
+
31
+
<article class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6 mb-6">
32
+
<header class="mb-4">
33
+
<h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-2">
34
+
{gallery.title}
35
+
</h2>
36
+
37
+
{showDescription && gallery.description && (
38
+
<div class="text-gray-600 dark:text-gray-400 mb-3">
39
+
{gallery.description}
40
+
</div>
41
+
)}
42
+
43
+
{showTimestamp && (
44
+
<div class="text-sm text-gray-500 dark:text-gray-400 mb-4">
45
+
Created on {formatDate(gallery.createdAt)}
46
+
</div>
47
+
)}
48
+
</header>
49
+
50
+
{gallery.images && gallery.images.length > 0 && (
51
+
<div class={`grid ${gridCols} gap-4`}>
52
+
{gallery.images.map((image) => (
53
+
<div class="relative group">
54
+
<img
55
+
src={image.url}
56
+
alt={image.alt || 'Gallery image'}
57
+
class="w-full h-48 object-cover rounded-lg transition-transform duration-200 group-hover:scale-105"
58
+
/>
59
+
{image.alt && (
60
+
<div class="absolute bottom-0 left-0 right-0 bg-black bg-opacity-50 text-white text-sm p-2 rounded-b-lg opacity-0 group-hover:opacity-100 transition-opacity duration-200">
61
+
{image.alt}
62
+
</div>
63
+
)}
64
+
</div>
65
+
))}
66
+
</div>
67
+
)}
68
+
</article>
+47
src/components/content/LeafletPublication.astro
+47
src/components/content/LeafletPublication.astro
···
1
+
---
2
+
import type { LeafletPublication } from '../../lib/types/atproto';
3
+
4
+
interface Props {
5
+
publication: LeafletPublication;
6
+
showCategory?: boolean;
7
+
showTimestamp?: boolean;
8
+
}
9
+
10
+
const { publication, showCategory = true, showTimestamp = true } = Astro.props;
11
+
12
+
const formatDate = (dateString: string) => {
13
+
return new Date(dateString).toLocaleDateString('en-US', {
14
+
year: 'numeric',
15
+
month: 'long',
16
+
day: 'numeric',
17
+
});
18
+
};
19
+
---
20
+
21
+
<article class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6 mb-6">
22
+
<header class="mb-4">
23
+
<div class="flex items-center justify-between mb-2">
24
+
<h2 class="text-2xl font-bold text-gray-900 dark:text-white">
25
+
{publication.title}
26
+
</h2>
27
+
28
+
{showCategory && publication.category && (
29
+
<span class="px-3 py-1 bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200 text-sm rounded-full">
30
+
{publication.category}
31
+
</span>
32
+
)}
33
+
</div>
34
+
35
+
{showTimestamp && (
36
+
<div class="text-sm text-gray-500 dark:text-gray-400 mb-3">
37
+
Published on {formatDate(publication.publishedAt)}
38
+
</div>
39
+
)}
40
+
</header>
41
+
42
+
<div class="prose prose-gray dark:prose-invert max-w-none">
43
+
<div class="text-gray-700 dark:text-gray-300 leading-relaxed">
44
+
{publication.content}
45
+
</div>
46
+
</div>
47
+
</article>
+49
src/components/content/WhitewindBlogPost.astro
+49
src/components/content/WhitewindBlogPost.astro
···
1
+
---
2
+
import type { WhitewindBlogPost } from '../../lib/types/atproto';
3
+
4
+
interface Props {
5
+
post: WhitewindBlogPost;
6
+
showTags?: boolean;
7
+
showTimestamp?: boolean;
8
+
}
9
+
10
+
const { post, showTags = true, showTimestamp = true } = Astro.props;
11
+
12
+
const formatDate = (dateString: string) => {
13
+
return new Date(dateString).toLocaleDateString('en-US', {
14
+
year: 'numeric',
15
+
month: 'long',
16
+
day: 'numeric',
17
+
});
18
+
};
19
+
---
20
+
21
+
<article class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6 mb-6">
22
+
<header class="mb-4">
23
+
<h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-2">
24
+
{post.title}
25
+
</h2>
26
+
27
+
{showTimestamp && (
28
+
<div class="text-sm text-gray-500 dark:text-gray-400 mb-3">
29
+
Published on {formatDate(post.publishedAt)}
30
+
</div>
31
+
)}
32
+
33
+
{showTags && post.tags && post.tags.length > 0 && (
34
+
<div class="flex flex-wrap gap-2 mb-4">
35
+
{post.tags.map((tag) => (
36
+
<span class="px-2 py-1 bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 text-xs rounded-full">
37
+
#{tag}
38
+
</span>
39
+
))}
40
+
</div>
41
+
)}
42
+
</header>
43
+
44
+
<div class="prose prose-gray dark:prose-invert max-w-none">
45
+
<div class="text-gray-700 dark:text-gray-300 leading-relaxed">
46
+
{post.content}
47
+
</div>
48
+
</div>
49
+
</article>
+26
src/layouts/Layout.astro
+26
src/layouts/Layout.astro
···
1
+
---
2
+
import '../styles/global.css';
3
+
4
+
interface Props {
5
+
title: string;
6
+
description?: string;
7
+
}
8
+
9
+
const { title, description } = Astro.props;
10
+
---
11
+
12
+
<!DOCTYPE html>
13
+
<html lang="en">
14
+
<head>
15
+
<meta charset="UTF-8" />
16
+
<meta name="description" content={description || "A personal website powered by ATproto"} />
17
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
18
+
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
19
+
<title>{title || 'Home'} | Tynanverse</title>
20
+
</head>
21
+
<body class="bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-white font-sans">
22
+
<div class="min-h-screen">
23
+
<slot />
24
+
</div>
25
+
</body>
26
+
</html>
+172
src/lib/atproto/client.ts
+172
src/lib/atproto/client.ts
···
1
+
import { AtpAgent } from '@atproto/api';
2
+
import type { AtprotoRecord } from '../types/atproto';
3
+
4
+
// Simple in-memory cache with TTL
5
+
class AtprotoCache {
6
+
private cache = new Map<string, { data: any; timestamp: number }>();
7
+
private ttl = 5 * 60 * 1000; // 5 minutes
8
+
9
+
set(key: string, data: any): void {
10
+
this.cache.set(key, { data, timestamp: Date.now() });
11
+
}
12
+
13
+
get(key: string): any | null {
14
+
const item = this.cache.get(key);
15
+
if (!item) return null;
16
+
17
+
if (Date.now() - item.timestamp > this.ttl) {
18
+
this.cache.delete(key);
19
+
return null;
20
+
}
21
+
22
+
return item.data;
23
+
}
24
+
25
+
clear(): void {
26
+
this.cache.clear();
27
+
}
28
+
}
29
+
30
+
export class AtprotoClient {
31
+
private agent: AtpAgent;
32
+
private cache: AtprotoCache;
33
+
34
+
constructor(pdsUrl: string = 'https://bsky.social') {
35
+
this.agent = new AtpAgent({ service: pdsUrl });
36
+
this.cache = new AtprotoCache();
37
+
}
38
+
39
+
async resolveHandle(handle: string): Promise<string | null> {
40
+
const cacheKey = `handle:${handle}`;
41
+
const cached = this.cache.get(cacheKey);
42
+
if (cached) return cached;
43
+
44
+
try {
45
+
const response = await this.agent.api.com.atproto.identity.resolveHandle({
46
+
handle: handle,
47
+
});
48
+
49
+
const did = response.data.did;
50
+
this.cache.set(cacheKey, did);
51
+
return did;
52
+
} catch (error) {
53
+
console.error('Error resolving handle:', error);
54
+
return null;
55
+
}
56
+
}
57
+
58
+
async getRecords(identifier: string, collection: string, limit: number = 50): Promise<AtprotoRecord[]> {
59
+
// Check if identifier is a handle (contains @) or DID
60
+
let did = identifier;
61
+
if (identifier.includes('@')) {
62
+
console.log('AtprotoClient: Resolving handle to DID:', identifier);
63
+
const resolvedDid = await this.resolveHandle(identifier);
64
+
if (!resolvedDid) {
65
+
console.error('AtprotoClient: Failed to resolve handle:', identifier);
66
+
return [];
67
+
}
68
+
did = resolvedDid;
69
+
console.log('AtprotoClient: Resolved handle to DID:', did);
70
+
}
71
+
72
+
const cacheKey = `records:${did}:${collection}:${limit}`;
73
+
const cached = this.cache.get(cacheKey);
74
+
if (cached) return cached;
75
+
76
+
console.log('AtprotoClient: Fetching records for DID:', did);
77
+
console.log('AtprotoClient: Collection:', collection);
78
+
console.log('AtprotoClient: Limit:', limit);
79
+
80
+
try {
81
+
const response = await this.agent.api.com.atproto.repo.listRecords({
82
+
repo: did,
83
+
collection,
84
+
limit,
85
+
});
86
+
87
+
console.log('AtprotoClient: API response received');
88
+
console.log('AtprotoClient: Records count:', response.data.records.length);
89
+
90
+
const records = response.data.records.map((record: any) => ({
91
+
uri: record.uri,
92
+
cid: record.cid,
93
+
value: record.value,
94
+
indexedAt: record.indexedAt,
95
+
}));
96
+
97
+
this.cache.set(cacheKey, records);
98
+
return records;
99
+
} catch (error) {
100
+
console.error('AtprotoClient: Error fetching records:', error);
101
+
console.error('AtprotoClient: Error details:', {
102
+
did,
103
+
collection,
104
+
limit,
105
+
error: error instanceof Error ? error.message : String(error)
106
+
});
107
+
return [];
108
+
}
109
+
}
110
+
111
+
async getFeed(feedUri: string, limit: number = 20): Promise<AtprotoRecord[]> {
112
+
const cacheKey = `feed:${feedUri}:${limit}`;
113
+
const cached = this.cache.get(cacheKey);
114
+
if (cached) return cached;
115
+
116
+
try {
117
+
const response = await this.agent.api.app.bsky.feed.getFeed({
118
+
feed: feedUri,
119
+
limit,
120
+
});
121
+
122
+
const records = response.data.feed.map((item: any) => ({
123
+
uri: item.post.uri,
124
+
cid: item.post.cid,
125
+
value: item.post.record,
126
+
indexedAt: item.post.indexedAt,
127
+
}));
128
+
129
+
this.cache.set(cacheKey, records);
130
+
return records;
131
+
} catch (error) {
132
+
console.error('Error fetching feed:', error);
133
+
return [];
134
+
}
135
+
}
136
+
137
+
async getProfile(did: string): Promise<any> {
138
+
const cacheKey = `profile:${did}`;
139
+
const cached = this.cache.get(cacheKey);
140
+
if (cached) return cached;
141
+
142
+
try {
143
+
const response = await this.agent.api.app.bsky.actor.getProfile({
144
+
actor: did,
145
+
});
146
+
147
+
this.cache.set(cacheKey, response.data);
148
+
return response.data;
149
+
} catch (error) {
150
+
console.error('Error fetching profile:', error);
151
+
return null;
152
+
}
153
+
}
154
+
155
+
// Filter records by supported content types
156
+
filterSupportedRecords(records: AtprotoRecord[]): AtprotoRecord[] {
157
+
return records.filter(record => {
158
+
const type = record.value?.$type;
159
+
return type && (
160
+
type === 'app.bsky.feed.post' ||
161
+
type === 'app.bsky.actor.profile#whitewindBlogPost' ||
162
+
type === 'app.bsky.actor.profile#leafletPublication' ||
163
+
type === 'app.bsky.actor.profile#grainImageGallery'
164
+
);
165
+
});
166
+
}
167
+
168
+
// Clear cache (useful for development)
169
+
clearCache(): void {
170
+
this.cache.clear();
171
+
}
172
+
}
+23
src/lib/components/register.ts
+23
src/lib/components/register.ts
···
1
+
import { registerComponent } from './registry';
2
+
import BlueskyPost from '../../components/content/BlueskyPost.astro';
3
+
import WhitewindBlogPost from '../../components/content/WhitewindBlogPost.astro';
4
+
import LeafletPublication from '../../components/content/LeafletPublication.astro';
5
+
import GrainImageGallery from '../../components/content/GrainImageGallery.astro';
6
+
7
+
// Register all content components
8
+
export function registerAllComponents() {
9
+
// Register Bluesky post component
10
+
registerComponent('app.bsky.feed.post', BlueskyPost);
11
+
12
+
// Register Whitewind blog post component
13
+
registerComponent('app.bsky.actor.profile#whitewindBlogPost', WhitewindBlogPost);
14
+
15
+
// Register Leaflet publication component
16
+
registerComponent('app.bsky.actor.profile#leafletPublication', LeafletPublication);
17
+
18
+
// Register Grain image gallery component
19
+
registerComponent('app.bsky.actor.profile#grainImageGallery', GrainImageGallery);
20
+
}
21
+
22
+
// Auto-register components when this module is imported
23
+
registerAllComponents();
+57
src/lib/components/registry.ts
+57
src/lib/components/registry.ts
···
1
+
import type { ContentComponent } from '../types/atproto';
2
+
3
+
// Component registry for type-safe content rendering
4
+
class ComponentRegistry {
5
+
private components = new Map<string, ContentComponent>();
6
+
7
+
// Register a component for a specific content type
8
+
register(type: string, component: any, props?: Record<string, any>): void {
9
+
this.components.set(type, {
10
+
type,
11
+
component,
12
+
props,
13
+
});
14
+
}
15
+
16
+
// Get a component for a specific content type
17
+
get(type: string): ContentComponent | undefined {
18
+
return this.components.get(type);
19
+
}
20
+
21
+
// Check if a component exists for a content type
22
+
has(type: string): boolean {
23
+
return this.components.has(type);
24
+
}
25
+
26
+
// Get all registered component types
27
+
getRegisteredTypes(): string[] {
28
+
return Array.from(this.components.keys());
29
+
}
30
+
31
+
// Clear all registered components
32
+
clear(): void {
33
+
this.components.clear();
34
+
}
35
+
}
36
+
37
+
// Global component registry instance
38
+
export const componentRegistry = new ComponentRegistry();
39
+
40
+
// Type-safe component registration helper
41
+
export function registerComponent(
42
+
type: string,
43
+
component: any,
44
+
props?: Record<string, any>
45
+
): void {
46
+
componentRegistry.register(type, component, props);
47
+
}
48
+
49
+
// Type-safe component retrieval helper
50
+
export function getComponent(type: string): ContentComponent | undefined {
51
+
return componentRegistry.get(type);
52
+
}
53
+
54
+
// Check if content type has a registered component
55
+
export function hasComponent(type: string): boolean {
56
+
return componentRegistry.has(type);
57
+
}
+87
src/lib/config/site.ts
+87
src/lib/config/site.ts
···
1
+
import dotenv from 'dotenv';
2
+
3
+
// Load environment variables from .env file
4
+
dotenv.config();
5
+
6
+
export interface SiteConfig {
7
+
// ATproto configuration
8
+
atproto: {
9
+
handle: string;
10
+
did?: string; // Keep for backward compatibility
11
+
pdsUrl?: string;
12
+
};
13
+
14
+
// Site metadata
15
+
site: {
16
+
title: string;
17
+
description: string;
18
+
author: string;
19
+
url: string;
20
+
};
21
+
22
+
// Theme configuration
23
+
theme: {
24
+
primaryColor: string;
25
+
secondaryColor: string;
26
+
accentColor: string;
27
+
fontFamily: string;
28
+
};
29
+
30
+
// Content configuration
31
+
content: {
32
+
defaultFeedLimit: number;
33
+
cacheTTL: number; // in milliseconds
34
+
};
35
+
}
36
+
37
+
// Default configuration
38
+
export const defaultConfig: SiteConfig = {
39
+
atproto: {
40
+
handle: '',
41
+
did: '',
42
+
pdsUrl: 'https://bsky.social',
43
+
},
44
+
site: {
45
+
title: 'Tynanverse',
46
+
description: 'A personal website powered by ATproto, made by Tynan',
47
+
author: 'Tynan',
48
+
url: 'https://your-domain.com',
49
+
},
50
+
theme: {
51
+
primaryColor: '#3b82f6',
52
+
secondaryColor: '#64748b',
53
+
accentColor: '#f59e0b',
54
+
fontFamily: 'Inter, system-ui, sans-serif',
55
+
},
56
+
content: {
57
+
defaultFeedLimit: 20,
58
+
cacheTTL: 5 * 60 * 1000, // 5 minutes
59
+
},
60
+
};
61
+
62
+
// Load configuration from environment variables
63
+
export function loadConfig(): SiteConfig {
64
+
return {
65
+
atproto: {
66
+
handle: process.env.ATPROTO_HANDLE || defaultConfig.atproto.handle,
67
+
did: process.env.ATPROTO_DID || defaultConfig.atproto.did,
68
+
pdsUrl: process.env.ATPROTO_PDS_URL || defaultConfig.atproto.pdsUrl,
69
+
},
70
+
site: {
71
+
title: process.env.SITE_TITLE || defaultConfig.site.title,
72
+
description: process.env.SITE_DESCRIPTION || defaultConfig.site.description,
73
+
author: process.env.SITE_AUTHOR || defaultConfig.site.author,
74
+
url: process.env.SITE_URL || defaultConfig.site.url,
75
+
},
76
+
theme: {
77
+
primaryColor: process.env.THEME_PRIMARY_COLOR || defaultConfig.theme.primaryColor,
78
+
secondaryColor: process.env.THEME_SECONDARY_COLOR || defaultConfig.theme.secondaryColor,
79
+
accentColor: process.env.THEME_ACCENT_COLOR || defaultConfig.theme.accentColor,
80
+
fontFamily: process.env.THEME_FONT_FAMILY || defaultConfig.theme.fontFamily,
81
+
},
82
+
content: {
83
+
defaultFeedLimit: parseInt(process.env.CONTENT_DEFAULT_FEED_LIMIT || '20'),
84
+
cacheTTL: parseInt(process.env.CONTENT_CACHE_TTL || '300000'),
85
+
},
86
+
};
87
+
}
+124
src/lib/types/atproto.ts
+124
src/lib/types/atproto.ts
···
1
+
// Base ATproto record types
2
+
export interface AtprotoRecord {
3
+
uri: string;
4
+
cid: string;
5
+
value: any;
6
+
indexedAt: string;
7
+
}
8
+
9
+
// Bluesky post types with proper embed handling
10
+
export interface BlueskyPost {
11
+
text: string;
12
+
createdAt: string;
13
+
embed?: {
14
+
$type: 'app.bsky.embed.images' | 'app.bsky.embed.external' | 'app.bsky.embed.record';
15
+
images?: Array<{
16
+
alt?: string;
17
+
image: {
18
+
$type: 'blob';
19
+
ref: {
20
+
$link: string;
21
+
};
22
+
mimeType: string;
23
+
size: number;
24
+
};
25
+
aspectRatio?: {
26
+
width: number;
27
+
height: number;
28
+
};
29
+
}>;
30
+
external?: {
31
+
uri: string;
32
+
title: string;
33
+
description?: string;
34
+
};
35
+
record?: {
36
+
uri: string;
37
+
cid: string;
38
+
};
39
+
};
40
+
author?: {
41
+
displayName?: string;
42
+
handle?: string;
43
+
};
44
+
reply?: {
45
+
root: {
46
+
uri: string;
47
+
cid: string;
48
+
};
49
+
parent: {
50
+
uri: string;
51
+
cid: string;
52
+
};
53
+
};
54
+
facets?: Array<{
55
+
index: {
56
+
byteStart: number;
57
+
byteEnd: number;
58
+
};
59
+
features: Array<{
60
+
$type: string;
61
+
[key: string]: any;
62
+
}>;
63
+
}>;
64
+
langs?: string[];
65
+
uri?: string;
66
+
cid?: string;
67
+
}
68
+
69
+
// Custom lexicon types (to be extended)
70
+
export interface CustomLexiconRecord {
71
+
$type: string;
72
+
[key: string]: any;
73
+
}
74
+
75
+
// Whitewind blog post type
76
+
export interface WhitewindBlogPost extends CustomLexiconRecord {
77
+
$type: 'app.bsky.actor.profile#whitewindBlogPost';
78
+
title: string;
79
+
content: string;
80
+
publishedAt: string;
81
+
tags?: string[];
82
+
}
83
+
84
+
// Leaflet publication type
85
+
export interface LeafletPublication extends CustomLexiconRecord {
86
+
$type: 'app.bsky.actor.profile#leafletPublication';
87
+
title: string;
88
+
content: string;
89
+
publishedAt: string;
90
+
category?: string;
91
+
}
92
+
93
+
// Grain social image gallery type
94
+
export interface GrainImageGallery extends CustomLexiconRecord {
95
+
$type: 'app.bsky.actor.profile#grainImageGallery';
96
+
title: string;
97
+
description?: string;
98
+
images: Array<{
99
+
alt: string;
100
+
url: string;
101
+
}>;
102
+
createdAt: string;
103
+
}
104
+
105
+
// Union type for all supported content types
106
+
export type SupportedContentType =
107
+
| BlueskyPost
108
+
| WhitewindBlogPost
109
+
| LeafletPublication
110
+
| GrainImageGallery;
111
+
112
+
// Component registry type
113
+
export interface ContentComponent {
114
+
type: string;
115
+
component: any;
116
+
props?: Record<string, any>;
117
+
}
118
+
119
+
// Feed configuration type
120
+
export interface FeedConfig {
121
+
uri: string;
122
+
limit?: number;
123
+
filter?: (record: AtprotoRecord) => boolean;
124
+
}
+51
-12
src/pages/index.astro
+51
-12
src/pages/index.astro
···
1
1
---
2
+
import Layout from '../layouts/Layout.astro';
3
+
import ContentFeed from '../components/content/ContentFeed.astro';
4
+
import { loadConfig } from '../lib/config/site';
2
5
6
+
const config = loadConfig();
3
7
---
4
8
5
-
<html lang="en">
6
-
<head>
7
-
<meta charset="utf-8" />
8
-
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
9
-
<meta name="viewport" content="width=device-width" />
10
-
<meta name="generator" content={Astro.generator} />
11
-
<title>Astro</title>
12
-
</head>
13
-
<body>
14
-
<h1>Astro</h1>
15
-
</body>
16
-
</html>
9
+
<Layout title="Home Page">
10
+
<div class="container mx-auto px-4 py-8">
11
+
<header class="text-center mb-12">
12
+
<h1 class="text-4xl font-bold text-gray-900 dark:text-white mb-4">
13
+
Welcome to {config.site.title || 'Tynanverse'}
14
+
</h1>
15
+
<p class="text-xl text-gray-600 dark:text-gray-400 max-w-2xl mx-auto">
16
+
{config.site.description || 'A personal website powered by ATproto, made by Tynan'}
17
+
</p>
18
+
</header>
19
+
20
+
<main class="max-w-4xl mx-auto space-y-12">
21
+
<!-- My Posts Feed -->
22
+
{config.atproto.handle && config.atproto.handle !== 'your-handle-here' ? (
23
+
<section>
24
+
<h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-6">
25
+
My Posts
26
+
</h2>
27
+
<ContentFeed
28
+
handle={config.atproto.handle}
29
+
limit={10}
30
+
showAuthor={false}
31
+
showTimestamp={true}
32
+
/>
33
+
</section>
34
+
) : (
35
+
<section>
36
+
<h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-6">
37
+
Configuration Required
38
+
</h2>
39
+
<div class="bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg p-6">
40
+
<p class="text-yellow-800 dark:text-yellow-200 mb-4">
41
+
To display your posts, please configure your Bluesky handle in the environment variables.
42
+
</p>
43
+
<div class="text-sm text-yellow-700 dark:text-yellow-300">
44
+
<p class="mb-2">Create a <code class="bg-yellow-100 dark:bg-yellow-800 px-1 rounded">.env</code> file with:</p>
45
+
<pre class="bg-yellow-100 dark:bg-yellow-800 p-3 rounded text-xs overflow-x-auto">
46
+
ATPROTO_HANDLE=your-handle.bsky.social
47
+
SITE_TITLE=Your Site Title
48
+
SITE_AUTHOR=Your Name</pre>
49
+
</div>
50
+
</div>
51
+
</section>
52
+
)}
53
+
</main>
54
+
</div>
55
+
</Layout>
+76
src/styles/global.css
+76
src/styles/global.css
···
1
+
@import "tailwindcss";
2
+
3
+
/* Custom styles */
4
+
html {
5
+
font-family: var(--font-family, Inter, system-ui, sans-serif);
6
+
}
7
+
8
+
body {
9
+
font-feature-settings: "rlig" 1, "calt" 1;
10
+
}
11
+
12
+
/* Prose styles */
13
+
.prose {
14
+
color: rgb(55 65 81);
15
+
}
16
+
17
+
.dark .prose {
18
+
color: rgb(209 213 219);
19
+
}
20
+
21
+
.prose h1, .prose h2, .prose h3, .prose h4, .prose h5, .prose h6 {
22
+
color: rgb(17 24 39);
23
+
font-weight: 600;
24
+
}
25
+
26
+
.dark .prose h1, .dark .prose h2, .dark .prose h3, .dark .prose h4, .dark .prose h5, .dark .prose h6 {
27
+
color: rgb(255 255 255);
28
+
}
29
+
30
+
.prose a {
31
+
color: rgb(37 99 235);
32
+
}
33
+
34
+
.prose a:hover {
35
+
color: rgb(30 64 175);
36
+
}
37
+
38
+
.dark .prose a {
39
+
color: rgb(96 165 250);
40
+
}
41
+
42
+
.dark .prose a:hover {
43
+
color: rgb(147 197 253);
44
+
}
45
+
46
+
.prose blockquote {
47
+
border-left: 4px solid rgb(209 213 219);
48
+
padding-left: 1rem;
49
+
font-style: italic;
50
+
}
51
+
52
+
.dark .prose blockquote {
53
+
border-left-color: rgb(75 85 99);
54
+
}
55
+
56
+
.prose code {
57
+
background-color: rgb(243 244 246);
58
+
padding: 0.125rem 0.25rem;
59
+
border-radius: 0.25rem;
60
+
font-size: 0.875rem;
61
+
}
62
+
63
+
.dark .prose code {
64
+
background-color: rgb(31 41 55);
65
+
}
66
+
67
+
.prose pre {
68
+
background-color: rgb(243 244 246);
69
+
padding: 1rem;
70
+
border-radius: 0.5rem;
71
+
overflow-x: auto;
72
+
}
73
+
74
+
.dark .prose pre {
75
+
background-color: rgb(31 41 55);
76
+
}