Initial commit

the3ash committed Jul 10, 2025 at 18:27 UTC a475947126f7460e916d8666d9325169fcc08cc4
74 files changed +9728
.gitignore new
+26
@@ -0,0 +1,26 @@
1 +# Build output
2 +dist/
3 +.output/
4 +
5 +# Generated types
6 +.astro/
7 +
8 +# Dependencies
9 +node_modules/
10 +
11 +# Logs
12 +npm-debug.log*
13 +yarn-debug.log*
14 +yarn-error.log*
15 +pnpm-debug.log*
16 +
17 +# Environment variables
18 +.env
19 +.env.production
20 +
21 +# macOS-specific files
22 +.DS_Store
23 +
24 +# IDE settings
25 +.idea/
26 +
.prettierignore new
+40
@@ -0,0 +1,40 @@
1 +# Build output
2 +dist/
3 +.output/
4 +
5 +# Dependencies
6 +node_modules/
7 +
8 +# Package manager files
9 +package-lock.json
10 +yarn.lock
11 +pnpm-lock.yaml
12 +
13 +# Log files
14 +*.log
15 +
16 +# Environment variables
17 +.env
18 +.env.*
19 +
20 +# Cache directories
21 +.cache/
22 +.astro/
23 +
24 +# Others
25 +.DS_Store
26 +coverage/
27 +
28 +# Media files
29 +*.png
30 +*.jpg
31 +*.jpeg
32 +*.gif
33 +*.svg
34 +*.ico
35 +*.webp
36 +*.mp4
37 +*.webm
38 +*.mp3
39 +*.wav
40 +*.pdf
\ No newline at end of file
.prettierrc new
+8
@@ -0,0 +1,8 @@
1 +{
2 + "plugins": ["prettier-plugin-astro"],
3 + "semi": false,
4 + "singleQuote": true,
5 + "trailingComma": "none",
6 + "printWidth": 100,
7 + "tabWidth": 2
8 +}
.vscode/extensions.json new
+4
@@ -0,0 +1,4 @@
1 +{
2 + "recommendations": ["astro-build.astro-vscode", "unifiedjs.vscode-mdx"],
3 + "unwantedRecommendations": []
4 +}
.vscode/launch.json new
+11
@@ -0,0 +1,11 @@
1 +{
2 + "version": "0.2.0",
3 + "configurations": [
4 + {
5 + "command": "./node_modules/.bin/astro dev",
6 + "name": "Development server",
7 + "request": "launch",
8 + "type": "node-terminal"
9 + }
10 + ]
11 +}
LICENSE new
+21
@@ -0,0 +1,21 @@
1 +MIT License
2 +
3 +Copyright (c) 2025 3ASH
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in all
13 +copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 +SOFTWARE.
README.md new
+59
@@ -0,0 +1,59 @@
1 +# Chiri 🌸
2 +
3 +![screenshot-light](public/images/screenshot-light.png)
4 +![screenshot-dark](public/images/screenshot-dark.png)
5 +
6 +Chiri is a minimal blog theme built with [Astro](https://astro.build), offering customization options while preserving its clean aesthetic.
7 +
8 +Check the [demo](https://astro-chiri.netlify.app/) for more details.
9 +
10 +## Features
11 +
12 +- Built with Astro
13 +- Responsive
14 +- Light / Dark mode
15 +- MD & MDX
16 +- KaTeX
17 +- Sitemap
18 +- RSS
19 +- ...
20 +
21 +## Getting Started
22 +
23 +1. [Fork](https://github.com/the3ash/astro-chiri/fork) this repository, or use this template to [create a new repository](https://github.com/new?template_name=astro-chiri&template_owner=the3ash).
24 +
25 +2. Run the following commands:
26 +
27 +```bash
28 +git clone <your-repo-url>
29 +
30 +cd <your-repo-name>
31 +
32 +pnpm install
33 +
34 +pnpm dev
35 +```
36 +
37 +3. Edit `src/config.ts` and `src/content/about/about.md` to your liking.
38 +
39 +4. Use `pnpm new <title>` to create new posts, or add your posts to `src/content/posts`.
40 +
41 +5. Deploy to Netlify, Vercel, or other platforms, refer to [Astro Deployment Guides](https://docs.astro.build/en/guides/deploy/) for more details.
42 +
43 +&emsp;[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start) [![Deploy to Vercel](https://vercel.com/button)](https://vercel.com/new)
44 +
45 +## Commands
46 +
47 +- `pnpm new <title>` - Create a new post (use `_title` for drafts)
48 +- `pnpm update-theme` - Update the theme to the latest version
49 +
50 +## References
51 +
52 +- https://paco.me/
53 +- https://benji.org/
54 +- https://shud.in/
55 +- https://retypeset.radishzz.cc/
56 +
57 +## License
58 +
59 +MIT
astro.config.ts new
+58
@@ -0,0 +1,58 @@
1 +import { defineConfig } from 'astro/config'
2 +import mdx from '@astrojs/mdx'
3 +import sitemap from '@astrojs/sitemap'
4 +import remarkMath from 'remark-math'
5 +import remarkDirective from 'remark-directive'
6 +import rehypeKatex from 'rehype-katex'
7 +import remarkEmbeddedMedia from './src/plugins/remark-embedded-media.mjs'
8 +import remarkReadingTime from './src/plugins/remark-reading-time.mjs'
9 +import rehypeCleanup from './src/plugins/rehype-cleanup.mjs'
10 +import rehypeImageProcessor from './src/plugins/rehype-image-processor.mjs'
11 +import rehypeCopyCode from './src/plugins/rehype-copy-code.mjs'
12 +import { SITE } from './src/config'
13 +import path from 'path'
14 +
15 +export default defineConfig({
16 + site: SITE.website,
17 + devToolbar: {
18 + enabled: false
19 + },
20 + output: 'static',
21 + build: {
22 + inlineStylesheets: 'auto'
23 + },
24 + image: {
25 + service: {
26 + entrypoint: 'astro/assets/services/sharp'
27 + }
28 + },
29 + markdown: {
30 + shikiConfig: {
31 + theme: 'css-variables',
32 + wrap: false
33 + },
34 + remarkPlugins: [remarkMath, remarkDirective, remarkEmbeddedMedia, remarkReadingTime],
35 + rehypePlugins: [rehypeKatex, rehypeCleanup, rehypeImageProcessor, rehypeCopyCode]
36 + },
37 + integrations: [mdx(), sitemap()],
38 + vite: {
39 + resolve: {
40 + alias: {
41 + '@': path.resolve('./src')
42 + }
43 + },
44 + build: {
45 + rollupOptions: {
46 + output: {
47 + manualChunks: {
48 + 'vendor-katex': ['katex'],
49 + 'vendor-utils': ['reading-time', 'mdast-util-to-string']
50 + }
51 + }
52 + }
53 + },
54 + optimizeDeps: {
55 + include: ['katex', 'reading-time']
56 + }
57 + }
58 +})
eslint.config.js new
+41
@@ -0,0 +1,41 @@
1 +import eslint from '@eslint/js'
2 +import globals from 'globals'
3 +import tseslint from 'typescript-eslint'
4 +import prettier from 'eslint-config-prettier'
5 +import eslintPluginAstro from 'eslint-plugin-astro'
6 +
7 +export default [
8 + eslint.configs.recommended,
9 + ...tseslint.configs.recommended,
10 + ...eslintPluginAstro.configs.recommended,
11 + {
12 + languageOptions: {
13 + globals: {
14 + ...globals.browser,
15 + ...globals.node
16 + }
17 + }
18 + },
19 + {
20 + rules: {
21 + 'no-console': ['warn', { allow: ['warn', 'error'] }],
22 + '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
23 + '@typescript-eslint/no-explicit-any': 'warn',
24 + 'astro/no-set-html-directive': 'off'
25 + }
26 + },
27 + prettier,
28 + {
29 + ignores: [
30 + 'dist/**',
31 + '.output/**',
32 + 'node_modules/**',
33 + '*.log',
34 + '.env*',
35 + '.cache/**',
36 + '.astro/**',
37 + '.DS_Store',
38 + 'coverage/**'
39 + ]
40 + }
41 +]
netlify.toml new
+127
@@ -0,0 +1,127 @@
1 +[build]
2 + publish = "dist"
3 + command = "pnpm run build"
4 +
5 +# Redirects for Astro static assets
6 +[[redirects]]
7 + from = "/_astro/*"
8 + to = "/_astro/:splat"
9 + status = 200
10 +
11 +# Enable Brotli Compression
12 +[build.processing]
13 + skip_processing = false
14 +[build.processing.css]
15 + bundle = true
16 + minify = true
17 +[build.processing.js]
18 + bundle = true
19 + minify = true
20 +[build.processing.html]
21 + pretty_urls = true
22 +
23 +# Global headers for performance
24 +[[headers]]
25 + for = "/*"
26 + [headers.values]
27 + X-Frame-Options = "SAMEORIGIN"
28 + X-Content-Type-Options = "nosniff"
29 + Referrer-Policy = "strict-origin-when-cross-origin"
30 + Permissions-Policy = "geolocation=(), microphone=(), camera=(), fullscreen=(self)"
31 + Content-Security-Policy = '''
32 + default-src 'self';
33 + script-src 'self' 'unsafe-inline' 'unsafe-eval' https:;
34 + style-src 'self' 'unsafe-inline' https:;
35 + img-src 'self' data: https: blob:;
36 + font-src 'self' data: https:;
37 + frame-src https:;
38 + connect-src 'self' https:;
39 + object-src 'none';
40 + worker-src 'self' blob:;
41 + child-src 'self' blob:;
42 + '''
43 +
44 +# Static assets caching
45 +[[headers]]
46 + for = "/assets/*"
47 + [headers.values]
48 + Cache-Control = "public, max-age=31536000, immutable"
49 + Vary = "Accept-Encoding"
50 +
51 +[[headers]]
52 + for = "/fonts/*"
53 + [headers.values]
54 + Cache-Control = "public, max-age=31536000, immutable"
55 + Vary = "Accept-Encoding"
56 +
57 +[[headers]]
58 + for = "/_astro/*"
59 + [headers.values]
60 + Cache-Control = "public, max-age=31536000, immutable"
61 + Vary = "Accept-Encoding"
62 +
63 +[[headers]]
64 + for = "*.css"
65 + [headers.values]
66 + Cache-Control = "public, max-age=31536000, immutable"
67 + Vary = "Accept-Encoding"
68 +
69 +[[headers]]
70 + for = "*.js"
71 + [headers.values]
72 + Cache-Control = "public, max-age=31536000, immutable"
73 + Vary = "Accept-Encoding"
74 +
75 +# HTML caching with revalidation
76 +[[headers]]
77 + for = "*.html"
78 + [headers.values]
79 + Cache-Control = "public, max-age=300, s-maxage=3600"
80 + Vary = "Accept-Encoding"
81 +
82 +# Image optimization
83 +[[headers]]
84 + for = "*.jpg"
85 + [headers.values]
86 + Cache-Control = "public, max-age=31536000, immutable"
87 + Vary = "Accept-Encoding"
88 +
89 +[[headers]]
90 + for = "*.png"
91 + [headers.values]
92 + Cache-Control = "public, max-age=31536000, immutable"
93 + Vary = "Accept-Encoding"
94 +
95 +[[headers]]
96 + for = "*.webp"
97 + [headers.values]
98 + Cache-Control = "public, max-age=31536000, immutable"
99 + Vary = "Accept-Encoding"
100 +
101 +# Homepage with resource hints
102 +[[headers]]
103 + for = "/"
104 + [headers.values]
105 + Link = "</fonts/Inter.woff2>; rel=preload; as=font; type=font/woff2; crossorigin=anonymous, </fonts/Besley-Italic.woff2>; rel=preload; as=font; type=font/woff2; crossorigin=anonymous"
106 + Cache-Control = "public, max-age=300, s-maxage=3600"
107 + Vary = "Accept-Encoding"
108 +
109 +# Article page optimization
110 +[[headers]]
111 + for = "/posts/*"
112 + [headers.values]
113 + Cache-Control = "public, max-age=600, s-maxage=3600"
114 + Vary = "Accept-Encoding"
115 +
116 +# Enable compression
117 +[[headers]]
118 + for = "/*"
119 + [headers.values]
120 + Vary = "Accept-Encoding"
121 +
122 +
123 +
124 +
125 +
126 +
127 +
package.json new
+45
@@ -0,0 +1,45 @@
1 +{
2 + "name": "astro-chiri",
3 + "type": "module",
4 + "version": "0.5.0",
5 + "license": "MIT",
6 + "scripts": {
7 + "dev": "astro dev",
8 + "build": "astro build",
9 + "preview": "astro preview",
10 + "astro": "astro",
11 + "lint": "eslint .",
12 + "lint:fix": "eslint . --fix",
13 + "format": "prettier --write .",
14 + "format:check": "prettier --check .",
15 + "new": "tsx scripts/new-post.ts",
16 + "update-theme": "tsx scripts/update-theme.ts"
17 + },
18 + "dependencies": {
19 + "@astrojs/mdx": "^4.3.0",
20 + "@astrojs/sitemap": "^3.4.1",
21 + "astro": "^5.11.0",
22 + "katex": "^0.16.22",
23 + "mdast-util-to-string": "^4.0.0",
24 + "reading-time": "^1.5.0",
25 + "rehype-katex": "^7.0.1",
26 + "remark-directive": "^4.0.0",
27 + "remark-math": "^6.0.0",
28 + "sharp": "^0.34.2",
29 + "unist-util-visit": "^5.0.0"
30 + },
31 + "devDependencies": {
32 + "@eslint/js": "^9.30.1",
33 + "@typescript-eslint/eslint-plugin": "^8.35.1",
34 + "@typescript-eslint/parser": "^8.35.1",
35 + "eslint": "^9.30.1",
36 + "eslint-config-prettier": "^10.1.5",
37 + "eslint-plugin-astro": "^1.3.1",
38 + "globals": "^16.3.0",
39 + "prettier": "^3.6.2",
40 + "prettier-plugin-astro": "^0.14.1",
41 + "tsx": "^4.19.2",
42 + "typescript": "^5.8.3",
43 + "typescript-eslint": "^8.35.1"
44 + }
45 +}
pnpm-lock.yaml new
+5165
@@ -0,0 +1,5165 @@
1 +lockfileVersion: '9.0'
2 +
3 +settings:
4 + autoInstallPeers: true
5 + excludeLinksFromLockfile: false
6 +
7 +importers:
8 +
9 + .:
10 + dependencies:
11 + '@astrojs/mdx':
12 + specifier: ^4.3.0
13 + version: 4.3.0(astro@5.11.0(@types/node@24.0.10)(rollup@4.44.1)(tsx@4.20.3)(typescript@5.8.3))
14 + '@astrojs/sitemap':
15 + specifier: ^3.4.1
16 + version: 3.4.1
17 + astro:
18 + specifier: ^5.11.0
19 + version: 5.11.0(@types/node@24.0.10)(rollup@4.44.1)(tsx@4.20.3)(typescript@5.8.3)
20 + katex:
21 + specifier: ^0.16.22
22 + version: 0.16.22
23 + mdast-util-to-string:
24 + specifier: ^4.0.0
25 + version: 4.0.0
26 + reading-time:
27 + specifier: ^1.5.0
28 + version: 1.5.0
29 + rehype-katex:
30 + specifier: ^7.0.1
31 + version: 7.0.1
32 + remark-directive:
33 + specifier: ^4.0.0
34 + version: 4.0.0
35 + remark-math:
36 + specifier: ^6.0.0
37 + version: 6.0.0
38 + sharp:
39 + specifier: ^0.34.2
40 + version: 0.34.2
41 + unist-util-visit:
42 + specifier: ^5.0.0
43 + version: 5.0.0
44 + devDependencies:
45 + '@eslint/js':
46 + specifier: ^9.30.1
47 + version: 9.30.1
48 + '@typescript-eslint/eslint-plugin':
49 + specifier: ^8.35.1
50 + version: 8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1)(typescript@5.8.3))(eslint@9.30.1)(typescript@5.8.3)
51 + '@typescript-eslint/parser':
52 + specifier: ^8.35.1
53 + version: 8.35.1(eslint@9.30.1)(typescript@5.8.3)
54 + eslint:
55 + specifier: ^9.30.1
56 + version: 9.30.1
57 + eslint-config-prettier:
58 + specifier: ^10.1.5
59 + version: 10.1.5(eslint@9.30.1)
60 + eslint-plugin-astro:
61 + specifier: ^1.3.1
62 + version: 1.3.1(eslint@9.30.1)
63 + globals:
64 + specifier: ^16.3.0
65 + version: 16.3.0
66 + prettier:
67 + specifier: ^3.6.2
68 + version: 3.6.2
69 + prettier-plugin-astro:
70 + specifier: ^0.14.1
71 + version: 0.14.1
72 + tsx:
73 + specifier: ^4.19.2
74 + version: 4.20.3
75 + typescript:
76 + specifier: ^5.8.3
77 + version: 5.8.3
78 + typescript-eslint:
79 + specifier: ^8.35.1
80 + version: 8.35.1(eslint@9.30.1)(typescript@5.8.3)
81 +
82 +packages:
83 +
84 + '@astrojs/compiler@2.12.2':
85 + resolution: {integrity: sha512-w2zfvhjNCkNMmMMOn5b0J8+OmUaBL1o40ipMvqcG6NRpdC+lKxmTi48DT8Xw0SzJ3AfmeFLB45zXZXtmbsjcgw==}
86 +
87 + '@astrojs/internal-helpers@0.6.1':
88 + resolution: {integrity: sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A==}
89 +
90 + '@astrojs/markdown-remark@6.3.2':
91 + resolution: {integrity: sha512-bO35JbWpVvyKRl7cmSJD822e8YA8ThR/YbUsciWNA7yTcqpIAL2hJDToWP5KcZBWxGT6IOdOkHSXARSNZc4l/Q==}
92 +
93 + '@astrojs/mdx@4.3.0':
94 + resolution: {integrity: sha512-OGX2KvPeBzjSSKhkCqrUoDMyzFcjKt5nTE5SFw3RdoLf0nrhyCXBQcCyclzWy1+P+XpOamn+p+hm1EhpCRyPxw==}
95 + engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0}
96 + peerDependencies:
97 + astro: ^5.0.0
98 +
99 + '@astrojs/prism@3.3.0':
100 + resolution: {integrity: sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ==}
101 + engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0}
102 +
103 + '@astrojs/sitemap@3.4.1':
104 + resolution: {integrity: sha512-VjZvr1e4FH6NHyyHXOiQgLiw94LnCVY4v06wN/D0gZKchTMkg71GrAHJz81/huafcmavtLkIv26HnpfDq6/h/Q==}
105 +
106 + '@astrojs/telemetry@3.3.0':
107 + resolution: {integrity: sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ==}
108 + engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0}
109 +
110 + '@babel/helper-string-parser@7.27.1':
111 + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
112 + engines: {node: '>=6.9.0'}
113 +
114 + '@babel/helper-validator-identifier@7.27.1':
115 + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==}
116 + engines: {node: '>=6.9.0'}
117 +
118 + '@babel/parser@7.28.0':
119 + resolution: {integrity: sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==}
120 + engines: {node: '>=6.0.0'}
121 + hasBin: true
122 +
123 + '@babel/types@7.28.0':
124 + resolution: {integrity: sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg==}
125 + engines: {node: '>=6.9.0'}
126 +
127 + '@capsizecss/unpack@2.4.0':
128 + resolution: {integrity: sha512-GrSU71meACqcmIUxPYOJvGKF0yryjN/L1aCuE9DViCTJI7bfkjgYDPD1zbNDcINJwSSP6UaBZY9GAbYDO7re0Q==}
129 +
130 + '@emnapi/runtime@1.4.3':
131 + resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==}
132 +
133 + '@esbuild/aix-ppc64@0.25.5':
134 + resolution: {integrity: sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==}
135 + engines: {node: '>=18'}
136 + cpu: [ppc64]
137 + os: [aix]
138 +
139 + '@esbuild/android-arm64@0.25.5':
140 + resolution: {integrity: sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==}
141 + engines: {node: '>=18'}
142 + cpu: [arm64]
143 + os: [android]
144 +
145 + '@esbuild/android-arm@0.25.5':
146 + resolution: {integrity: sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==}
147 + engines: {node: '>=18'}
148 + cpu: [arm]
149 + os: [android]
150 +
151 + '@esbuild/android-x64@0.25.5':
152 + resolution: {integrity: sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==}
153 + engines: {node: '>=18'}
154 + cpu: [x64]
155 + os: [android]
156 +
157 + '@esbuild/darwin-arm64@0.25.5':
158 + resolution: {integrity: sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==}
159 + engines: {node: '>=18'}
160 + cpu: [arm64]
161 + os: [darwin]
162 +
163 + '@esbuild/darwin-x64@0.25.5':
164 + resolution: {integrity: sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==}
165 + engines: {node: '>=18'}
166 + cpu: [x64]
167 + os: [darwin]
168 +
169 + '@esbuild/freebsd-arm64@0.25.5':
170 + resolution: {integrity: sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==}
171 + engines: {node: '>=18'}
172 + cpu: [arm64]
173 + os: [freebsd]
174 +
175 + '@esbuild/freebsd-x64@0.25.5':
176 + resolution: {integrity: sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==}
177 + engines: {node: '>=18'}
178 + cpu: [x64]
179 + os: [freebsd]
180 +
181 + '@esbuild/linux-arm64@0.25.5':
182 + resolution: {integrity: sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==}
183 + engines: {node: '>=18'}
184 + cpu: [arm64]
185 + os: [linux]
186 +
187 + '@esbuild/linux-arm@0.25.5':
188 + resolution: {integrity: sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==}
189 + engines: {node: '>=18'}
190 + cpu: [arm]
191 + os: [linux]
192 +
193 + '@esbuild/linux-ia32@0.25.5':
194 + resolution: {integrity: sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==}
195 + engines: {node: '>=18'}
196 + cpu: [ia32]
197 + os: [linux]
198 +
199 + '@esbuild/linux-loong64@0.25.5':
200 + resolution: {integrity: sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==}
201 + engines: {node: '>=18'}
202 + cpu: [loong64]
203 + os: [linux]
204 +
205 + '@esbuild/linux-mips64el@0.25.5':
206 + resolution: {integrity: sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==}
207 + engines: {node: '>=18'}
208 + cpu: [mips64el]
209 + os: [linux]
210 +
211 + '@esbuild/linux-ppc64@0.25.5':
212 + resolution: {integrity: sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==}
213 + engines: {node: '>=18'}
214 + cpu: [ppc64]
215 + os: [linux]
216 +
217 + '@esbuild/linux-riscv64@0.25.5':
218 + resolution: {integrity: sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==}
219 + engines: {node: '>=18'}
220 + cpu: [riscv64]
221 + os: [linux]
222 +
223 + '@esbuild/linux-s390x@0.25.5':
224 + resolution: {integrity: sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==}
225 + engines: {node: '>=18'}
226 + cpu: [s390x]
227 + os: [linux]
228 +
229 + '@esbuild/linux-x64@0.25.5':
230 + resolution: {integrity: sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==}
231 + engines: {node: '>=18'}
232 + cpu: [x64]
233 + os: [linux]
234 +
235 + '@esbuild/netbsd-arm64@0.25.5':
236 + resolution: {integrity: sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==}
237 + engines: {node: '>=18'}
238 + cpu: [arm64]
239 + os: [netbsd]
240 +
241 + '@esbuild/netbsd-x64@0.25.5':
242 + resolution: {integrity: sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==}
243 + engines: {node: '>=18'}
244 + cpu: [x64]
245 + os: [netbsd]
246 +
247 + '@esbuild/openbsd-arm64@0.25.5':
248 + resolution: {integrity: sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==}
249 + engines: {node: '>=18'}
250 + cpu: [arm64]
251 + os: [openbsd]
252 +
253 + '@esbuild/openbsd-x64@0.25.5':
254 + resolution: {integrity: sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==}
255 + engines: {node: '>=18'}
256 + cpu: [x64]
257 + os: [openbsd]
258 +
259 + '@esbuild/sunos-x64@0.25.5':
260 + resolution: {integrity: sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==}
261 + engines: {node: '>=18'}
262 + cpu: [x64]
263 + os: [sunos]
264 +
265 + '@esbuild/win32-arm64@0.25.5':
266 + resolution: {integrity: sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==}
267 + engines: {node: '>=18'}
268 + cpu: [arm64]
269 + os: [win32]
270 +
271 + '@esbuild/win32-ia32@0.25.5':
272 + resolution: {integrity: sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==}
273 + engines: {node: '>=18'}
274 + cpu: [ia32]
275 + os: [win32]
276 +
277 + '@esbuild/win32-x64@0.25.5':
278 + resolution: {integrity: sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==}
279 + engines: {node: '>=18'}
280 + cpu: [x64]
281 + os: [win32]
282 +
283 + '@eslint-community/eslint-utils@4.7.0':
284 + resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==}
285 + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
286 + peerDependencies:
287 + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
288 +
289 + '@eslint-community/regexpp@4.12.1':
290 + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==}
291 + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
292 +
293 + '@eslint/config-array@0.21.0':
294 + resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==}
295 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
296 +
297 + '@eslint/config-helpers@0.3.0':
298 + resolution: {integrity: sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==}
299 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
300 +
301 + '@eslint/core@0.14.0':
302 + resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==}
303 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
304 +
305 + '@eslint/core@0.15.1':
306 + resolution: {integrity: sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==}
307 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
308 +
309 + '@eslint/eslintrc@3.3.1':
310 + resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==}
311 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
312 +
313 + '@eslint/js@9.30.1':
314 + resolution: {integrity: sha512-zXhuECFlyep42KZUhWjfvsmXGX39W8K8LFb8AWXM9gSV9dQB+MrJGLKvW6Zw0Ggnbpw0VHTtrhFXYe3Gym18jg==}
315 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
316 +
317 + '@eslint/object-schema@2.1.6':
318 + resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==}
319 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
320 +
321 + '@eslint/plugin-kit@0.3.3':
322 + resolution: {integrity: sha512-1+WqvgNMhmlAambTvT3KPtCl/Ibr68VldY2XY40SL1CE0ZXiakFR/cbTspaF5HsnpDMvcYYoJHfl4980NBjGag==}
323 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
324 +
325 + '@humanfs/core@0.19.1':
326 + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
327 + engines: {node: '>=18.18.0'}
328 +
329 + '@humanfs/node@0.16.6':
330 + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==}
331 + engines: {node: '>=18.18.0'}
332 +
333 + '@humanwhocodes/module-importer@1.0.1':
334 + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
335 + engines: {node: '>=12.22'}
336 +
337 + '@humanwhocodes/retry@0.3.1':
338 + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==}
339 + engines: {node: '>=18.18'}
340 +
341 + '@humanwhocodes/retry@0.4.3':
342 + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
343 + engines: {node: '>=18.18'}
344 +
345 + '@img/sharp-darwin-arm64@0.33.5':
346 + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==}
347 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
348 + cpu: [arm64]
349 + os: [darwin]
350 +
351 + '@img/sharp-darwin-arm64@0.34.2':
352 + resolution: {integrity: sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==}
353 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
354 + cpu: [arm64]
355 + os: [darwin]
356 +
357 + '@img/sharp-darwin-x64@0.33.5':
358 + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==}
359 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
360 + cpu: [x64]
361 + os: [darwin]
362 +
363 + '@img/sharp-darwin-x64@0.34.2':
364 + resolution: {integrity: sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==}
365 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
366 + cpu: [x64]
367 + os: [darwin]
368 +
369 + '@img/sharp-libvips-darwin-arm64@1.0.4':
370 + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==}
371 + cpu: [arm64]
372 + os: [darwin]
373 +
374 + '@img/sharp-libvips-darwin-arm64@1.1.0':
375 + resolution: {integrity: sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==}
376 + cpu: [arm64]
377 + os: [darwin]
378 +
379 + '@img/sharp-libvips-darwin-x64@1.0.4':
380 + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==}
381 + cpu: [x64]
382 + os: [darwin]
383 +
384 + '@img/sharp-libvips-darwin-x64@1.1.0':
385 + resolution: {integrity: sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==}
386 + cpu: [x64]
387 + os: [darwin]
388 +
389 + '@img/sharp-libvips-linux-arm64@1.0.4':
390 + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==}
391 + cpu: [arm64]
392 + os: [linux]
393 +
394 + '@img/sharp-libvips-linux-arm64@1.1.0':
395 + resolution: {integrity: sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==}
396 + cpu: [arm64]
397 + os: [linux]
398 +
399 + '@img/sharp-libvips-linux-arm@1.0.5':
400 + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==}
401 + cpu: [arm]
402 + os: [linux]
403 +
404 + '@img/sharp-libvips-linux-arm@1.1.0':
405 + resolution: {integrity: sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==}
406 + cpu: [arm]
407 + os: [linux]
408 +
409 + '@img/sharp-libvips-linux-ppc64@1.1.0':
410 + resolution: {integrity: sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==}
411 + cpu: [ppc64]
412 + os: [linux]
413 +
414 + '@img/sharp-libvips-linux-s390x@1.0.4':
415 + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==}
416 + cpu: [s390x]
417 + os: [linux]
418 +
419 + '@img/sharp-libvips-linux-s390x@1.1.0':
420 + resolution: {integrity: sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==}
421 + cpu: [s390x]
422 + os: [linux]
423 +
424 + '@img/sharp-libvips-linux-x64@1.0.4':
425 + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==}
426 + cpu: [x64]
427 + os: [linux]
428 +
429 + '@img/sharp-libvips-linux-x64@1.1.0':
430 + resolution: {integrity: sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==}
431 + cpu: [x64]
432 + os: [linux]
433 +
434 + '@img/sharp-libvips-linuxmusl-arm64@1.0.4':
435 + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==}
436 + cpu: [arm64]
437 + os: [linux]
438 +
439 + '@img/sharp-libvips-linuxmusl-arm64@1.1.0':
440 + resolution: {integrity: sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==}
441 + cpu: [arm64]
442 + os: [linux]
443 +
444 + '@img/sharp-libvips-linuxmusl-x64@1.0.4':
445 + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==}
446 + cpu: [x64]
447 + os: [linux]
448 +
449 + '@img/sharp-libvips-linuxmusl-x64@1.1.0':
450 + resolution: {integrity: sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==}
451 + cpu: [x64]
452 + os: [linux]
453 +
454 + '@img/sharp-linux-arm64@0.33.5':
455 + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==}
456 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
457 + cpu: [arm64]
458 + os: [linux]
459 +
460 + '@img/sharp-linux-arm64@0.34.2':
461 + resolution: {integrity: sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==}
462 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
463 + cpu: [arm64]
464 + os: [linux]
465 +
466 + '@img/sharp-linux-arm@0.33.5':
467 + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==}
468 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
469 + cpu: [arm]
470 + os: [linux]
471 +
472 + '@img/sharp-linux-arm@0.34.2':
473 + resolution: {integrity: sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==}
474 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
475 + cpu: [arm]
476 + os: [linux]
477 +
478 + '@img/sharp-linux-s390x@0.33.5':
479 + resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==}
480 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
481 + cpu: [s390x]
482 + os: [linux]
483 +
484 + '@img/sharp-linux-s390x@0.34.2':
485 + resolution: {integrity: sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==}
486 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
487 + cpu: [s390x]
488 + os: [linux]
489 +
490 + '@img/sharp-linux-x64@0.33.5':
491 + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==}
492 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
493 + cpu: [x64]
494 + os: [linux]
495 +
496 + '@img/sharp-linux-x64@0.34.2':
497 + resolution: {integrity: sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==}
498 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
499 + cpu: [x64]
500 + os: [linux]
501 +
502 + '@img/sharp-linuxmusl-arm64@0.33.5':
503 + resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==}
504 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
505 + cpu: [arm64]
506 + os: [linux]
507 +
508 + '@img/sharp-linuxmusl-arm64@0.34.2':
509 + resolution: {integrity: sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==}
510 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
511 + cpu: [arm64]
512 + os: [linux]
513 +
514 + '@img/sharp-linuxmusl-x64@0.33.5':
515 + resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==}
516 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
517 + cpu: [x64]
518 + os: [linux]
519 +
520 + '@img/sharp-linuxmusl-x64@0.34.2':
521 + resolution: {integrity: sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==}
522 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
523 + cpu: [x64]
524 + os: [linux]
525 +
526 + '@img/sharp-wasm32@0.33.5':
527 + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==}
528 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
529 + cpu: [wasm32]
530 +
531 + '@img/sharp-wasm32@0.34.2':
532 + resolution: {integrity: sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==}
533 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
534 + cpu: [wasm32]
535 +
536 + '@img/sharp-win32-arm64@0.34.2':
537 + resolution: {integrity: sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==}
538 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
539 + cpu: [arm64]
540 + os: [win32]
541 +
542 + '@img/sharp-win32-ia32@0.33.5':
543 + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==}
544 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
545 + cpu: [ia32]
546 + os: [win32]
547 +
548 + '@img/sharp-win32-ia32@0.34.2':
549 + resolution: {integrity: sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==}
550 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
551 + cpu: [ia32]
552 + os: [win32]
553 +
554 + '@img/sharp-win32-x64@0.33.5':
555 + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==}
556 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
557 + cpu: [x64]
558 + os: [win32]
559 +
560 + '@img/sharp-win32-x64@0.34.2':
561 + resolution: {integrity: sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==}
562 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
563 + cpu: [x64]
564 + os: [win32]
565 +
566 + '@jridgewell/sourcemap-codec@1.5.4':
567 + resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==}
568 +
569 + '@mdx-js/mdx@3.1.0':
570 + resolution: {integrity: sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw==}
571 +
572 + '@nodelib/fs.scandir@2.1.5':
573 + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
574 + engines: {node: '>= 8'}
575 +
576 + '@nodelib/fs.stat@2.0.5':
577 + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
578 + engines: {node: '>= 8'}
579 +
580 + '@nodelib/fs.walk@1.2.8':
581 + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
582 + engines: {node: '>= 8'}
583 +
584 + '@oslojs/encoding@1.1.0':
585 + resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==}
586 +
587 + '@pkgr/core@0.2.7':
588 + resolution: {integrity: sha512-YLT9Zo3oNPJoBjBc4q8G2mjU4tqIbf5CEOORbUUr48dCD9q3umJ3IPlVqOqDakPfd2HuwccBaqlGhN4Gmr5OWg==}
589 + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
590 +
591 + '@rollup/pluginutils@5.2.0':
592 + resolution: {integrity: sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==}
593 + engines: {node: '>=14.0.0'}
594 + peerDependencies:
595 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
596 + peerDependenciesMeta:
597 + rollup:
598 + optional: true
599 +
600 + '@rollup/rollup-android-arm-eabi@4.44.1':
601 + resolution: {integrity: sha512-JAcBr1+fgqx20m7Fwe1DxPUl/hPkee6jA6Pl7n1v2EFiktAHenTaXl5aIFjUIEsfn9w3HE4gK1lEgNGMzBDs1w==}
602 + cpu: [arm]
603 + os: [android]
604 +
605 + '@rollup/rollup-android-arm64@4.44.1':
606 + resolution: {integrity: sha512-RurZetXqTu4p+G0ChbnkwBuAtwAbIwJkycw1n6GvlGlBuS4u5qlr5opix8cBAYFJgaY05TWtM+LaoFggUmbZEQ==}
607 + cpu: [arm64]
608 + os: [android]
609 +
610 + '@rollup/rollup-darwin-arm64@4.44.1':
611 + resolution: {integrity: sha512-fM/xPesi7g2M7chk37LOnmnSTHLG/v2ggWqKj3CCA1rMA4mm5KVBT1fNoswbo1JhPuNNZrVwpTvlCVggv8A2zg==}
612 + cpu: [arm64]
613 + os: [darwin]
614 +
615 + '@rollup/rollup-darwin-x64@4.44.1':
616 + resolution: {integrity: sha512-gDnWk57urJrkrHQ2WVx9TSVTH7lSlU7E3AFqiko+bgjlh78aJ88/3nycMax52VIVjIm3ObXnDL2H00e/xzoipw==}
617 + cpu: [x64]
618 + os: [darwin]
619 +
620 + '@rollup/rollup-freebsd-arm64@4.44.1':
621 + resolution: {integrity: sha512-wnFQmJ/zPThM5zEGcnDcCJeYJgtSLjh1d//WuHzhf6zT3Md1BvvhJnWoy+HECKu2bMxaIcfWiu3bJgx6z4g2XA==}
622 + cpu: [arm64]
623 + os: [freebsd]
624 +
625 + '@rollup/rollup-freebsd-x64@4.44.1':
626 + resolution: {integrity: sha512-uBmIxoJ4493YATvU2c0upGz87f99e3wop7TJgOA/bXMFd2SvKCI7xkxY/5k50bv7J6dw1SXT4MQBQSLn8Bb/Uw==}
627 + cpu: [x64]
628 + os: [freebsd]
629 +
630 + '@rollup/rollup-linux-arm-gnueabihf@4.44.1':
631 + resolution: {integrity: sha512-n0edDmSHlXFhrlmTK7XBuwKlG5MbS7yleS1cQ9nn4kIeW+dJH+ExqNgQ0RrFRew8Y+0V/x6C5IjsHrJmiHtkxQ==}
632 + cpu: [arm]
633 + os: [linux]
634 +
635 + '@rollup/rollup-linux-arm-musleabihf@4.44.1':
636 + resolution: {integrity: sha512-8WVUPy3FtAsKSpyk21kV52HCxB+me6YkbkFHATzC2Yd3yuqHwy2lbFL4alJOLXKljoRw08Zk8/xEj89cLQ/4Nw==}
637 + cpu: [arm]
638 + os: [linux]
639 +
640 + '@rollup/rollup-linux-arm64-gnu@4.44.1':
641 + resolution: {integrity: sha512-yuktAOaeOgorWDeFJggjuCkMGeITfqvPgkIXhDqsfKX8J3jGyxdDZgBV/2kj/2DyPaLiX6bPdjJDTu9RB8lUPQ==}
642 + cpu: [arm64]
643 + os: [linux]
644 +
645 + '@rollup/rollup-linux-arm64-musl@4.44.1':
646 + resolution: {integrity: sha512-W+GBM4ifET1Plw8pdVaecwUgxmiH23CfAUj32u8knq0JPFyK4weRy6H7ooxYFD19YxBulL0Ktsflg5XS7+7u9g==}
647 + cpu: [arm64]
648 + os: [linux]
649 +
650 + '@rollup/rollup-linux-loongarch64-gnu@4.44.1':
651 + resolution: {integrity: sha512-1zqnUEMWp9WrGVuVak6jWTl4fEtrVKfZY7CvcBmUUpxAJ7WcSowPSAWIKa/0o5mBL/Ij50SIf9tuirGx63Ovew==}
652 + cpu: [loong64]
653 + os: [linux]
654 +
655 + '@rollup/rollup-linux-powerpc64le-gnu@4.44.1':
656 + resolution: {integrity: sha512-Rl3JKaRu0LHIx7ExBAAnf0JcOQetQffaw34T8vLlg9b1IhzcBgaIdnvEbbsZq9uZp3uAH+JkHd20Nwn0h9zPjA==}
657 + cpu: [ppc64]
658 + os: [linux]
659 +
660 + '@rollup/rollup-linux-riscv64-gnu@4.44.1':
661 + resolution: {integrity: sha512-j5akelU3snyL6K3N/iX7otLBIl347fGwmd95U5gS/7z6T4ftK288jKq3A5lcFKcx7wwzb5rgNvAg3ZbV4BqUSw==}
662 + cpu: [riscv64]
663 + os: [linux]
664 +
665 + '@rollup/rollup-linux-riscv64-musl@4.44.1':
666 + resolution: {integrity: sha512-ppn5llVGgrZw7yxbIm8TTvtj1EoPgYUAbfw0uDjIOzzoqlZlZrLJ/KuiE7uf5EpTpCTrNt1EdtzF0naMm0wGYg==}
667 + cpu: [riscv64]
668 + os: [linux]
669 +
670 + '@rollup/rollup-linux-s390x-gnu@4.44.1':
671 + resolution: {integrity: sha512-Hu6hEdix0oxtUma99jSP7xbvjkUM/ycke/AQQ4EC5g7jNRLLIwjcNwaUy95ZKBJJwg1ZowsclNnjYqzN4zwkAw==}
672 + cpu: [s390x]
673 + os: [linux]
674 +
675 + '@rollup/rollup-linux-x64-gnu@4.44.1':
676 + resolution: {integrity: sha512-EtnsrmZGomz9WxK1bR5079zee3+7a+AdFlghyd6VbAjgRJDbTANJ9dcPIPAi76uG05micpEL+gPGmAKYTschQw==}
677 + cpu: [x64]
678 + os: [linux]
679 +
680 + '@rollup/rollup-linux-x64-musl@4.44.1':
681 + resolution: {integrity: sha512-iAS4p+J1az6Usn0f8xhgL4PaU878KEtutP4hqw52I4IO6AGoyOkHCxcc4bqufv1tQLdDWFx8lR9YlwxKuv3/3g==}
682 + cpu: [x64]
683 + os: [linux]
684 +
685 + '@rollup/rollup-win32-arm64-msvc@4.44.1':
686 + resolution: {integrity: sha512-NtSJVKcXwcqozOl+FwI41OH3OApDyLk3kqTJgx8+gp6On9ZEt5mYhIsKNPGuaZr3p9T6NWPKGU/03Vw4CNU9qg==}
687 + cpu: [arm64]
688 + os: [win32]
689 +
690 + '@rollup/rollup-win32-ia32-msvc@4.44.1':
691 + resolution: {integrity: sha512-JYA3qvCOLXSsnTR3oiyGws1Dm0YTuxAAeaYGVlGpUsHqloPcFjPg+X0Fj2qODGLNwQOAcCiQmHub/V007kiH5A==}
692 + cpu: [ia32]
693 + os: [win32]
694 +
695 + '@rollup/rollup-win32-x64-msvc@4.44.1':
696 + resolution: {integrity: sha512-J8o22LuF0kTe7m+8PvW9wk3/bRq5+mRo5Dqo6+vXb7otCm3TPhYOJqOaQtGU9YMWQSL3krMnoOxMr0+9E6F3Ug==}
697 + cpu: [x64]
698 + os: [win32]
699 +
700 + '@shikijs/core@3.7.0':
701 + resolution: {integrity: sha512-yilc0S9HvTPyahHpcum8eonYrQtmGTU0lbtwxhA6jHv4Bm1cAdlPFRCJX4AHebkCm75aKTjjRAW+DezqD1b/cg==}
702 +
703 + '@shikijs/engine-javascript@3.7.0':
704 + resolution: {integrity: sha512-0t17s03Cbv+ZcUvv+y33GtX75WBLQELgNdVghnsdhTgU3hVcWcMsoP6Lb0nDTl95ZJfbP1mVMO0p3byVh3uuzA==}
705 +
706 + '@shikijs/engine-oniguruma@3.7.0':
707 + resolution: {integrity: sha512-5BxcD6LjVWsGu4xyaBC5bu8LdNgPCVBnAkWTtOCs/CZxcB22L8rcoWfv7Hh/3WooVjBZmFtyxhgvkQFedPGnFw==}
708 +
709 + '@shikijs/langs@3.7.0':
710 + resolution: {integrity: sha512-1zYtdfXLr9xDKLTGy5kb7O0zDQsxXiIsw1iIBcNOO8Yi5/Y1qDbJ+0VsFoqTlzdmneO8Ij35g7QKF8kcLyznCQ==}
711 +
712 + '@shikijs/themes@3.7.0':
713 + resolution: {integrity: sha512-VJx8497iZPy5zLiiCTSIaOChIcKQwR0FebwE9S3rcN0+J/GTWwQ1v/bqhTbpbY3zybPKeO8wdammqkpXc4NVjQ==}
714 +
715 + '@shikijs/types@3.7.0':
716 + resolution: {integrity: sha512-MGaLeaRlSWpnP0XSAum3kP3a8vtcTsITqoEPYdt3lQG3YCdQH4DnEhodkYcNMcU0uW0RffhoD1O3e0vG5eSBBg==}
717 +
718 + '@shikijs/vscode-textmate@10.0.2':
719 + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==}
720 +
721 + '@swc/helpers@0.5.17':
722 + resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==}
723 +
724 + '@types/debug@4.1.12':
725 + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
726 +
727 + '@types/estree-jsx@1.0.5':
728 + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==}
729 +
730 + '@types/estree@1.0.8':
731 + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
732 +
733 + '@types/fontkit@2.0.8':
734 + resolution: {integrity: sha512-wN+8bYxIpJf+5oZdrdtaX04qUuWHcKxcDEgRS9Qm9ZClSHjzEn13SxUC+5eRM+4yXIeTYk8mTzLAWGF64847ew==}
735 +
736 + '@types/hast@3.0.4':
737 + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
738 +
739 + '@types/json-schema@7.0.15':
740 + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
741 +
742 + '@types/katex@0.16.7':
743 + resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==}
744 +
745 + '@types/mdast@4.0.4':
746 + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
747 +
748 + '@types/mdx@2.0.13':
749 + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==}
750 +
751 + '@types/ms@2.1.0':
752 + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
753 +
754 + '@types/nlcst@2.0.3':
755 + resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==}
756 +
757 + '@types/node@17.0.45':
758 + resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==}
759 +
760 + '@types/node@24.0.10':
761 + resolution: {integrity: sha512-ENHwaH+JIRTDIEEbDK6QSQntAYGtbvdDXnMXnZaZ6k13Du1dPMmprkEHIL7ok2Wl2aZevetwTAb5S+7yIF+enA==}
762 +
763 + '@types/sax@1.2.7':
764 + resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==}
765 +
766 + '@types/unist@2.0.11':
767 + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
768 +
769 + '@types/unist@3.0.3':
770 + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
771 +
772 + '@typescript-eslint/eslint-plugin@8.35.1':
773 + resolution: {integrity: sha512-9XNTlo7P7RJxbVeICaIIIEipqxLKguyh+3UbXuT2XQuFp6d8VOeDEGuz5IiX0dgZo8CiI6aOFLg4e8cF71SFVg==}
774 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
775 + peerDependencies:
776 + '@typescript-eslint/parser': ^8.35.1
777 + eslint: ^8.57.0 || ^9.0.0
778 + typescript: '>=4.8.4 <5.9.0'
779 +
780 + '@typescript-eslint/parser@8.35.1':
781 + resolution: {integrity: sha512-3MyiDfrfLeK06bi/g9DqJxP5pV74LNv4rFTyvGDmT3x2p1yp1lOd+qYZfiRPIOf/oON+WRZR5wxxuF85qOar+w==}
782 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
783 + peerDependencies:
784 + eslint: ^8.57.0 || ^9.0.0
785 + typescript: '>=4.8.4 <5.9.0'
786 +
787 + '@typescript-eslint/project-service@8.35.1':
788 + resolution: {integrity: sha512-VYxn/5LOpVxADAuP3NrnxxHYfzVtQzLKeldIhDhzC8UHaiQvYlXvKuVho1qLduFbJjjy5U5bkGwa3rUGUb1Q6Q==}
789 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
790 + peerDependencies:
791 + typescript: '>=4.8.4 <5.9.0'
792 +
793 + '@typescript-eslint/scope-manager@8.35.1':
794 + resolution: {integrity: sha512-s/Bpd4i7ht2934nG+UoSPlYXd08KYz3bmjLEb7Ye1UVob0d1ENiT3lY8bsCmik4RqfSbPw9xJJHbugpPpP5JUg==}
795 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
796 +
797 + '@typescript-eslint/tsconfig-utils@8.35.1':
798 + resolution: {integrity: sha512-K5/U9VmT9dTHoNowWZpz+/TObS3xqC5h0xAIjXPw+MNcKV9qg6eSatEnmeAwkjHijhACH0/N7bkhKvbt1+DXWQ==}
799 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
800 + peerDependencies:
801 + typescript: '>=4.8.4 <5.9.0'
802 +
803 + '@typescript-eslint/type-utils@8.35.1':
804 + resolution: {integrity: sha512-HOrUBlfVRz5W2LIKpXzZoy6VTZzMu2n8q9C2V/cFngIC5U1nStJgv0tMV4sZPzdf4wQm9/ToWUFPMN9Vq9VJQQ==}
805 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
806 + peerDependencies:
807 + eslint: ^8.57.0 || ^9.0.0
808 + typescript: '>=4.8.4 <5.9.0'
809 +
810 + '@typescript-eslint/types@8.35.1':
811 + resolution: {integrity: sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ==}
812 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
813 +
814 + '@typescript-eslint/typescript-estree@8.35.1':
815 + resolution: {integrity: sha512-Vvpuvj4tBxIka7cPs6Y1uvM7gJgdF5Uu9F+mBJBPY4MhvjrjWGK4H0lVgLJd/8PWZ23FTqsaJaLEkBCFUk8Y9g==}
816 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
817 + peerDependencies:
818 + typescript: '>=4.8.4 <5.9.0'
819 +
820 + '@typescript-eslint/utils@8.35.1':
821 + resolution: {integrity: sha512-lhnwatFmOFcazAsUm3ZnZFpXSxiwoa1Lj50HphnDe1Et01NF4+hrdXONSUHIcbVu2eFb1bAf+5yjXkGVkXBKAQ==}
822 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
823 + peerDependencies:
824 + eslint: ^8.57.0 || ^9.0.0
825 + typescript: '>=4.8.4 <5.9.0'
826 +
827 + '@typescript-eslint/visitor-keys@8.35.1':
828 + resolution: {integrity: sha512-VRwixir4zBWCSTP/ljEo091lbpypz57PoeAQ9imjG+vbeof9LplljsL1mos4ccG6H9IjfrVGM359RozUnuFhpw==}
829 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
830 +
831 + '@ungap/structured-clone@1.3.0':
832 + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
833 +
834 + acorn-jsx@5.3.2:
835 + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
836 + peerDependencies:
837 + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
838 +
839 + acorn@8.15.0:
840 + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==}
841 + engines: {node: '>=0.4.0'}
842 + hasBin: true
843 +
844 + ajv@6.12.6:
845 + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
846 +
847 + ansi-align@3.0.1:
848 + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==}
849 +
850 + ansi-regex@5.0.1:
851 + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
852 + engines: {node: '>=8'}
853 +
854 + ansi-regex@6.1.0:
855 + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==}
856 + engines: {node: '>=12'}
857 +
858 + ansi-styles@4.3.0:
859 + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
860 + engines: {node: '>=8'}
861 +
862 + ansi-styles@6.2.1:
863 + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
864 + engines: {node: '>=12'}
865 +
866 + anymatch@3.1.3:
867 + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
868 + engines: {node: '>= 8'}
869 +
870 + arg@5.0.2:
871 + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
872 +
873 + argparse@2.0.1:
874 + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
875 +
876 + aria-query@5.3.2:
877 + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
878 + engines: {node: '>= 0.4'}
879 +
880 + array-iterate@2.0.1:
881 + resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==}
882 +
883 + astring@1.9.0:
884 + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==}
885 + hasBin: true
886 +
887 + astro-eslint-parser@1.2.2:
888 + resolution: {integrity: sha512-JepyLROIad6f44uyqMF6HKE2QbunNzp3mYKRcPoDGt0QkxXmH222FAFC64WTyQu2Kg8NNEXHTN/sWuUId9sSxw==}
889 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
890 +
891 + astro@5.11.0:
892 + resolution: {integrity: sha512-MEICntERthUxJPSSDsDiZuwiCMrsaYy3fnDhp4c6ScUfldCB8RBnB/myYdpTFXpwYBy6SgVsHQ1H4MuuA7ro/Q==}
893 + engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'}
894 + hasBin: true
895 +
896 + astrojs-compiler-sync@1.1.1:
897 + resolution: {integrity: sha512-0mKvB9sDQRIZPsEJadw6OaFbGJ92cJPPR++ICca9XEyiUAZqgVuk25jNmzHPT0KF80rI94trSZrUR5iHFXGGOQ==}
898 + engines: {node: ^18.18.0 || >=20.9.0}
899 + peerDependencies:
900 + '@astrojs/compiler': '>=0.27.0'
901 +
902 + axobject-query@4.1.0:
903 + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
904 + engines: {node: '>= 0.4'}
905 +
906 + bail@2.0.2:
907 + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
908 +
909 + balanced-match@1.0.2:
910 + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
911 +
912 + base-64@1.0.0:
913 + resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==}
914 +
915 + base64-js@1.5.1:
916 + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
917 +
918 + blob-to-buffer@1.2.9:
919 + resolution: {integrity: sha512-BF033y5fN6OCofD3vgHmNtwZWRcq9NLyyxyILx9hfMy1sXYy4ojFl765hJ2lP0YaN2fuxPaLO2Vzzoxy0FLFFA==}
920 +
921 + boxen@8.0.1:
922 + resolution: {integrity: sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==}
923 + engines: {node: '>=18'}
924 +
925 + brace-expansion@1.1.12:
926 + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==}
927 +
928 + brace-expansion@2.0.2:
929 + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==}
930 +
931 + braces@3.0.3:
932 + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
933 + engines: {node: '>=8'}
934 +
935 + brotli@1.3.3:
936 + resolution: {integrity: sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==}
937 +
938 + callsites@3.1.0:
939 + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
940 + engines: {node: '>=6'}
941 +
942 + camelcase@8.0.0:
943 + resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==}
944 + engines: {node: '>=16'}
945 +
946 + ccount@2.0.1:
947 + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
948 +
949 + chalk@4.1.2:
950 + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
951 + engines: {node: '>=10'}
952 +
953 + chalk@5.4.1:
954 + resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==}
955 + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
956 +
957 + character-entities-html4@2.1.0:
958 + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
959 +
960 + character-entities-legacy@3.0.0:
961 + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==}
962 +
963 + character-entities@2.0.2:
964 + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==}
965 +
966 + character-reference-invalid@2.0.1:
967 + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==}
968 +
969 + chokidar@4.0.3:
970 + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
971 + engines: {node: '>= 14.16.0'}
972 +
973 + ci-info@4.2.0:
974 + resolution: {integrity: sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg==}
975 + engines: {node: '>=8'}
976 +
977 + cli-boxes@3.0.0:
978 + resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==}
979 + engines: {node: '>=10'}
980 +
981 + clone@2.1.2:
982 + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==}
983 + engines: {node: '>=0.8'}
984 +
985 + clsx@2.1.1:
986 + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
987 + engines: {node: '>=6'}
988 +
989 + collapse-white-space@2.1.0:
990 + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==}
991 +
992 + color-convert@2.0.1:
993 + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
994 + engines: {node: '>=7.0.0'}
995 +
996 + color-name@1.1.4:
997 + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
998 +
999 + color-string@1.9.1:
1000 + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
1001 +
1002 + color@4.2.3:
1003 + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
1004 + engines: {node: '>=12.5.0'}
1005 +
1006 + comma-separated-tokens@2.0.3:
1007 + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
1008 +
1009 + commander@8.3.0:
1010 + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==}
1011 + engines: {node: '>= 12'}
1012 +
1013 + common-ancestor-path@1.0.1:
1014 + resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==}
1015 +
1016 + concat-map@0.0.1:
1017 + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
1018 +
1019 + cookie-es@1.2.2:
1020 + resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==}
1021 +
1022 + cookie@1.0.2:
1023 + resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==}
1024 + engines: {node: '>=18'}
1025 +
1026 + cross-fetch@3.2.0:
1027 + resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==}
1028 +
1029 + cross-spawn@7.0.6:
1030 + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
1031 + engines: {node: '>= 8'}
1032 +
1033 + crossws@0.3.5:
1034 + resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==}
1035 +
1036 + css-tree@3.1.0:
1037 + resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==}
1038 + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
1039 +
1040 + cssesc@3.0.0:
1041 + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
1042 + engines: {node: '>=4'}
1043 + hasBin: true
1044 +
1045 + debug@4.4.1:
1046 + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==}
1047 + engines: {node: '>=6.0'}
1048 + peerDependencies:
1049 + supports-color: '*'
1050 + peerDependenciesMeta:
1051 + supports-color:
1052 + optional: true
1053 +
1054 + decode-named-character-reference@1.2.0:
1055 + resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==}
1056 +
1057 + deep-is@0.1.4:
1058 + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
1059 +
1060 + defu@6.1.4:
1061 + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
1062 +
1063 + dequal@2.0.3:
1064 + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
1065 + engines: {node: '>=6'}
1066 +
1067 + destr@2.0.5:
1068 + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==}
1069 +
1070 + detect-libc@2.0.4:
1071 + resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==}
1072 + engines: {node: '>=8'}
1073 +
1074 + deterministic-object-hash@2.0.2:
1075 + resolution: {integrity: sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==}
1076 + engines: {node: '>=18'}
1077 +
1078 + devalue@5.1.1:
1079 + resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==}
1080 +
1081 + devlop@1.1.0:
1082 + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
1083 +
1084 + dfa@1.2.0:
1085 + resolution: {integrity: sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==}
1086 +
1087 + diff@5.2.0:
1088 + resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==}
1089 + engines: {node: '>=0.3.1'}
1090 +
1091 + dlv@1.1.3:
1092 + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
1093 +
1094 + dset@3.1.4:
1095 + resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==}
1096 + engines: {node: '>=4'}
1097 +
1098 + emoji-regex@10.4.0:
1099 + resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==}
1100 +
1101 + emoji-regex@8.0.0:
1102 + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
1103 +
1104 + entities@6.0.1:
1105 + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==}
1106 + engines: {node: '>=0.12'}
1107 +
1108 + es-module-lexer@1.7.0:
1109 + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==}
1110 +
1111 + esast-util-from-estree@2.0.0:
1112 + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==}
1113 +
1114 + esast-util-from-js@2.0.1:
1115 + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==}
1116 +
1117 + esbuild@0.25.5:
1118 + resolution: {integrity: sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==}
1119 + engines: {node: '>=18'}
1120 + hasBin: true
1121 +
1122 + escape-string-regexp@4.0.0:
1123 + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
1124 + engines: {node: '>=10'}
1125 +
1126 + escape-string-regexp@5.0.0:
1127 + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
1128 + engines: {node: '>=12'}
1129 +
1130 + eslint-compat-utils@0.6.5:
1131 + resolution: {integrity: sha512-vAUHYzue4YAa2hNACjB8HvUQj5yehAZgiClyFVVom9cP8z5NSFq3PwB/TtJslN2zAMgRX6FCFCjYBbQh71g5RQ==}
1132 + engines: {node: '>=12'}
1133 + peerDependencies:
1134 + eslint: '>=6.0.0'
1135 +
1136 + eslint-config-prettier@10.1.5:
1137 + resolution: {integrity: sha512-zc1UmCpNltmVY34vuLRV61r1K27sWuX39E+uyUnY8xS2Bex88VV9cugG+UZbRSRGtGyFboj+D8JODyme1plMpw==}
1138 + hasBin: true
1139 + peerDependencies:
1140 + eslint: '>=7.0.0'
1141 +
1142 + eslint-plugin-astro@1.3.1:
1143 + resolution: {integrity: sha512-2XaLCMQm8htW1UvJvy1Zcmg8l0ziskitiUfJTn/w1Mk7r4Mxj0fZeNpN6UTNrm64XBIXSa5h8UCGrg8mdu47+g==}
1144 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1145 + peerDependencies:
1146 + eslint: '>=8.57.0'
1147 +
1148 + eslint-scope@8.4.0:
1149 + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==}
1150 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1151 +
1152 + eslint-visitor-keys@3.4.3:
1153 + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
1154 + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
1155 +
1156 + eslint-visitor-keys@4.2.1:
1157 + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==}
1158 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1159 +
1160 + eslint@9.30.1:
1161 + resolution: {integrity: sha512-zmxXPNMOXmwm9E0yQLi5uqXHs7uq2UIiqEKo3Gq+3fwo1XrJ+hijAZImyF7hclW3E6oHz43Yk3RP8at6OTKflQ==}
1162 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1163 + hasBin: true
1164 + peerDependencies:
1165 + jiti: '*'
1166 + peerDependenciesMeta:
1167 + jiti:
1168 + optional: true
1169 +
1170 + espree@10.4.0:
1171 + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==}
1172 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1173 +
1174 + esquery@1.6.0:
1175 + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==}
1176 + engines: {node: '>=0.10'}
1177 +
1178 + esrecurse@4.3.0:
1179 + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
1180 + engines: {node: '>=4.0'}
1181 +
1182 + estraverse@5.3.0:
1183 + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
1184 + engines: {node: '>=4.0'}
1185 +
1186 + estree-util-attach-comments@3.0.0:
1187 + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==}
1188 +
1189 + estree-util-build-jsx@3.0.1:
1190 + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==}
1191 +
1192 + estree-util-is-identifier-name@3.0.0:
1193 + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==}
1194 +
1195 + estree-util-scope@1.0.0:
1196 + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==}
1197 +
1198 + estree-util-to-js@2.0.0:
1199 + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==}
1200 +
1201 + estree-util-visit@2.0.0:
1202 + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==}
1203 +
1204 + estree-walker@2.0.2:
1205 + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
1206 +
1207 + estree-walker@3.0.3:
1208 + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
1209 +
1210 + esutils@2.0.3:
1211 + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
1212 + engines: {node: '>=0.10.0'}
1213 +
1214 + eventemitter3@5.0.1:
1215 + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
1216 +
1217 + extend@3.0.2:
1218 + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
1219 +
1220 + fast-deep-equal@3.1.3:
1221 + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
1222 +
1223 + fast-glob@3.3.3:
1224 + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
1225 + engines: {node: '>=8.6.0'}
1226 +
1227 + fast-json-stable-stringify@2.1.0:
1228 + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
1229 +
1230 + fast-levenshtein@2.0.6:
1231 + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
1232 +
1233 + fastq@1.19.1:
1234 + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==}
1235 +
1236 + fdir@6.4.6:
1237 + resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==}
1238 + peerDependencies:
1239 + picomatch: ^3 || ^4
1240 + peerDependenciesMeta:
1241 + picomatch:
1242 + optional: true
1243 +
1244 + file-entry-cache@8.0.0:
1245 + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
1246 + engines: {node: '>=16.0.0'}
1247 +
1248 + fill-range@7.1.1:
1249 + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
1250 + engines: {node: '>=8'}
1251 +
1252 + find-up@5.0.0:
1253 + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
1254 + engines: {node: '>=10'}
1255 +
1256 + flat-cache@4.0.1:
1257 + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==}
1258 + engines: {node: '>=16'}
1259 +
1260 + flatted@3.3.3:
1261 + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==}
1262 +
1263 + flattie@1.1.1:
1264 + resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==}
1265 + engines: {node: '>=8'}
1266 +
1267 + fontace@0.3.0:
1268 + resolution: {integrity: sha512-czoqATrcnxgWb/nAkfyIrRp6Q8biYj7nGnL6zfhTcX+JKKpWHFBnb8uNMw/kZr7u++3Y3wYSYoZgHkCcsuBpBg==}
1269 +
1270 + fontkit@2.0.4:
1271 + resolution: {integrity: sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g==}
1272 +
1273 + fsevents@2.3.3:
1274 + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
1275 + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
1276 + os: [darwin]
1277 +
1278 + get-east-asian-width@1.3.0:
1279 + resolution: {integrity: sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==}
1280 + engines: {node: '>=18'}
1281 +
1282 + get-tsconfig@4.10.1:
1283 + resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==}
1284 +
1285 + github-slugger@2.0.0:
1286 + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==}
1287 +
1288 + glob-parent@5.1.2:
1289 + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
1290 + engines: {node: '>= 6'}
1291 +
1292 + glob-parent@6.0.2:
1293 + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
1294 + engines: {node: '>=10.13.0'}
1295 +
1296 + globals@14.0.0:
1297 + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
1298 + engines: {node: '>=18'}
1299 +
1300 + globals@15.15.0:
1301 + resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==}
1302 + engines: {node: '>=18'}
1303 +
1304 + globals@16.3.0:
1305 + resolution: {integrity: sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==}
1306 + engines: {node: '>=18'}
1307 +
1308 + graphemer@1.4.0:
1309 + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
1310 +
1311 + h3@1.15.3:
1312 + resolution: {integrity: sha512-z6GknHqyX0h9aQaTx22VZDf6QyZn+0Nh+Ym8O/u0SGSkyF5cuTJYKlc8MkzW3Nzf9LE1ivcpmYC3FUGpywhuUQ==}
1313 +
1314 + has-flag@4.0.0:
1315 + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
1316 + engines: {node: '>=8'}
1317 +
1318 + hast-util-from-dom@5.0.1:
1319 + resolution: {integrity: sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q==}
1320 +
1321 + hast-util-from-html-isomorphic@2.0.0:
1322 + resolution: {integrity: sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==}
1323 +
1324 + hast-util-from-html@2.0.3:
1325 + resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==}
1326 +
1327 + hast-util-from-parse5@8.0.3:
1328 + resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==}
1329 +
1330 + hast-util-is-element@3.0.0:
1331 + resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==}
1332 +
1333 + hast-util-parse-selector@4.0.0:
1334 + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==}
1335 +
1336 + hast-util-raw@9.1.0:
1337 + resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==}
1338 +
1339 + hast-util-to-estree@3.1.3:
1340 + resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==}
1341 +
1342 + hast-util-to-html@9.0.5:
1343 + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==}
1344 +
1345 + hast-util-to-jsx-runtime@2.3.6:
1346 + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==}
1347 +
1348 + hast-util-to-parse5@8.0.0:
1349 + resolution: {integrity: sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==}
1350 +
1351 + hast-util-to-text@4.0.2:
1352 + resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==}
1353 +
1354 + hast-util-whitespace@3.0.0:
1355 + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
1356 +
1357 + hastscript@9.0.1:
1358 + resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==}
1359 +
1360 + html-escaper@3.0.3:
1361 + resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==}
1362 +
1363 + html-void-elements@3.0.0:
1364 + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
1365 +
1366 + http-cache-semantics@4.2.0:
1367 + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==}
1368 +
1369 + ignore@5.3.2:
1370 + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
1371 + engines: {node: '>= 4'}
1372 +
1373 + ignore@7.0.5:
1374 + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==}
1375 + engines: {node: '>= 4'}
1376 +
1377 + import-fresh@3.3.1:
1378 + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==}
1379 + engines: {node: '>=6'}
1380 +
1381 + import-meta-resolve@4.1.0:
1382 + resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==}
1383 +
1384 + imurmurhash@0.1.4:
1385 + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
1386 + engines: {node: '>=0.8.19'}
1387 +
1388 + inline-style-parser@0.2.4:
1389 + resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==}
1390 +
1391 + iron-webcrypto@1.2.1:
1392 + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==}
1393 +
1394 + is-alphabetical@2.0.1:
1395 + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==}
1396 +
1397 + is-alphanumerical@2.0.1:
1398 + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==}
1399 +
1400 + is-arrayish@0.3.2:
1401 + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
1402 +
1403 + is-decimal@2.0.1:
1404 + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==}
1405 +
1406 + is-docker@3.0.0:
1407 + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==}
1408 + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
1409 + hasBin: true
1410 +
1411 + is-extglob@2.1.1:
1412 + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
1413 + engines: {node: '>=0.10.0'}
1414 +
1415 + is-fullwidth-code-point@3.0.0:
1416 + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
1417 + engines: {node: '>=8'}
1418 +
1419 + is-glob@4.0.3:
1420 + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
1421 + engines: {node: '>=0.10.0'}
1422 +
1423 + is-hexadecimal@2.0.1:
1424 + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==}
1425 +
1426 + is-inside-container@1.0.0:
1427 + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==}
1428 + engines: {node: '>=14.16'}
1429 + hasBin: true
1430 +
1431 + is-number@7.0.0:
1432 + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
1433 + engines: {node: '>=0.12.0'}
1434 +
1435 + is-plain-obj@4.1.0:
1436 + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
1437 + engines: {node: '>=12'}
1438 +
1439 + is-wsl@3.1.0:
1440 + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==}
1441 + engines: {node: '>=16'}
1442 +
1443 + isexe@2.0.0:
1444 + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
1445 +
1446 + js-yaml@4.1.0:
1447 + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
1448 + hasBin: true
1449 +
1450 + json-buffer@3.0.1:
1451 + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
1452 +
1453 + json-schema-traverse@0.4.1:
1454 + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
1455 +
1456 + json-stable-stringify-without-jsonify@1.0.1:
1457 + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
1458 +
1459 + katex@0.16.22:
1460 + resolution: {integrity: sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==}
1461 + hasBin: true
1462 +
1463 + keyv@4.5.4:
1464 + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
1465 +
1466 + kleur@3.0.3:
1467 + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
1468 + engines: {node: '>=6'}
1469 +
1470 + kleur@4.1.5:
1471 + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
1472 + engines: {node: '>=6'}
1473 +
1474 + levn@0.4.1:
1475 + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
1476 + engines: {node: '>= 0.8.0'}
1477 +
1478 + locate-path@6.0.0:
1479 + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
1480 + engines: {node: '>=10'}
1481 +
1482 + lodash.merge@4.6.2:
1483 + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
1484 +
1485 + longest-streak@3.1.0:
1486 + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
1487 +
1488 + lru-cache@10.4.3:
1489 + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
1490 +
1491 + magic-string@0.30.17:
1492 + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
1493 +
1494 + magicast@0.3.5:
1495 + resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==}
1496 +
1497 + markdown-extensions@2.0.0:
1498 + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==}
1499 + engines: {node: '>=16'}
1500 +
1501 + markdown-table@3.0.4:
1502 + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
1503 +
1504 + mdast-util-definitions@6.0.0:
1505 + resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==}
1506 +
1507 + mdast-util-directive@3.1.0:
1508 + resolution: {integrity: sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==}
1509 +
1510 + mdast-util-find-and-replace@3.0.2:
1511 + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==}
1512 +
1513 + mdast-util-from-markdown@2.0.2:
1514 + resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==}
1515 +
1516 + mdast-util-gfm-autolink-literal@2.0.1:
1517 + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==}
1518 +
1519 + mdast-util-gfm-footnote@2.1.0:
1520 + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==}
1521 +
1522 + mdast-util-gfm-strikethrough@2.0.0:
1523 + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==}
1524 +
1525 + mdast-util-gfm-table@2.0.0:
1526 + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==}
1527 +
1528 + mdast-util-gfm-task-list-item@2.0.0:
1529 + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==}
1530 +
1531 + mdast-util-gfm@3.1.0:
1532 + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==}
1533 +
1534 + mdast-util-math@3.0.0:
1535 + resolution: {integrity: sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==}
1536 +
1537 + mdast-util-mdx-expression@2.0.1:
1538 + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==}
1539 +
1540 + mdast-util-mdx-jsx@3.2.0:
1541 + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==}
1542 +
1543 + mdast-util-mdx@3.0.0:
1544 + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==}
1545 +
1546 + mdast-util-mdxjs-esm@2.0.1:
1547 + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==}
1548 +
1549 + mdast-util-phrasing@4.1.0:
1550 + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==}
1551 +
1552 + mdast-util-to-hast@13.2.0:
1553 + resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==}
1554 +
1555 + mdast-util-to-markdown@2.1.2:
1556 + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==}
1557 +
1558 + mdast-util-to-string@4.0.0:
1559 + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==}
1560 +
1561 + mdn-data@2.12.2:
1562 + resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==}
1563 +
1564 + merge2@1.4.1:
1565 + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
1566 + engines: {node: '>= 8'}
1567 +
1568 + micromark-core-commonmark@2.0.3:
1569 + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==}
1570 +
1571 + micromark-extension-directive@4.0.0:
1572 + resolution: {integrity: sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==}
1573 +
1574 + micromark-extension-gfm-autolink-literal@2.1.0:
1575 + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==}
1576 +
1577 + micromark-extension-gfm-footnote@2.1.0:
1578 + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==}
1579 +
1580 + micromark-extension-gfm-strikethrough@2.1.0:
1581 + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==}
1582 +
1583 + micromark-extension-gfm-table@2.1.1:
1584 + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==}
1585 +
1586 + micromark-extension-gfm-tagfilter@2.0.0:
1587 + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==}
1588 +
1589 + micromark-extension-gfm-task-list-item@2.1.0:
1590 + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==}
1591 +
1592 + micromark-extension-gfm@3.0.0:
1593 + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==}
1594 +
1595 + micromark-extension-math@3.1.0:
1596 + resolution: {integrity: sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==}
1597 +
1598 + micromark-extension-mdx-expression@3.0.1:
1599 + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==}
1600 +
1601 + micromark-extension-mdx-jsx@3.0.2:
1602 + resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==}
1603 +
1604 + micromark-extension-mdx-md@2.0.0:
1605 + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==}
1606 +
1607 + micromark-extension-mdxjs-esm@3.0.0:
1608 + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==}
1609 +
1610 + micromark-extension-mdxjs@3.0.0:
1611 + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==}
1612 +
1613 + micromark-factory-destination@2.0.1:
1614 + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==}
1615 +
1616 + micromark-factory-label@2.0.1:
1617 + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==}
1618 +
1619 + micromark-factory-mdx-expression@2.0.3:
1620 + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==}
1621 +
1622 + micromark-factory-space@2.0.1:
1623 + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==}
1624 +
1625 + micromark-factory-title@2.0.1:
1626 + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==}
1627 +
1628 + micromark-factory-whitespace@2.0.1:
1629 + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==}
1630 +
1631 + micromark-util-character@2.1.1:
1632 + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==}
1633 +
1634 + micromark-util-chunked@2.0.1:
1635 + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==}
1636 +
1637 + micromark-util-classify-character@2.0.1:
1638 + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==}
1639 +
1640 + micromark-util-combine-extensions@2.0.1:
1641 + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==}
1642 +
1643 + micromark-util-decode-numeric-character-reference@2.0.2:
1644 + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==}
1645 +
1646 + micromark-util-decode-string@2.0.1:
1647 + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==}
1648 +
1649 + micromark-util-encode@2.0.1:
1650 + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==}
1651 +
1652 + micromark-util-events-to-acorn@2.0.3:
1653 + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==}
1654 +
1655 + micromark-util-html-tag-name@2.0.1:
1656 + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==}
1657 +
1658 + micromark-util-normalize-identifier@2.0.1:
1659 + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==}
1660 +
1661 + micromark-util-resolve-all@2.0.1:
1662 + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==}
1663 +
1664 + micromark-util-sanitize-uri@2.0.1:
1665 + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==}
1666 +
1667 + micromark-util-subtokenize@2.1.0:
1668 + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==}
1669 +
1670 + micromark-util-symbol@2.0.1:
1671 + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==}
1672 +
1673 + micromark-util-types@2.0.2:
1674 + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==}
1675 +
1676 + micromark@4.0.2:
1677 + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==}
1678 +
1679 + micromatch@4.0.8:
1680 + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
1681 + engines: {node: '>=8.6'}
1682 +
1683 + minimatch@3.1.2:
1684 + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
1685 +
1686 + minimatch@9.0.5:
1687 + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
1688 + engines: {node: '>=16 || 14 >=14.17'}
1689 +
1690 + mrmime@2.0.1:
1691 + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==}
1692 + engines: {node: '>=10'}
1693 +
1694 + ms@2.1.3:
1695 + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
1696 +
1697 + nanoid@3.3.11:
1698 + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
1699 + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
1700 + hasBin: true
1701 +
1702 + natural-compare@1.4.0:
1703 + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
1704 +
1705 + neotraverse@0.6.18:
1706 + resolution: {integrity: sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==}
1707 + engines: {node: '>= 10'}
1708 +
1709 + nlcst-to-string@4.0.0:
1710 + resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==}
1711 +
1712 + node-fetch-native@1.6.6:
1713 + resolution: {integrity: sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==}
1714 +
1715 + node-fetch@2.7.0:
1716 + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
1717 + engines: {node: 4.x || >=6.0.0}
1718 + peerDependencies:
1719 + encoding: ^0.1.0
1720 + peerDependenciesMeta:
1721 + encoding:
1722 + optional: true
1723 +
1724 + node-mock-http@1.0.1:
1725 + resolution: {integrity: sha512-0gJJgENizp4ghds/Ywu2FCmcRsgBTmRQzYPZm61wy+Em2sBarSka0OhQS5huLBg6od1zkNpnWMCZloQDFVvOMQ==}
1726 +
1727 + normalize-path@3.0.0:
1728 + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
1729 + engines: {node: '>=0.10.0'}
1730 +
1731 + ofetch@1.4.1:
1732 + resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==}
1733 +
1734 + ohash@2.0.11:
1735 + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==}
1736 +
1737 + oniguruma-parser@0.12.1:
1738 + resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==}
1739 +
1740 + oniguruma-to-es@4.3.3:
1741 + resolution: {integrity: sha512-rPiZhzC3wXwE59YQMRDodUwwT9FZ9nNBwQQfsd1wfdtlKEyCdRV0avrTcSZ5xlIvGRVPd/cx6ZN45ECmS39xvg==}
1742 +
1743 + optionator@0.9.4:
1744 + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
1745 + engines: {node: '>= 0.8.0'}
1746 +
1747 + p-limit@3.1.0:
1748 + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
1749 + engines: {node: '>=10'}
1750 +
1751 + p-limit@6.2.0:
1752 + resolution: {integrity: sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==}
1753 + engines: {node: '>=18'}
1754 +
1755 + p-locate@5.0.0:
1756 + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
1757 + engines: {node: '>=10'}
1758 +
1759 + p-queue@8.1.0:
1760 + resolution: {integrity: sha512-mxLDbbGIBEXTJL0zEx8JIylaj3xQ7Z/7eEVjcF9fJX4DBiH9oqe+oahYnlKKxm0Ci9TlWTyhSHgygxMxjIB2jw==}
1761 + engines: {node: '>=18'}
1762 +
1763 + p-timeout@6.1.4:
1764 + resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==}
1765 + engines: {node: '>=14.16'}
1766 +
1767 + package-manager-detector@1.3.0:
1768 + resolution: {integrity: sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==}
1769 +
1770 + pako@0.2.9:
1771 + resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==}
1772 +
1773 + parent-module@1.0.1:
1774 + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
1775 + engines: {node: '>=6'}
1776 +
1777 + parse-entities@4.0.2:
1778 + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==}
1779 +
1780 + parse-latin@7.0.0:
1781 + resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==}
1782 +
1783 + parse5@7.3.0:
1784 + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==}
1785 +
1786 + path-exists@4.0.0:
1787 + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
1788 + engines: {node: '>=8'}
1789 +
1790 + path-key@3.1.1:
1791 + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
1792 + engines: {node: '>=8'}
1793 +
1794 + picocolors@1.1.1:
1795 + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
1796 +
1797 + picomatch@2.3.1:
1798 + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
1799 + engines: {node: '>=8.6'}
1800 +
1801 + picomatch@4.0.2:
1802 + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==}
1803 + engines: {node: '>=12'}
1804 +
1805 + postcss-selector-parser@7.1.0:
1806 + resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==}
1807 + engines: {node: '>=4'}
1808 +
1809 + postcss@8.5.6:
1810 + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
1811 + engines: {node: ^10 || ^12 || >=14}
1812 +
1813 + prelude-ls@1.2.1:
1814 + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
1815 + engines: {node: '>= 0.8.0'}
1816 +
1817 + prettier-plugin-astro@0.14.1:
1818 + resolution: {integrity: sha512-RiBETaaP9veVstE4vUwSIcdATj6dKmXljouXc/DDNwBSPTp8FRkLGDSGFClKsAFeeg+13SB0Z1JZvbD76bigJw==}
1819 + engines: {node: ^14.15.0 || >=16.0.0}
1820 +
1821 + prettier@3.6.2:
1822 + resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==}
1823 + engines: {node: '>=14'}
1824 + hasBin: true
1825 +
1826 + prismjs@1.30.0:
1827 + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==}
1828 + engines: {node: '>=6'}
1829 +
1830 + prompts@2.4.2:
1831 + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==}
1832 + engines: {node: '>= 6'}
1833 +
1834 + property-information@6.5.0:
1835 + resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==}
1836 +
1837 + property-information@7.1.0:
1838 + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==}
1839 +
1840 + punycode@2.3.1:
1841 + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
1842 + engines: {node: '>=6'}
1843 +
1844 + queue-microtask@1.2.3:
1845 + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
1846 +
1847 + radix3@1.1.2:
1848 + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==}
1849 +
1850 + readdirp@4.1.2:
1851 + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
1852 + engines: {node: '>= 14.18.0'}
1853 +
1854 + reading-time@1.5.0:
1855 + resolution: {integrity: sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==}
1856 +
1857 + recma-build-jsx@1.0.0:
1858 + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==}
1859 +
1860 + recma-jsx@1.0.0:
1861 + resolution: {integrity: sha512-5vwkv65qWwYxg+Atz95acp8DMu1JDSqdGkA2Of1j6rCreyFUE/gp15fC8MnGEuG1W68UKjM6x6+YTWIh7hZM/Q==}
1862 +
1863 + recma-parse@1.0.0:
1864 + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==}
1865 +
1866 + recma-stringify@1.0.0:
1867 + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==}
1868 +
1869 + regex-recursion@6.0.2:
1870 + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==}
1871 +
1872 + regex-utilities@2.3.0:
1873 + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==}
1874 +
1875 + regex@6.0.1:
1876 + resolution: {integrity: sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==}
1877 +
1878 + rehype-katex@7.0.1:
1879 + resolution: {integrity: sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==}
1880 +
1881 + rehype-parse@9.0.1:
1882 + resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==}
1883 +
1884 + rehype-raw@7.0.0:
1885 + resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==}
1886 +
1887 + rehype-recma@1.0.0:
1888 + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==}
1889 +
1890 + rehype-stringify@10.0.1:
1891 + resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==}
1892 +
1893 + rehype@13.0.2:
1894 + resolution: {integrity: sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==}
1895 +
1896 + remark-directive@4.0.0:
1897 + resolution: {integrity: sha512-7sxn4RfF1o3izevPV1DheyGDD6X4c9hrGpfdUpm7uC++dqrnJxIZVkk7CoKqcLm0VUMAuOol7Mno3m6g8cfMuA==}
1898 +
1899 + remark-gfm@4.0.1:
1900 + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==}
1901 +
1902 + remark-math@6.0.0:
1903 + resolution: {integrity: sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==}
1904 +
1905 + remark-mdx@3.1.0:
1906 + resolution: {integrity: sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA==}
1907 +
1908 + remark-parse@11.0.0:
1909 + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==}
1910 +
1911 + remark-rehype@11.1.2:
1912 + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==}
1913 +
1914 + remark-smartypants@3.0.2:
1915 + resolution: {integrity: sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==}
1916 + engines: {node: '>=16.0.0'}
1917 +
1918 + remark-stringify@11.0.0:
1919 + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
1920 +
1921 + resolve-from@4.0.0:
1922 + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
1923 + engines: {node: '>=4'}
1924 +
1925 + resolve-pkg-maps@1.0.0:
1926 + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
1927 +
1928 + restructure@3.0.2:
1929 + resolution: {integrity: sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw==}
1930 +
1931 + retext-latin@4.0.0:
1932 + resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==}
1933 +
1934 + retext-smartypants@6.2.0:
1935 + resolution: {integrity: sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==}
1936 +
1937 + retext-stringify@4.0.0:
1938 + resolution: {integrity: sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==}
1939 +
1940 + retext@9.0.0:
1941 + resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==}
1942 +
1943 + reusify@1.1.0:
1944 + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
1945 + engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
1946 +
1947 + rollup@4.44.1:
1948 + resolution: {integrity: sha512-x8H8aPvD+xbl0Do8oez5f5o8eMS3trfCghc4HhLAnCkj7Vl0d1JWGs0UF/D886zLW2rOj2QymV/JcSSsw+XDNg==}
1949 + engines: {node: '>=18.0.0', npm: '>=8.0.0'}
1950 + hasBin: true
1951 +
1952 + run-parallel@1.2.0:
1953 + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
1954 +
1955 + s.color@0.0.15:
1956 + resolution: {integrity: sha512-AUNrbEUHeKY8XsYr/DYpl+qk5+aM+DChopnWOPEzn8YKzOhv4l2zH6LzZms3tOZP3wwdOyc0RmTciyi46HLIuA==}
1957 +
1958 + sass-formatter@0.7.9:
1959 + resolution: {integrity: sha512-CWZ8XiSim+fJVG0cFLStwDvft1VI7uvXdCNJYXhDvowiv+DsbD1nXLiQ4zrE5UBvj5DWZJ93cwN0NX5PMsr1Pw==}
1960 +
1961 + sax@1.4.1:
1962 + resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==}
1963 +
1964 + semver@7.7.2:
1965 + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==}
1966 + engines: {node: '>=10'}
1967 + hasBin: true
1968 +
1969 + sharp@0.33.5:
1970 + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==}
1971 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
1972 +
1973 + sharp@0.34.2:
1974 + resolution: {integrity: sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==}
1975 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
1976 +
1977 + shebang-command@2.0.0:
1978 + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
1979 + engines: {node: '>=8'}
1980 +
1981 + shebang-regex@3.0.0:
1982 + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
1983 + engines: {node: '>=8'}
1984 +
1985 + shiki@3.7.0:
1986 + resolution: {integrity: sha512-ZcI4UT9n6N2pDuM2n3Jbk0sR4Swzq43nLPgS/4h0E3B/NrFn2HKElrDtceSf8Zx/OWYOo7G1SAtBLypCp+YXqg==}
1987 +
1988 + simple-swizzle@0.2.2:
1989 + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
1990 +
1991 + sisteransi@1.0.5:
1992 + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
1993 +
1994 + sitemap@8.0.0:
1995 + resolution: {integrity: sha512-+AbdxhM9kJsHtruUF39bwS/B0Fytw6Fr1o4ZAIAEqA6cke2xcoO2GleBw9Zw7nRzILVEgz7zBM5GiTJjie1G9A==}
1996 + engines: {node: '>=14.0.0', npm: '>=6.0.0'}
1997 + hasBin: true
1998 +
1999 + smol-toml@1.4.1:
2000 + resolution: {integrity: sha512-CxdwHXyYTONGHThDbq5XdwbFsuY4wlClRGejfE2NtwUtiHYsP1QtNsHb/hnj31jKYSchztJsaA8pSQoVzkfCFg==}
2001 + engines: {node: '>= 18'}
2002 +
2003 + source-map-js@1.2.1:
2004 + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
2005 + engines: {node: '>=0.10.0'}
2006 +
2007 + source-map@0.7.4:
2008 + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==}
2009 + engines: {node: '>= 8'}
2010 +
2011 + space-separated-tokens@2.0.2:
2012 + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
2013 +
2014 + stream-replace-string@2.0.0:
2015 + resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==}
2016 +
2017 + string-width@4.2.3:
2018 + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
2019 + engines: {node: '>=8'}
2020 +
2021 + string-width@7.2.0:
2022 + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==}
2023 + engines: {node: '>=18'}
2024 +
2025 + stringify-entities@4.0.4:
2026 + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==}
2027 +
2028 + strip-ansi@6.0.1:
2029 + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
2030 + engines: {node: '>=8'}
2031 +
2032 + strip-ansi@7.1.0:
2033 + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
2034 + engines: {node: '>=12'}
2035 +
2036 + strip-json-comments@3.1.1:
2037 + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
2038 + engines: {node: '>=8'}
2039 +
2040 + style-to-js@1.1.17:
2041 + resolution: {integrity: sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA==}
2042 +
2043 + style-to-object@1.0.9:
2044 + resolution: {integrity: sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw==}
2045 +
2046 + suf-log@2.5.3:
2047 + resolution: {integrity: sha512-KvC8OPjzdNOe+xQ4XWJV2whQA0aM1kGVczMQ8+dStAO6KfEB140JEVQ9dE76ONZ0/Ylf67ni4tILPJB41U0eow==}
2048 +
2049 + supports-color@7.2.0:
2050 + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
2051 + engines: {node: '>=8'}
2052 +
2053 + synckit@0.11.8:
2054 + resolution: {integrity: sha512-+XZ+r1XGIJGeQk3VvXhT6xx/VpbHsRzsTkGgF6E5RX9TTXD0118l87puaEBZ566FhqblC6U0d4XnubznJDm30A==}
2055 + engines: {node: ^14.18.0 || >=16.0.0}
2056 +
2057 + tiny-inflate@1.0.3:
2058 + resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==}
2059 +
2060 + tinyexec@0.3.2:
2061 + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
2062 +
2063 + tinyglobby@0.2.14:
2064 + resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==}
2065 + engines: {node: '>=12.0.0'}
2066 +
2067 + to-regex-range@5.0.1:
2068 + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
2069 + engines: {node: '>=8.0'}
2070 +
2071 + tr46@0.0.3:
2072 + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
2073 +
2074 + trim-lines@3.0.1:
2075 + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
2076 +
2077 + trough@2.2.0:
2078 + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==}
2079 +
2080 + ts-api-utils@2.1.0:
2081 + resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==}
2082 + engines: {node: '>=18.12'}
2083 + peerDependencies:
2084 + typescript: '>=4.8.4'
2085 +
2086 + tsconfck@3.1.6:
2087 + resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==}
2088 + engines: {node: ^18 || >=20}
2089 + hasBin: true
2090 + peerDependencies:
2091 + typescript: ^5.0.0
2092 + peerDependenciesMeta:
2093 + typescript:
2094 + optional: true
2095 +
2096 + tslib@2.8.1:
2097 + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
2098 +
2099 + tsx@4.20.3:
2100 + resolution: {integrity: sha512-qjbnuR9Tr+FJOMBqJCW5ehvIo/buZq7vH7qD7JziU98h6l3qGy0a/yPFjwO+y0/T7GFpNgNAvEcPPVfyT8rrPQ==}
2101 + engines: {node: '>=18.0.0'}
2102 + hasBin: true
2103 +
2104 + type-check@0.4.0:
2105 + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
2106 + engines: {node: '>= 0.8.0'}
2107 +
2108 + type-fest@4.41.0:
2109 + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==}
2110 + engines: {node: '>=16'}
2111 +
2112 + typescript-eslint@8.35.1:
2113 + resolution: {integrity: sha512-xslJjFzhOmHYQzSB/QTeASAHbjmxOGEP6Coh93TXmUBFQoJ1VU35UHIDmG06Jd6taf3wqqC1ntBnCMeymy5Ovw==}
2114 + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
2115 + peerDependencies:
2116 + eslint: ^8.57.0 || ^9.0.0
2117 + typescript: '>=4.8.4 <5.9.0'
2118 +
2119 + typescript@5.8.3:
2120 + resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==}
2121 + engines: {node: '>=14.17'}
2122 + hasBin: true
2123 +
2124 + ufo@1.6.1:
2125 + resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==}
2126 +
2127 + ultrahtml@1.6.0:
2128 + resolution: {integrity: sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==}
2129 +
2130 + uncrypto@0.1.3:
2131 + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==}
2132 +
2133 + undici-types@7.8.0:
2134 + resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==}
2135 +
2136 + unicode-properties@1.4.1:
2137 + resolution: {integrity: sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==}
2138 +
2139 + unicode-trie@2.0.0:
2140 + resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==}
2141 +
2142 + unified@11.0.5:
2143 + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==}
2144 +
2145 + unifont@0.5.2:
2146 + resolution: {integrity: sha512-LzR4WUqzH9ILFvjLAUU7dK3Lnou/qd5kD+IakBtBK4S15/+x2y9VX+DcWQv6s551R6W+vzwgVS6tFg3XggGBgg==}
2147 +
2148 + unist-util-find-after@5.0.0:
2149 + resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==}
2150 +
2151 + unist-util-is@6.0.0:
2152 + resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==}
2153 +
2154 + unist-util-modify-children@4.0.0:
2155 + resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==}
2156 +
2157 + unist-util-position-from-estree@2.0.0:
2158 + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==}
2159 +
2160 + unist-util-position@5.0.0:
2161 + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==}
2162 +
2163 + unist-util-remove-position@5.0.0:
2164 + resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==}
2165 +
2166 + unist-util-stringify-position@4.0.0:
2167 + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==}
2168 +
2169 + unist-util-visit-children@3.0.0:
2170 + resolution: {integrity: sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==}
2171 +
2172 + unist-util-visit-parents@6.0.1:
2173 + resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==}
2174 +
2175 + unist-util-visit@5.0.0:
2176 + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==}
2177 +
2178 + unstorage@1.16.0:
2179 + resolution: {integrity: sha512-WQ37/H5A7LcRPWfYOrDa1Ys02xAbpPJq6q5GkO88FBXVSQzHd7+BjEwfRqyaSWCv9MbsJy058GWjjPjcJ16GGA==}
2180 + peerDependencies:
2181 + '@azure/app-configuration': ^1.8.0
2182 + '@azure/cosmos': ^4.2.0
2183 + '@azure/data-tables': ^13.3.0
2184 + '@azure/identity': ^4.6.0
2185 + '@azure/keyvault-secrets': ^4.9.0
2186 + '@azure/storage-blob': ^12.26.0
2187 + '@capacitor/preferences': ^6.0.3 || ^7.0.0
2188 + '@deno/kv': '>=0.9.0'
2189 + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0
2190 + '@planetscale/database': ^1.19.0
2191 + '@upstash/redis': ^1.34.3
2192 + '@vercel/blob': '>=0.27.1'
2193 + '@vercel/kv': ^1.0.1
2194 + aws4fetch: ^1.0.20
2195 + db0: '>=0.2.1'
2196 + idb-keyval: ^6.2.1
2197 + ioredis: ^5.4.2
2198 + uploadthing: ^7.4.4
2199 + peerDependenciesMeta:
2200 + '@azure/app-configuration':
2201 + optional: true
2202 + '@azure/cosmos':
2203 + optional: true
2204 + '@azure/data-tables':
2205 + optional: true
2206 + '@azure/identity':
2207 + optional: true
2208 + '@azure/keyvault-secrets':
2209 + optional: true
2210 + '@azure/storage-blob':
2211 + optional: true
2212 + '@capacitor/preferences':
2213 + optional: true
2214 + '@deno/kv':
2215 + optional: true
2216 + '@netlify/blobs':
2217 + optional: true
2218 + '@planetscale/database':
2219 + optional: true
2220 + '@upstash/redis':
2221 + optional: true
2222 + '@vercel/blob':
2223 + optional: true
2224 + '@vercel/kv':
2225 + optional: true
2226 + aws4fetch:
2227 + optional: true
2228 + db0:
2229 + optional: true
2230 + idb-keyval:
2231 + optional: true
2232 + ioredis:
2233 + optional: true
2234 + uploadthing:
2235 + optional: true
2236 +
2237 + uri-js@4.4.1:
2238 + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
2239 +
2240 + util-deprecate@1.0.2:
2241 + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
2242 +
2243 + vfile-location@5.0.3:
2244 + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==}
2245 +
2246 + vfile-message@4.0.2:
2247 + resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==}
2248 +
2249 + vfile@6.0.3:
2250 + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
2251 +
2252 + vite@6.3.5:
2253 + resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==}
2254 + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
2255 + hasBin: true
2256 + peerDependencies:
2257 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
2258 + jiti: '>=1.21.0'
2259 + less: '*'
2260 + lightningcss: ^1.21.0
2261 + sass: '*'
2262 + sass-embedded: '*'
2263 + stylus: '*'
2264 + sugarss: '*'
2265 + terser: ^5.16.0
2266 + tsx: ^4.8.1
2267 + yaml: ^2.4.2
2268 + peerDependenciesMeta:
2269 + '@types/node':
2270 + optional: true
2271 + jiti:
2272 + optional: true
2273 + less:
2274 + optional: true
2275 + lightningcss:
2276 + optional: true
2277 + sass:
2278 + optional: true
2279 + sass-embedded:
2280 + optional: true
2281 + stylus:
2282 + optional: true
2283 + sugarss:
2284 + optional: true
2285 + terser:
2286 + optional: true
2287 + tsx:
2288 + optional: true
2289 + yaml:
2290 + optional: true
2291 +
2292 + vitefu@1.1.0:
2293 + resolution: {integrity: sha512-AiG/L9DVsEYHWQ9jAEnke0nKiASlPw+JYwDl6Z4l6a6/IqT1tKseEl6R5+rVnKJt/K3jCTWiQvgoIh5MuqBJJQ==}
2294 + peerDependencies:
2295 + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0
2296 + peerDependenciesMeta:
2297 + vite:
2298 + optional: true
2299 +
2300 + web-namespaces@2.0.1:
2301 + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
2302 +
2303 + webidl-conversions@3.0.1:
2304 + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
2305 +
2306 + whatwg-url@5.0.0:
2307 + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
2308 +
2309 + which-pm-runs@1.1.0:
2310 + resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==}
2311 + engines: {node: '>=4'}
2312 +
2313 + which@2.0.2:
2314 + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
2315 + engines: {node: '>= 8'}
2316 + hasBin: true
2317 +
2318 + widest-line@5.0.0:
2319 + resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==}
2320 + engines: {node: '>=18'}
2321 +
2322 + word-wrap@1.2.5:
2323 + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
2324 + engines: {node: '>=0.10.0'}
2325 +
2326 + wrap-ansi@9.0.0:
2327 + resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==}
2328 + engines: {node: '>=18'}
2329 +
2330 + xxhash-wasm@1.1.0:
2331 + resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==}
2332 +
2333 + yargs-parser@21.1.1:
2334 + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
2335 + engines: {node: '>=12'}
2336 +
2337 + yocto-queue@0.1.0:
2338 + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
2339 + engines: {node: '>=10'}
2340 +
2341 + yocto-queue@1.2.1:
2342 + resolution: {integrity: sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==}
2343 + engines: {node: '>=12.20'}
2344 +
2345 + yocto-spinner@0.2.3:
2346 + resolution: {integrity: sha512-sqBChb33loEnkoXte1bLg45bEBsOP9N1kzQh5JZNKj/0rik4zAPTNSAVPj3uQAdc6slYJ0Ksc403G2XgxsJQFQ==}
2347 + engines: {node: '>=18.19'}
2348 +
2349 + yoctocolors@2.1.1:
2350 + resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==}
2351 + engines: {node: '>=18'}
2352 +
2353 + zod-to-json-schema@3.24.6:
2354 + resolution: {integrity: sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==}
2355 + peerDependencies:
2356 + zod: ^3.24.1
2357 +
2358 + zod-to-ts@1.2.0:
2359 + resolution: {integrity: sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==}
2360 + peerDependencies:
2361 + typescript: ^4.9.4 || ^5.0.2
2362 + zod: ^3
2363 +
2364 + zod@3.25.73:
2365 + resolution: {integrity: sha512-fuIKbQAWQl22Ba5d1quwEETQYjqnpKVyZIWAhbnnHgnDd3a+z4YgEfkI5SZ2xMELnLAXo/Flk2uXgysZNf0uaA==}
2366 +
2367 + zwitch@2.0.4:
2368 + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
2369 +
2370 +snapshots:
2371 +
2372 + '@astrojs/compiler@2.12.2': {}
2373 +
2374 + '@astrojs/internal-helpers@0.6.1': {}
2375 +
2376 + '@astrojs/markdown-remark@6.3.2':
2377 + dependencies:
2378 + '@astrojs/internal-helpers': 0.6.1
2379 + '@astrojs/prism': 3.3.0
2380 + github-slugger: 2.0.0
2381 + hast-util-from-html: 2.0.3
2382 + hast-util-to-text: 4.0.2
2383 + import-meta-resolve: 4.1.0
2384 + js-yaml: 4.1.0
2385 + mdast-util-definitions: 6.0.0
2386 + rehype-raw: 7.0.0
2387 + rehype-stringify: 10.0.1
2388 + remark-gfm: 4.0.1
2389 + remark-parse: 11.0.0
2390 + remark-rehype: 11.1.2
2391 + remark-smartypants: 3.0.2
2392 + shiki: 3.7.0
2393 + smol-toml: 1.4.1
2394 + unified: 11.0.5
2395 + unist-util-remove-position: 5.0.0
2396 + unist-util-visit: 5.0.0
2397 + unist-util-visit-parents: 6.0.1
2398 + vfile: 6.0.3
2399 + transitivePeerDependencies:
2400 + - supports-color
2401 +
2402 + '@astrojs/mdx@4.3.0(astro@5.11.0(@types/node@24.0.10)(rollup@4.44.1)(tsx@4.20.3)(typescript@5.8.3))':
2403 + dependencies:
2404 + '@astrojs/markdown-remark': 6.3.2
2405 + '@mdx-js/mdx': 3.1.0(acorn@8.15.0)
2406 + acorn: 8.15.0
2407 + astro: 5.11.0(@types/node@24.0.10)(rollup@4.44.1)(tsx@4.20.3)(typescript@5.8.3)
2408 + es-module-lexer: 1.7.0
2409 + estree-util-visit: 2.0.0
2410 + hast-util-to-html: 9.0.5
2411 + kleur: 4.1.5
2412 + rehype-raw: 7.0.0
2413 + remark-gfm: 4.0.1
2414 + remark-smartypants: 3.0.2
2415 + source-map: 0.7.4
2416 + unist-util-visit: 5.0.0
2417 + vfile: 6.0.3
2418 + transitivePeerDependencies:
2419 + - supports-color
2420 +
2421 + '@astrojs/prism@3.3.0':
2422 + dependencies:
2423 + prismjs: 1.30.0
2424 +
2425 + '@astrojs/sitemap@3.4.1':
2426 + dependencies:
2427 + sitemap: 8.0.0
2428 + stream-replace-string: 2.0.0
2429 + zod: 3.25.73
2430 +
2431 + '@astrojs/telemetry@3.3.0':
2432 + dependencies:
2433 + ci-info: 4.2.0
2434 + debug: 4.4.1
2435 + dlv: 1.1.3
2436 + dset: 3.1.4
2437 + is-docker: 3.0.0
2438 + is-wsl: 3.1.0
2439 + which-pm-runs: 1.1.0
2440 + transitivePeerDependencies:
2441 + - supports-color
2442 +
2443 + '@babel/helper-string-parser@7.27.1': {}
2444 +
2445 + '@babel/helper-validator-identifier@7.27.1': {}
2446 +
2447 + '@babel/parser@7.28.0':
2448 + dependencies:
2449 + '@babel/types': 7.28.0
2450 +
2451 + '@babel/types@7.28.0':
2452 + dependencies:
2453 + '@babel/helper-string-parser': 7.27.1
2454 + '@babel/helper-validator-identifier': 7.27.1
2455 +
2456 + '@capsizecss/unpack@2.4.0':
2457 + dependencies:
2458 + blob-to-buffer: 1.2.9
2459 + cross-fetch: 3.2.0
2460 + fontkit: 2.0.4
2461 + transitivePeerDependencies:
2462 + - encoding
2463 +
2464 + '@emnapi/runtime@1.4.3':
2465 + dependencies:
2466 + tslib: 2.8.1
2467 + optional: true
2468 +
2469 + '@esbuild/aix-ppc64@0.25.5':
2470 + optional: true
2471 +
2472 + '@esbuild/android-arm64@0.25.5':
2473 + optional: true
2474 +
2475 + '@esbuild/android-arm@0.25.5':
2476 + optional: true
2477 +
2478 + '@esbuild/android-x64@0.25.5':
2479 + optional: true
2480 +
2481 + '@esbuild/darwin-arm64@0.25.5':
2482 + optional: true
2483 +
2484 + '@esbuild/darwin-x64@0.25.5':
2485 + optional: true
2486 +
2487 + '@esbuild/freebsd-arm64@0.25.5':
2488 + optional: true
2489 +
2490 + '@esbuild/freebsd-x64@0.25.5':
2491 + optional: true
2492 +
2493 + '@esbuild/linux-arm64@0.25.5':
2494 + optional: true
2495 +
2496 + '@esbuild/linux-arm@0.25.5':
2497 + optional: true
2498 +
2499 + '@esbuild/linux-ia32@0.25.5':
2500 + optional: true
2501 +
2502 + '@esbuild/linux-loong64@0.25.5':
2503 + optional: true
2504 +
2505 + '@esbuild/linux-mips64el@0.25.5':
2506 + optional: true
2507 +
2508 + '@esbuild/linux-ppc64@0.25.5':
2509 + optional: true
2510 +
2511 + '@esbuild/linux-riscv64@0.25.5':
2512 + optional: true
2513 +
2514 + '@esbuild/linux-s390x@0.25.5':
2515 + optional: true
2516 +
2517 + '@esbuild/linux-x64@0.25.5':
2518 + optional: true
2519 +
2520 + '@esbuild/netbsd-arm64@0.25.5':
2521 + optional: true
2522 +
2523 + '@esbuild/netbsd-x64@0.25.5':
2524 + optional: true
2525 +
2526 + '@esbuild/openbsd-arm64@0.25.5':
2527 + optional: true
2528 +
2529 + '@esbuild/openbsd-x64@0.25.5':
2530 + optional: true
2531 +
2532 + '@esbuild/sunos-x64@0.25.5':
2533 + optional: true
2534 +
2535 + '@esbuild/win32-arm64@0.25.5':
2536 + optional: true
2537 +
2538 + '@esbuild/win32-ia32@0.25.5':
2539 + optional: true
2540 +
2541 + '@esbuild/win32-x64@0.25.5':
2542 + optional: true
2543 +
2544 + '@eslint-community/eslint-utils@4.7.0(eslint@9.30.1)':
2545 + dependencies:
2546 + eslint: 9.30.1
2547 + eslint-visitor-keys: 3.4.3
2548 +
2549 + '@eslint-community/regexpp@4.12.1': {}
2550 +
2551 + '@eslint/config-array@0.21.0':
2552 + dependencies:
2553 + '@eslint/object-schema': 2.1.6
2554 + debug: 4.4.1
2555 + minimatch: 3.1.2
2556 + transitivePeerDependencies:
2557 + - supports-color
2558 +
2559 + '@eslint/config-helpers@0.3.0': {}
2560 +
2561 + '@eslint/core@0.14.0':
2562 + dependencies:
2563 + '@types/json-schema': 7.0.15
2564 +
2565 + '@eslint/core@0.15.1':
2566 + dependencies:
2567 + '@types/json-schema': 7.0.15
2568 +
2569 + '@eslint/eslintrc@3.3.1':
2570 + dependencies:
2571 + ajv: 6.12.6
2572 + debug: 4.4.1
2573 + espree: 10.4.0
2574 + globals: 14.0.0
2575 + ignore: 5.3.2
2576 + import-fresh: 3.3.1
2577 + js-yaml: 4.1.0
2578 + minimatch: 3.1.2
2579 + strip-json-comments: 3.1.1
2580 + transitivePeerDependencies:
2581 + - supports-color
2582 +
2583 + '@eslint/js@9.30.1': {}
2584 +
2585 + '@eslint/object-schema@2.1.6': {}
2586 +
2587 + '@eslint/plugin-kit@0.3.3':
2588 + dependencies:
2589 + '@eslint/core': 0.15.1
2590 + levn: 0.4.1
2591 +
2592 + '@humanfs/core@0.19.1': {}
2593 +
2594 + '@humanfs/node@0.16.6':
2595 + dependencies:
2596 + '@humanfs/core': 0.19.1
2597 + '@humanwhocodes/retry': 0.3.1
2598 +
2599 + '@humanwhocodes/module-importer@1.0.1': {}
2600 +
2601 + '@humanwhocodes/retry@0.3.1': {}
2602 +
2603 + '@humanwhocodes/retry@0.4.3': {}
2604 +
2605 + '@img/sharp-darwin-arm64@0.33.5':
2606 + optionalDependencies:
2607 + '@img/sharp-libvips-darwin-arm64': 1.0.4
2608 + optional: true
2609 +
2610 + '@img/sharp-darwin-arm64@0.34.2':
2611 + optionalDependencies:
2612 + '@img/sharp-libvips-darwin-arm64': 1.1.0
2613 + optional: true
2614 +
2615 + '@img/sharp-darwin-x64@0.33.5':
2616 + optionalDependencies:
2617 + '@img/sharp-libvips-darwin-x64': 1.0.4
2618 + optional: true
2619 +
2620 + '@img/sharp-darwin-x64@0.34.2':
2621 + optionalDependencies:
2622 + '@img/sharp-libvips-darwin-x64': 1.1.0
2623 + optional: true
2624 +
2625 + '@img/sharp-libvips-darwin-arm64@1.0.4':
2626 + optional: true
2627 +
2628 + '@img/sharp-libvips-darwin-arm64@1.1.0':
2629 + optional: true
2630 +
2631 + '@img/sharp-libvips-darwin-x64@1.0.4':
2632 + optional: true
2633 +
2634 + '@img/sharp-libvips-darwin-x64@1.1.0':
2635 + optional: true
2636 +
2637 + '@img/sharp-libvips-linux-arm64@1.0.4':
2638 + optional: true
2639 +
2640 + '@img/sharp-libvips-linux-arm64@1.1.0':
2641 + optional: true
2642 +
2643 + '@img/sharp-libvips-linux-arm@1.0.5':
2644 + optional: true
2645 +
2646 + '@img/sharp-libvips-linux-arm@1.1.0':
2647 + optional: true
2648 +
2649 + '@img/sharp-libvips-linux-ppc64@1.1.0':
2650 + optional: true
2651 +
2652 + '@img/sharp-libvips-linux-s390x@1.0.4':
2653 + optional: true
2654 +
2655 + '@img/sharp-libvips-linux-s390x@1.1.0':
2656 + optional: true
2657 +
2658 + '@img/sharp-libvips-linux-x64@1.0.4':
2659 + optional: true
2660 +
2661 + '@img/sharp-libvips-linux-x64@1.1.0':
2662 + optional: true
2663 +
2664 + '@img/sharp-libvips-linuxmusl-arm64@1.0.4':
2665 + optional: true
2666 +
2667 + '@img/sharp-libvips-linuxmusl-arm64@1.1.0':
2668 + optional: true
2669 +
2670 + '@img/sharp-libvips-linuxmusl-x64@1.0.4':
2671 + optional: true
2672 +
2673 + '@img/sharp-libvips-linuxmusl-x64@1.1.0':
2674 + optional: true
2675 +
2676 + '@img/sharp-linux-arm64@0.33.5':
2677 + optionalDependencies:
2678 + '@img/sharp-libvips-linux-arm64': 1.0.4
2679 + optional: true
2680 +
2681 + '@img/sharp-linux-arm64@0.34.2':
2682 + optionalDependencies:
2683 + '@img/sharp-libvips-linux-arm64': 1.1.0
2684 + optional: true
2685 +
2686 + '@img/sharp-linux-arm@0.33.5':
2687 + optionalDependencies:
2688 + '@img/sharp-libvips-linux-arm': 1.0.5
2689 + optional: true
2690 +
2691 + '@img/sharp-linux-arm@0.34.2':
2692 + optionalDependencies:
2693 + '@img/sharp-libvips-linux-arm': 1.1.0
2694 + optional: true
2695 +
2696 + '@img/sharp-linux-s390x@0.33.5':
2697 + optionalDependencies:
2698 + '@img/sharp-libvips-linux-s390x': 1.0.4
2699 + optional: true
2700 +
2701 + '@img/sharp-linux-s390x@0.34.2':
2702 + optionalDependencies:
2703 + '@img/sharp-libvips-linux-s390x': 1.1.0
2704 + optional: true
2705 +
2706 + '@img/sharp-linux-x64@0.33.5':
2707 + optionalDependencies:
2708 + '@img/sharp-libvips-linux-x64': 1.0.4
2709 + optional: true
2710 +
2711 + '@img/sharp-linux-x64@0.34.2':
2712 + optionalDependencies:
2713 + '@img/sharp-libvips-linux-x64': 1.1.0
2714 + optional: true
2715 +
2716 + '@img/sharp-linuxmusl-arm64@0.33.5':
2717 + optionalDependencies:
2718 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4
2719 + optional: true
2720 +
2721 + '@img/sharp-linuxmusl-arm64@0.34.2':
2722 + optionalDependencies:
2723 + '@img/sharp-libvips-linuxmusl-arm64': 1.1.0
2724 + optional: true
2725 +
2726 + '@img/sharp-linuxmusl-x64@0.33.5':
2727 + optionalDependencies:
2728 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4
2729 + optional: true
2730 +
2731 + '@img/sharp-linuxmusl-x64@0.34.2':
2732 + optionalDependencies:
2733 + '@img/sharp-libvips-linuxmusl-x64': 1.1.0
2734 + optional: true
2735 +
2736 + '@img/sharp-wasm32@0.33.5':
2737 + dependencies:
2738 + '@emnapi/runtime': 1.4.3
2739 + optional: true
2740 +
2741 + '@img/sharp-wasm32@0.34.2':
2742 + dependencies:
2743 + '@emnapi/runtime': 1.4.3
2744 + optional: true
2745 +
2746 + '@img/sharp-win32-arm64@0.34.2':
2747 + optional: true
2748 +
2749 + '@img/sharp-win32-ia32@0.33.5':
2750 + optional: true
2751 +
2752 + '@img/sharp-win32-ia32@0.34.2':
2753 + optional: true
2754 +
2755 + '@img/sharp-win32-x64@0.33.5':
2756 + optional: true
2757 +
2758 + '@img/sharp-win32-x64@0.34.2':
2759 + optional: true
2760 +
2761 + '@jridgewell/sourcemap-codec@1.5.4': {}
2762 +
2763 + '@mdx-js/mdx@3.1.0(acorn@8.15.0)':
2764 + dependencies:
2765 + '@types/estree': 1.0.8
2766 + '@types/estree-jsx': 1.0.5
2767 + '@types/hast': 3.0.4
2768 + '@types/mdx': 2.0.13
2769 + collapse-white-space: 2.1.0
2770 + devlop: 1.1.0
2771 + estree-util-is-identifier-name: 3.0.0
2772 + estree-util-scope: 1.0.0
2773 + estree-walker: 3.0.3
2774 + hast-util-to-jsx-runtime: 2.3.6
2775 + markdown-extensions: 2.0.0
2776 + recma-build-jsx: 1.0.0
2777 + recma-jsx: 1.0.0(acorn@8.15.0)
2778 + recma-stringify: 1.0.0
2779 + rehype-recma: 1.0.0
2780 + remark-mdx: 3.1.0
2781 + remark-parse: 11.0.0
2782 + remark-rehype: 11.1.2
2783 + source-map: 0.7.4
2784 + unified: 11.0.5
2785 + unist-util-position-from-estree: 2.0.0
2786 + unist-util-stringify-position: 4.0.0
2787 + unist-util-visit: 5.0.0
2788 + vfile: 6.0.3
2789 + transitivePeerDependencies:
2790 + - acorn
2791 + - supports-color
2792 +
2793 + '@nodelib/fs.scandir@2.1.5':
2794 + dependencies:
2795 + '@nodelib/fs.stat': 2.0.5
2796 + run-parallel: 1.2.0
2797 +
2798 + '@nodelib/fs.stat@2.0.5': {}
2799 +
2800 + '@nodelib/fs.walk@1.2.8':
2801 + dependencies:
2802 + '@nodelib/fs.scandir': 2.1.5
2803 + fastq: 1.19.1
2804 +
2805 + '@oslojs/encoding@1.1.0': {}
2806 +
2807 + '@pkgr/core@0.2.7': {}
2808 +
2809 + '@rollup/pluginutils@5.2.0(rollup@4.44.1)':
2810 + dependencies:
2811 + '@types/estree': 1.0.8
2812 + estree-walker: 2.0.2
2813 + picomatch: 4.0.2
2814 + optionalDependencies:
2815 + rollup: 4.44.1
2816 +
2817 + '@rollup/rollup-android-arm-eabi@4.44.1':
2818 + optional: true
2819 +
2820 + '@rollup/rollup-android-arm64@4.44.1':
2821 + optional: true
2822 +
2823 + '@rollup/rollup-darwin-arm64@4.44.1':
2824 + optional: true
2825 +
2826 + '@rollup/rollup-darwin-x64@4.44.1':
2827 + optional: true
2828 +
2829 + '@rollup/rollup-freebsd-arm64@4.44.1':
2830 + optional: true
2831 +
2832 + '@rollup/rollup-freebsd-x64@4.44.1':
2833 + optional: true
2834 +
2835 + '@rollup/rollup-linux-arm-gnueabihf@4.44.1':
2836 + optional: true
2837 +
2838 + '@rollup/rollup-linux-arm-musleabihf@4.44.1':
2839 + optional: true
2840 +
2841 + '@rollup/rollup-linux-arm64-gnu@4.44.1':
2842 + optional: true
2843 +
2844 + '@rollup/rollup-linux-arm64-musl@4.44.1':
2845 + optional: true
2846 +
2847 + '@rollup/rollup-linux-loongarch64-gnu@4.44.1':
2848 + optional: true
2849 +
2850 + '@rollup/rollup-linux-powerpc64le-gnu@4.44.1':
2851 + optional: true
2852 +
2853 + '@rollup/rollup-linux-riscv64-gnu@4.44.1':
2854 + optional: true
2855 +
2856 + '@rollup/rollup-linux-riscv64-musl@4.44.1':
2857 + optional: true
2858 +
2859 + '@rollup/rollup-linux-s390x-gnu@4.44.1':
2860 + optional: true
2861 +
2862 + '@rollup/rollup-linux-x64-gnu@4.44.1':
2863 + optional: true
2864 +
2865 + '@rollup/rollup-linux-x64-musl@4.44.1':
2866 + optional: true
2867 +
2868 + '@rollup/rollup-win32-arm64-msvc@4.44.1':
2869 + optional: true
2870 +
2871 + '@rollup/rollup-win32-ia32-msvc@4.44.1':
2872 + optional: true
2873 +
2874 + '@rollup/rollup-win32-x64-msvc@4.44.1':
2875 + optional: true
2876 +
2877 + '@shikijs/core@3.7.0':
2878 + dependencies:
2879 + '@shikijs/types': 3.7.0
2880 + '@shikijs/vscode-textmate': 10.0.2
2881 + '@types/hast': 3.0.4
2882 + hast-util-to-html: 9.0.5
2883 +
2884 + '@shikijs/engine-javascript@3.7.0':
2885 + dependencies:
2886 + '@shikijs/types': 3.7.0
2887 + '@shikijs/vscode-textmate': 10.0.2
2888 + oniguruma-to-es: 4.3.3
2889 +
2890 + '@shikijs/engine-oniguruma@3.7.0':
2891 + dependencies:
2892 + '@shikijs/types': 3.7.0
2893 + '@shikijs/vscode-textmate': 10.0.2
2894 +
2895 + '@shikijs/langs@3.7.0':
2896 + dependencies:
2897 + '@shikijs/types': 3.7.0
2898 +
2899 + '@shikijs/themes@3.7.0':
2900 + dependencies:
2901 + '@shikijs/types': 3.7.0
2902 +
2903 + '@shikijs/types@3.7.0':
2904 + dependencies:
2905 + '@shikijs/vscode-textmate': 10.0.2
2906 + '@types/hast': 3.0.4
2907 +
2908 + '@shikijs/vscode-textmate@10.0.2': {}
2909 +
2910 + '@swc/helpers@0.5.17':
2911 + dependencies:
2912 + tslib: 2.8.1
2913 +
2914 + '@types/debug@4.1.12':
2915 + dependencies:
2916 + '@types/ms': 2.1.0
2917 +
2918 + '@types/estree-jsx@1.0.5':
2919 + dependencies:
2920 + '@types/estree': 1.0.8
2921 +
2922 + '@types/estree@1.0.8': {}
2923 +
2924 + '@types/fontkit@2.0.8':
2925 + dependencies:
2926 + '@types/node': 24.0.10
2927 +
2928 + '@types/hast@3.0.4':
2929 + dependencies:
2930 + '@types/unist': 3.0.3
2931 +
2932 + '@types/json-schema@7.0.15': {}
2933 +
2934 + '@types/katex@0.16.7': {}
2935 +
2936 + '@types/mdast@4.0.4':
2937 + dependencies:
2938 + '@types/unist': 3.0.3
2939 +
2940 + '@types/mdx@2.0.13': {}
2941 +
2942 + '@types/ms@2.1.0': {}
2943 +
2944 + '@types/nlcst@2.0.3':
2945 + dependencies:
2946 + '@types/unist': 3.0.3
2947 +
2948 + '@types/node@17.0.45': {}
2949 +
2950 + '@types/node@24.0.10':
2951 + dependencies:
2952 + undici-types: 7.8.0
2953 +
2954 + '@types/sax@1.2.7':
2955 + dependencies:
2956 + '@types/node': 17.0.45
2957 +
2958 + '@types/unist@2.0.11': {}
2959 +
2960 + '@types/unist@3.0.3': {}
2961 +
2962 + '@typescript-eslint/eslint-plugin@8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1)(typescript@5.8.3))(eslint@9.30.1)(typescript@5.8.3)':
2963 + dependencies:
2964 + '@eslint-community/regexpp': 4.12.1
2965 + '@typescript-eslint/parser': 8.35.1(eslint@9.30.1)(typescript@5.8.3)
2966 + '@typescript-eslint/scope-manager': 8.35.1
2967 + '@typescript-eslint/type-utils': 8.35.1(eslint@9.30.1)(typescript@5.8.3)
2968 + '@typescript-eslint/utils': 8.35.1(eslint@9.30.1)(typescript@5.8.3)
2969 + '@typescript-eslint/visitor-keys': 8.35.1
2970 + eslint: 9.30.1
2971 + graphemer: 1.4.0
2972 + ignore: 7.0.5
2973 + natural-compare: 1.4.0
2974 + ts-api-utils: 2.1.0(typescript@5.8.3)
2975 + typescript: 5.8.3
2976 + transitivePeerDependencies:
2977 + - supports-color
2978 +
2979 + '@typescript-eslint/parser@8.35.1(eslint@9.30.1)(typescript@5.8.3)':
2980 + dependencies:
2981 + '@typescript-eslint/scope-manager': 8.35.1
2982 + '@typescript-eslint/types': 8.35.1
2983 + '@typescript-eslint/typescript-estree': 8.35.1(typescript@5.8.3)
2984 + '@typescript-eslint/visitor-keys': 8.35.1
2985 + debug: 4.4.1
2986 + eslint: 9.30.1
2987 + typescript: 5.8.3
2988 + transitivePeerDependencies:
2989 + - supports-color
2990 +
2991 + '@typescript-eslint/project-service@8.35.1(typescript@5.8.3)':
2992 + dependencies:
2993 + '@typescript-eslint/tsconfig-utils': 8.35.1(typescript@5.8.3)
2994 + '@typescript-eslint/types': 8.35.1
2995 + debug: 4.4.1
2996 + typescript: 5.8.3
2997 + transitivePeerDependencies:
2998 + - supports-color
2999 +
3000 + '@typescript-eslint/scope-manager@8.35.1':
3001 + dependencies:
3002 + '@typescript-eslint/types': 8.35.1
3003 + '@typescript-eslint/visitor-keys': 8.35.1
3004 +
3005 + '@typescript-eslint/tsconfig-utils@8.35.1(typescript@5.8.3)':
3006 + dependencies:
3007 + typescript: 5.8.3
3008 +
3009 + '@typescript-eslint/type-utils@8.35.1(eslint@9.30.1)(typescript@5.8.3)':
3010 + dependencies:
3011 + '@typescript-eslint/typescript-estree': 8.35.1(typescript@5.8.3)
3012 + '@typescript-eslint/utils': 8.35.1(eslint@9.30.1)(typescript@5.8.3)
3013 + debug: 4.4.1
3014 + eslint: 9.30.1
3015 + ts-api-utils: 2.1.0(typescript@5.8.3)
3016 + typescript: 5.8.3
3017 + transitivePeerDependencies:
3018 + - supports-color
3019 +
3020 + '@typescript-eslint/types@8.35.1': {}
3021 +
3022 + '@typescript-eslint/typescript-estree@8.35.1(typescript@5.8.3)':
3023 + dependencies:
3024 + '@typescript-eslint/project-service': 8.35.1(typescript@5.8.3)
3025 + '@typescript-eslint/tsconfig-utils': 8.35.1(typescript@5.8.3)
3026 + '@typescript-eslint/types': 8.35.1
3027 + '@typescript-eslint/visitor-keys': 8.35.1
3028 + debug: 4.4.1
3029 + fast-glob: 3.3.3
3030 + is-glob: 4.0.3
3031 + minimatch: 9.0.5
3032 + semver: 7.7.2
3033 + ts-api-utils: 2.1.0(typescript@5.8.3)
3034 + typescript: 5.8.3
3035 + transitivePeerDependencies:
3036 + - supports-color
3037 +
3038 + '@typescript-eslint/utils@8.35.1(eslint@9.30.1)(typescript@5.8.3)':
3039 + dependencies:
3040 + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1)
3041 + '@typescript-eslint/scope-manager': 8.35.1
3042 + '@typescript-eslint/types': 8.35.1
3043 + '@typescript-eslint/typescript-estree': 8.35.1(typescript@5.8.3)
3044 + eslint: 9.30.1
3045 + typescript: 5.8.3
3046 + transitivePeerDependencies:
3047 + - supports-color
3048 +
3049 + '@typescript-eslint/visitor-keys@8.35.1':
3050 + dependencies:
3051 + '@typescript-eslint/types': 8.35.1
3052 + eslint-visitor-keys: 4.2.1
3053 +
3054 + '@ungap/structured-clone@1.3.0': {}
3055 +
3056 + acorn-jsx@5.3.2(acorn@8.15.0):
3057 + dependencies:
3058 + acorn: 8.15.0
3059 +
3060 + acorn@8.15.0: {}
3061 +
3062 + ajv@6.12.6:
3063 + dependencies:
3064 + fast-deep-equal: 3.1.3
3065 + fast-json-stable-stringify: 2.1.0
3066 + json-schema-traverse: 0.4.1
3067 + uri-js: 4.4.1
3068 +
3069 + ansi-align@3.0.1:
3070 + dependencies:
3071 + string-width: 4.2.3
3072 +
3073 + ansi-regex@5.0.1: {}
3074 +
3075 + ansi-regex@6.1.0: {}
3076 +
3077 + ansi-styles@4.3.0:
3078 + dependencies:
3079 + color-convert: 2.0.1
3080 +
3081 + ansi-styles@6.2.1: {}
3082 +
3083 + anymatch@3.1.3:
3084 + dependencies:
3085 + normalize-path: 3.0.0
3086 + picomatch: 2.3.1
3087 +
3088 + arg@5.0.2: {}
3089 +
3090 + argparse@2.0.1: {}
3091 +
3092 + aria-query@5.3.2: {}
3093 +
3094 + array-iterate@2.0.1: {}
3095 +
3096 + astring@1.9.0: {}
3097 +
3098 + astro-eslint-parser@1.2.2:
3099 + dependencies:
3100 + '@astrojs/compiler': 2.12.2
3101 + '@typescript-eslint/scope-manager': 8.35.1
3102 + '@typescript-eslint/types': 8.35.1
3103 + astrojs-compiler-sync: 1.1.1(@astrojs/compiler@2.12.2)
3104 + debug: 4.4.1
3105 + entities: 6.0.1
3106 + eslint-scope: 8.4.0
3107 + eslint-visitor-keys: 4.2.1
3108 + espree: 10.4.0
3109 + fast-glob: 3.3.3
3110 + is-glob: 4.0.3
3111 + semver: 7.7.2
3112 + transitivePeerDependencies:
3113 + - supports-color
3114 +
3115 + astro@5.11.0(@types/node@24.0.10)(rollup@4.44.1)(tsx@4.20.3)(typescript@5.8.3):
3116 + dependencies:
3117 + '@astrojs/compiler': 2.12.2
3118 + '@astrojs/internal-helpers': 0.6.1
3119 + '@astrojs/markdown-remark': 6.3.2
3120 + '@astrojs/telemetry': 3.3.0
3121 + '@capsizecss/unpack': 2.4.0
3122 + '@oslojs/encoding': 1.1.0
3123 + '@rollup/pluginutils': 5.2.0(rollup@4.44.1)
3124 + acorn: 8.15.0
3125 + aria-query: 5.3.2
3126 + axobject-query: 4.1.0
3127 + boxen: 8.0.1
3128 + ci-info: 4.2.0
3129 + clsx: 2.1.1
3130 + common-ancestor-path: 1.0.1
3131 + cookie: 1.0.2
3132 + cssesc: 3.0.0
3133 + debug: 4.4.1
3134 + deterministic-object-hash: 2.0.2
3135 + devalue: 5.1.1
3136 + diff: 5.2.0
3137 + dlv: 1.1.3
3138 + dset: 3.1.4
3139 + es-module-lexer: 1.7.0
3140 + esbuild: 0.25.5
3141 + estree-walker: 3.0.3
3142 + flattie: 1.1.1
3143 + fontace: 0.3.0
3144 + github-slugger: 2.0.0
3145 + html-escaper: 3.0.3
3146 + http-cache-semantics: 4.2.0
3147 + import-meta-resolve: 4.1.0
3148 + js-yaml: 4.1.0
3149 + kleur: 4.1.5
3150 + magic-string: 0.30.17
3151 + magicast: 0.3.5
3152 + mrmime: 2.0.1
3153 + neotraverse: 0.6.18
3154 + p-limit: 6.2.0
3155 + p-queue: 8.1.0
3156 + package-manager-detector: 1.3.0
3157 + picomatch: 4.0.2
3158 + prompts: 2.4.2
3159 + rehype: 13.0.2
3160 + semver: 7.7.2
3161 + shiki: 3.7.0
3162 + tinyexec: 0.3.2
3163 + tinyglobby: 0.2.14
3164 + tsconfck: 3.1.6(typescript@5.8.3)
3165 + ultrahtml: 1.6.0
3166 + unifont: 0.5.2
3167 + unist-util-visit: 5.0.0
3168 + unstorage: 1.16.0
3169 + vfile: 6.0.3
3170 + vite: 6.3.5(@types/node@24.0.10)(tsx@4.20.3)
3171 + vitefu: 1.1.0(vite@6.3.5(@types/node@24.0.10)(tsx@4.20.3))
3172 + xxhash-wasm: 1.1.0
3173 + yargs-parser: 21.1.1
3174 + yocto-spinner: 0.2.3
3175 + zod: 3.25.73
3176 + zod-to-json-schema: 3.24.6(zod@3.25.73)
3177 + zod-to-ts: 1.2.0(typescript@5.8.3)(zod@3.25.73)
3178 + optionalDependencies:
3179 + sharp: 0.33.5
3180 + transitivePeerDependencies:
3181 + - '@azure/app-configuration'
3182 + - '@azure/cosmos'
3183 + - '@azure/data-tables'
3184 + - '@azure/identity'
3185 + - '@azure/keyvault-secrets'
3186 + - '@azure/storage-blob'
3187 + - '@capacitor/preferences'
3188 + - '@deno/kv'
3189 + - '@netlify/blobs'
3190 + - '@planetscale/database'
3191 + - '@types/node'
3192 + - '@upstash/redis'
3193 + - '@vercel/blob'
3194 + - '@vercel/kv'
3195 + - aws4fetch
3196 + - db0
3197 + - encoding
3198 + - idb-keyval
3199 + - ioredis
3200 + - jiti
3201 + - less
3202 + - lightningcss
3203 + - rollup
3204 + - sass
3205 + - sass-embedded
3206 + - stylus
3207 + - sugarss
3208 + - supports-color
3209 + - terser
3210 + - tsx
3211 + - typescript
3212 + - uploadthing
3213 + - yaml
3214 +
3215 + astrojs-compiler-sync@1.1.1(@astrojs/compiler@2.12.2):
3216 + dependencies:
3217 + '@astrojs/compiler': 2.12.2
3218 + synckit: 0.11.8
3219 +
3220 + axobject-query@4.1.0: {}
3221 +
3222 + bail@2.0.2: {}
3223 +
3224 + balanced-match@1.0.2: {}
3225 +
3226 + base-64@1.0.0: {}
3227 +
3228 + base64-js@1.5.1: {}
3229 +
3230 + blob-to-buffer@1.2.9: {}
3231 +
3232 + boxen@8.0.1:
3233 + dependencies:
3234 + ansi-align: 3.0.1
3235 + camelcase: 8.0.0
3236 + chalk: 5.4.1
3237 + cli-boxes: 3.0.0
3238 + string-width: 7.2.0
3239 + type-fest: 4.41.0
3240 + widest-line: 5.0.0
3241 + wrap-ansi: 9.0.0
3242 +
3243 + brace-expansion@1.1.12:
3244 + dependencies:
3245 + balanced-match: 1.0.2
3246 + concat-map: 0.0.1
3247 +
3248 + brace-expansion@2.0.2:
3249 + dependencies:
3250 + balanced-match: 1.0.2
3251 +
3252 + braces@3.0.3:
3253 + dependencies:
3254 + fill-range: 7.1.1
3255 +
3256 + brotli@1.3.3:
3257 + dependencies:
3258 + base64-js: 1.5.1
3259 +
3260 + callsites@3.1.0: {}
3261 +
3262 + camelcase@8.0.0: {}
3263 +
3264 + ccount@2.0.1: {}
3265 +
3266 + chalk@4.1.2:
3267 + dependencies:
3268 + ansi-styles: 4.3.0
3269 + supports-color: 7.2.0
3270 +
3271 + chalk@5.4.1: {}
3272 +
3273 + character-entities-html4@2.1.0: {}
3274 +
3275 + character-entities-legacy@3.0.0: {}
3276 +
3277 + character-entities@2.0.2: {}
3278 +
3279 + character-reference-invalid@2.0.1: {}
3280 +
3281 + chokidar@4.0.3:
3282 + dependencies:
3283 + readdirp: 4.1.2
3284 +
3285 + ci-info@4.2.0: {}
3286 +
3287 + cli-boxes@3.0.0: {}
3288 +
3289 + clone@2.1.2: {}
3290 +
3291 + clsx@2.1.1: {}
3292 +
3293 + collapse-white-space@2.1.0: {}
3294 +
3295 + color-convert@2.0.1:
3296 + dependencies:
3297 + color-name: 1.1.4
3298 +
3299 + color-name@1.1.4: {}
3300 +
3301 + color-string@1.9.1:
3302 + dependencies:
3303 + color-name: 1.1.4
3304 + simple-swizzle: 0.2.2
3305 +
3306 + color@4.2.3:
3307 + dependencies:
3308 + color-convert: 2.0.1
3309 + color-string: 1.9.1
3310 +
3311 + comma-separated-tokens@2.0.3: {}
3312 +
3313 + commander@8.3.0: {}
3314 +
3315 + common-ancestor-path@1.0.1: {}
3316 +
3317 + concat-map@0.0.1: {}
3318 +
3319 + cookie-es@1.2.2: {}
3320 +
3321 + cookie@1.0.2: {}
3322 +
3323 + cross-fetch@3.2.0:
3324 + dependencies:
3325 + node-fetch: 2.7.0
3326 + transitivePeerDependencies:
3327 + - encoding
3328 +
3329 + cross-spawn@7.0.6:
3330 + dependencies:
3331 + path-key: 3.1.1
3332 + shebang-command: 2.0.0
3333 + which: 2.0.2
3334 +
3335 + crossws@0.3.5:
3336 + dependencies:
3337 + uncrypto: 0.1.3
3338 +
3339 + css-tree@3.1.0:
3340 + dependencies:
3341 + mdn-data: 2.12.2
3342 + source-map-js: 1.2.1
3343 +
3344 + cssesc@3.0.0: {}
3345 +
3346 + debug@4.4.1:
3347 + dependencies:
3348 + ms: 2.1.3
3349 +
3350 + decode-named-character-reference@1.2.0:
3351 + dependencies:
3352 + character-entities: 2.0.2
3353 +
3354 + deep-is@0.1.4: {}
3355 +
3356 + defu@6.1.4: {}
3357 +
3358 + dequal@2.0.3: {}
3359 +
3360 + destr@2.0.5: {}
3361 +
3362 + detect-libc@2.0.4: {}
3363 +
3364 + deterministic-object-hash@2.0.2:
3365 + dependencies:
3366 + base-64: 1.0.0
3367 +
3368 + devalue@5.1.1: {}
3369 +
3370 + devlop@1.1.0:
3371 + dependencies:
3372 + dequal: 2.0.3
3373 +
3374 + dfa@1.2.0: {}
3375 +
3376 + diff@5.2.0: {}
3377 +
3378 + dlv@1.1.3: {}
3379 +
3380 + dset@3.1.4: {}
3381 +
3382 + emoji-regex@10.4.0: {}
3383 +
3384 + emoji-regex@8.0.0: {}
3385 +
3386 + entities@6.0.1: {}
3387 +
3388 + es-module-lexer@1.7.0: {}
3389 +
3390 + esast-util-from-estree@2.0.0:
3391 + dependencies:
3392 + '@types/estree-jsx': 1.0.5
3393 + devlop: 1.1.0
3394 + estree-util-visit: 2.0.0
3395 + unist-util-position-from-estree: 2.0.0
3396 +
3397 + esast-util-from-js@2.0.1:
3398 + dependencies:
3399 + '@types/estree-jsx': 1.0.5
3400 + acorn: 8.15.0
3401 + esast-util-from-estree: 2.0.0
3402 + vfile-message: 4.0.2
3403 +
3404 + esbuild@0.25.5:
3405 + optionalDependencies:
3406 + '@esbuild/aix-ppc64': 0.25.5
3407 + '@esbuild/android-arm': 0.25.5
3408 + '@esbuild/android-arm64': 0.25.5
3409 + '@esbuild/android-x64': 0.25.5
3410 + '@esbuild/darwin-arm64': 0.25.5
3411 + '@esbuild/darwin-x64': 0.25.5
3412 + '@esbuild/freebsd-arm64': 0.25.5
3413 + '@esbuild/freebsd-x64': 0.25.5
3414 + '@esbuild/linux-arm': 0.25.5
3415 + '@esbuild/linux-arm64': 0.25.5
3416 + '@esbuild/linux-ia32': 0.25.5
3417 + '@esbuild/linux-loong64': 0.25.5
3418 + '@esbuild/linux-mips64el': 0.25.5
3419 + '@esbuild/linux-ppc64': 0.25.5
3420 + '@esbuild/linux-riscv64': 0.25.5
3421 + '@esbuild/linux-s390x': 0.25.5
3422 + '@esbuild/linux-x64': 0.25.5
3423 + '@esbuild/netbsd-arm64': 0.25.5
3424 + '@esbuild/netbsd-x64': 0.25.5
3425 + '@esbuild/openbsd-arm64': 0.25.5
3426 + '@esbuild/openbsd-x64': 0.25.5
3427 + '@esbuild/sunos-x64': 0.25.5
3428 + '@esbuild/win32-arm64': 0.25.5
3429 + '@esbuild/win32-ia32': 0.25.5
3430 + '@esbuild/win32-x64': 0.25.5
3431 +
3432 + escape-string-regexp@4.0.0: {}
3433 +
3434 + escape-string-regexp@5.0.0: {}
3435 +
3436 + eslint-compat-utils@0.6.5(eslint@9.30.1):
3437 + dependencies:
3438 + eslint: 9.30.1
3439 + semver: 7.7.2
3440 +
3441 + eslint-config-prettier@10.1.5(eslint@9.30.1):
3442 + dependencies:
3443 + eslint: 9.30.1
3444 +
3445 + eslint-plugin-astro@1.3.1(eslint@9.30.1):
3446 + dependencies:
3447 + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1)
3448 + '@jridgewell/sourcemap-codec': 1.5.4
3449 + '@typescript-eslint/types': 8.35.1
3450 + astro-eslint-parser: 1.2.2
3451 + eslint: 9.30.1
3452 + eslint-compat-utils: 0.6.5(eslint@9.30.1)
3453 + globals: 15.15.0
3454 + postcss: 8.5.6
3455 + postcss-selector-parser: 7.1.0
3456 + transitivePeerDependencies:
3457 + - supports-color
3458 +
3459 + eslint-scope@8.4.0:
3460 + dependencies:
3461 + esrecurse: 4.3.0
3462 + estraverse: 5.3.0
3463 +
3464 + eslint-visitor-keys@3.4.3: {}
3465 +
3466 + eslint-visitor-keys@4.2.1: {}
3467 +
3468 + eslint@9.30.1:
3469 + dependencies:
3470 + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1)
3471 + '@eslint-community/regexpp': 4.12.1
3472 + '@eslint/config-array': 0.21.0
3473 + '@eslint/config-helpers': 0.3.0
3474 + '@eslint/core': 0.14.0
3475 + '@eslint/eslintrc': 3.3.1
3476 + '@eslint/js': 9.30.1
3477 + '@eslint/plugin-kit': 0.3.3
3478 + '@humanfs/node': 0.16.6
3479 + '@humanwhocodes/module-importer': 1.0.1
3480 + '@humanwhocodes/retry': 0.4.3
3481 + '@types/estree': 1.0.8
3482 + '@types/json-schema': 7.0.15
3483 + ajv: 6.12.6
3484 + chalk: 4.1.2
3485 + cross-spawn: 7.0.6
3486 + debug: 4.4.1
3487 + escape-string-regexp: 4.0.0
3488 + eslint-scope: 8.4.0
3489 + eslint-visitor-keys: 4.2.1
3490 + espree: 10.4.0
3491 + esquery: 1.6.0
3492 + esutils: 2.0.3
3493 + fast-deep-equal: 3.1.3
3494 + file-entry-cache: 8.0.0
3495 + find-up: 5.0.0
3496 + glob-parent: 6.0.2
3497 + ignore: 5.3.2
3498 + imurmurhash: 0.1.4
3499 + is-glob: 4.0.3
3500 + json-stable-stringify-without-jsonify: 1.0.1
3501 + lodash.merge: 4.6.2
3502 + minimatch: 3.1.2
3503 + natural-compare: 1.4.0
3504 + optionator: 0.9.4
3505 + transitivePeerDependencies:
3506 + - supports-color
3507 +
3508 + espree@10.4.0:
3509 + dependencies:
3510 + acorn: 8.15.0
3511 + acorn-jsx: 5.3.2(acorn@8.15.0)
3512 + eslint-visitor-keys: 4.2.1
3513 +
3514 + esquery@1.6.0:
3515 + dependencies:
3516 + estraverse: 5.3.0
3517 +
3518 + esrecurse@4.3.0:
3519 + dependencies:
3520 + estraverse: 5.3.0
3521 +
3522 + estraverse@5.3.0: {}
3523 +
3524 + estree-util-attach-comments@3.0.0:
3525 + dependencies:
3526 + '@types/estree': 1.0.8
3527 +
3528 + estree-util-build-jsx@3.0.1:
3529 + dependencies:
3530 + '@types/estree-jsx': 1.0.5
3531 + devlop: 1.1.0
3532 + estree-util-is-identifier-name: 3.0.0
3533 + estree-walker: 3.0.3
3534 +
3535 + estree-util-is-identifier-name@3.0.0: {}
3536 +
3537 + estree-util-scope@1.0.0:
3538 + dependencies:
3539 + '@types/estree': 1.0.8
3540 + devlop: 1.1.0
3541 +
3542 + estree-util-to-js@2.0.0:
3543 + dependencies:
3544 + '@types/estree-jsx': 1.0.5
3545 + astring: 1.9.0
3546 + source-map: 0.7.4
3547 +
3548 + estree-util-visit@2.0.0:
3549 + dependencies:
3550 + '@types/estree-jsx': 1.0.5
3551 + '@types/unist': 3.0.3
3552 +
3553 + estree-walker@2.0.2: {}
3554 +
3555 + estree-walker@3.0.3:
3556 + dependencies:
3557 + '@types/estree': 1.0.8
3558 +
3559 + esutils@2.0.3: {}
3560 +
3561 + eventemitter3@5.0.1: {}
3562 +
3563 + extend@3.0.2: {}
3564 +
3565 + fast-deep-equal@3.1.3: {}
3566 +
3567 + fast-glob@3.3.3:
3568 + dependencies:
3569 + '@nodelib/fs.stat': 2.0.5
3570 + '@nodelib/fs.walk': 1.2.8
3571 + glob-parent: 5.1.2
3572 + merge2: 1.4.1
3573 + micromatch: 4.0.8
3574 +
3575 + fast-json-stable-stringify@2.1.0: {}
3576 +
3577 + fast-levenshtein@2.0.6: {}
3578 +
3579 + fastq@1.19.1:
3580 + dependencies:
3581 + reusify: 1.1.0
3582 +
3583 + fdir@6.4.6(picomatch@4.0.2):
3584 + optionalDependencies:
3585 + picomatch: 4.0.2
3586 +
3587 + file-entry-cache@8.0.0:
3588 + dependencies:
3589 + flat-cache: 4.0.1
3590 +
3591 + fill-range@7.1.1:
3592 + dependencies:
3593 + to-regex-range: 5.0.1
3594 +
3595 + find-up@5.0.0:
3596 + dependencies:
3597 + locate-path: 6.0.0
3598 + path-exists: 4.0.0
3599 +
3600 + flat-cache@4.0.1:
3601 + dependencies:
3602 + flatted: 3.3.3
3603 + keyv: 4.5.4
3604 +
3605 + flatted@3.3.3: {}
3606 +
3607 + flattie@1.1.1: {}
3608 +
3609 + fontace@0.3.0:
3610 + dependencies:
3611 + '@types/fontkit': 2.0.8
3612 + fontkit: 2.0.4
3613 +
3614 + fontkit@2.0.4:
3615 + dependencies:
3616 + '@swc/helpers': 0.5.17
3617 + brotli: 1.3.3
3618 + clone: 2.1.2
3619 + dfa: 1.2.0
3620 + fast-deep-equal: 3.1.3
3621 + restructure: 3.0.2
3622 + tiny-inflate: 1.0.3
3623 + unicode-properties: 1.4.1
3624 + unicode-trie: 2.0.0
3625 +
3626 + fsevents@2.3.3:
3627 + optional: true
3628 +
3629 + get-east-asian-width@1.3.0: {}
3630 +
3631 + get-tsconfig@4.10.1:
3632 + dependencies:
3633 + resolve-pkg-maps: 1.0.0
3634 +
3635 + github-slugger@2.0.0: {}
3636 +
3637 + glob-parent@5.1.2:
3638 + dependencies:
3639 + is-glob: 4.0.3
3640 +
3641 + glob-parent@6.0.2:
3642 + dependencies:
3643 + is-glob: 4.0.3
3644 +
3645 + globals@14.0.0: {}
3646 +
3647 + globals@15.15.0: {}
3648 +
3649 + globals@16.3.0: {}
3650 +
3651 + graphemer@1.4.0: {}
3652 +
3653 + h3@1.15.3:
3654 + dependencies:
3655 + cookie-es: 1.2.2
3656 + crossws: 0.3.5
3657 + defu: 6.1.4
3658 + destr: 2.0.5
3659 + iron-webcrypto: 1.2.1
3660 + node-mock-http: 1.0.1
3661 + radix3: 1.1.2
3662 + ufo: 1.6.1
3663 + uncrypto: 0.1.3
3664 +
3665 + has-flag@4.0.0: {}
3666 +
3667 + hast-util-from-dom@5.0.1:
3668 + dependencies:
3669 + '@types/hast': 3.0.4
3670 + hastscript: 9.0.1
3671 + web-namespaces: 2.0.1
3672 +
3673 + hast-util-from-html-isomorphic@2.0.0:
3674 + dependencies:
3675 + '@types/hast': 3.0.4
3676 + hast-util-from-dom: 5.0.1
3677 + hast-util-from-html: 2.0.3
3678 + unist-util-remove-position: 5.0.0
3679 +
3680 + hast-util-from-html@2.0.3:
3681 + dependencies:
3682 + '@types/hast': 3.0.4
3683 + devlop: 1.1.0
3684 + hast-util-from-parse5: 8.0.3
3685 + parse5: 7.3.0
3686 + vfile: 6.0.3
3687 + vfile-message: 4.0.2
3688 +
3689 + hast-util-from-parse5@8.0.3:
3690 + dependencies:
3691 + '@types/hast': 3.0.4
3692 + '@types/unist': 3.0.3
3693 + devlop: 1.1.0
3694 + hastscript: 9.0.1
3695 + property-information: 7.1.0
3696 + vfile: 6.0.3
3697 + vfile-location: 5.0.3
3698 + web-namespaces: 2.0.1
3699 +
3700 + hast-util-is-element@3.0.0:
3701 + dependencies:
3702 + '@types/hast': 3.0.4
3703 +
3704 + hast-util-parse-selector@4.0.0:
3705 + dependencies:
3706 + '@types/hast': 3.0.4
3707 +
3708 + hast-util-raw@9.1.0:
3709 + dependencies:
3710 + '@types/hast': 3.0.4
3711 + '@types/unist': 3.0.3
3712 + '@ungap/structured-clone': 1.3.0
3713 + hast-util-from-parse5: 8.0.3
3714 + hast-util-to-parse5: 8.0.0
3715 + html-void-elements: 3.0.0
3716 + mdast-util-to-hast: 13.2.0
3717 + parse5: 7.3.0
3718 + unist-util-position: 5.0.0
3719 + unist-util-visit: 5.0.0
3720 + vfile: 6.0.3
3721 + web-namespaces: 2.0.1
3722 + zwitch: 2.0.4
3723 +
3724 + hast-util-to-estree@3.1.3:
3725 + dependencies:
3726 + '@types/estree': 1.0.8
3727 + '@types/estree-jsx': 1.0.5
3728 + '@types/hast': 3.0.4
3729 + comma-separated-tokens: 2.0.3
3730 + devlop: 1.1.0
3731 + estree-util-attach-comments: 3.0.0
3732 + estree-util-is-identifier-name: 3.0.0
3733 + hast-util-whitespace: 3.0.0
3734 + mdast-util-mdx-expression: 2.0.1
3735 + mdast-util-mdx-jsx: 3.2.0
3736 + mdast-util-mdxjs-esm: 2.0.1
3737 + property-information: 7.1.0
3738 + space-separated-tokens: 2.0.2
3739 + style-to-js: 1.1.17
3740 + unist-util-position: 5.0.0
3741 + zwitch: 2.0.4
3742 + transitivePeerDependencies:
3743 + - supports-color
3744 +
3745 + hast-util-to-html@9.0.5:
3746 + dependencies:
3747 + '@types/hast': 3.0.4
3748 + '@types/unist': 3.0.3
3749 + ccount: 2.0.1
3750 + comma-separated-tokens: 2.0.3
3751 + hast-util-whitespace: 3.0.0
3752 + html-void-elements: 3.0.0
3753 + mdast-util-to-hast: 13.2.0
3754 + property-information: 7.1.0
3755 + space-separated-tokens: 2.0.2
3756 + stringify-entities: 4.0.4
3757 + zwitch: 2.0.4
3758 +
3759 + hast-util-to-jsx-runtime@2.3.6:
3760 + dependencies:
3761 + '@types/estree': 1.0.8
3762 + '@types/hast': 3.0.4
3763 + '@types/unist': 3.0.3
3764 + comma-separated-tokens: 2.0.3
3765 + devlop: 1.1.0
3766 + estree-util-is-identifier-name: 3.0.0
3767 + hast-util-whitespace: 3.0.0
3768 + mdast-util-mdx-expression: 2.0.1
3769 + mdast-util-mdx-jsx: 3.2.0
3770 + mdast-util-mdxjs-esm: 2.0.1
3771 + property-information: 7.1.0
3772 + space-separated-tokens: 2.0.2
3773 + style-to-js: 1.1.17
3774 + unist-util-position: 5.0.0
3775 + vfile-message: 4.0.2
3776 + transitivePeerDependencies:
3777 + - supports-color
3778 +
3779 + hast-util-to-parse5@8.0.0:
3780 + dependencies:
3781 + '@types/hast': 3.0.4
3782 + comma-separated-tokens: 2.0.3
3783 + devlop: 1.1.0
3784 + property-information: 6.5.0
3785 + space-separated-tokens: 2.0.2
3786 + web-namespaces: 2.0.1
3787 + zwitch: 2.0.4
3788 +
3789 + hast-util-to-text@4.0.2:
3790 + dependencies:
3791 + '@types/hast': 3.0.4
3792 + '@types/unist': 3.0.3
3793 + hast-util-is-element: 3.0.0
3794 + unist-util-find-after: 5.0.0
3795 +
3796 + hast-util-whitespace@3.0.0:
3797 + dependencies:
3798 + '@types/hast': 3.0.4
3799 +
3800 + hastscript@9.0.1:
3801 + dependencies:
3802 + '@types/hast': 3.0.4
3803 + comma-separated-tokens: 2.0.3
3804 + hast-util-parse-selector: 4.0.0
3805 + property-information: 7.1.0
3806 + space-separated-tokens: 2.0.2
3807 +
3808 + html-escaper@3.0.3: {}
3809 +
3810 + html-void-elements@3.0.0: {}
3811 +
3812 + http-cache-semantics@4.2.0: {}
3813 +
3814 + ignore@5.3.2: {}
3815 +
3816 + ignore@7.0.5: {}
3817 +
3818 + import-fresh@3.3.1:
3819 + dependencies:
3820 + parent-module: 1.0.1
3821 + resolve-from: 4.0.0
3822 +
3823 + import-meta-resolve@4.1.0: {}
3824 +
3825 + imurmurhash@0.1.4: {}
3826 +
3827 + inline-style-parser@0.2.4: {}
3828 +
3829 + iron-webcrypto@1.2.1: {}
3830 +
3831 + is-alphabetical@2.0.1: {}
3832 +
3833 + is-alphanumerical@2.0.1:
3834 + dependencies:
3835 + is-alphabetical: 2.0.1
3836 + is-decimal: 2.0.1
3837 +
3838 + is-arrayish@0.3.2: {}
3839 +
3840 + is-decimal@2.0.1: {}
3841 +
3842 + is-docker@3.0.0: {}
3843 +
3844 + is-extglob@2.1.1: {}
3845 +
3846 + is-fullwidth-code-point@3.0.0: {}
3847 +
3848 + is-glob@4.0.3:
3849 + dependencies:
3850 + is-extglob: 2.1.1
3851 +
3852 + is-hexadecimal@2.0.1: {}
3853 +
3854 + is-inside-container@1.0.0:
3855 + dependencies:
3856 + is-docker: 3.0.0
3857 +
3858 + is-number@7.0.0: {}
3859 +
3860 + is-plain-obj@4.1.0: {}
3861 +
3862 + is-wsl@3.1.0:
3863 + dependencies:
3864 + is-inside-container: 1.0.0
3865 +
3866 + isexe@2.0.0: {}
3867 +
3868 + js-yaml@4.1.0:
3869 + dependencies:
3870 + argparse: 2.0.1
3871 +
3872 + json-buffer@3.0.1: {}
3873 +
3874 + json-schema-traverse@0.4.1: {}
3875 +
3876 + json-stable-stringify-without-jsonify@1.0.1: {}
3877 +
3878 + katex@0.16.22:
3879 + dependencies:
3880 + commander: 8.3.0
3881 +
3882 + keyv@4.5.4:
3883 + dependencies:
3884 + json-buffer: 3.0.1
3885 +
3886 + kleur@3.0.3: {}
3887 +
3888 + kleur@4.1.5: {}
3889 +
3890 + levn@0.4.1:
3891 + dependencies:
3892 + prelude-ls: 1.2.1
3893 + type-check: 0.4.0
3894 +
3895 + locate-path@6.0.0:
3896 + dependencies:
3897 + p-locate: 5.0.0
3898 +
3899 + lodash.merge@4.6.2: {}
3900 +
3901 + longest-streak@3.1.0: {}
3902 +
3903 + lru-cache@10.4.3: {}
3904 +
3905 + magic-string@0.30.17:
3906 + dependencies:
3907 + '@jridgewell/sourcemap-codec': 1.5.4
3908 +
3909 + magicast@0.3.5:
3910 + dependencies:
3911 + '@babel/parser': 7.28.0
3912 + '@babel/types': 7.28.0
3913 + source-map-js: 1.2.1
3914 +
3915 + markdown-extensions@2.0.0: {}
3916 +
3917 + markdown-table@3.0.4: {}
3918 +
3919 + mdast-util-definitions@6.0.0:
3920 + dependencies:
3921 + '@types/mdast': 4.0.4
3922 + '@types/unist': 3.0.3
3923 + unist-util-visit: 5.0.0
3924 +
3925 + mdast-util-directive@3.1.0:
3926 + dependencies:
3927 + '@types/mdast': 4.0.4
3928 + '@types/unist': 3.0.3
3929 + ccount: 2.0.1
3930 + devlop: 1.1.0
3931 + mdast-util-from-markdown: 2.0.2
3932 + mdast-util-to-markdown: 2.1.2
3933 + parse-entities: 4.0.2
3934 + stringify-entities: 4.0.4
3935 + unist-util-visit-parents: 6.0.1
3936 + transitivePeerDependencies:
3937 + - supports-color
3938 +
3939 + mdast-util-find-and-replace@3.0.2:
3940 + dependencies:
3941 + '@types/mdast': 4.0.4
3942 + escape-string-regexp: 5.0.0
3943 + unist-util-is: 6.0.0
3944 + unist-util-visit-parents: 6.0.1
3945 +
3946 + mdast-util-from-markdown@2.0.2:
3947 + dependencies:
3948 + '@types/mdast': 4.0.4
3949 + '@types/unist': 3.0.3
3950 + decode-named-character-reference: 1.2.0
3951 + devlop: 1.1.0
3952 + mdast-util-to-string: 4.0.0
3953 + micromark: 4.0.2
3954 + micromark-util-decode-numeric-character-reference: 2.0.2
3955 + micromark-util-decode-string: 2.0.1
3956 + micromark-util-normalize-identifier: 2.0.1
3957 + micromark-util-symbol: 2.0.1
3958 + micromark-util-types: 2.0.2
3959 + unist-util-stringify-position: 4.0.0
3960 + transitivePeerDependencies:
3961 + - supports-color
3962 +
3963 + mdast-util-gfm-autolink-literal@2.0.1:
3964 + dependencies:
3965 + '@types/mdast': 4.0.4
3966 + ccount: 2.0.1
3967 + devlop: 1.1.0
3968 + mdast-util-find-and-replace: 3.0.2
3969 + micromark-util-character: 2.1.1
3970 +
3971 + mdast-util-gfm-footnote@2.1.0:
3972 + dependencies:
3973 + '@types/mdast': 4.0.4
3974 + devlop: 1.1.0
3975 + mdast-util-from-markdown: 2.0.2
3976 + mdast-util-to-markdown: 2.1.2
3977 + micromark-util-normalize-identifier: 2.0.1
3978 + transitivePeerDependencies:
3979 + - supports-color
3980 +
3981 + mdast-util-gfm-strikethrough@2.0.0:
3982 + dependencies:
3983 + '@types/mdast': 4.0.4
3984 + mdast-util-from-markdown: 2.0.2
3985 + mdast-util-to-markdown: 2.1.2
3986 + transitivePeerDependencies:
3987 + - supports-color
3988 +
3989 + mdast-util-gfm-table@2.0.0:
3990 + dependencies:
3991 + '@types/mdast': 4.0.4
3992 + devlop: 1.1.0
3993 + markdown-table: 3.0.4
3994 + mdast-util-from-markdown: 2.0.2
3995 + mdast-util-to-markdown: 2.1.2
3996 + transitivePeerDependencies:
3997 + - supports-color
3998 +
3999 + mdast-util-gfm-task-list-item@2.0.0:
4000 + dependencies:
4001 + '@types/mdast': 4.0.4
4002 + devlop: 1.1.0
4003 + mdast-util-from-markdown: 2.0.2
4004 + mdast-util-to-markdown: 2.1.2
4005 + transitivePeerDependencies:
4006 + - supports-color
4007 +
4008 + mdast-util-gfm@3.1.0:
4009 + dependencies:
4010 + mdast-util-from-markdown: 2.0.2
4011 + mdast-util-gfm-autolink-literal: 2.0.1
4012 + mdast-util-gfm-footnote: 2.1.0
4013 + mdast-util-gfm-strikethrough: 2.0.0
4014 + mdast-util-gfm-table: 2.0.0
4015 + mdast-util-gfm-task-list-item: 2.0.0
4016 + mdast-util-to-markdown: 2.1.2
4017 + transitivePeerDependencies:
4018 + - supports-color
4019 +
4020 + mdast-util-math@3.0.0:
4021 + dependencies:
4022 + '@types/hast': 3.0.4
4023 + '@types/mdast': 4.0.4
4024 + devlop: 1.1.0
4025 + longest-streak: 3.1.0
4026 + mdast-util-from-markdown: 2.0.2
4027 + mdast-util-to-markdown: 2.1.2
4028 + unist-util-remove-position: 5.0.0
4029 + transitivePeerDependencies:
4030 + - supports-color
4031 +
4032 + mdast-util-mdx-expression@2.0.1:
4033 + dependencies:
4034 + '@types/estree-jsx': 1.0.5
4035 + '@types/hast': 3.0.4
4036 + '@types/mdast': 4.0.4
4037 + devlop: 1.1.0
4038 + mdast-util-from-markdown: 2.0.2
4039 + mdast-util-to-markdown: 2.1.2
4040 + transitivePeerDependencies:
4041 + - supports-color
4042 +
4043 + mdast-util-mdx-jsx@3.2.0:
4044 + dependencies:
4045 + '@types/estree-jsx': 1.0.5
4046 + '@types/hast': 3.0.4
4047 + '@types/mdast': 4.0.4
4048 + '@types/unist': 3.0.3
4049 + ccount: 2.0.1
4050 + devlop: 1.1.0
4051 + mdast-util-from-markdown: 2.0.2
4052 + mdast-util-to-markdown: 2.1.2
4053 + parse-entities: 4.0.2
4054 + stringify-entities: 4.0.4
4055 + unist-util-stringify-position: 4.0.0
4056 + vfile-message: 4.0.2
4057 + transitivePeerDependencies:
4058 + - supports-color
4059 +
4060 + mdast-util-mdx@3.0.0:
4061 + dependencies:
4062 + mdast-util-from-markdown: 2.0.2
4063 + mdast-util-mdx-expression: 2.0.1
4064 + mdast-util-mdx-jsx: 3.2.0
4065 + mdast-util-mdxjs-esm: 2.0.1
4066 + mdast-util-to-markdown: 2.1.2
4067 + transitivePeerDependencies:
4068 + - supports-color
4069 +
4070 + mdast-util-mdxjs-esm@2.0.1:
4071 + dependencies:
4072 + '@types/estree-jsx': 1.0.5
4073 + '@types/hast': 3.0.4
4074 + '@types/mdast': 4.0.4
4075 + devlop: 1.1.0
4076 + mdast-util-from-markdown: 2.0.2
4077 + mdast-util-to-markdown: 2.1.2
4078 + transitivePeerDependencies:
4079 + - supports-color
4080 +
4081 + mdast-util-phrasing@4.1.0:
4082 + dependencies:
4083 + '@types/mdast': 4.0.4
4084 + unist-util-is: 6.0.0
4085 +
4086 + mdast-util-to-hast@13.2.0:
4087 + dependencies:
4088 + '@types/hast': 3.0.4
4089 + '@types/mdast': 4.0.4
4090 + '@ungap/structured-clone': 1.3.0
4091 + devlop: 1.1.0
4092 + micromark-util-sanitize-uri: 2.0.1
4093 + trim-lines: 3.0.1
4094 + unist-util-position: 5.0.0
4095 + unist-util-visit: 5.0.0
4096 + vfile: 6.0.3
4097 +
4098 + mdast-util-to-markdown@2.1.2:
4099 + dependencies:
4100 + '@types/mdast': 4.0.4
4101 + '@types/unist': 3.0.3
4102 + longest-streak: 3.1.0
4103 + mdast-util-phrasing: 4.1.0
4104 + mdast-util-to-string: 4.0.0
4105 + micromark-util-classify-character: 2.0.1
4106 + micromark-util-decode-string: 2.0.1
4107 + unist-util-visit: 5.0.0
4108 + zwitch: 2.0.4
4109 +
4110 + mdast-util-to-string@4.0.0:
4111 + dependencies:
4112 + '@types/mdast': 4.0.4
4113 +
4114 + mdn-data@2.12.2: {}
4115 +
4116 + merge2@1.4.1: {}
4117 +
4118 + micromark-core-commonmark@2.0.3:
4119 + dependencies:
4120 + decode-named-character-reference: 1.2.0
4121 + devlop: 1.1.0
4122 + micromark-factory-destination: 2.0.1
4123 + micromark-factory-label: 2.0.1
4124 + micromark-factory-space: 2.0.1
4125 + micromark-factory-title: 2.0.1
4126 + micromark-factory-whitespace: 2.0.1
4127 + micromark-util-character: 2.1.1
4128 + micromark-util-chunked: 2.0.1
4129 + micromark-util-classify-character: 2.0.1
4130 + micromark-util-html-tag-name: 2.0.1
4131 + micromark-util-normalize-identifier: 2.0.1
4132 + micromark-util-resolve-all: 2.0.1
4133 + micromark-util-subtokenize: 2.1.0
4134 + micromark-util-symbol: 2.0.1
4135 + micromark-util-types: 2.0.2
4136 +
4137 + micromark-extension-directive@4.0.0:
4138 + dependencies:
4139 + devlop: 1.1.0
4140 + micromark-factory-space: 2.0.1
4141 + micromark-factory-whitespace: 2.0.1
4142 + micromark-util-character: 2.1.1
4143 + micromark-util-symbol: 2.0.1
4144 + micromark-util-types: 2.0.2
4145 + parse-entities: 4.0.2
4146 +
4147 + micromark-extension-gfm-autolink-literal@2.1.0:
4148 + dependencies:
4149 + micromark-util-character: 2.1.1
4150 + micromark-util-sanitize-uri: 2.0.1
4151 + micromark-util-symbol: 2.0.1
4152 + micromark-util-types: 2.0.2
4153 +
4154 + micromark-extension-gfm-footnote@2.1.0:
4155 + dependencies:
4156 + devlop: 1.1.0
4157 + micromark-core-commonmark: 2.0.3
4158 + micromark-factory-space: 2.0.1
4159 + micromark-util-character: 2.1.1
4160 + micromark-util-normalize-identifier: 2.0.1
4161 + micromark-util-sanitize-uri: 2.0.1
4162 + micromark-util-symbol: 2.0.1
4163 + micromark-util-types: 2.0.2
4164 +
4165 + micromark-extension-gfm-strikethrough@2.1.0:
4166 + dependencies:
4167 + devlop: 1.1.0
4168 + micromark-util-chunked: 2.0.1
4169 + micromark-util-classify-character: 2.0.1
4170 + micromark-util-resolve-all: 2.0.1
4171 + micromark-util-symbol: 2.0.1
4172 + micromark-util-types: 2.0.2
4173 +
4174 + micromark-extension-gfm-table@2.1.1:
4175 + dependencies:
4176 + devlop: 1.1.0
4177 + micromark-factory-space: 2.0.1
4178 + micromark-util-character: 2.1.1
4179 + micromark-util-symbol: 2.0.1
4180 + micromark-util-types: 2.0.2
4181 +
4182 + micromark-extension-gfm-tagfilter@2.0.0:
4183 + dependencies:
4184 + micromark-util-types: 2.0.2
4185 +
4186 + micromark-extension-gfm-task-list-item@2.1.0:
4187 + dependencies:
4188 + devlop: 1.1.0
4189 + micromark-factory-space: 2.0.1
4190 + micromark-util-character: 2.1.1
4191 + micromark-util-symbol: 2.0.1
4192 + micromark-util-types: 2.0.2
4193 +
4194 + micromark-extension-gfm@3.0.0:
4195 + dependencies:
4196 + micromark-extension-gfm-autolink-literal: 2.1.0
4197 + micromark-extension-gfm-footnote: 2.1.0
4198 + micromark-extension-gfm-strikethrough: 2.1.0
4199 + micromark-extension-gfm-table: 2.1.1
4200 + micromark-extension-gfm-tagfilter: 2.0.0
4201 + micromark-extension-gfm-task-list-item: 2.1.0
4202 + micromark-util-combine-extensions: 2.0.1
4203 + micromark-util-types: 2.0.2
4204 +
4205 + micromark-extension-math@3.1.0:
4206 + dependencies:
4207 + '@types/katex': 0.16.7
4208 + devlop: 1.1.0
4209 + katex: 0.16.22
4210 + micromark-factory-space: 2.0.1
4211 + micromark-util-character: 2.1.1
4212 + micromark-util-symbol: 2.0.1
4213 + micromark-util-types: 2.0.2
4214 +
4215 + micromark-extension-mdx-expression@3.0.1:
4216 + dependencies:
4217 + '@types/estree': 1.0.8
4218 + devlop: 1.1.0
4219 + micromark-factory-mdx-expression: 2.0.3
4220 + micromark-factory-space: 2.0.1
4221 + micromark-util-character: 2.1.1
4222 + micromark-util-events-to-acorn: 2.0.3
4223 + micromark-util-symbol: 2.0.1
4224 + micromark-util-types: 2.0.2
4225 +
4226 + micromark-extension-mdx-jsx@3.0.2:
4227 + dependencies:
4228 + '@types/estree': 1.0.8
4229 + devlop: 1.1.0
4230 + estree-util-is-identifier-name: 3.0.0
4231 + micromark-factory-mdx-expression: 2.0.3
4232 + micromark-factory-space: 2.0.1
4233 + micromark-util-character: 2.1.1
4234 + micromark-util-events-to-acorn: 2.0.3
4235 + micromark-util-symbol: 2.0.1
4236 + micromark-util-types: 2.0.2
4237 + vfile-message: 4.0.2
4238 +
4239 + micromark-extension-mdx-md@2.0.0:
4240 + dependencies:
4241 + micromark-util-types: 2.0.2
4242 +
4243 + micromark-extension-mdxjs-esm@3.0.0:
4244 + dependencies:
4245 + '@types/estree': 1.0.8
4246 + devlop: 1.1.0
4247 + micromark-core-commonmark: 2.0.3
4248 + micromark-util-character: 2.1.1
4249 + micromark-util-events-to-acorn: 2.0.3
4250 + micromark-util-symbol: 2.0.1
4251 + micromark-util-types: 2.0.2
4252 + unist-util-position-from-estree: 2.0.0
4253 + vfile-message: 4.0.2
4254 +
4255 + micromark-extension-mdxjs@3.0.0:
4256 + dependencies:
4257 + acorn: 8.15.0
4258 + acorn-jsx: 5.3.2(acorn@8.15.0)
4259 + micromark-extension-mdx-expression: 3.0.1
4260 + micromark-extension-mdx-jsx: 3.0.2
4261 + micromark-extension-mdx-md: 2.0.0
4262 + micromark-extension-mdxjs-esm: 3.0.0
4263 + micromark-util-combine-extensions: 2.0.1
4264 + micromark-util-types: 2.0.2
4265 +
4266 + micromark-factory-destination@2.0.1:
4267 + dependencies:
4268 + micromark-util-character: 2.1.1
4269 + micromark-util-symbol: 2.0.1
4270 + micromark-util-types: 2.0.2
4271 +
4272 + micromark-factory-label@2.0.1:
4273 + dependencies:
4274 + devlop: 1.1.0
4275 + micromark-util-character: 2.1.1
4276 + micromark-util-symbol: 2.0.1
4277 + micromark-util-types: 2.0.2
4278 +
4279 + micromark-factory-mdx-expression@2.0.3:
4280 + dependencies:
4281 + '@types/estree': 1.0.8
4282 + devlop: 1.1.0
4283 + micromark-factory-space: 2.0.1
4284 + micromark-util-character: 2.1.1
4285 + micromark-util-events-to-acorn: 2.0.3
4286 + micromark-util-symbol: 2.0.1
4287 + micromark-util-types: 2.0.2
4288 + unist-util-position-from-estree: 2.0.0
4289 + vfile-message: 4.0.2
4290 +
4291 + micromark-factory-space@2.0.1:
4292 + dependencies:
4293 + micromark-util-character: 2.1.1
4294 + micromark-util-types: 2.0.2
4295 +
4296 + micromark-factory-title@2.0.1:
4297 + dependencies:
4298 + micromark-factory-space: 2.0.1
4299 + micromark-util-character: 2.1.1
4300 + micromark-util-symbol: 2.0.1
4301 + micromark-util-types: 2.0.2
4302 +
4303 + micromark-factory-whitespace@2.0.1:
4304 + dependencies:
4305 + micromark-factory-space: 2.0.1
4306 + micromark-util-character: 2.1.1
4307 + micromark-util-symbol: 2.0.1
4308 + micromark-util-types: 2.0.2
4309 +
4310 + micromark-util-character@2.1.1:
4311 + dependencies:
4312 + micromark-util-symbol: 2.0.1
4313 + micromark-util-types: 2.0.2
4314 +
4315 + micromark-util-chunked@2.0.1:
4316 + dependencies:
4317 + micromark-util-symbol: 2.0.1
4318 +
4319 + micromark-util-classify-character@2.0.1:
4320 + dependencies:
4321 + micromark-util-character: 2.1.1
4322 + micromark-util-symbol: 2.0.1
4323 + micromark-util-types: 2.0.2
4324 +
4325 + micromark-util-combine-extensions@2.0.1:
4326 + dependencies:
4327 + micromark-util-chunked: 2.0.1
4328 + micromark-util-types: 2.0.2
4329 +
4330 + micromark-util-decode-numeric-character-reference@2.0.2:
4331 + dependencies:
4332 + micromark-util-symbol: 2.0.1
4333 +
4334 + micromark-util-decode-string@2.0.1:
4335 + dependencies:
4336 + decode-named-character-reference: 1.2.0
4337 + micromark-util-character: 2.1.1
4338 + micromark-util-decode-numeric-character-reference: 2.0.2
4339 + micromark-util-symbol: 2.0.1
4340 +
4341 + micromark-util-encode@2.0.1: {}
4342 +
4343 + micromark-util-events-to-acorn@2.0.3:
4344 + dependencies:
4345 + '@types/estree': 1.0.8
4346 + '@types/unist': 3.0.3
4347 + devlop: 1.1.0
4348 + estree-util-visit: 2.0.0
4349 + micromark-util-symbol: 2.0.1
4350 + micromark-util-types: 2.0.2
4351 + vfile-message: 4.0.2
4352 +
4353 + micromark-util-html-tag-name@2.0.1: {}
4354 +
4355 + micromark-util-normalize-identifier@2.0.1:
4356 + dependencies:
4357 + micromark-util-symbol: 2.0.1
4358 +
4359 + micromark-util-resolve-all@2.0.1:
4360 + dependencies:
4361 + micromark-util-types: 2.0.2
4362 +
4363 + micromark-util-sanitize-uri@2.0.1:
4364 + dependencies:
4365 + micromark-util-character: 2.1.1
4366 + micromark-util-encode: 2.0.1
4367 + micromark-util-symbol: 2.0.1
4368 +
4369 + micromark-util-subtokenize@2.1.0:
4370 + dependencies:
4371 + devlop: 1.1.0
4372 + micromark-util-chunked: 2.0.1
4373 + micromark-util-symbol: 2.0.1
4374 + micromark-util-types: 2.0.2
4375 +
4376 + micromark-util-symbol@2.0.1: {}
4377 +
4378 + micromark-util-types@2.0.2: {}
4379 +
4380 + micromark@4.0.2:
4381 + dependencies:
4382 + '@types/debug': 4.1.12
4383 + debug: 4.4.1
4384 + decode-named-character-reference: 1.2.0
4385 + devlop: 1.1.0
4386 + micromark-core-commonmark: 2.0.3
4387 + micromark-factory-space: 2.0.1
4388 + micromark-util-character: 2.1.1
4389 + micromark-util-chunked: 2.0.1
4390 + micromark-util-combine-extensions: 2.0.1
4391 + micromark-util-decode-numeric-character-reference: 2.0.2
4392 + micromark-util-encode: 2.0.1
4393 + micromark-util-normalize-identifier: 2.0.1
4394 + micromark-util-resolve-all: 2.0.1
4395 + micromark-util-sanitize-uri: 2.0.1
4396 + micromark-util-subtokenize: 2.1.0
4397 + micromark-util-symbol: 2.0.1
4398 + micromark-util-types: 2.0.2
4399 + transitivePeerDependencies:
4400 + - supports-color
4401 +
4402 + micromatch@4.0.8:
4403 + dependencies:
4404 + braces: 3.0.3
4405 + picomatch: 2.3.1
4406 +
4407 + minimatch@3.1.2:
4408 + dependencies:
4409 + brace-expansion: 1.1.12
4410 +
4411 + minimatch@9.0.5:
4412 + dependencies:
4413 + brace-expansion: 2.0.2
4414 +
4415 + mrmime@2.0.1: {}
4416 +
4417 + ms@2.1.3: {}
4418 +
4419 + nanoid@3.3.11: {}
4420 +
4421 + natural-compare@1.4.0: {}
4422 +
4423 + neotraverse@0.6.18: {}
4424 +
4425 + nlcst-to-string@4.0.0:
4426 + dependencies:
4427 + '@types/nlcst': 2.0.3
4428 +
4429 + node-fetch-native@1.6.6: {}
4430 +
4431 + node-fetch@2.7.0:
4432 + dependencies:
4433 + whatwg-url: 5.0.0
4434 +
4435 + node-mock-http@1.0.1: {}
4436 +
4437 + normalize-path@3.0.0: {}
4438 +
4439 + ofetch@1.4.1:
4440 + dependencies:
4441 + destr: 2.0.5
4442 + node-fetch-native: 1.6.6
4443 + ufo: 1.6.1
4444 +
4445 + ohash@2.0.11: {}
4446 +
4447 + oniguruma-parser@0.12.1: {}
4448 +
4449 + oniguruma-to-es@4.3.3:
4450 + dependencies:
4451 + oniguruma-parser: 0.12.1
4452 + regex: 6.0.1
4453 + regex-recursion: 6.0.2
4454 +
4455 + optionator@0.9.4:
4456 + dependencies:
4457 + deep-is: 0.1.4
4458 + fast-levenshtein: 2.0.6
4459 + levn: 0.4.1
4460 + prelude-ls: 1.2.1
4461 + type-check: 0.4.0
4462 + word-wrap: 1.2.5
4463 +
4464 + p-limit@3.1.0:
4465 + dependencies:
4466 + yocto-queue: 0.1.0
4467 +
4468 + p-limit@6.2.0:
4469 + dependencies:
4470 + yocto-queue: 1.2.1
4471 +
4472 + p-locate@5.0.0:
4473 + dependencies:
4474 + p-limit: 3.1.0
4475 +
4476 + p-queue@8.1.0:
4477 + dependencies:
4478 + eventemitter3: 5.0.1
4479 + p-timeout: 6.1.4
4480 +
4481 + p-timeout@6.1.4: {}
4482 +
4483 + package-manager-detector@1.3.0: {}
4484 +
4485 + pako@0.2.9: {}
4486 +
4487 + parent-module@1.0.1:
4488 + dependencies:
4489 + callsites: 3.1.0
4490 +
4491 + parse-entities@4.0.2:
4492 + dependencies:
4493 + '@types/unist': 2.0.11
4494 + character-entities-legacy: 3.0.0
4495 + character-reference-invalid: 2.0.1
4496 + decode-named-character-reference: 1.2.0
4497 + is-alphanumerical: 2.0.1
4498 + is-decimal: 2.0.1
4499 + is-hexadecimal: 2.0.1
4500 +
4501 + parse-latin@7.0.0:
4502 + dependencies:
4503 + '@types/nlcst': 2.0.3
4504 + '@types/unist': 3.0.3
4505 + nlcst-to-string: 4.0.0
4506 + unist-util-modify-children: 4.0.0
4507 + unist-util-visit-children: 3.0.0
4508 + vfile: 6.0.3
4509 +
4510 + parse5@7.3.0:
4511 + dependencies:
4512 + entities: 6.0.1
4513 +
4514 + path-exists@4.0.0: {}
4515 +
4516 + path-key@3.1.1: {}
4517 +
4518 + picocolors@1.1.1: {}
4519 +
4520 + picomatch@2.3.1: {}
4521 +
4522 + picomatch@4.0.2: {}
4523 +
4524 + postcss-selector-parser@7.1.0:
4525 + dependencies:
4526 + cssesc: 3.0.0
4527 + util-deprecate: 1.0.2
4528 +
4529 + postcss@8.5.6:
4530 + dependencies:
4531 + nanoid: 3.3.11
4532 + picocolors: 1.1.1
4533 + source-map-js: 1.2.1
4534 +
4535 + prelude-ls@1.2.1: {}
4536 +
4537 + prettier-plugin-astro@0.14.1:
4538 + dependencies:
4539 + '@astrojs/compiler': 2.12.2
4540 + prettier: 3.6.2
4541 + sass-formatter: 0.7.9
4542 +
4543 + prettier@3.6.2: {}
4544 +
4545 + prismjs@1.30.0: {}
4546 +
4547 + prompts@2.4.2:
4548 + dependencies:
4549 + kleur: 3.0.3
4550 + sisteransi: 1.0.5
4551 +
4552 + property-information@6.5.0: {}
4553 +
4554 + property-information@7.1.0: {}
4555 +
4556 + punycode@2.3.1: {}
4557 +
4558 + queue-microtask@1.2.3: {}
4559 +
4560 + radix3@1.1.2: {}
4561 +
4562 + readdirp@4.1.2: {}
4563 +
4564 + reading-time@1.5.0: {}
4565 +
4566 + recma-build-jsx@1.0.0:
4567 + dependencies:
4568 + '@types/estree': 1.0.8
4569 + estree-util-build-jsx: 3.0.1
4570 + vfile: 6.0.3
4571 +
4572 + recma-jsx@1.0.0(acorn@8.15.0):
4573 + dependencies:
4574 + acorn-jsx: 5.3.2(acorn@8.15.0)
4575 + estree-util-to-js: 2.0.0
4576 + recma-parse: 1.0.0
4577 + recma-stringify: 1.0.0
4578 + unified: 11.0.5
4579 + transitivePeerDependencies:
4580 + - acorn
4581 +
4582 + recma-parse@1.0.0:
4583 + dependencies:
4584 + '@types/estree': 1.0.8
4585 + esast-util-from-js: 2.0.1
4586 + unified: 11.0.5
4587 + vfile: 6.0.3
4588 +
4589 + recma-stringify@1.0.0:
4590 + dependencies:
4591 + '@types/estree': 1.0.8
4592 + estree-util-to-js: 2.0.0
4593 + unified: 11.0.5
4594 + vfile: 6.0.3
4595 +
4596 + regex-recursion@6.0.2:
4597 + dependencies:
4598 + regex-utilities: 2.3.0
4599 +
4600 + regex-utilities@2.3.0: {}
4601 +
4602 + regex@6.0.1:
4603 + dependencies:
4604 + regex-utilities: 2.3.0
4605 +
4606 + rehype-katex@7.0.1:
4607 + dependencies:
4608 + '@types/hast': 3.0.4
4609 + '@types/katex': 0.16.7
4610 + hast-util-from-html-isomorphic: 2.0.0
4611 + hast-util-to-text: 4.0.2
4612 + katex: 0.16.22
4613 + unist-util-visit-parents: 6.0.1
4614 + vfile: 6.0.3
4615 +
4616 + rehype-parse@9.0.1:
4617 + dependencies:
4618 + '@types/hast': 3.0.4
4619 + hast-util-from-html: 2.0.3
4620 + unified: 11.0.5
4621 +
4622 + rehype-raw@7.0.0:
4623 + dependencies:
4624 + '@types/hast': 3.0.4
4625 + hast-util-raw: 9.1.0
4626 + vfile: 6.0.3
4627 +
4628 + rehype-recma@1.0.0:
4629 + dependencies:
4630 + '@types/estree': 1.0.8
4631 + '@types/hast': 3.0.4
4632 + hast-util-to-estree: 3.1.3
4633 + transitivePeerDependencies:
4634 + - supports-color
4635 +
4636 + rehype-stringify@10.0.1:
4637 + dependencies:
4638 + '@types/hast': 3.0.4
4639 + hast-util-to-html: 9.0.5
4640 + unified: 11.0.5
4641 +
4642 + rehype@13.0.2:
4643 + dependencies:
4644 + '@types/hast': 3.0.4
4645 + rehype-parse: 9.0.1
4646 + rehype-stringify: 10.0.1
4647 + unified: 11.0.5
4648 +
4649 + remark-directive@4.0.0:
4650 + dependencies:
4651 + '@types/mdast': 4.0.4
4652 + mdast-util-directive: 3.1.0
4653 + micromark-extension-directive: 4.0.0
4654 + unified: 11.0.5
4655 + transitivePeerDependencies:
4656 + - supports-color
4657 +
4658 + remark-gfm@4.0.1:
4659 + dependencies:
4660 + '@types/mdast': 4.0.4
4661 + mdast-util-gfm: 3.1.0
4662 + micromark-extension-gfm: 3.0.0
4663 + remark-parse: 11.0.0
4664 + remark-stringify: 11.0.0
4665 + unified: 11.0.5
4666 + transitivePeerDependencies:
4667 + - supports-color
4668 +
4669 + remark-math@6.0.0:
4670 + dependencies:
4671 + '@types/mdast': 4.0.4
4672 + mdast-util-math: 3.0.0
4673 + micromark-extension-math: 3.1.0
4674 + unified: 11.0.5
4675 + transitivePeerDependencies:
4676 + - supports-color
4677 +
4678 + remark-mdx@3.1.0:
4679 + dependencies:
4680 + mdast-util-mdx: 3.0.0
4681 + micromark-extension-mdxjs: 3.0.0
4682 + transitivePeerDependencies:
4683 + - supports-color
4684 +
4685 + remark-parse@11.0.0:
4686 + dependencies:
4687 + '@types/mdast': 4.0.4
4688 + mdast-util-from-markdown: 2.0.2
4689 + micromark-util-types: 2.0.2
4690 + unified: 11.0.5
4691 + transitivePeerDependencies:
4692 + - supports-color
4693 +
4694 + remark-rehype@11.1.2:
4695 + dependencies:
4696 + '@types/hast': 3.0.4
4697 + '@types/mdast': 4.0.4
4698 + mdast-util-to-hast: 13.2.0
4699 + unified: 11.0.5
4700 + vfile: 6.0.3
4701 +
4702 + remark-smartypants@3.0.2:
4703 + dependencies:
4704 + retext: 9.0.0
4705 + retext-smartypants: 6.2.0
4706 + unified: 11.0.5
4707 + unist-util-visit: 5.0.0
4708 +
4709 + remark-stringify@11.0.0:
4710 + dependencies:
4711 + '@types/mdast': 4.0.4
4712 + mdast-util-to-markdown: 2.1.2
4713 + unified: 11.0.5
4714 +
4715 + resolve-from@4.0.0: {}
4716 +
4717 + resolve-pkg-maps@1.0.0: {}
4718 +
4719 + restructure@3.0.2: {}
4720 +
4721 + retext-latin@4.0.0:
4722 + dependencies:
4723 + '@types/nlcst': 2.0.3
4724 + parse-latin: 7.0.0
4725 + unified: 11.0.5
4726 +
4727 + retext-smartypants@6.2.0:
4728 + dependencies:
4729 + '@types/nlcst': 2.0.3
4730 + nlcst-to-string: 4.0.0
4731 + unist-util-visit: 5.0.0
4732 +
4733 + retext-stringify@4.0.0:
4734 + dependencies:
4735 + '@types/nlcst': 2.0.3
4736 + nlcst-to-string: 4.0.0
4737 + unified: 11.0.5
4738 +
4739 + retext@9.0.0:
4740 + dependencies:
4741 + '@types/nlcst': 2.0.3
4742 + retext-latin: 4.0.0
4743 + retext-stringify: 4.0.0
4744 + unified: 11.0.5
4745 +
4746 + reusify@1.1.0: {}
4747 +
4748 + rollup@4.44.1:
4749 + dependencies:
4750 + '@types/estree': 1.0.8
4751 + optionalDependencies:
4752 + '@rollup/rollup-android-arm-eabi': 4.44.1
4753 + '@rollup/rollup-android-arm64': 4.44.1
4754 + '@rollup/rollup-darwin-arm64': 4.44.1
4755 + '@rollup/rollup-darwin-x64': 4.44.1
4756 + '@rollup/rollup-freebsd-arm64': 4.44.1
4757 + '@rollup/rollup-freebsd-x64': 4.44.1
4758 + '@rollup/rollup-linux-arm-gnueabihf': 4.44.1
4759 + '@rollup/rollup-linux-arm-musleabihf': 4.44.1
4760 + '@rollup/rollup-linux-arm64-gnu': 4.44.1
4761 + '@rollup/rollup-linux-arm64-musl': 4.44.1
4762 + '@rollup/rollup-linux-loongarch64-gnu': 4.44.1
4763 + '@rollup/rollup-linux-powerpc64le-gnu': 4.44.1
4764 + '@rollup/rollup-linux-riscv64-gnu': 4.44.1
4765 + '@rollup/rollup-linux-riscv64-musl': 4.44.1
4766 + '@rollup/rollup-linux-s390x-gnu': 4.44.1
4767 + '@rollup/rollup-linux-x64-gnu': 4.44.1
4768 + '@rollup/rollup-linux-x64-musl': 4.44.1
4769 + '@rollup/rollup-win32-arm64-msvc': 4.44.1
4770 + '@rollup/rollup-win32-ia32-msvc': 4.44.1
4771 + '@rollup/rollup-win32-x64-msvc': 4.44.1
4772 + fsevents: 2.3.3
4773 +
4774 + run-parallel@1.2.0:
4775 + dependencies:
4776 + queue-microtask: 1.2.3
4777 +
4778 + s.color@0.0.15: {}
4779 +
4780 + sass-formatter@0.7.9:
4781 + dependencies:
4782 + suf-log: 2.5.3
4783 +
4784 + sax@1.4.1: {}
4785 +
4786 + semver@7.7.2: {}
4787 +
4788 + sharp@0.33.5:
4789 + dependencies:
4790 + color: 4.2.3
4791 + detect-libc: 2.0.4
4792 + semver: 7.7.2
4793 + optionalDependencies:
4794 + '@img/sharp-darwin-arm64': 0.33.5
4795 + '@img/sharp-darwin-x64': 0.33.5
4796 + '@img/sharp-libvips-darwin-arm64': 1.0.4
4797 + '@img/sharp-libvips-darwin-x64': 1.0.4
4798 + '@img/sharp-libvips-linux-arm': 1.0.5
4799 + '@img/sharp-libvips-linux-arm64': 1.0.4
4800 + '@img/sharp-libvips-linux-s390x': 1.0.4
4801 + '@img/sharp-libvips-linux-x64': 1.0.4
4802 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4
4803 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4
4804 + '@img/sharp-linux-arm': 0.33.5
4805 + '@img/sharp-linux-arm64': 0.33.5
4806 + '@img/sharp-linux-s390x': 0.33.5
4807 + '@img/sharp-linux-x64': 0.33.5
4808 + '@img/sharp-linuxmusl-arm64': 0.33.5
4809 + '@img/sharp-linuxmusl-x64': 0.33.5
4810 + '@img/sharp-wasm32': 0.33.5
4811 + '@img/sharp-win32-ia32': 0.33.5
4812 + '@img/sharp-win32-x64': 0.33.5
4813 + optional: true
4814 +
4815 + sharp@0.34.2:
4816 + dependencies:
4817 + color: 4.2.3
4818 + detect-libc: 2.0.4
4819 + semver: 7.7.2
4820 + optionalDependencies:
4821 + '@img/sharp-darwin-arm64': 0.34.2
4822 + '@img/sharp-darwin-x64': 0.34.2
4823 + '@img/sharp-libvips-darwin-arm64': 1.1.0
4824 + '@img/sharp-libvips-darwin-x64': 1.1.0
4825 + '@img/sharp-libvips-linux-arm': 1.1.0
4826 + '@img/sharp-libvips-linux-arm64': 1.1.0
4827 + '@img/sharp-libvips-linux-ppc64': 1.1.0
4828 + '@img/sharp-libvips-linux-s390x': 1.1.0
4829 + '@img/sharp-libvips-linux-x64': 1.1.0
4830 + '@img/sharp-libvips-linuxmusl-arm64': 1.1.0
4831 + '@img/sharp-libvips-linuxmusl-x64': 1.1.0
4832 + '@img/sharp-linux-arm': 0.34.2
4833 + '@img/sharp-linux-arm64': 0.34.2
4834 + '@img/sharp-linux-s390x': 0.34.2
4835 + '@img/sharp-linux-x64': 0.34.2
4836 + '@img/sharp-linuxmusl-arm64': 0.34.2
4837 + '@img/sharp-linuxmusl-x64': 0.34.2
4838 + '@img/sharp-wasm32': 0.34.2
4839 + '@img/sharp-win32-arm64': 0.34.2
4840 + '@img/sharp-win32-ia32': 0.34.2
4841 + '@img/sharp-win32-x64': 0.34.2
4842 +
4843 + shebang-command@2.0.0:
4844 + dependencies:
4845 + shebang-regex: 3.0.0
4846 +
4847 + shebang-regex@3.0.0: {}
4848 +
4849 + shiki@3.7.0:
4850 + dependencies:
4851 + '@shikijs/core': 3.7.0
4852 + '@shikijs/engine-javascript': 3.7.0
4853 + '@shikijs/engine-oniguruma': 3.7.0
4854 + '@shikijs/langs': 3.7.0
4855 + '@shikijs/themes': 3.7.0
4856 + '@shikijs/types': 3.7.0
4857 + '@shikijs/vscode-textmate': 10.0.2
4858 + '@types/hast': 3.0.4
4859 +
4860 + simple-swizzle@0.2.2:
4861 + dependencies:
4862 + is-arrayish: 0.3.2
4863 +
4864 + sisteransi@1.0.5: {}
4865 +
4866 + sitemap@8.0.0:
4867 + dependencies:
4868 + '@types/node': 17.0.45
4869 + '@types/sax': 1.2.7
4870 + arg: 5.0.2
4871 + sax: 1.4.1
4872 +
4873 + smol-toml@1.4.1: {}
4874 +
4875 + source-map-js@1.2.1: {}
4876 +
4877 + source-map@0.7.4: {}
4878 +
4879 + space-separated-tokens@2.0.2: {}
4880 +
4881 + stream-replace-string@2.0.0: {}
4882 +
4883 + string-width@4.2.3:
4884 + dependencies:
4885 + emoji-regex: 8.0.0
4886 + is-fullwidth-code-point: 3.0.0
4887 + strip-ansi: 6.0.1
4888 +
4889 + string-width@7.2.0:
4890 + dependencies:
4891 + emoji-regex: 10.4.0
4892 + get-east-asian-width: 1.3.0
4893 + strip-ansi: 7.1.0
4894 +
4895 + stringify-entities@4.0.4:
4896 + dependencies:
4897 + character-entities-html4: 2.1.0
4898 + character-entities-legacy: 3.0.0
4899 +
4900 + strip-ansi@6.0.1:
4901 + dependencies:
4902 + ansi-regex: 5.0.1
4903 +
4904 + strip-ansi@7.1.0:
4905 + dependencies:
4906 + ansi-regex: 6.1.0
4907 +
4908 + strip-json-comments@3.1.1: {}
4909 +
4910 + style-to-js@1.1.17:
4911 + dependencies:
4912 + style-to-object: 1.0.9
4913 +
4914 + style-to-object@1.0.9:
4915 + dependencies:
4916 + inline-style-parser: 0.2.4
4917 +
4918 + suf-log@2.5.3:
4919 + dependencies:
4920 + s.color: 0.0.15
4921 +
4922 + supports-color@7.2.0:
4923 + dependencies:
4924 + has-flag: 4.0.0
4925 +
4926 + synckit@0.11.8:
4927 + dependencies:
4928 + '@pkgr/core': 0.2.7
4929 +
4930 + tiny-inflate@1.0.3: {}
4931 +
4932 + tinyexec@0.3.2: {}
4933 +
4934 + tinyglobby@0.2.14:
4935 + dependencies:
4936 + fdir: 6.4.6(picomatch@4.0.2)
4937 + picomatch: 4.0.2
4938 +
4939 + to-regex-range@5.0.1:
4940 + dependencies:
4941 + is-number: 7.0.0
4942 +
4943 + tr46@0.0.3: {}
4944 +
4945 + trim-lines@3.0.1: {}
4946 +
4947 + trough@2.2.0: {}
4948 +
4949 + ts-api-utils@2.1.0(typescript@5.8.3):
4950 + dependencies:
4951 + typescript: 5.8.3
4952 +
4953 + tsconfck@3.1.6(typescript@5.8.3):
4954 + optionalDependencies:
4955 + typescript: 5.8.3
4956 +
4957 + tslib@2.8.1: {}
4958 +
4959 + tsx@4.20.3:
4960 + dependencies:
4961 + esbuild: 0.25.5
4962 + get-tsconfig: 4.10.1
4963 + optionalDependencies:
4964 + fsevents: 2.3.3
4965 +
4966 + type-check@0.4.0:
4967 + dependencies:
4968 + prelude-ls: 1.2.1
4969 +
4970 + type-fest@4.41.0: {}
4971 +
4972 + typescript-eslint@8.35.1(eslint@9.30.1)(typescript@5.8.3):
4973 + dependencies:
4974 + '@typescript-eslint/eslint-plugin': 8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1)(typescript@5.8.3))(eslint@9.30.1)(typescript@5.8.3)
4975 + '@typescript-eslint/parser': 8.35.1(eslint@9.30.1)(typescript@5.8.3)
4976 + '@typescript-eslint/utils': 8.35.1(eslint@9.30.1)(typescript@5.8.3)
4977 + eslint: 9.30.1
4978 + typescript: 5.8.3
4979 + transitivePeerDependencies:
4980 + - supports-color
4981 +
4982 + typescript@5.8.3: {}
4983 +
4984 + ufo@1.6.1: {}
4985 +
4986 + ultrahtml@1.6.0: {}
4987 +
4988 + uncrypto@0.1.3: {}
4989 +
4990 + undici-types@7.8.0: {}
4991 +
4992 + unicode-properties@1.4.1:
4993 + dependencies:
4994 + base64-js: 1.5.1
4995 + unicode-trie: 2.0.0
4996 +
4997 + unicode-trie@2.0.0:
4998 + dependencies:
4999 + pako: 0.2.9

This file is too large to show in full.

public/apple-touch-icon.png
Binary files /dev/null and b/public/apple-touch-icon.png differ
public/chiri-og.png
Binary files /dev/null and b/public/chiri-og.png differ
public/favicon.svg new
+15
@@ -0,0 +1,15 @@
1 +<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2 + <path
3 + d="M12.3785 2C16.2799 2.0001 15.793 5.9958 15.3053 7.99414C16.7687 6.99515 19.8498 5.92943 21.6451 8.99414C23.1079 11.4917 19.6947 14.3221 17.7437 14.9883C19.2069 15.9875 21.3523 18.5847 18.231 20.9824C15.1095 23.3803 12.7031 20.983 11.8902 19.4844C10.9146 20.983 8.28152 23.3801 5.55039 20.9824C2.81905 18.5846 4.41233 16.3199 5.55039 15.4873C3.76201 14.9878 0.672689 12.0909 2.62363 8.49414C3.85202 6.22947 7.01339 6.66254 7.98886 7.49512C7.6637 5.66344 8.47661 2 12.3785 2ZM12.3121 9.49316C8.42708 9.49327 7.3044 16.1247 12.3121 15.4375C15.6222 14.9833 15.6814 9.49316 12.3121 9.49316Z"
4 + />
5 + <style>
6 + path {
7 + fill:#111;
8 + }
9 + @media (prefers-color-scheme: dark) {
10 + path {
11 + fill: #ccc;
12 + }
13 + }
14 + </style>
15 +</svg>
\ No newline at end of file
public/fonts/Besley-Italic.woff2
Binary files /dev/null and b/public/fonts/Besley-Italic.woff2 differ
public/fonts/Inter.woff2
Binary files /dev/null and b/public/fonts/Inter.woff2 differ
public/images/screenshot-dark.png
Binary files /dev/null and b/public/images/screenshot-dark.png differ
public/images/screenshot-light.png
Binary files /dev/null and b/public/images/screenshot-light.png differ
scripts/new-post.ts new
+55
@@ -0,0 +1,55 @@
1 +/**
2 + * Create a new post with frontmatter
3 + * Usage: pnpm new <title>
4 + */
5 +
6 +import { existsSync, mkdirSync, writeFileSync } from 'node:fs'
7 +import { dirname, join } from 'node:path'
8 +import process from 'node:process'
9 +
10 +// Process title from all arguments
11 +const titleArgs: string[] = process.argv.slice(2)
12 +const rawTitle: string = titleArgs.length > 0 ? titleArgs.join(' ') : 'new-post'
13 +
14 +// Check if title starts with underscore (draft post)
15 +const isDraft: boolean = rawTitle.startsWith('_')
16 +const displayTitle: string = isDraft ? rawTitle.slice(1) : rawTitle
17 +
18 +const fileName: string = rawTitle
19 + .toLowerCase()
20 + .replace(/[^a-z0-9\s-_]/g, '') // Remove special characters but keep underscore and hyphen
21 + .replace(/\s+/g, '-') // Replace spaces with hyphens
22 + .replace(/-+/g, '-') // Replace multiple hyphens with single
23 + .replace(/^-|-$/g, '') // Remove leading/trailing hyphens
24 +const targetFile: string = `${fileName}.md`
25 +const fullPath: string = join('src/content/posts', targetFile)
26 +
27 +// Check if the target file already exists
28 +if (existsSync(fullPath)) {
29 + console.error(`😇 File already exists: ${fullPath}`)
30 + process.exit(1)
31 +}
32 +
33 +// Ensure the directory structure exists
34 +mkdirSync(dirname(fullPath), { recursive: true })
35 +
36 +// Generate frontmatter with current date
37 +const content: string = `---
38 +title: ${displayTitle}
39 +pubDate: '${new Date().toISOString().split('T')[0]}'
40 +---
41 +
42 +`
43 +
44 +// Write the new post file
45 +try {
46 + writeFileSync(fullPath, content)
47 + if (isDraft) {
48 + console.log(`📝 Draft created: ${fullPath}`)
49 + } else {
50 + console.log(`✅ Post created: ${fullPath}`)
51 + }
52 +} catch (error) {
53 + console.error('⚠️ Failed to create post:', error)
54 + process.exit(1)
55 +}
scripts/update-theme.ts new
+46
@@ -0,0 +1,46 @@
1 +#!/usr/bin/env tsx
2 +
3 +/**
4 + * Update theme from upstream repository
5 + * Usage: pnpm update-theme
6 + */
7 +
8 +import { execSync } from 'node:child_process'
9 +import fs from 'node:fs'
10 +import path from 'node:path'
11 +import process from 'node:process'
12 +
13 +// Check and set up the upstream remote repository
14 +try {
15 + execSync('git remote get-url upstream', { stdio: 'ignore' })
16 +} catch {
17 + execSync('git remote add upstream https://github.com/the3ash/astro-chiri.git', {
18 + stdio: 'inherit'
19 + })
20 +}
21 +
22 +// Update theme from upstream repository
23 +try {
24 + execSync('git fetch upstream', { stdio: 'inherit' })
25 +
26 + const currentCommit = execSync('git rev-parse HEAD', { encoding: 'utf8' }).trim()
27 + execSync('git merge upstream/main --allow-unrelated-histories', { stdio: 'inherit' })
28 + const newCommit = execSync('git rev-parse HEAD', { encoding: 'utf8' }).trim()
29 +
30 + if (currentCommit === newCommit) {
31 + console.log('🤗 No updates available, already up to date')
32 + } else {
33 + console.log('✅ Theme updated')
34 + }
35 +} catch (error) {
36 + // Check if there's a merge conflict
37 + const gitDirectory = execSync('git rev-parse --git-dir', { encoding: 'utf8' }).trim()
38 + const mergeHeadFile = path.join(gitDirectory, 'MERGE_HEAD')
39 +
40 + if (fs.existsSync(mergeHeadFile)) {
41 + console.log('⚠️ Update fetched with merge conflicts. Please resolve manually')
42 + } else {
43 + console.error('❌ Update failed:', error)
44 + process.exit(1)
45 + }
46 +}
src/components/examples/Callout.astro new
+52
@@ -0,0 +1,52 @@
1 +<div class="callout-card">
2 + <div class="callout-container">
3 + <div class="callout">
4 + <span class="callout-icon">🙊</span>
5 + <span class="callout-text">Ape shall never kill ape.</span>
6 + </div>
7 + </div>
8 +</div>
9 +
10 +<style>
11 + .callout-card {
12 + border: 1px solid var(--border);
13 + width: 100%;
14 + height: 12rem;
15 + display: flex;
16 + align-items: center;
17 + justify-content: center;
18 + border-radius: 10px;
19 + }
20 +
21 + .callout-container {
22 + display: flex;
23 + justify-content: center;
24 + align-items: center;
25 + width: 100%;
26 + padding: 0 4rem;
27 + }
28 +
29 + .callout {
30 + background-color: var(--astro-code-background);
31 + border: 1px solid var(--code-bg);
32 + border-radius: 10px;
33 + padding: 1rem;
34 + display: flex;
35 + align-items: center;
36 + gap: 0.5rem;
37 + width: 100%;
38 + }
39 +
40 + .callout-icon {
41 + padding-right: 0.5rem;
42 + font-size: 1.25rem;
43 + line-height: 1;
44 + display: flex;
45 + align-items: center;
46 + }
47 +
48 + .callout-text {
49 + color: var(--text-primary);
50 + line-height: 1.5;
51 + }
52 +</style>
src/components/examples/CounterButton.astro new
+55
@@ -0,0 +1,55 @@
1 +<div class="counter-card">
2 + <div class="counter-container">
3 + <button id="counter-btn" class="counter-button">
4 + Click me (<span id="counter-value">0</span>)
5 + </button>
6 + </div>
7 +</div>
8 +
9 +<style>
10 + .counter-card {
11 + border: 1px solid var(--border);
12 + width: 100%;
13 + height: 12rem;
14 + display: flex;
15 + align-items: center;
16 + justify-content: center;
17 + border-radius: 10px;
18 + }
19 +
20 + .counter-container {
21 + display: flex;
22 + justify-content: center;
23 + align-items: center;
24 + }
25 +
26 + .counter-button {
27 + background-color: var(--text-primary);
28 + color: var(--bg);
29 + border: none;
30 + font-family: var(--font-mono);
31 + font-size: var(--font-size-s);
32 + border-radius: 12px;
33 + cursor: pointer;
34 + width: 160px;
35 + height: 44px;
36 + transition: all 0.15s ease-in-out;
37 + }
38 +
39 + .counter-button:hover {
40 + opacity: 0.9;
41 + }
42 +</style>
43 +
44 +<script>
45 + let count = 0
46 + const button = document.getElementById('counter-btn')
47 + const valueSpan = document.getElementById('counter-value')
48 +
49 + if (button && valueSpan) {
50 + button.addEventListener('click', () => {
51 + count++
52 + valueSpan.textContent = count.toString()
53 + })
54 + }
55 +</script>
src/components/examples/Tag.astro new
+424
@@ -0,0 +1,424 @@
1 +<div class="tag-card">
2 + <div class="tag-container">
3 + <div id="tag-component" class="tag-component">
4 + <button id="add-button" class="add-button">
5 + <svg
6 + class="add-icon"
7 + xmlns="http://www.w3.org/2000/svg"
8 + viewBox="0 0 16 16"
9 + width="16"
10 + height="16"
11 + >
12 + <path
13 + d="M7.75 2a.75.75 0 0 1 .75.75V7h4.25a.75.75 0 0 1 0 1.5H8.5v4.25a.75.75 0 0 1-1.5 0V8.5H2.75a.75.75 0 0 1 0-1.5H7V2.75A.75.75 0 0 1 7.75 2Z"
14 + ></path>
15 + </svg>
16 + </button>
17 +
18 + <div id="input-state" class="input-state">
19 + <input id="tag-input" type="text" placeholder="Tag Name" class="tag-input" />
20 + <button id="confirm-button" class="confirm-button disabled">
21 + <svg
22 + class="confirm-icon"
23 + xmlns="http://www.w3.org/2000/svg"
24 + viewBox="0 0 16 16"
25 + width="16"
26 + height="16"
27 + >
28 + <path
29 + d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"
30 + ></path>
31 + </svg>
32 + </button>
33 + <button id="cancel-button" class="cancel-button">
34 + <svg
35 + class="cancel-icon"
36 + xmlns="http://www.w3.org/2000/svg"
37 + viewBox="0 0 16 16"
38 + width="16"
39 + height="16"
40 + >
41 + <path
42 + d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"
43 + ></path>
44 + </svg>
45 + </button>
46 + </div>
47 +
48 + <div id="tag-display" class="tag-display">
49 + <span id="tag-text" class="tag-text"></span>
50 + <button id="delete-button" class="delete-button">
51 + <svg
52 + class="delete-icon"
53 + xmlns="http://www.w3.org/2000/svg"
54 + viewBox="0 0 16 16"
55 + width="16"
56 + height="16"
57 + >
58 + <path
59 + d="M11 1.75V3h2.25a.75.75 0 0 1 0 1.5H2.75a.75.75 0 0 1 0-1.5H5V1.75C5 .784 5.784 0 6.75 0h2.5C10.216 0 11 .784 11 1.75ZM4.496 6.675l.66 6.6a.25.25 0 0 0 .249.225h5.19a.25.25 0 0 0 .249-.225l.66-6.6a.75.75 0 0 1 1.492.149l-.66 6.6A1.748 1.748 0 0 1 10.595 15h-5.19a1.75 1.75 0 0 1-1.741-1.575l-.66-6.6a.75.75 0 1 1 1.492-.15ZM6.5 1.75V3h3V1.75a.25.25 0 0 0-.25-.25h-2.5a.25.25 0 0 0-.25.25Z"
60 + ></path>
61 + </svg>
62 + </button>
63 + </div>
64 + </div>
65 + </div>
66 +</div>
67 +
68 +<script>
69 + let currentState = 'add' // 'add', 'input', 'display'
70 + let tagValue = ''
71 +
72 + const addButton = document.getElementById('add-button') as HTMLButtonElement
73 + const inputState = document.getElementById('input-state') as HTMLDivElement
74 + const tagDisplay = document.getElementById('tag-display') as HTMLDivElement
75 + const tagInput = document.getElementById('tag-input') as HTMLInputElement
76 + const confirmButton = document.getElementById('confirm-button') as HTMLButtonElement
77 + const cancelButton = document.getElementById('cancel-button') as HTMLButtonElement
78 + const deleteButton = document.getElementById('delete-button') as HTMLButtonElement
79 + const tagText = document.getElementById('tag-text') as HTMLSpanElement
80 +
81 + // Switch to input state
82 + function switchToInput() {
83 + currentState = 'input'
84 + addButton?.classList.add('hidden')
85 +
86 + setTimeout(() => {
87 + inputState?.classList.add('active')
88 + tagInput?.focus()
89 + }, 100)
90 + }
91 +
92 + // Switch to display state
93 + function switchToDisplay() {
94 + currentState = 'display'
95 +
96 + inputState?.classList.remove('active')
97 +
98 + setTimeout(() => {
99 + tagDisplay?.classList.add('active')
100 + if (tagText) tagText.textContent = tagValue
101 + }, 300)
102 + }
103 +
104 + // Return to add state
105 + function switchToAdd() {
106 + if (currentState === 'display') {
107 + tagDisplay?.classList.remove('active')
108 + } else if (currentState === 'input') {
109 + inputState?.classList.remove('active')
110 + }
111 +
112 + currentState = 'add'
113 +
114 + setTimeout(() => {
115 + addButton?.classList.remove('hidden')
116 + tagValue = ''
117 + if (tagInput) tagInput.value = ''
118 + updateConfirmButton()
119 + }, 300)
120 + }
121 +
122 + // Update confirm button state
123 + function updateConfirmButton() {
124 + if (tagInput?.value.trim()) {
125 + confirmButton?.classList.remove('disabled')
126 + } else {
127 + confirmButton?.classList.add('disabled')
128 + }
129 + }
130 +
131 + addButton?.addEventListener('click', switchToInput)
132 +
133 + tagInput?.addEventListener('input', (e) => {
134 + const target = e.target as HTMLInputElement
135 + tagValue = target.value
136 + updateConfirmButton()
137 + })
138 +
139 + tagInput?.addEventListener('keydown', (e) => {
140 + if (e.key === 'Enter' && tagValue.trim()) {
141 + switchToDisplay()
142 + } else if (e.key === 'Escape') {
143 + switchToAdd()
144 + }
145 + })
146 +
147 + confirmButton?.addEventListener('click', () => {
148 + if (tagValue.trim()) {
149 + switchToDisplay()
150 + }
151 + })
152 +
153 + cancelButton?.addEventListener('click', switchToAdd)
154 +
155 + deleteButton?.addEventListener('click', switchToAdd)
156 +</script>
157 +
158 +<style>
159 + .tag-card {
160 + border: 1px solid var(--border);
161 + width: 100%;
162 + height: 12rem;
163 + display: flex;
164 + align-items: center;
165 + justify-content: center;
166 + border-radius: 10px;
167 + }
168 +
169 + .tag-container {
170 + display: flex;
171 + justify-content: center;
172 + align-items: center;
173 + width: 100%;
174 + padding: 0 2rem;
175 + overflow: hidden;
176 + }
177 +
178 + .tag-component {
179 + display: flex;
180 + align-items: center;
181 + justify-content: center;
182 + gap: 0.5rem;
183 + position: relative;
184 + width: 100%;
185 + }
186 +
187 + .add-button {
188 + background-color: var(--text-primary);
189 + color: var(--bg);
190 + border: none;
191 + border-radius: 50%;
192 + width: 40px;
193 + height: 40px;
194 + cursor: pointer;
195 + display: flex;
196 + align-items: center;
197 + justify-content: center;
198 + transition: all 0.3s ease;
199 + position: absolute;
200 + top: 50%;
201 + left: 50%;
202 + transform: translate(-50%, -50%) scale(1);
203 + z-index: 1;
204 + opacity: 1;
205 + }
206 +
207 + .add-button.hidden {
208 + opacity: 0;
209 + transform: translate(-50%, -50%) scale(0.8);
210 + pointer-events: none;
211 + }
212 +
213 + .add-icon,
214 + .confirm-icon,
215 + .cancel-icon,
216 + .delete-icon {
217 + fill: currentColor;
218 + width: 1rem;
219 + height: 1rem;
220 + }
221 +
222 + .add-button:hover {
223 + opacity: 0.9;
224 + }
225 +
226 + .input-state {
227 + display: flex;
228 + align-items: center;
229 + gap: 0.75rem;
230 + background-color: var(--astro-code-background);
231 + border: 1px solid var(--code-bg);
232 + border-radius: 20px;
233 + padding: 0.5rem 0.75rem 0.5rem 0.5rem;
234 + width: 40px;
235 + max-width: 40px;
236 + opacity: 0;
237 + overflow: hidden;
238 + transition: all 0.3s ease;
239 + position: relative;
240 + z-index: 2;
241 + pointer-events: none;
242 + }
243 +
244 + .input-state.active {
245 + width: 240px;
246 + max-width: 240px;
247 + opacity: 1;
248 + pointer-events: all;
249 + }
250 +
251 + .tag-input {
252 + background: transparent;
253 + border: none;
254 + outline: none;
255 + color: var(--text-primary);
256 + font-size: 0.9rem;
257 + font-family: var(--font-mono);
258 + min-width: 120px;
259 + padding: 0.25rem 0.5rem;
260 + opacity: 0;
261 + transform: translateX(-8px);
262 + transition:
263 + opacity 0.2s ease 0.15s,
264 + transform 0.2s ease 0.15s;
265 + }
266 +
267 + .input-state.active .tag-input {
268 + opacity: 1;
269 + transform: translateX(0);
270 + }
271 +
272 + .tag-input::placeholder {
273 + color: var(--text-tertiary);
274 + }
275 +
276 + .confirm-button,
277 + .cancel-button {
278 + background: none;
279 + border: none;
280 + border-radius: 50%;
281 + width: 24px;
282 + height: 24px;
283 + cursor: pointer;
284 + display: flex;
285 + align-items: center;
286 + justify-content: center;
287 + font-size: 0.8rem;
288 + opacity: 0;
289 + transform: scale(0.8);
290 + transition: all 0.2s ease;
291 + position: relative;
292 + }
293 +
294 + .confirm-button::before,
295 + .cancel-button::before {
296 + content: '';
297 + position: absolute;
298 + top: 50%;
299 + left: 50%;
300 + transform: translate(-50%, -50%);
301 + border-radius: 50%;
302 + background-color: var(--code-bg);
303 + opacity: 0;
304 + transition: opacity 0.2s ease;
305 + z-index: -1;
306 + width: 32px;
307 + height: 32px;
308 + }
309 +
310 + .confirm-button:hover::before,
311 + .cancel-button:hover::before {
312 + opacity: 1;
313 + }
314 +
315 + .input-state.active .confirm-button,
316 + .input-state.active .cancel-button {
317 + transform: scale(1);
318 + }
319 +
320 + .confirm-button {
321 + color: var(--text-primary);
322 + opacity: 0.6;
323 + }
324 +
325 + .confirm-button.disabled {
326 + opacity: 0.3;
327 + cursor: not-allowed;
328 + }
329 +
330 + .confirm-button:not(.disabled):hover {
331 + opacity: 1;
332 + }
333 +
334 + .confirm-button.disabled:hover::before {
335 + opacity: 0;
336 + }
337 +
338 + .cancel-button {
339 + color: var(--text-primary);
340 + opacity: 0.6;
341 + }
342 +
343 + .cancel-button:hover {
344 + opacity: 1;
345 + }
346 +
347 + .tag-display {
348 + display: flex;
349 + align-items: center;
350 + gap: 0.5rem;
351 + background-color: var(--astro-code-background);
352 + border: 1px solid var(--code-bg);
353 + border-radius: 20px;
354 + padding: 0.5rem 0.75rem 0.5rem 1rem;
355 + position: absolute;
356 + top: 50%;
357 + left: 50%;
358 + transform: translate(-50%, -50%);
359 + z-index: 3;
360 + opacity: 0;
361 + pointer-events: none;
362 + transition: all 0.25s ease-out;
363 + }
364 +
365 + .tag-display > * {
366 + margin-right: 8px;
367 + }
368 +
369 + .tag-display > *:last-child {
370 + margin-right: 0;
371 + }
372 +
373 + .tag-display.active {
374 + opacity: 1;
375 + transform: translate(-50%, -50%);
376 + pointer-events: all;
377 + }
378 +
379 + .tag-text {
380 + color: var(--text-primary);
381 + font-size: 0.9rem;
382 + font-family: var(--font-mono);
383 + }
384 +
385 + .delete-button {
386 + background: none;
387 + border: none;
388 + border-radius: 50%;
389 + width: 24px;
390 + height: 24px;
391 + cursor: pointer;
392 + display: flex;
393 + align-items: center;
394 + justify-content: center;
395 + font-size: 0.8rem;
396 + color: var(--text-primary);
397 + opacity: 0.6;
398 + transition: all 0.2s ease;
399 + position: relative;
400 + }
401 +
402 + .delete-button::before {
403 + content: '';
404 + position: absolute;
405 + top: 50%;
406 + left: 50%;
407 + transform: translate(-50%, -50%);
408 + border-radius: 50%;
409 + background-color: var(--code-bg);
410 + opacity: 0;
411 + transition: opacity 0.2s ease;
412 + z-index: -1;
413 + width: 32px;
414 + height: 32px;
415 + }
416 +
417 + .delete-button:hover {
418 + opacity: 1;
419 + }
420 +
421 + .delete-button:hover::before {
422 + opacity: 1;
423 + }
424 +</style>
src/components/features/FootnoteScroll.astro new
+23
@@ -0,0 +1,23 @@
1 +<script>
2 + document.addEventListener('astro:page-load', () => {
3 + const footnoteLinks = document.querySelectorAll('[data-footnote-ref], [data-footnote-backref]')
4 +
5 + footnoteLinks.forEach((link) => {
6 + link.addEventListener('click', (e) => {
7 + e.preventDefault()
8 + const href = link.getAttribute('href')
9 + if (!href) return
10 +
11 + const target = document.querySelector(href)
12 + if (!target) return
13 +
14 + // Calculate scroll position with offset (6 * 16px = 96px from top)
15 + const targetPosition = target.getBoundingClientRect().top + window.scrollY - 6 * 16
16 + window.scrollTo({
17 + top: targetPosition,
18 + behavior: 'smooth'
19 + })
20 + })
21 + })
22 + })
23 +</script>
src/components/features/FormattedDate.astro new
+29
@@ -0,0 +1,29 @@
1 +---
2 +import { formatDate } from '@/utils/date'
3 +import { SITE } from '@/config'
4 +
5 +interface Props {
6 + date: Date
7 + format?: string
8 +}
9 +
10 +const { date, format } = Astro.props
11 +---
12 +
13 +<time
14 + datetime={date.toISOString()}
15 + class={!SITE.dateOnRight &&
16 + (SITE.dateFormat === 'MONTH DAY YYYY' || SITE.dateFormat === 'DAY MONTH YYYY')
17 + ? 'date-left'
18 + : ''}
19 +>
20 + <Fragment set:html={formatDate(date, format)} />
21 +</time>
22 +
23 +<style>
24 + .date-left {
25 + display: inline-block;
26 + min-width: 86px;
27 + text-align: right;
28 + }
29 +</style>
src/components/features/PostList.astro new
+105
@@ -0,0 +1,105 @@
1 +---
2 +import FormattedDate from '@/components/features/FormattedDate.astro'
3 +import type { CollectionEntry } from 'astro:content'
4 +import { SITE } from '@/config'
5 +
6 +interface Props {
7 + posts: CollectionEntry<'posts'>[]
8 +}
9 +
10 +const { posts } = Astro.props
11 +---
12 +
13 +<ul>
14 + {
15 + posts.map((post) => (
16 + <li>
17 + <a href={`/${post.id}/`}>
18 + <div class={`post-item ${!SITE.dateOnRight ? 'date-left' : ''}`}>
19 + {!SITE.dateOnRight && (
20 + <p class="date font-features">
21 + <FormattedDate date={post.data.pubDate} />
22 + </p>
23 + )}
24 + <p class="title">{post.data.title}</p>
25 + {SITE.dateOnRight && <div class="divider" />}
26 + {SITE.dateOnRight && (
27 + <p class="date font-features">
28 + <FormattedDate date={post.data.pubDate} />
29 + </p>
30 + )}
31 + </div>
32 + </a>
33 + </li>
34 + ))
35 + }
36 +</ul>
37 +<div class="placeholder"></div>
38 +
39 +<style>
40 + ul {
41 + padding: 0;
42 + margin: 0;
43 + list-style-type: none;
44 + display: flex;
45 + flex-direction: column;
46 + gap: 0;
47 + }
48 +
49 + a {
50 + color: var(--text-primary);
51 + display: block;
52 + text-decoration: none;
53 + transition: opacity 0.15s ease-out;
54 + }
55 +
56 + ul:hover a {
57 + opacity: 0.4;
58 + }
59 +
60 + ul:hover a:hover {
61 + opacity: 1;
62 + }
63 +
64 + .post-item {
65 + height: 2.75rem;
66 + display: flex;
67 + justify-content: space-between;
68 + align-items: center;
69 + gap: 1rem;
70 + }
71 +
72 + .post-item.date-left {
73 + justify-content: flex-start;
74 + }
75 +
76 + .post-item.date-left .title {
77 + flex: 1 1 auto;
78 + min-width: 0;
79 + }
80 +
81 + .title {
82 + margin: 0;
83 + white-space: nowrap;
84 + overflow: hidden;
85 + text-overflow: ellipsis;
86 + }
87 +
88 + .date {
89 + margin: 0;
90 + color: var(--text-secondary);
91 + letter-spacing: var(--spacing-s);
92 + flex-shrink: 0;
93 + }
94 +
95 + .divider {
96 + flex: 1;
97 + min-width: 24px;
98 + height: 0.5px;
99 + background-color: var(--border);
100 + }
101 +
102 + .placeholder {
103 + height: 3rem;
104 + }
105 +</style>
src/components/layout/BaseHead.astro new
+99
@@ -0,0 +1,99 @@
1 +---
2 +// Import the global.css file here so that it is included on
3 +// all pages through the use of the <BaseHead /> component.
4 +import 'katex/dist/katex.min.css'
5 +import { SITE } from '@/config'
6 +
7 +interface Props {
8 + title: string
9 + description: string
10 +}
11 +
12 +const canonicalURL = new URL(Astro.url.pathname, Astro.site)
13 +
14 +const { title, description } = Astro.props
15 +---
16 +
17 +<!-- Global Metadata -->
18 +<meta charset="utf-8" />
19 +<meta name="viewport" content="width=device-width,initial-scale=1" />
20 +{SITE.fadeAnimation && <meta name="view-transition" content="same-origin" />}
21 +<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
22 +<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
23 +<link rel="preload" href="/fonts/Inter.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
24 +<link
25 + rel="preload"
26 + href="/fonts/Besley-Italic.woff2"
27 + as="font"
28 + type="font/woff2"
29 + crossorigin="anonymous"
30 +/>
31 +<link rel="sitemap" href="/sitemap-index.xml" />
32 +<link
33 + rel="alternate"
34 + type="application/rss+xml"
35 + title={SITE.title}
36 + href={new URL('rss.xml', Astro.site)}
37 +/>
38 +<meta name="generator" content={Astro.generator} />
39 +
40 +<!-- Canonical URL -->
41 +<link rel="canonical" href={canonicalURL} />
42 +
43 +<!-- Primary Meta Tags -->
44 +<title>
45 + {title || SITE.title}
46 +</title>
47 +<meta name="title" content={title} />
48 +<meta name="description" content={description} />
49 +
50 +<!-- Open Graph / Facebook -->
51 +<meta property="og:type" content="website" />
52 +<meta property="og:url" content={Astro.url} />
53 +<meta property="og:title" content={title} />
54 +<meta property="og:description" content={description} />
55 +<meta property="og:image" content={new URL('/chiri-og.png', Astro.url)} />
56 +
57 +<!-- Twitter -->
58 +<meta property="twitter:card" content="summary_large_image" />
59 +<meta property="twitter:url" content={Astro.url} />
60 +<meta property="twitter:title" content={title} />
61 +<meta property="twitter:description" content={description} />
62 +<meta property="twitter:image" content={new URL('/chiri-og.png', Astro.url)} />
63 +
64 +<!-- Transitions Initialization -->
65 +<script is:inline define:vars={{ fadeAnimation: SITE.fadeAnimation }}>
66 + function initMotionPref(doc = document) {
67 + const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches
68 + const supportsViewTransitions = 'startViewTransition' in document
69 +
70 + doc.documentElement.classList.toggle('reduce-motion', prefersReducedMotion)
71 +
72 + doc.documentElement.classList.toggle(
73 + 'disable-transitions',
74 + !fadeAnimation || !supportsViewTransitions
75 + )
76 +
77 + doc.documentElement.classList.add('js')
78 + }
79 +
80 + initMotionPref()
81 +
82 + document.addEventListener('astro:before-swap', ({ newDocument }) => {
83 + initMotionPref(newDocument)
84 + })
85 +
86 + document.addEventListener('astro:page-load', () => {
87 + initMotionPref()
88 + })
89 +
90 + document.addEventListener('visibilitychange', () => {
91 + if (document.visibilityState === 'visible') {
92 + initMotionPref()
93 + }
94 + })
95 +
96 + window.addEventListener('pageshow', () => {
97 + initMotionPref()
98 + })
99 +</script>
src/components/layout/Footer.astro new
+54
@@ -0,0 +1,54 @@
1 +---
2 +import { SITE } from '@/config'
3 +const today = new Date()
4 +---
5 +
6 +<footer>
7 + <div class="footer-content">
8 + <div class="copyright">
9 + <span class="date">
10 + &copy;
11 + {today.getFullYear()}
12 + </span>
13 + {SITE.author}
14 + </div>
15 + <div class="powered-by">
16 + Powered by{' '}
17 + <a href="https://astro.build">Astro</a> &{' '}
18 + <a href="https://github.com/the3ash/astro-chiri">Chiri</a>
19 + </div>
20 + </div>
21 +</footer>
22 +<style>
23 + footer {
24 + font-size: var(--font-size-s);
25 + font-weight: var(--font-weight-light);
26 + line-height: 1.75;
27 + color: var(--text-secondary);
28 + margin-top: 4rem;
29 + }
30 +
31 + .footer-content {
32 + display: flex;
33 + justify-content: space-between;
34 + align-items: center;
35 + flex-direction: row;
36 + flex-wrap: nowrap;
37 + width: 100%;
38 + }
39 +
40 + .copyright,
41 + .powered-by {
42 + white-space: nowrap;
43 + }
44 +
45 + footer a {
46 + color: var(--text-secondary);
47 + text-decoration: none;
48 + transition: color 0.2s ease-out;
49 + }
50 +
51 + footer a:hover {
52 + color: var(--text-primary);
53 + }
54 +</style>
src/components/layout/Header.astro new
+41
@@ -0,0 +1,41 @@
1 +---
2 +import { SITE } from '@/config'
3 +import ThemeToggle from '@/components/ui/ThemeToggle.astro'
4 +---
5 +
6 +<header>
7 + <nav>
8 + <div class="logo-container">
9 + {SITE.favicon && <img src="/favicon.svg" alt="favicon" class="favicon" />}
10 + <a href="/">{SITE.title}</a>
11 + </div>
12 + <ThemeToggle />
13 + </nav>
14 +</header>
15 +<style>
16 + header {
17 + margin: 0 0 1.75rem 0;
18 + }
19 + nav {
20 + display: flex;
21 + justify-content: space-between;
22 + align-items: center;
23 + }
24 + header a {
25 + font-weight: var(--font-weight-bold);
26 + color: var(--text-primary);
27 + text-decoration: none;
28 + min-width: 3rem;
29 + display: inline-block;
30 + }
31 + .logo-container {
32 + position: relative;
33 + }
34 + .favicon {
35 + position: absolute;
36 + width: 1.125rem;
37 + height: 1.125rem;
38 + bottom: calc(100% + 3.5rem);
39 + left: 0;
40 + }
41 +</style>
src/components/layout/TransitionWrapper.astro new
+89
@@ -0,0 +1,89 @@
1 +---
2 +import { SITE } from '@/config'
3 +import type { TransitionProps } from '@/types'
4 +
5 +type Props = TransitionProps
6 +
7 +const { type, class: className = '' } = Astro.props
8 +const transitionName = type === 'post' ? 'post-content' : 'page-content'
9 +---
10 +
11 +{
12 + SITE.fadeAnimation ? (
13 + <div transition:name={transitionName} transition:animate="initial" class={className}>
14 + <slot />
15 + </div>
16 + ) : (
17 + <div class={className}>
18 + <slot />
19 + </div>
20 + )
21 +}
22 +
23 +<style is:global>
24 + @supports (view-transition-name: none) {
25 + @media not (prefers-reduced-motion: reduce) {
26 + ::view-transition-old(post-content),
27 + ::view-transition-old(page-content) {
28 + animation: fade-out 0.4s cubic-bezier(0.4, 0, 0.2, 1) forwards;
29 + }
30 +
31 + ::view-transition-new(post-content),
32 + ::view-transition-new(page-content) {
33 + opacity: 0;
34 + animation: fade-in 0.4s ease 0.2s forwards;
35 + }
36 + }
37 + }
38 +
39 + @keyframes fade-out {
40 + 0% {
41 + opacity: 1;
42 + }
43 + 100% {
44 + opacity: 0;
45 + }
46 + }
47 +
48 + @keyframes fade-in {
49 + 0% {
50 + opacity: 0;
51 + filter: blur(8px);
52 + }
53 + 30% {
54 + opacity: 0.5;
55 + filter: blur(4px);
56 + }
57 + 100% {
58 + opacity: 1;
59 + filter: blur(0);
60 + }
61 + }
62 +
63 + .no-fade ::view-transition-old(post-content),
64 + .no-fade ::view-transition-new(post-content),
65 + .no-fade ::view-transition-old(page-content),
66 + .no-fade ::view-transition-new(page-content),
67 + .disable-transitions ::view-transition-old(post-content),
68 + .disable-transitions ::view-transition-new(post-content),
69 + .disable-transitions ::view-transition-old(page-content),
70 + .disable-transitions ::view-transition-new(page-content) {
71 + animation: none !important;
72 + }
73 +
74 + .reduce-motion ::view-transition-old(post-content),
75 + .reduce-motion ::view-transition-new(post-content),
76 + .reduce-motion ::view-transition-old(page-content),
77 + .reduce-motion ::view-transition-new(page-content) {
78 + animation: none !important;
79 + }
80 +
81 + @media (prefers-reduced-motion: reduce) {
82 + * {
83 + animation-duration: 0.01ms !important;
84 + transition-duration: 0.01ms !important;
85 + animation-iteration-count: 1 !important;
86 + scroll-behavior: auto !important;
87 + }
88 + }
89 +</style>
src/components/pages/About.astro new
+25
@@ -0,0 +1,25 @@
1 +---
2 +import { getEntry } from 'astro:content'
3 +import { render } from 'astro:content'
4 +
5 +const aboutEntry = await getEntry('about', 'about')
6 +// Check if there is actual content (excluding comments)
7 +const hasContent = aboutEntry?.body
8 + ? aboutEntry.body.replace(/<!--[\s\S]*?-->/g, '').trim().length > 0
9 + : false
10 +const { Content } = hasContent && aboutEntry ? await render(aboutEntry) : { Content: null }
11 +---
12 +
13 +{
14 + hasContent && Content && (
15 + <div class="about prose">
16 + <Content />
17 + </div>
18 + )
19 +}
20 +
21 +<style>
22 + .about:not(:empty) {
23 + margin-bottom: 1.25rem;
24 + }
25 +</style>
src/components/ui/BackButton.astro new
+102
@@ -0,0 +1,102 @@
1 +---
2 +import { SITE } from '@/config'
3 +---
4 +
5 +<a href="/" class="back-button">
6 + <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
7 + <path
8 + d="M2.5 6.5H9.5C11.1569 6.5 12.5 7.84315 12.5 9.5V9.5C12.5 11.1569 11.1569 12.5 9.5 12.5H7.5M2.5 6.5L5.5 9.5M2.5 6.5L5.5 3.5"
9 + stroke="currentColor"
10 + stroke-width="1.25"
11 + stroke-linecap="round"
12 + stroke-linejoin="round"></path>
13 + </svg>
14 + index
15 +</a>
16 +
17 +<script
18 + is:inline
19 + define:vars={{ contentWidth: SITE.contentWidth, centeredLayout: SITE.centeredLayout }}
20 +>
21 + ;(function () {
22 + // Adjust back button position based on layout and screen size
23 + function adjustBackButtonPosition() {
24 + const button = document.querySelector('.back-button')
25 + if (!button) return
26 +
27 + // If not using centered layout, remove fixed positioning
28 + if (!centeredLayout) {
29 + button.classList.remove('fixed-position')
30 + button.style.left = ''
31 + return
32 + }
33 +
34 + // Calculate available margin space for positioning
35 + const pageWidth = window.innerWidth
36 + const contentWidthValue = parseFloat(contentWidth)
37 + const margin = (pageWidth - contentWidthValue * 16) / 2
38 + const minSpace = 9 * 16 // Minimum space needed
39 +
40 + // Position button fixed on the left if there's enough space
41 + if (margin >= minSpace) {
42 + button.classList.add('fixed-position')
43 + button.style.left = `${margin - minSpace}px`
44 + } else {
45 + button.classList.remove('fixed-position')
46 + button.style.left = ''
47 + }
48 + }
49 +
50 + adjustBackButtonPosition()
51 +
52 + document.addEventListener('astro:page-load', () => {
53 + adjustBackButtonPosition()
54 + })
55 + document.addEventListener('DOMContentLoaded', () => {
56 + adjustBackButtonPosition()
57 + })
58 + window.addEventListener('resize', adjustBackButtonPosition)
59 + })()
60 +</script>
61 +
62 +<style>
63 + .back-button {
64 + width: 128px;
65 + display: inline-flex;
66 + align-items: center;
67 + gap: 0.375rem;
68 + font-family: var(--font-serif);
69 + font-size: var(--font-size-m);
70 + font-style: italic;
71 + letter-spacing: 0;
72 + line-height: 1.75;
73 + color: var(--text-secondary);
74 + cursor: pointer;
75 + border: none;
76 + background-color: transparent;
77 + position: relative;
78 + margin-bottom: 2.5em;
79 + padding: 0;
80 + left: -0.175em;
81 + transition: color 0.2s ease-out;
82 + text-decoration: none;
83 + }
84 +
85 + .back-button:hover {
86 + color: var(--text-primary);
87 + }
88 +
89 + .back-button svg {
90 + width: 0.8rem;
91 + height: 0.8rem;
92 + flex-shrink: 0;
93 + }
94 +
95 + .back-button.fixed-position {
96 + position: fixed;
97 + top: 6rem;
98 + margin-bottom: 0;
99 + padding-left: 1rem;
100 + z-index: 10;
101 + }
102 +</style>
src/components/ui/CopyCode.astro new
+179
@@ -0,0 +1,179 @@
1 +---
2 +import { SITE } from '@/config'
3 +---
4 +
5 +<script define:vars={{ copyCode: SITE.copyCode }}>
6 + function initCopyCode() {
7 + const copyIcon = `
8 + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="14" height="14" fill="currentColor">
9 + <path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path>
10 + <path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>
11 + </svg>
12 + `
13 +
14 + const copiedIcon = `
15 + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
16 + <path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path>
17 + </svg>
18 + `
19 +
20 + document.documentElement.setAttribute('data-copy-code', copyCode ? 'enabled' : 'disabled')
21 +
22 + if (!copyCode) {
23 + return
24 + }
25 +
26 + const copyButtons = document.querySelectorAll('.copy-button')
27 +
28 + copyButtons.forEach((button) => {
29 + const preElement = button.closest('.copy-code-block')
30 + if (!preElement) return
31 +
32 + const codeElement = preElement.querySelector('code')
33 + if (!codeElement) return
34 +
35 + if (!button.querySelector('svg')) {
36 + button.innerHTML = copyIcon
37 + }
38 +
39 + button.style.opacity = '0'
40 + button.style.pointerEvents = 'none'
41 +
42 + preElement.addEventListener('mouseenter', () => {
43 + button.style.opacity = '1'
44 + button.style.pointerEvents = 'auto'
45 + })
46 +
47 + preElement.addEventListener('mouseleave', () => {
48 + if (!button.hasAttribute('data-copying')) {
49 + button.style.opacity = '0'
50 + button.style.pointerEvents = 'none'
51 + }
52 + })
53 +
54 + button.addEventListener('click', async () => {
55 + const codeText = codeElement.textContent || ''
56 +
57 + try {
58 + // Primary method: use modern clipboard API
59 + await navigator.clipboard.writeText(codeText)
60 + button.setAttribute('data-copying', 'true')
61 + button.innerHTML = copiedIcon
62 +
63 + setTimeout(() => {
64 + if (!preElement.matches(':hover')) {
65 + button.style.opacity = '0'
66 + button.style.pointerEvents = 'none'
67 + }
68 + button.removeAttribute('data-copying')
69 +
70 + setTimeout(() => {
71 + button.innerHTML = copyIcon
72 + }, 500)
73 + }, 1500)
74 + } catch (err) {
75 + console.error('Failed to copy code:', err)
76 +
77 + // Fallback method: create temporary textarea for older browsers
78 + try {
79 + const textArea = document.createElement('textarea')
80 + textArea.value = codeText
81 + textArea.style.position = 'fixed'
82 + textArea.style.opacity = '0'
83 + document.body.appendChild(textArea)
84 + textArea.focus()
85 + textArea.select()
86 +
87 + navigator.clipboard
88 + .writeText(codeText)
89 + .then(() => {
90 + document.body.removeChild(textArea)
91 + })
92 + .catch(() => {
93 + console.error('Both clipboard methods failed')
94 + document.body.removeChild(textArea)
95 + })
96 + } catch (fallbackErr) {
97 + console.error('All clipboard methods failed:', fallbackErr)
98 + }
99 +
100 + button.setAttribute('data-copying', 'true')
101 + button.innerHTML = copiedIcon
102 +
103 + setTimeout(() => {
104 + if (!preElement.matches(':hover')) {
105 + button.style.opacity = '0'
106 + button.style.pointerEvents = 'none'
107 + }
108 + button.removeAttribute('data-copying')
109 +
110 + setTimeout(() => {
111 + button.innerHTML = copyIcon
112 + }, 500)
113 + }, 1500)
114 + }
115 + })
116 + })
117 + }
118 +
119 + document.addEventListener('astro:page-load', initCopyCode)
120 + document.addEventListener('DOMContentLoaded', initCopyCode)
121 +</script>
122 +
123 +<style is:global>
124 + .copy-code-block {
125 + position: relative !important;
126 + }
127 +
128 + .copy-button {
129 + position: absolute;
130 + top: 0.5rem;
131 + right: 0.5rem;
132 + width: 2rem;
133 + height: 2rem;
134 + z-index: 10;
135 + background: var(--bg);
136 + border-radius: 0.375rem;
137 + font-size: 0.75rem;
138 + color: var(--text-secondary);
139 + cursor: pointer;
140 + transition: all 0.15s ease-out;
141 + display: flex;
142 + align-items: center;
143 + justify-content: center;
144 + border: 1px solid var(--border);
145 + backdrop-filter: blur(48px);
146 + }
147 +
148 + [data-copy-code='disabled'] .copy-button {
149 + display: none !important;
150 + }
151 +
152 + .copy-button::before {
153 + content: '';
154 + position: absolute;
155 + top: 0;
156 + left: 0;
157 + right: 0;
158 + bottom: 0;
159 + background: var(--code-bg);
160 + border-radius: 0.325rem;
161 + opacity: 0;
162 + transition: opacity 0.15s ease-out;
163 + pointer-events: none;
164 + }
165 +
166 + .copy-button:hover::before {
167 + opacity: 1;
168 + }
169 +
170 + .copy-button:hover {
171 + color: var(--text-primary);
172 + }
173 +
174 + .copy-button svg {
175 + flex-shrink: 0;
176 + position: relative;
177 + z-index: 1;
178 + }
179 +</style>
src/components/ui/GitHubCard.astro new
+259
@@ -0,0 +1,259 @@
1 +<script>
2 + let githubCardsObserver: IntersectionObserver | null = null
3 +
4 + interface GitHubRepoData {
5 + owner?: {
6 + avatar_url: string
7 + }
8 + description?: string
9 + stargazers_count?: number
10 + forks_count?: number
11 + license?: {
12 + spdx_id: string
13 + }
14 + }
15 +
16 + interface CachedRepoData {
17 + data: GitHubRepoData
18 + timestamp: number
19 + }
20 +
21 + // Retrieve cached GitHub repository data from localStorage with expiration check
22 + function getCachedData(repo: string): GitHubRepoData | null {
23 + try {
24 + const cacheKey = `github-repo-${repo}`
25 + const cached = localStorage.getItem(cacheKey)
26 +
27 + if (!cached) {
28 + return null
29 + }
30 +
31 + const parsedCache: CachedRepoData = JSON.parse(cached)
32 + const now = Date.now()
33 + const oneHour = 60 * 60 * 1000 // 1 hour in milliseconds
34 +
35 + // Check if cache is expired (older than 1 hour)
36 + if (now - parsedCache.timestamp > oneHour) {
37 + localStorage.removeItem(cacheKey)
38 + return null
39 + }
40 +
41 + return parsedCache.data
42 + } catch (error) {
43 + console.warn('Failed to read from cache:', error)
44 + return null
45 + }
46 + }
47 +
48 + // Store GitHub repository data in localStorage with timestamp for cache expiration
49 + function setCachedData(repo: string, data: GitHubRepoData): void {
50 + try {
51 + const cacheKey = `github-repo-${repo}`
52 + const cacheData: CachedRepoData = {
53 + data,
54 + timestamp: Date.now()
55 + }
56 + localStorage.setItem(cacheKey, JSON.stringify(cacheData))
57 + } catch (error) {
58 + console.warn('Failed to save to cache:', error)
59 + }
60 + }
61 +
62 + interface CardElements {
63 + avatar: HTMLElement | null
64 + desc: HTMLElement | null
65 + stars: HTMLElement | null
66 + forks: HTMLElement | null
67 + license: HTMLElement | null
68 + }
69 +
70 + // Update the GitHub card UI elements with fetched repository data
71 + function updateCardUI(el: CardElements, data: GitHubRepoData) {
72 + const numberFormat = new Intl.NumberFormat('en', {
73 + notation: 'compact',
74 + maximumFractionDigits: 1
75 + })
76 +
77 + if (el.avatar && data.owner?.avatar_url) {
78 + el.avatar.style.backgroundImage = `url(${data.owner.avatar_url})`
79 + }
80 +
81 + if (el.desc) {
82 + el.desc.textContent = data.description ?? 'No description'
83 + }
84 +
85 + if (el.stars) {
86 + el.stars.textContent = numberFormat.format(data.stargazers_count ?? 0)
87 + }
88 +
89 + if (el.forks) {
90 + el.forks.textContent = numberFormat.format(data.forks_count ?? 0)
91 + }
92 +
93 + if (el.license) {
94 + el.license.textContent = data.license?.spdx_id ?? 'No License'
95 + }
96 + }
97 +
98 + // Load GitHub repository data for a card, using cache if available or fetching from API
99 + async function loadCardData(card: HTMLElement) {
100 + const repo = card.dataset.repo
101 + if (!repo) {
102 + return
103 + }
104 +
105 + const el = {
106 + avatar: card.querySelector('.gc-owner-avatar') as HTMLElement,
107 + desc: card.querySelector('.gc-repo-description') as HTMLElement,
108 + stars: card.querySelector('.gc-stars-count') as HTMLElement,
109 + forks: card.querySelector('.gc-forks-count') as HTMLElement,
110 + license: card.querySelector('.gc-license-info') as HTMLElement
111 + } as const
112 +
113 + // Try to get cached data first
114 + const cachedData = getCachedData(repo)
115 + if (cachedData) {
116 + updateCardUI(el, cachedData)
117 + return
118 + }
119 +
120 + // If no cache, fetch from API
121 + try {
122 + const response = await fetch(`https://api.github.com/repos/${repo}`)
123 +
124 + if (!response.ok) {
125 + if (el.desc) {
126 + el.desc.textContent = '⚠ Loading failed'
127 + }
128 + return
129 + }
130 +
131 + const data = await response.json()
132 +
133 + setCachedData(repo, data)
134 +
135 + updateCardUI(el, data)
136 + } catch (error) {
137 + console.error(`Failed to fetch ${repo}:`, error)
138 + if (el.desc) {
139 + el.desc.textContent = '⚠ Loading failed'
140 + }
141 + }
142 + }
143 +
144 + // Set up intersection observer for lazy loading GitHub cards when they enter viewport
145 + function lazySetupGithubCards() {
146 + githubCardsObserver?.disconnect()
147 +
148 + const githubCards = document.getElementsByClassName('gc-container')
149 + if (githubCards.length === 0) {
150 + return
151 + }
152 +
153 + // Create an intersection observer to lazy load GitHub repo data when cards enter viewport
154 + githubCardsObserver = new IntersectionObserver(
155 + (entries) => {
156 + entries.forEach((entry) => {
157 + if (entry.isIntersecting) {
158 + loadCardData(entry.target as HTMLElement)
159 + githubCardsObserver?.unobserve(entry.target)
160 + }
161 + })
162 + },
163 + { rootMargin: '200px' }
164 + )
165 +
166 + Array.from(githubCards).forEach((card) => githubCardsObserver?.observe(card))
167 + }
168 +
169 + lazySetupGithubCards()
170 + document.addEventListener('astro:page-load', lazySetupGithubCards)
171 +</script>
172 +
173 +<style>
174 + :global(.prose .gc-container) {
175 + display: block;
176 + border: 0.5px solid var(--border);
177 + border-radius: 10px;
178 + padding: 1rem 1.25rem 0.75rem 1.25rem;
179 + margin: 1.25rem 0 1.75rem 0;
180 + text-decoration: none;
181 + color: inherit;
182 + transition: background 0.2s ease-out;
183 + background: var(--astro-code-background);
184 + }
185 +
186 + :global(.prose .gc-container:hover) {
187 + background: var(--code-bg);
188 + text-decoration: none;
189 + }
190 +
191 + :global(.prose .gc-title-bar) {
192 + display: flex;
193 + align-items: center;
194 + gap: 0.75rem;
195 + margin-bottom: 0.75rem;
196 + }
197 +
198 + :global(.prose .gc-owner-avatar) {
199 + width: 1.5rem;
200 + height: 1.5rem;
201 + border-radius: 50%;
202 + background-color: var(--border);
203 + flex-shrink: 0;
204 + }
205 +
206 + :global(.prose .gc-repo-title) {
207 + font-size: var(--font-size-xl);
208 + font-weight: var(--font-weight-regular);
209 + color: var(--text-primary);
210 + flex-grow: 1;
211 + }
212 +
213 + :global(.prose .gc-repo-title strong) {
214 + font-weight: var(--font-weight-bold);
215 + }
216 +
217 + :global(.prose .gc-slash) {
218 + color: var(--text-secondary);
219 + margin: 0 0.375rem;
220 + }
221 +
222 + :global(.prose .gc-github-icon) {
223 + width: 1.5rem;
224 + height: 1.5rem;
225 + color: var(--text-primary);
226 + flex-shrink: 0;
227 + }
228 +
229 + :global(.prose .gc-repo-description) {
230 + font-size: var(--font-size-m);
231 + color: var(--text-primary);
232 + opacity: 0.75;
233 + margin: 0 0 0.75rem 0;
234 + line-height: 1.4;
235 + }
236 +
237 + :global(.prose .gc-info-bar) {
238 + display: flex;
239 + align-items: center;
240 + color: var(--text-primary);
241 + opacity: 0.75;
242 + gap: 0.35rem;
243 + }
244 +
245 + :global(
246 + .prose .gc-info-bar .gc-stars-count,
247 + .prose .gc-info-bar .gc-forks-count,
248 + .prose .gc-info-bar .gc-license-info
249 + ) {
250 + margin-right: 0.675rem;
251 + font-size: var(--font-size-s);
252 + }
253 +
254 + :global(.prose .gc-info-icon) {
255 + color: var(--text-primary);
256 + width: 0.875rem;
257 + height: 0.875rem;
258 + }
259 +</style>
src/components/ui/GradientMask.astro new
+55
@@ -0,0 +1,55 @@
1 +<div class="gradient-mask">
2 + <slot />
3 +</div>
4 +
5 +<script>
6 + function updateMask() {
7 + const mask = document.querySelector('.gradient-mask') as HTMLElement
8 + const threshold = 64
9 + const scrollY = window.scrollY
10 +
11 + if (scrollY >= threshold) {
12 + mask.style.opacity = '1'
13 + } else {
14 + mask.style.opacity = '0'
15 + }
16 + }
17 +
18 + document.addEventListener('DOMContentLoaded', () => {
19 + updateMask()
20 + window.addEventListener('scroll', updateMask)
21 + })
22 +</script>
23 +
24 +<style>
25 + .gradient-mask {
26 + position: fixed;
27 + top: 0;
28 + left: 0;
29 + width: 100%;
30 + height: 6rem;
31 + z-index: 99;
32 + pointer-events: none;
33 + background: linear-gradient(to bottom, var(--bg) 0%, transparent 100%);
34 + mask-image: linear-gradient(
35 + to bottom,
36 + black 0%,
37 + rgba(0, 0, 0, 0.8) 20%,
38 + rgba(0, 0, 0, 0.6) 40%,
39 + rgba(0, 0, 0, 0.4) 60%,
40 + rgba(0, 0, 0, 0.2) 80%,
41 + transparent 100%
42 + );
43 + -webkit-mask-image: linear-gradient(
44 + to bottom,
45 + black 0%,
46 + rgba(0, 0, 0, 0.8) 20%,
47 + rgba(0, 0, 0, 0.6) 40%,
48 + rgba(0, 0, 0, 0.4) 60%,
49 + rgba(0, 0, 0, 0.2) 80%,
50 + transparent 100%
51 + );
52 + opacity: 0;
53 + transition: opacity 0.3s ease;
54 + }
55 +</style>
src/components/ui/ImageViewer.astro new
+129
@@ -0,0 +1,129 @@
1 +<div id="image-viewer" class="image-viewer">
2 + <img id="image-viewer-img" src="" alt="" />
3 +</div>
4 +
5 +<script>
6 + function initImageViewer() {
7 + const viewer = document.getElementById('image-viewer')
8 + const viewerImg = document.getElementById('image-viewer-img') as HTMLImageElement
9 +
10 + if (!viewer || !viewerImg || viewerImg.tagName !== 'IMG') return
11 +
12 + // Display image in fullscreen viewer overlay
13 + function showImage(src: string, alt?: string) {
14 + if (viewerImg && src) {
15 + viewerImg.src = src
16 + viewerImg.alt = alt || ''
17 + }
18 + viewer?.classList.add('active')
19 + document.body.classList.add('image-viewer-open')
20 + document.body.style.overflow = 'hidden'
21 + if (viewer) {
22 + viewer.style.cursor = 'auto'
23 + setTimeout(() => {
24 + viewer.style.cursor = ''
25 + }, 10)
26 + }
27 + }
28 +
29 + // Hide the image viewer and restore page scroll
30 + function hideImage() {
31 + viewer?.classList.remove('active')
32 + document.body.classList.remove('image-viewer-open')
33 + document.body.style.overflow = ''
34 + setTimeout(() => {
35 + if (viewer && !viewer.classList.contains('active') && viewerImg) {
36 + viewerImg.src = ''
37 + viewerImg.alt = ''
38 + viewer.style.cursor = 'auto'
39 + setTimeout(() => {
40 + viewer.style.cursor = ''
41 + }, 10)
42 + }
43 + }, 300)
44 + }
45 +
46 + // Bind click events to images with data-preview="true" attribute
47 + function bindImageClickEvents() {
48 + const previewImages = document.querySelectorAll('img[data-preview="true"]')
49 + previewImages.forEach((img) => {
50 + const imgElement = img as HTMLImageElement
51 + imgElement.style.cursor = 'zoom-in'
52 + imgElement.addEventListener('click', (e) => {
53 + e.preventDefault()
54 + const target = e.target as HTMLImageElement
55 + showImage(target.src, target.alt || '')
56 + })
57 + })
58 + }
59 +
60 + viewer?.addEventListener('click', hideImage)
61 +
62 + document.addEventListener('keydown', (e) => {
63 + if (e.key === 'Escape' && viewer.classList.contains('active')) {
64 + hideImage()
65 + }
66 + })
67 +
68 + bindImageClickEvents()
69 +
70 + const observer = new MutationObserver(() => {
71 + bindImageClickEvents()
72 + })
73 +
74 + observer.observe(document.body, {
75 + childList: true,
76 + subtree: true
77 + })
78 + }
79 +
80 + if (document.readyState === 'loading') {
81 + document.addEventListener('DOMContentLoaded', initImageViewer)
82 + } else {
83 + initImageViewer()
84 + }
85 +
86 + document.addEventListener('astro:page-load', initImageViewer)
87 +</script>
88 +
89 +<style>
90 + .image-viewer {
91 + position: fixed;
92 + top: 0;
93 + left: 0;
94 + width: 100%;
95 + height: 100%;
96 + z-index: 9999;
97 + display: flex;
98 + align-items: center;
99 + justify-content: center;
100 + opacity: 0;
101 + visibility: hidden;
102 + transition: all 0.15s ease-in-out;
103 + background: color-mix(in srgb, var(--bg) 90%, transparent);
104 + cursor: zoom-out;
105 + }
106 +
107 + .image-viewer.active {
108 + opacity: 1;
109 + visibility: visible;
110 + }
111 +
112 + .image-viewer img {
113 + min-width: 45rem;
114 + max-width: 60vw;
115 + max-height: 80vh;
116 + object-fit: contain;
117 + cursor: zoom-out;
118 + }
119 +
120 + @media (max-width: 768px) {
121 + .image-viewer img {
122 + min-width: 100vw;
123 + }
124 + }
125 +
126 + body.image-viewer-open {
127 + overflow: hidden;
128 + }
129 +</style>
src/components/ui/ThemeToggle.astro new
+124
@@ -0,0 +1,124 @@
1 +---
2 +import { SITE } from '@/config'
3 +---
4 +
5 +{
6 + SITE.themeToggle && (
7 + <button id="theme-toggle" class="theme-toggle" aria-label="Toggle theme">
8 + <div class="theme-icon hollow-circle" />
9 + <div class="theme-icon solid-circle" />
10 + </button>
11 + )
12 +}
13 +
14 +<script is:inline>
15 + window.addEventListener('DOMContentLoaded', function () {
16 + const htmlElement = document.documentElement
17 +
18 + // Get system theme preference
19 + function getSystemTheme() {
20 + const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches
21 + return isDark ? 'dark' : 'light'
22 + }
23 +
24 + // Get current actual theme state
25 + function getCurrentTheme() {
26 + const hasLight = htmlElement.classList.contains('light')
27 + const hasDark = htmlElement.classList.contains('dark')
28 +
29 + if (hasLight) {
30 + return 'light'
31 + }
32 + if (hasDark) {
33 + return 'dark'
34 + }
35 +
36 + const systemTheme = getSystemTheme()
37 + return systemTheme
38 + }
39 +
40 + // Apply theme
41 + function applyTheme(theme) {
42 + htmlElement.classList.remove('light', 'dark')
43 +
44 + if (theme === 'dark') {
45 + htmlElement.classList.add('dark')
46 + } else {
47 + htmlElement.classList.add('light')
48 + }
49 + }
50 +
51 + // Initialize theme - ensure explicit classes are always present
52 + function initTheme() {
53 + const systemTheme = getSystemTheme()
54 + applyTheme(systemTheme)
55 + }
56 +
57 + // Listen for system theme changes
58 + const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
59 + mediaQuery.addEventListener('change', function (e) {
60 + const newTheme = e.matches ? 'dark' : 'light'
61 + applyTheme(newTheme)
62 + })
63 +
64 + // Get theme toggle button (only if it exists)
65 + const themeToggle = document.getElementById('theme-toggle')
66 + if (themeToggle) {
67 + // Toggle theme function
68 + function toggleTheme() {
69 + const currentTheme = getCurrentTheme()
70 + const newTheme = currentTheme === 'dark' ? 'light' : 'dark'
71 + applyTheme(newTheme)
72 + }
73 +
74 + themeToggle.addEventListener('click', function (e) {
75 + e.preventDefault()
76 + e.stopPropagation()
77 + toggleTheme()
78 + })
79 + }
80 +
81 + initTheme()
82 + })
83 +</script>
84 +
85 +<style>
86 + .theme-toggle {
87 + background: none;
88 + border: none;
89 + cursor: pointer;
90 + display: flex;
91 + align-items: center;
92 + height: 1.5rem;
93 + gap: 0.325rem;
94 + color: var(--text-primary);
95 + transition: opacity 0.2s ease;
96 + padding: 0;
97 + position: relative;
98 + }
99 +
100 + .theme-toggle:hover {
101 + opacity: 0.7;
102 + }
103 +
104 + .theme-toggle:active {
105 + opacity: 0.5;
106 + }
107 +
108 + .theme-icon {
109 + width: 0.5625rem;
110 + height: 0.5625rem;
111 + transition: all 0.2s ease;
112 + }
113 +
114 + .hollow-circle {
115 + border: none;
116 + border-radius: 50%;
117 + box-shadow: inset 0 0 0 1.5px var(--text-primary);
118 + }
119 +
120 + .solid-circle {
121 + background-color: var(--text-primary);
122 + border-radius: 50%;
123 + }
124 +</style>
src/components/ui/XPOST.astro new
+43
@@ -0,0 +1,43 @@
1 +<script>
2 + function loadXCards() {
3 + const xCards = document.querySelectorAll('.twitter-tweet')
4 + if (xCards.length === 0) return
5 +
6 + if (document.querySelector('script[src*="platform.twitter.com/widgets.js"]')) {
7 + return
8 + }
9 +
10 + const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches
11 + xCards.forEach((element) => {
12 + element.setAttribute('data-theme', isDark ? 'dark' : 'light')
13 + })
14 +
15 + const script = document.createElement('script')
16 + script.src = 'https://platform.twitter.com/widgets.js'
17 + script.async = true
18 + document.head.appendChild(script)
19 + }
20 +
21 + document.addEventListener('DOMContentLoaded', loadXCards)
22 +
23 + document.addEventListener('astro:page-load', loadXCards)
24 +</script>
25 +
26 +<style>
27 + :global(.prose .x-card) {
28 + width: 100%;
29 + margin: 1em auto;
30 + text-align: center;
31 + }
32 +
33 + :global(.prose .x-card > *) {
34 + display: inline-block;
35 + max-width: 100%;
36 + margin: 0 auto;
37 + }
38 +
39 + :global(.prose .x-card iframe) {
40 + max-width: 100%;
41 + width: auto;
42 + }
43 +</style>
src/components/ui/_VariableBlurMask.astro new
+160
@@ -0,0 +1,160 @@
1 +<div class="variable-blur-mask">
2 + <div class="blur-bottom">
3 + <!-- Layer 1 -->
4 + <div
5 + class="blur-layer layer-1"
6 + style={{
7 + maskImage:
8 + 'linear-gradient(to top, rgba(0,0,0,0) 0%, rgba(255,255,255,1) 12.5%, rgba(255,255,255,1) 25%, rgba(0,0,0,0) 37.5%)',
9 + WebkitMaskImage:
10 + 'linear-gradient(to top, rgba(0,0,0,0) 0%, rgba(255,255,255,1) 12.5%, rgba(255,255,255,1) 25%, rgba(0,0,0,0) 37.5%)'
11 + }}
12 + >
13 + </div>
14 + <!-- Layer 2 -->
15 + <div
16 + class="blur-layer layer-2"
17 + style={{
18 + maskImage:
19 + 'linear-gradient(to top, rgba(0,0,0,0) 12.5%, rgba(255,255,255,1) 25%, rgba(255,255,255,1) 37.5%, rgba(0,0,0,0) 50%)',
20 + WebkitMaskImage:
21 + 'linear-gradient(to top, rgba(0,0,0,0) 12.5%, rgba(255,255,255,1) 25%, rgba(255,255,255,1) 37.5%, rgba(0,0,0,0) 50%)'
22 + }}
23 + >
24 + </div>
25 + <!-- Layer 3 -->
26 + <div
27 + class="blur-layer layer-3"
28 + style={{
29 + maskImage:
30 + 'linear-gradient(to top, rgba(0,0,0,0) 25%, rgba(255,255,255,1) 37.5%, rgba(255,255,255,1) 50%, rgba(0,0,0,0) 62.5%)',
31 + WebkitMaskImage:
32 + 'linear-gradient(to top, rgba(0,0,0,0) 25%, rgba(255,255,255,1) 37.5%, rgba(255,255,255,1) 50%, rgba(0,0,0,0) 62.5%)'
33 + }}
34 + >
35 + </div>
36 + <!-- Layer 4 -->
37 + <div
38 + class="blur-layer layer-4"
39 + style={{
40 + maskImage:
41 + 'linear-gradient(to top, rgba(0,0,0,0) 37.5%, rgba(255,255,255,1) 50%, rgba(255,255,255,1) 62.5%, rgba(0,0,0,0) 75%)',
42 + WebkitMaskImage:
43 + 'linear-gradient(to top, rgba(0,0,0,0) 37.5%, rgba(255,255,255,1) 50%, rgba(255,255,255,1) 62.5%, rgba(0,0,0,0) 75%)'
44 + }}
45 + >
46 + </div>
47 + <!-- Layer 5 -->
48 + <div
49 + class="blur-layer layer-5"
50 + style={{
51 + maskImage:
52 + 'linear-gradient(to top, rgba(0,0,0,0) 50%, rgba(255,255,255,1) 62.5%, rgba(255,255,255,1) 75%, rgba(0,0,0,0) 87.5%)',
53 + WebkitMaskImage:
54 + 'linear-gradient(to top, rgba(0,0,0,0) 50%, rgba(255,255,255,1) 62.5%, rgba(255,255,255,1) 75%, rgba(0,0,0,0) 87.5%)'
55 + }}
56 + >
57 + </div>
58 + <!-- Layer 6 -->
59 + <div
60 + class="blur-layer layer-6"
61 + style={{
62 + maskImage:
63 + 'linear-gradient(to top, rgba(0,0,0,0) 62.5%, rgba(255,255,255,1) 75%, rgba(255,255,255,1) 87.5%, rgba(0,0,0,0) 100%)',
64 + WebkitMaskImage:
65 + 'linear-gradient(to top, rgba(0,0,0,0) 62.5%, rgba(255,255,255,1) 75%, rgba(255,255,255,1) 87.5%, rgba(0,0,0,0) 100%)'
66 + }}
67 + >
68 + </div>
69 + <!-- Layer 7 -->
70 + <div
71 + class="blur-layer layer-7"
72 + style={{
73 + maskImage:
74 + 'linear-gradient(to top, rgba(0,0,0,0) 75%, rgba(255,255,255,1) 87.5%, rgba(255,255,255,1) 100%)',
75 + WebkitMaskImage:
76 + 'linear-gradient(to top, rgba(0,0,0,0) 75%, rgba(255,255,255,1) 87.5%, rgba(255,255,255,1) 100%)'
77 + }}
78 + >
79 + </div>
80 + <!-- Layer 8 -->
81 + <div
82 + class="blur-layer layer-8"
83 + style={{
84 + maskImage: 'linear-gradient(to top, rgba(0,0,0,0) 87.5%, rgba(255,255,255,1) 100%)',
85 + WebkitMaskImage: 'linear-gradient(to top, rgba(0,0,0,0) 87.5%, rgba(255,255,255,1) 100%)'
86 + }}
87 + >
88 + </div>
89 + </div>
90 + <slot />
91 +</div>
92 +
93 +<style>
94 + .variable-blur-mask {
95 + position: fixed;
96 + top: 0;
97 + left: 0;
98 + width: 100%;
99 + height: 4rem;
100 + z-index: 99;
101 + pointer-events: none;
102 + }
103 +
104 + .blur-bottom {
105 + position: absolute;
106 + top: 0;
107 + left: 0;
108 + width: 100%;
109 + height: 100%;
110 + pointer-events: none;
111 + }
112 +
113 + .blur-layer {
114 + position: absolute;
115 + top: 0;
116 + left: 0;
117 + width: 100%;
118 + height: 100%;
119 + }
120 +
121 + .layer-1 {
122 + z-index: 1;
123 + backdrop-filter: blur(0.5px);
124 + }
125 +
126 + .layer-2 {
127 + z-index: 2;
128 + backdrop-filter: blur(1px);
129 + }
130 +
131 + .layer-3 {
132 + z-index: 3;
133 + backdrop-filter: blur(2px);
134 + }
135 +
136 + .layer-4 {
137 + z-index: 4;
138 + backdrop-filter: blur(4px);
139 + }
140 +
141 + .layer-5 {
142 + z-index: 5;
143 + backdrop-filter: blur(8px);
144 + }
145 +
146 + .layer-6 {
147 + z-index: 6;
148 + backdrop-filter: blur(16px);
149 + }
150 +
151 + .layer-7 {
152 + z-index: 7;
153 + backdrop-filter: blur(32px);
154 + }
155 +
156 + .layer-8 {
157 + z-index: 8;
158 + backdrop-filter: blur(64px);
159 + }
160 +</style>
src/config.ts new
+26
@@ -0,0 +1,26 @@
1 +export const SITE = {
2 + // SITE INFO ///////////////////////////////////////////////////////////////////////////////////////////
3 + website: 'https://astro-chiri.netlify.app/', // Site domain
4 + title: 'CHIRI', // Site title
5 + author: '3ASH', // Author name
6 + description: 'Minimal blog built by Astro', // Site description
7 + language: 'en-US', // Default language
8 +
9 + // GENERAL SETTINGS ////////////////////////////////////////////////////////////////////////////////////
10 + contentWidth: '35rem', // Content area width
11 + centeredLayout: true, // Use centered layout (false for left-aligned)
12 + favicon: false, // Show favicon on index page
13 + themeToggle: false, // Show theme toggle button
14 + footer: true, // Show footer
15 + fadeAnimation: true, // Enable fade animations
16 +
17 + // DATE SETTINGS ///////////////////////////////////////////////////////////////////////////////////////
18 + dateFormat: 'YYYY-MM-DD', // Date format: YYYY-MM-DD, MM-DD-YYYY, DD-MM-YYYY, MONTH DAY YYYY, DAY MONTH YYYY
19 + dateSeparator: '.', // Date separator: . - / (except for MONTH DAY YYYY and DAY MONTH YYYY)
20 + dateOnRight: true, // Date position in post list (true for right, false for left)
21 +
22 + // POST SETTINGS ///////////////////////////////////////////////////////////////////////////////////////
23 + readingTime: false, // Show reading time in posts
24 + imageViewer: true, // Enable image viewer
25 + copyCode: false // Enable copy button in code blocks
26 +}
src/content.config.ts new
+24
@@ -0,0 +1,24 @@
1 +import { glob } from 'astro/loaders'
2 +import { defineCollection, z } from 'astro:content'
3 +
4 +const posts = defineCollection({
5 + // Load Markdown and MDX files in the `src/content/posts/` directory.
6 + loader: glob({ base: './src/content/posts', pattern: '**/*.{md,mdx}' }),
7 + // Type-check frontmatter using a schema
8 + schema: () =>
9 + z.object({
10 + title: z.string(),
11 + // Transform string to Date object
12 + pubDate: z.coerce.date(),
13 + image: z.string().optional()
14 + })
15 +})
16 +
17 +const about = defineCollection({
18 + // Load Markdown files in the `src/content/about/` directory.
19 + loader: glob({ base: './src/content/about', pattern: '**/*.md' }),
20 + // Type-check frontmatter using a schema
21 + schema: z.object({})
22 +})
23 +
24 +export const collections = { posts, about }
src/content/about/about.md new
+16
@@ -0,0 +1,16 @@
1 +---
2 +title: About
3 +---
4 +
5 +<!--
6 +This content will be displayed at the top of the index page.
7 +You can leave this empty if you don’t want to show any content.
8 +-->
9 +
10 +A static blog theme based on [Astro](https://astro.build), designed for clarity and focus.
11 +
12 +The layout is intentionally minimal, letting your content take center stage without distraction. Built with flexibility in mind, the theme offers some freedom to customize while preserving its clean aesthetic.
13 +
14 +Effortlessly share your thoughts in _a calm & dustless space._
15 +
16 +Check posts below for details and view source on [GitHub](https://github.com/the3ash/astro-chiri).
src/content/config.ts new
+13
@@ -0,0 +1,13 @@
1 +import { defineCollection, z } from 'astro:content'
2 +
3 +const posts = defineCollection({
4 + type: 'content',
5 + schema: z.object({
6 + title: z.string(),
7 + pubDate: z.date()
8 + })
9 +})
10 +
11 +export const collections = {
12 + posts
13 +}
src/content/posts/KaTeX-example.md new
+49
@@ -0,0 +1,49 @@
1 +---
2 +title: 'KaTeX Examples'
3 +pubDate: '2025-05-19'
4 +---
5 +
6 +This theme includes built-in KaTeX support for rendering mathematical expressions in your content.
7 +
8 +---
9 +
10 +## Examples
11 +
12 +- Inline math: $E = mc^2$
13 +- Block math:
14 +
15 +$$
16 +\begin{equation}
17 +\sum_{i=1}^{k+1} i = \left(\sum_{i=1}^{k} i\right) + (k+1)
18 +\end{equation}
19 +$$
20 +
21 +$$
22 +\begin{equation}
23 += \frac{k(k+1)}{2} + k + 1
24 +\end{equation}
25 +$$
26 +
27 +$$
28 +\begin{equation}
29 += \frac{k(k+1) + 2(k+1)}{2}
30 +\end{equation}
31 +$$
32 +
33 +$$
34 +\begin{equation}
35 += \frac{(k+1)(k+2)}{2}
36 +\end{equation}
37 +$$
38 +
39 +$$
40 +\begin{equation}
41 += \frac{(k+1)((k+1)+1)}{2}
42 +\end{equation}
43 +$$
44 +
45 +---
46 +
47 +## Ref
48 +
49 +- [KaTeX Documentation](https://katex.org/docs/supported.html)
src/content/posts/_assets/hikari.jpg
Binary files /dev/null and b/src/content/posts/_assets/hikari.jpg differ
src/content/posts/_draft-example.md new
+6
@@ -0,0 +1,6 @@
1 +---
2 +title: draft-example
3 +pubDate: '2025-07-09'
4 +---
5 +
6 +Start the filename with `_` to mark it as a draft and hide it from the list.
src/content/posts/embedded-content.md new
+42
@@ -0,0 +1,42 @@
1 +---
2 +title: 'Embedded Content'
3 +pubDate: '2025-06-06'
4 +---
5 +
6 +Use these directives to embed media:
7 +
8 +```
9 +::spotify{url="https://open.spotify.com/type/xxxxxx"}
10 +
11 +::youtube{url="https://www.youtube.com/watch?v=xxxxxx"}
12 +
13 +::bilibili{url="https://www.bilibili.com/video/xxxxxx"}
14 +
15 +::github{repo="username/repo"}
16 +
17 +::x{url="https://x.com/username/status/xxxxxx"}
18 +```
19 +
20 +---
21 +
22 +## Spotify
23 +
24 +::spotify{url="https://open.spotify.com/track/41Y0ch6R3jzpJOZv6nhf9Z?si=6c82dbed65ab4853"}
25 +
26 +::spotify{url="https://open.spotify.com/album/1kBPEN3NIVwjdmIjjNk9vB?si=Lz29MvjwRnKX9y3dhxlbaQ"}
27 +
28 +## YouTube
29 +
30 +::youtube{url="https://www.youtube.com/embed/GlhV-OKHecI?si=KdB4rRPLAMEK-ozf"}
31 +
32 +## BiliBili
33 +
34 +::bilibili{url="https://www.bilibili.com/video/BV1Vm421W7pX/?vd_source=c0bc2746a6d2b23de50d26376498b2ff"}
35 +
36 +## GitHub
37 +
38 +::github{repo="the3ash/astro-chiri"}
39 +
40 +## X Post
41 +
42 +::x{url="https://x.com/DAVID_LYNCH/status/1174367510893752321"}
src/content/posts/markdown-style-guide.md new
+87
@@ -0,0 +1,87 @@
1 +---
2 +title: 'Markdown Style Guide'
3 +pubDate: '2025-06-28'
4 +---
5 +
6 +This theme does not define more levels of headlines. If needed, you can define them in `src/styles/post.css`.
7 +
8 +---
9 +
10 +## Paragraph
11 +
12 +Here's a practical example of a paragraph in Markdown. This text demonstrates how content flows naturally in a blog post.
13 +
14 +You can use various formatting options like **bold**, _italic_, ~~strikethrough~~, and `code` within your paragraphs.
15 +
16 +## Blockquotes
17 +
18 +> Don't communicate by sharing memory, share memory by communicating.<br>
19 +> — <cite>Rob Pike[^1]</cite>
20 +
21 +[^1]: The above quote is excerpted from Rob Pike's [talk](https://www.youtube.com/watch?v=PAAkCSZUG1c) during Gopherfest, November 18, 2015.
22 +
23 +### Ordered List
24 +
25 +1. First item
26 +2. Second item
27 +3. Third item
28 +
29 +### Unordered List
30 +
31 +- Item
32 + - Subitem
33 + - Subitem
34 +
35 +## Task List
36 +
37 +- [ ] First item
38 +- [ ] Second item
39 +- [x] Third item
40 +
41 +## Image
42 +
43 +To hide the caption, start it with an underscore `_` or leave the alt text empty.
44 +
45 +![HIKARI](./_assets/hikari.jpg)
46 +
47 +## Tables
48 +
49 +| Style | Weight | Other |
50 +| -------- | -------- | ------ |
51 +| Normal | Regular | Text |
52 +| _Italic_ | **Bold** | `Code` |
53 +
54 +## Code Blocks
55 +
56 +```jsx
57 +// Button.jsx
58 +
59 +const Button = ({ text, onClick }) => {
60 + const [count, setCount] = useState(0)
61 +
62 + const handleClick = () => {
63 + setCount(count + 1)
64 + onClick?.()
65 + }
66 +
67 + return (
68 + <button className="btn" onClick={handleClick}>
69 + {text} ({count})
70 + </button>
71 + )
72 +}
73 +```
74 +
75 +## Other Elements — sub, sup, abbr, kbd, mark
76 +
77 +H<sub>2</sub>O
78 +
79 +X<sup>n</sup> + Y<sup>n</sup> = Z<sup>n</sup>
80 +
81 +<abbr title="Graphics Interchange Format">GIF</abbr> is a bitmap image format.
82 +
83 +Press <kbd>CTRL</kbd> + <kbd>ALT</kbd> + <kbd>Delete</kbd> to end the session.
84 +
85 +Most <mark>salamanders</mark> are nocturnal, and hunt for insects, worms, and other small creatures.
86 +
87 +---
src/content/posts/theme-guide.md new
+72
@@ -0,0 +1,72 @@
1 +---
2 +title: 'Theme Guide'
3 +pubDate: '2025-07-10'
4 +---
5 +
6 +Chiri is a minimal blog theme built with [Astro](https://astro.build), offering customization options while preserving its clean aesthetic.
7 +
8 +---
9 +
10 +## Basic Commands
11 +
12 +- `pnpm new <title>` - Create a new post (use `_title` for drafts)
13 +- `pnpm update-theme` - Update the theme to the latest version
14 +
15 +## Main Files & Directories
16 +
17 +- `src/content/about/about.md` - Edit the about section of the index page. Leave it empty if you don’t want any content.
18 +- `src/content/posts/` - All blog posts are stored here
19 +- `src/config.ts` - Configure main site info and settings ↓
20 +
21 +```ts
22 +export const SITE = {
23 + // Site domain
24 + website: 'https://astro-chiri.netlify.app/',
25 + // Site title
26 + title: 'CHIRI',
27 + // Author name
28 + author: '3ASH',
29 + // Site description
30 + description: 'Minimal blog built by Astro',
31 + // Default language
32 + language: 'en-US',
33 +
34 + // Content area width
35 + contentWidth: '35rem',
36 + // Use centered layout (false for left-aligned)
37 + centeredLayout: true,
38 + // Show favicon on index page
39 + favicon: false,
40 + // Show theme toggle button
41 + themeToggle: false,
42 + // Show footer
43 + footer: true,
44 + // Enable fade animations
45 + fadeAnimation: true,
46 +
47 + // Date format: YYYY-MM-DD, MM-DD-YYYY, DD-MM-YYYY, MONTH DAY YYYY, DAY MONTH YYYY
48 + dateFormat: 'YYYY-MM-DD',
49 + // Date separator: . - / (except for MONTH DAY YYYY and DAY MONTH YYYY)
50 + dateSeparator: '.',
51 + // Date position in post list (true for right, false for left)
52 + dateOnRight: true,
53 +
54 + // Show reading time in posts
55 + readingTime: false,
56 + // Enable image viewer
57 + imageViewer: true,
58 + // Enable copy button in code blocks
59 + copyCode: false
60 +}
61 +```
62 +
63 +## Post Frontmatter
64 +
65 +Only `title` and `pubDate` are required fields
66 +
67 +```md
68 +---
69 +title: 'Post Title'
70 +pubDate: '2025-07-10'
71 +---
72 +```
src/content/posts/using-mdx.mdx new
+31
@@ -0,0 +1,31 @@
1 +---
2 +title: 'Using MDX'
3 +pubDate: '2025-05-12'
4 +---
5 +
6 +import Callout from '@/components/examples/Callout.astro'
7 +import CounterButton from '@/components/examples/CounterButton.astro'
8 +import Tag from '@/components/examples/Tag.astro'
9 +
10 +MDX combines Markdown with embedded JavaScript and JSX, making it easy to build interactive content. Below are some examples.
11 +
12 +---
13 +
14 +## Callout
15 +
16 +<Callout />
17 +
18 +## Button
19 +
20 +<CounterButton />
21 +
22 +## Tag
23 +
24 +<Tag />
25 +
26 +---
27 +
28 +## Ref
29 +
30 +- [MDX Syntax Documentation](https://mdxjs.com/docs/what-is-mdx)
31 +- [Astro Usage Documentation](https://docs.astro.build/en/guides/markdown-content/#markdown-and-mdx-pages)
src/env.d.ts new
+12
@@ -0,0 +1,12 @@
1 +/// <reference types="astro/client" />
2 +/// <reference types="astro/content" />
3 +
4 +declare module 'astro:content' {
5 + interface Render {
6 + '.md': Promise<{
7 + Content: import('astro').MarkdownInstance<Record<string, unknown>>['Content']
8 + headings: import('astro').MarkdownHeading[]
9 + remarkPluginFrontmatter: Record<string, unknown>
10 + }>
11 + }
12 +}
src/layouts/BaseLayout.astro new
+51
@@ -0,0 +1,51 @@
1 +---
2 +import { SITE } from '@/config'
3 +import TransitionWrapper from '@/components/layout/TransitionWrapper.astro'
4 +import type { LayoutProps } from '@/types'
5 +
6 +type Props = LayoutProps
7 +
8 +const { type = 'page' } = Astro.props
9 +const contentWidth = SITE.contentWidth
10 +const widthValue = Math.min(parseFloat(contentWidth), 50)
11 +const shouldUseCustomWidth = widthValue > 25
12 +const finalWidth = shouldUseCustomWidth ? `${widthValue}rem` : '25rem'
13 +
14 +const language = SITE.language || 'en-US'
15 +---
16 +
17 +<html
18 + lang={language}
19 + class={SITE.fadeAnimation ? 'view-transitions-enabled' : 'view-transitions-disabled'}
20 + {...SITE.fadeAnimation ? { 'transition:animate': 'initial' } : {}}
21 +>
22 + <head>
23 + <slot name="head" />
24 + </head>
25 + <body
26 + data-centered={SITE.centeredLayout}
27 + class={!SITE.fadeAnimation ? 'no-fade' : ''}
28 + style={`
29 + max-width: ${finalWidth};
30 + ${shouldUseCustomWidth ? `--content-width: ${widthValue}rem;` : ''}
31 + `}
32 + >
33 + <TransitionWrapper type={type} class="layout-wrapper">
34 + <slot />
35 + </TransitionWrapper>
36 + </body>
37 +</html>
38 +
39 +<style is:global>
40 + .layout-wrapper {
41 + display: flex;
42 + flex-direction: column;
43 + min-height: calc(100vh - 7.5rem);
44 + }
45 +
46 + @media (max-width: 768px) {
47 + .layout-wrapper {
48 + min-height: calc(100vh - 5.5rem);
49 + }
50 + }
51 +</style>
src/layouts/IndexLayout.astro new
+43
@@ -0,0 +1,43 @@
1 +---
2 +import '@/styles/global.css'
3 +import BaseHead from '@/components/layout/BaseHead.astro'
4 +import Header from '@/components/layout/Header.astro'
5 +import Footer from '@/components/layout/Footer.astro'
6 +import BaseLayout from '@/layouts/BaseLayout.astro'
7 +import GradientMask from '@/components/ui/GradientMask.astro'
8 +import { SITE } from '@/config'
9 +
10 +const { title, description } = Astro.props
11 +---
12 +
13 +<BaseLayout title={title} description={description} type="page">
14 + <BaseHead title={title} description={description} slot="head" />
15 + <div class="page-content">
16 + <GradientMask />
17 + <div>
18 + <Header />
19 + </div>
20 + <main>
21 + <slot />
22 + </main>
23 + {
24 + SITE.footer && (
25 + <div>
26 + <Footer />
27 + </div>
28 + )
29 + }
30 + </div>
31 +</BaseLayout>
32 +
33 +<style is:global>
34 + .page-content {
35 + flex: 1;
36 + display: flex;
37 + flex-direction: column;
38 + }
39 +
40 + .page-content main {
41 + flex: 1;
42 + }
43 +</style>
src/layouts/PostLayout.astro new
+73
@@ -0,0 +1,73 @@
1 +---
2 +import '@/styles/global.css'
3 +import type { CollectionEntry } from 'astro:content'
4 +import FormattedDate from '@/components/features/FormattedDate.astro'
5 +import FootnoteScroll from '@/components/features/FootnoteScroll.astro'
6 +import BaseHead from '@/components/layout/BaseHead.astro'
7 +import Footer from '@/components/layout/Footer.astro'
8 +import BackButton from '@/components/ui/BackButton.astro'
9 +import GradientMask from '@/components/ui/GradientMask.astro'
10 +import ImageViewer from '@/components/ui/ImageViewer.astro'
11 +import GitHubCard from '@/components/ui/GitHubCard.astro'
12 +import XPOST from '@/components/ui/XPOST.astro'
13 +import CopyCode from '@/components/ui/CopyCode.astro'
14 +import BaseLayout from '@/layouts/BaseLayout.astro'
15 +
16 +import { SITE } from '@/config'
17 +
18 +type Props = CollectionEntry<'posts'>['data'] & {
19 + readingTime?: {
20 + text: string
21 + minutes: number
22 + time: number
23 + words: number
24 + }
25 +}
26 +
27 +const { title, pubDate, readingTime } = Astro.props
28 +---
29 +
30 +<BaseLayout title={`${title} · ${SITE.title}`} description={SITE.description} type="post">
31 + <BaseHead title={`${title} · ${SITE.title}`} description={SITE.description} slot="head" />
32 + <div class="post-container">
33 + <main>
34 + <div class="prose">
35 + <GradientMask />
36 + <BackButton />
37 + <div class="title">
38 + <h1>{title}</h1>
39 + <div class="date">
40 + <FormattedDate date={pubDate} />
41 + {
42 + SITE.readingTime && readingTime && (
43 + <span class="reading-time">
44 + <span class="separator">·</span>
45 + {readingTime.text}
46 + </span>
47 + )
48 + }
49 + </div>
50 + </div>
51 + <slot />
52 + </div>
53 + </main>
54 + <FootnoteScroll />
55 + <CopyCode />
56 + <GitHubCard />
57 + <XPOST />
58 + {SITE.imageViewer && <ImageViewer />}
59 + {SITE.footer && <Footer />}
60 + </div>
61 +</BaseLayout>
62 +
63 +<style>
64 + .post-container {
65 + display: flex;
66 + flex-direction: column;
67 + flex: 1;
68 + }
69 +
70 + .post-container main {
71 + flex: 1;
72 + }
73 +</style>
src/pages/404.astro new
+13
@@ -0,0 +1,13 @@
1 +---
2 +import IndexLayout from '@/layouts/IndexLayout.astro'
3 +import { SITE } from '@/config'
4 +---
5 +
6 +<IndexLayout title={`404 - ${SITE.title}`} description="Not Found">
7 + <style>
8 + .error-container {
9 + color: var(--text-secondary);
10 + }
11 + </style>
12 + <p class="error-container">Page Not Found...</p>
13 +</IndexLayout>
src/pages/[...slug].astro new
+25
@@ -0,0 +1,25 @@
1 +---
2 +import { type CollectionEntry, getCollection } from 'astro:content'
3 +import PostLayout from '@/layouts/PostLayout.astro'
4 +import { render } from 'astro:content'
5 +
6 +export async function getStaticPaths() {
7 + const posts = await getCollection('posts')
8 + return posts
9 + .filter((post) => !post.id.startsWith('_'))
10 + .map((post) => ({
11 + params: { slug: post.id },
12 + props: post
13 + }))
14 +}
15 +type Props = CollectionEntry<'posts'>
16 +
17 +const post = Astro.props
18 +const { Content, remarkPluginFrontmatter } = await render(post)
19 +
20 +const readingTime = remarkPluginFrontmatter.readingTime
21 +---
22 +
23 +<PostLayout {...post.data} readingTime={readingTime}>
24 + <Content />
25 +</PostLayout>
src/pages/atom.xml.ts new
+6
@@ -0,0 +1,6 @@
1 +import type { APIContext } from 'astro'
2 +import { generateAtom } from '@/utils/feed'
3 +
4 +export async function GET(context: APIContext) {
5 + return generateAtom(context)
6 +}
src/pages/index.astro new
+16
@@ -0,0 +1,16 @@
1 +---
2 +import IndexLayout from '@/layouts/IndexLayout.astro'
3 +import About from '@/components/pages/About.astro'
4 +import PostList from '@/components/features/PostList.astro'
5 +import { SITE } from '@/config'
6 +import { getSortedFilteredPosts } from '@/utils/draft'
7 +
8 +const posts = await getSortedFilteredPosts()
9 +---
10 +
11 +<IndexLayout title={SITE.title} description={SITE.description}>
12 + <About />
13 + <main>
14 + <PostList posts={posts} />
15 + </main>
16 +</IndexLayout>
src/pages/rss.xml.ts new
+6
@@ -0,0 +1,6 @@
1 +import type { APIContext } from 'astro'
2 +import { generateRSS } from '@/utils/feed'
3 +
4 +export async function GET(context: APIContext) {
5 + return generateRSS(context)
6 +}
src/plugins/rehype-cleanup.mjs new
+35
@@ -0,0 +1,35 @@
1 +import { visit } from 'unist-util-visit'
2 +
3 +/**
4 + * Rehype plugin to cleanup and extract raw figure elements from paragraph nodes
5 + */
6 +export default function rehypeCleanup() {
7 + return (tree) => {
8 + visit(tree, 'element', (node, index, parent) => {
9 + if (node.tagName !== 'p') {
10 + return
11 + }
12 + if (!node.children?.length) {
13 + return
14 + }
15 + if (!parent) {
16 + return
17 + }
18 +
19 + const rawFigureNodes = []
20 +
21 + for (const child of node.children) {
22 + if (child.type === 'raw' && child.value && child.value.trim().startsWith('<figure')) {
23 + rawFigureNodes.push(child)
24 + } else if (child.type !== 'text' || child.value.trim() !== '') {
25 + return
26 + }
27 + }
28 +
29 + if (rawFigureNodes.length > 0) {
30 + parent.children.splice(index, 1, ...rawFigureNodes)
31 + return index
32 + }
33 + })
34 + }
35 +}
src/plugins/rehype-copy-code.mjs new
+38
@@ -0,0 +1,38 @@
1 +import { visit } from 'unist-util-visit'
2 +
3 +/**
4 + * Rehype plugin that adds copy button to code blocks for easy code copying functionality
5 + */
6 +export default function rehypeCopyCode() {
7 + return (tree) => {
8 + visit(tree, 'element', (node) => {
9 + if (node.tagName === 'pre') {
10 + if (!node.children || node.children.length === 0) {
11 + return
12 + }
13 +
14 + const codeElement = node.children.find((child) => child.tagName === 'code')
15 + if (!codeElement) {
16 + return
17 + }
18 +
19 + node.properties = node.properties || {}
20 + node.properties.className = node.properties.className || []
21 + node.properties.className.push('copy-code-block')
22 +
23 + const copyButton = {
24 + type: 'element',
25 + tagName: 'button',
26 + properties: {
27 + className: ['copy-button'],
28 + type: 'button',
29 + 'aria-label': 'Copy code'
30 + },
31 + children: []
32 + }
33 +
34 + node.children.unshift(copyButton)
35 + }
36 + })
37 + }
38 +}
src/plugins/rehype-image-processor.mjs new
+83
@@ -0,0 +1,83 @@
1 +import { visit } from 'unist-util-visit'
2 +import { SITE } from '../config.ts'
3 +
4 +/**
5 + * Rehype plugin that processes images in markdown content:
6 + * - Wraps images with alt text in figure/figcaption elements
7 + * - Adds data-preview attribute for image viewer functionality
8 + * - Handles multiple images in a single paragraph
9 + */
10 +export default function rehypeImageProcessor() {
11 + return (tree) => {
12 + visit(tree, 'element', (node, index, parent) => {
13 + if (node.tagName !== 'p') {
14 + return
15 + }
16 + if (!parent || typeof index !== 'number') {
17 + return
18 + }
19 +
20 + const imgNodes = []
21 + let hasNonImageContent = false
22 +
23 + for (const child of node.children) {
24 + if (child.type === 'element' && child.tagName === 'img') {
25 + imgNodes.push(child)
26 + } else if (child.type !== 'text' || child.value.trim() !== '') {
27 + hasNonImageContent = true
28 + }
29 + }
30 +
31 + if (hasNonImageContent || imgNodes.length === 0) {
32 + return
33 + }
34 +
35 + const newNodes = []
36 +
37 + for (const imgNode of imgNodes) {
38 + const alt = imgNode.properties?.alt?.trim()
39 +
40 + imgNode.properties = {
41 + ...imgNode.properties,
42 + 'data-preview': SITE.imageViewer ? 'true' : 'false'
43 + }
44 +
45 + if (!alt || alt.includes('_')) {
46 + newNodes.push(imgNode)
47 + continue
48 + }
49 +
50 + const figure = {
51 + type: 'element',
52 + tagName: 'figure',
53 + properties: {
54 + className: ['image-caption-wrapper']
55 + },
56 + children: [
57 + imgNode,
58 + {
59 + type: 'element',
60 + tagName: 'figcaption',
61 + properties: {
62 + className: ['img-caption']
63 + },
64 + children: [
65 + {
66 + type: 'text',
67 + value: alt
68 + }
69 + ]
70 + }
71 + ]
72 + }
73 +
74 + newNodes.push(figure)
75 + }
76 +
77 + if (newNodes.length > 0) {
78 + parent.children.splice(index, 1, ...newNodes)
79 + return index + newNodes.length - 1
80 + }
81 + })
82 + }
83 +}
src/plugins/remark-embedded-media.mjs new
+187
@@ -0,0 +1,187 @@
1 +import { visit } from 'unist-util-visit'
2 +
3 +/**
4 + * A remark plugin that converts custom directives to embedded media HTML elements
5 + */
6 +const embedHandlers = {
7 + // Spotify
8 + spotify: (node) => {
9 + const url = node.attributes?.url ?? ''
10 + if (!url) {
11 + return false
12 + }
13 + if (!/^https:\/\/open\.spotify\.com\//.test(url)) {
14 + return false
15 + }
16 + let embedUrl = url.replace('open.spotify.com/', 'open.spotify.com/embed/')
17 + if (!embedUrl.includes('utm_source=')) {
18 + embedUrl += (embedUrl.includes('?') ? '&' : '?') + 'utm_source=generator'
19 + }
20 +
21 + let height = '152'
22 + if (
23 + url.includes('/album/') ||
24 + url.includes('/playlist/') ||
25 + url.includes('/artist/') ||
26 + url.includes('/show/')
27 + ) {
28 + height = '352'
29 + }
30 +
31 + return `
32 + <figure>
33 + <iframe
34 + style="border-radius:12px"
35 + src="${embedUrl}"
36 + width="100%"
37 + height="${height}"
38 + frameBorder="0"
39 + allowfullscreen=""
40 + allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture"
41 + loading="lazy"
42 + ></iframe>
43 + </figure>
44 + `
45 + },
46 +
47 + // Youtube
48 + youtube: (node) => {
49 + let videoId = node.attributes?.id ?? ''
50 + const url = node.attributes?.url ?? ''
51 +
52 + if (!videoId && url) {
53 + const match = url.match(/(?:v=|\/embed\/|youtu\.be\/)([\w-]{11})/)
54 + if (match) videoId = match[1]
55 + }
56 +
57 + if (!videoId) {
58 + return false
59 + }
60 +
61 + return `
62 + <figure>
63 + <iframe
64 + src="https://www.youtube.com/embed/${videoId}"
65 + title="YouTube video player"
66 + loading="lazy"
67 + frameborder="0"
68 + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
69 + allowfullscreen
70 + ></iframe>
71 + </figure>
72 + `
73 + },
74 +
75 + // Bilibili
76 + bilibili: (node) => {
77 + let bvid = node.attributes?.id ?? ''
78 + const url = node.attributes?.url ?? ''
79 + if (!bvid && url) {
80 + const match = url.match(/\/BV([\w]+)/)
81 + if (match) bvid = 'BV' + match[1]
82 + }
83 + if (!bvid) {
84 + return false
85 + }
86 +
87 + return `
88 + <figure>
89 + <iframe
90 + src="//player.bilibili.com/player.html?isOutside=true&bvid=${bvid}&p=1&autoplay=0&muted=0"
91 + title="Bilibili video player"
92 + loading="lazy"
93 + scrolling="no"
94 + border="0"
95 + frameborder="no"
96 + framespacing="0"
97 + allowfullscreen="true"
98 + ></iframe>
99 + </figure>
100 + `
101 + },
102 +
103 + // X Post Card
104 + x: (node) => {
105 + const xUrl = node.attributes?.url ?? ''
106 + if (!xUrl) {
107 + return false
108 + }
109 +
110 + const twitterUrl = xUrl.replace(/(\w+:\/\/)?x\.com\//g, '$1twitter.com/')
111 + const uniqueId = `x-card-${Math.random().toString(36).slice(2, 11)}`
112 +
113 + return `
114 + <figure class="x-card">
115 + <blockquote class="twitter-tweet" data-dnt="true" id="${uniqueId}">
116 + <a href="${twitterUrl}"></a>
117 + </blockquote>
118 + </figure>
119 + `
120 + },
121 +
122 + // Github Repository Card
123 + github: (node) => {
124 + const repo = node.attributes?.repo ?? ''
125 + if (!repo) {
126 + console.warn(`Missing GitHub repository`)
127 + return false
128 + }
129 +
130 + const [owner, name] = repo.split('/')
131 + if (!owner || !name) {
132 + console.warn(`Invalid GitHub repository format: "${repo}"`)
133 + return false
134 + }
135 +
136 + return `
137 + <a href="https://github.com/${repo}" class="gc-container" target="_blank" rel="noopener noreferrer" data-repo="${repo}">
138 + <div class="gc-title-bar">
139 + <div class="gc-owner-avatar" style="background-size: cover; background-position: center;" aria-hidden="true"></div>
140 + <span class="gc-repo-title">
141 + <span>${owner}<span class="gc-slash" aria-hidden="true">/</span><strong>${name}</strong></span>
142 + </span>
143 + <svg class="gc-github-icon" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
144 + <path d="M12 1C5.9225 1 1 5.9225 1 12C1 16.8675 4.14875 20.9787 8.52125 22.4362C9.07125 22.5325 9.2775 22.2025 9.2775 21.9137C9.2775 21.6525 9.26375 20.7862 9.26375 19.865C6.5 20.3737 5.785 19.1912 5.565 18.5725C5.44125 18.2562 4.905 17.28 4.4375 17.0187C4.0525 16.8125 3.5025 16.3037 4.42375 16.29C5.29 16.2762 5.90875 17.0875 6.115 17.4175C7.105 19.0812 8.68625 18.6137 9.31875 18.325C9.415 17.61 9.70375 17.1287 10.02 16.8537C7.5725 16.5787 5.015 15.63 5.015 11.4225C5.015 10.2262 5.44125 9.23625 6.1425 8.46625C6.0325 8.19125 5.6475 7.06375 6.2525 5.55125C6.2525 5.55125 7.17375 5.2625 9.2775 6.67875C10.1575 6.43125 11.0925 6.3075 12.0275 6.3075C12.9625 6.3075 13.8975 6.43125 14.7775 6.67875C16.8813 5.24875 17.8025 5.55125 17.8025 5.55125C18.4075 7.06375 18.0225 8.19125 17.9125 8.46625C18.6138 9.23625 19.04 10.2125 19.04 11.4225C19.04 15.6437 16.4688 16.5787 14.0213 16.8537C14.42 17.1975 14.7638 17.8575 14.7638 18.8887C14.7638 20.36 14.75 21.5425 14.75 21.9137C14.75 22.2025 14.9563 22.5462 15.5063 22.4362C19.8513 20.9787 23 16.8537 23 12C23 5.9225 18.0775 1 12 1Z"></path>
145 + </svg>
146 + </div>
147 + <p class="gc-repo-description">Loading repository data...</p>
148 + <div class="gc-info-bar">
149 + <svg class="gc-info-icon" height="16" width="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
150 + <path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z"></path>
151 + </svg>
152 + <span class="gc-stars-count" aria-label="Stars count">--</span>
153 + <svg class="gc-info-icon" height="16" width="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
154 + <path d="M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z"></path>
155 + </svg>
156 + <span class="gc-forks-count" aria-label="Forks count">--</span>
157 + <svg class="gc-info-icon" height="16" width="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
158 + <path d="M8.75.75V2h.985c.304 0 .603.08.867.231l1.29.736c.038.022.08.033.124.033h2.234a.75.75 0 0 1 0 1.5h-.427l2.111 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.006.005-.01.01-.045.04c-.21.176-.441.327-.686.45C14.556 10.78 13.88 11 13 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L12.178 4.5h-.162c-.305 0-.604-.079-.868-.231l-1.29-.736a.245.245 0 0 0-.124-.033H8.75V13h2.5a.75.75 0 0 1 0 1.5h-6.5a.75.75 0 0 1 0-1.5h2.5V3.5h-.984a.245.245 0 0 0-.124.033l-1.289.737c-.265.15-.564.23-.869.23h-.162l2.112 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.016.015-.045.04c-.21.176-.441.327-.686.45C4.556 10.78 3.88 11 3 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L2.178 4.5H1.75a.75.75 0 0 1 0-1.5h2.234a.249.249 0 0 0 .125-.033l1.288-.737c.265-.15.564-.23.869-.23h.984V.75a.75.75 0 0 1 1.5 0Zm2.945 8.477c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L13 6.327Zm-10 0c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L3 6.327Z"></path>
159 + </svg>
160 + <span class="gc-license-info" aria-label="License">--</span>
161 + </div>
162 + </a>
163 + `
164 + }
165 +}
166 +
167 +export default function remarkEmbeddedMedia() {
168 + return (tree) => {
169 + visit(tree, ['leafDirective', 'containerDirective', 'textDirective'], (node) => {
170 + const handler = embedHandlers[node.name]
171 + if (!handler) {
172 + return
173 + }
174 +
175 + const htmlContent = handler(node)
176 + if (!htmlContent) {
177 + return
178 + }
179 +
180 + node.type = 'html'
181 + node.value = htmlContent
182 + delete node.name
183 + delete node.attributes
184 + delete node.children
185 + })
186 + }
187 +}
src/plugins/remark-reading-time.mjs new
+21
@@ -0,0 +1,21 @@
1 +import { toString } from 'mdast-util-to-string'
2 +import getReadingTime from 'reading-time'
3 +
4 +/**
5 + * Remark plugin to calculate and add reading time information to markdown frontmatter
6 + */
7 +export default function remarkReadingTime() {
8 + return function (tree, file) {
9 + const textOnPage = toString(tree)
10 + const readingTime = getReadingTime(textOnPage)
11 +
12 + const minutes = Math.max(1, Math.round(readingTime.minutes))
13 + file.data.astro.frontmatter.minutesRead = `${minutes}min`
14 + file.data.astro.frontmatter.readingTime = {
15 + text: `${minutes}min`,
16 + minutes: minutes,
17 + time: readingTime.time,
18 + words: readingTime.words
19 + }
20 + }
21 +}
src/styles/fonts.css new
+21
@@ -0,0 +1,21 @@
1 +@font-face {
2 + font-family: 'Inter';
3 + font-style: normal;
4 + font-weight: 100 900;
5 + font-display: swap;
6 + src: url('/fonts/Inter.woff2') format('woff2');
7 + unicode-range:
8 + U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074,
9 + U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
10 +}
11 +
12 +@font-face {
13 + font-family: 'Besley';
14 + font-style: italic;
15 + font-weight: 400;
16 + font-display: swap;
17 + src: url('/fonts/Besley-Italic.woff2') format('woff2');
18 + unicode-range:
19 + U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074,
20 + U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
21 +}
src/styles/global.css new
+216
@@ -0,0 +1,216 @@
1 +@import './fonts.css';
2 +@import './post.css';
3 +
4 +:root {
5 + /* Min Content Width */
6 + --content-width: 25rem;
7 +
8 + /* Typography */
9 + --font-sans:
10 + Inter, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell,
11 + Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
12 + --font-serif: Besley, Baskerville, Georgia, Cambria, 'Times New Roman', Times, serif;
13 + --font-mono: SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
14 +
15 + --font-size-s: 0.8125rem;
16 + --font-size-m: 0.9375rem;
17 + --font-size-l: 1.0625rem;
18 +
19 + --font-weight-light: 350;
20 + --font-weight-regular: 400;
21 + --font-weight-bold: 500;
22 +
23 + --spacing-s: -0.08em;
24 + --spacing-m: -0.02em;
25 +
26 + /* Light Mode Colors (Default) */
27 + --bg: #ffffff;
28 + --text-primary: rgba(0, 0, 0, 0.85);
29 + --text-secondary: rgba(0, 0, 0, 0.4);
30 + --text-tertiary: rgba(0, 0, 0, 0.24);
31 + --border: rgba(0, 0, 0, 0.1);
32 + --selection: rgba(0, 0, 0, 0.08);
33 + --code-bg: rgba(0, 0, 0, 0.06);
34 + --mark: #f3ffc4;
35 +
36 + /* Syntax Theme */
37 + --astro-code-foreground: rgba(0, 0, 0, 0.85);
38 + --astro-code-background: rgba(0, 0, 0, 0.03);
39 + --astro-code-token-constant: rgba(0, 0, 0, 0.85);
40 + --astro-code-token-string: rgba(0, 0, 0, 0.85);
41 + --astro-code-token-comment: rgba(0, 0, 0, 0.35);
42 + --astro-code-token-keyword: rgba(0, 0, 0, 0.55);
43 + --astro-code-token-parameter: rgba(0, 0, 0, 0.85);
44 + --astro-code-token-function: rgba(0, 0, 0, 0.85);
45 + --astro-code-token-string-expression: rgba(0, 0, 0, 0.55);
46 + --astro-code-token-punctuation: rgba(0, 0, 0, 0.55);
47 + --astro-code-token-link: rgba(0, 0, 0, 0.55);
48 +}
49 +
50 +/* Light Mode (Explicit) */
51 +html.light {
52 + --bg: #ffffff;
53 + --text-primary: rgba(0, 0, 0, 0.85);
54 + --text-secondary: rgba(0, 0, 0, 0.4);
55 + --text-tertiary: rgba(0, 0, 0, 0.24);
56 + --border: rgba(0, 0, 0, 0.1);
57 + --selection: rgba(0, 0, 0, 0.08);
58 + --code-bg: rgba(0, 0, 0, 0.06);
59 + --mark: #f3ffc4;
60 +
61 + /* Syntax Theme */
62 + --astro-code-foreground: rgba(0, 0, 0, 0.85);
63 + --astro-code-background: rgba(0, 0, 0, 0.03);
64 + --astro-code-token-constant: rgba(0, 0, 0, 0.85);
65 + --astro-code-token-string: rgba(0, 0, 0, 0.85);
66 + --astro-code-token-comment: rgba(0, 0, 0, 0.35);
67 + --astro-code-token-keyword: rgba(0, 0, 0, 0.5);
68 + --astro-code-token-parameter: rgba(0, 0, 0, 0.85);
69 + --astro-code-token-function: rgba(0, 0, 0, 0.85);
70 + --astro-code-token-string-expression: rgba(0, 0, 0, 0.55);
71 + --astro-code-token-punctuation: rgba(0, 0, 0, 0.55);
72 + --astro-code-token-link: rgba(0, 0, 0, 0.55);
73 +}
74 +
75 +/* Dark Mode (Explicit) */
76 +html.dark {
77 + --bg: #1c1c1c;
78 + --text-primary: rgba(255, 255, 255, 0.9);
79 + --text-secondary: rgba(255, 255, 255, 0.4);
80 + --text-tertiary: rgba(255, 255, 255, 0.24);
81 + --border: rgba(255, 255, 255, 0.1);
82 + --selection: rgba(255, 255, 255, 0.08);
83 + --code-bg: rgba(255, 255, 255, 0.06);
84 + --mark: #545b37;
85 +
86 + /* Syntax Theme */
87 + --astro-code-foreground: rgba(255, 255, 255, 0.9);
88 + --astro-code-background: rgba(255, 255, 255, 0.03);
89 + --astro-code-token-constant: rgba(255, 255, 255, 0.9);
90 + --astro-code-token-string: rgba(255, 255, 255, 0.9);
91 + --astro-code-token-comment: rgba(255, 255, 255, 0.35);
92 + --astro-code-token-keyword: rgba(255, 255, 255, 0.55);
93 + --astro-code-token-parameter: rgba(255, 255, 255, 0.9);
94 + --astro-code-token-function: rgba(255, 255, 255, 0.9);
95 + --astro-code-token-string-expression: rgba(255, 255, 255, 0.55);
96 + --astro-code-token-punctuation: rgba(255, 255, 255, 0.55);
97 + --astro-code-token-link: rgba(255, 255, 255, 0.55);
98 +}
99 +
100 +body {
101 + background-color: var(--bg);
102 + font-family: var(--font-sans);
103 + font-size: var(--font-size-m);
104 + line-height: 1.75;
105 + color: var(--text-primary);
106 + font-display: swap;
107 + word-wrap: break-word;
108 + overflow-wrap: break-word;
109 + margin: 0;
110 + min-height: 100vh;
111 + display: flex;
112 + flex-direction: column;
113 + box-sizing: border-box;
114 + letter-spacing: var(--spacing-m);
115 + padding: 6rem 1.5rem 1.5rem 1.5rem;
116 + overscroll-behavior-y: contain;
117 + transition: background-color 0.2s ease-out;
118 +}
119 +
120 +@media (max-width: 768px) {
121 + body {
122 + padding: 4rem 1.25rem 1.25rem 1.25rem;
123 + }
124 +}
125 +
126 +html {
127 + overscroll-behavior-y: contain;
128 + -webkit-overflow-scrolling: touch;
129 + scroll-behavior: smooth;
130 +}
131 +
132 +html.view-transitions-enabled {
133 + view-transition-name: enabled;
134 +}
135 +
136 +@view-transition {
137 + navigation: auto;
138 +}
139 +
140 +html.view-transitions-disabled {
141 + view-transition-name: none;
142 +}
143 +
144 +@media (prefers-reduced-motion: reduce) {
145 + @view-transition {
146 + navigation: none;
147 + }
148 +}
149 +
150 +::selection {
151 + background-color: var(--selection);
152 +}
153 +
154 +:focus {
155 + outline: 2px solid var(--text-tertiary);
156 + outline-offset: 2px;
157 +}
158 +
159 +:focus:not(:focus-visible) {
160 + outline: none;
161 +}
162 +
163 +:focus-visible {
164 + outline: 2px solid var(--text-tertiary);
165 + outline-offset: 2px;
166 +}
167 +
168 +body[data-width] {
169 + max-width: var(--content-width);
170 +}
171 +
172 +body[data-centered='true'] {
173 + margin: 0 auto;
174 +}
175 +
176 +main {
177 + flex: 1;
178 + display: flex;
179 + flex-direction: column;
180 + box-sizing: border-box;
181 +}
182 +
183 +.date {
184 + margin: 0;
185 + font-weight: var(--font-weight-light);
186 + color: var(--text-secondary);
187 + flex-shrink: 0;
188 + letter-spacing: var(--spacing-s);
189 + font-variant-numeric: tabular-nums;
190 + font-feature-settings:
191 + 'tnum' 1,
192 + 'zero' 0,
193 + 'cv01' 1,
194 + 'cv02' 1,
195 + 'calt' 1,
196 + 'ss03' 1,
197 + 'ordn' 1;
198 +}
199 +
200 +.date .month {
201 + letter-spacing: var(--spacing-m);
202 +}
203 +
204 +.sr-only {
205 + border: 0;
206 + padding: 0;
207 + margin: 0;
208 + position: absolute !important;
209 + height: 1px;
210 + width: 1px;
211 + overflow: hidden;
212 + clip: rect(1px 1px 1px 1px);
213 + clip: rect(1px, 1px, 1px, 1px);
214 + clip-path: inset(50%);
215 + white-space: nowrap;
216 +}
src/styles/post.css new
+531
@@ -0,0 +1,531 @@
1 +/* Base styles for all elements */
2 +.prose * {
3 + margin: 0;
4 + padding: 0;
5 + font-size: var(--font-size-m);
6 +}
7 +
8 +/* Main content container */
9 +.prose {
10 + margin-bottom: 8rem;
11 +}
12 +
13 +/* Post title section */
14 +.prose .title {
15 + margin-bottom: 2.5em;
16 +}
17 +
18 +.prose .title h1 {
19 + margin: 0 0 0.25rem 0;
20 +}
21 +
22 +/* Headings (h1-h5) */
23 +.prose h1,
24 +.prose h2,
25 +.prose h3,
26 +.prose h4,
27 +.prose h5 {
28 + font-size: var(--font-size-m);
29 + font-weight: var(--font-weight-bold);
30 + line-height: 1.75;
31 + margin: 2.5em 0 1em 0;
32 +}
33 +
34 +/* Bold text */
35 +.prose strong,
36 +.prose b {
37 + font-weight: var(--font-weight-bold);
38 +}
39 +
40 +/* Italic text */
41 +.prose em {
42 + font-family: var(--font-serif);
43 + font-style: italic;
44 + letter-spacing: 0;
45 +}
46 +
47 +/* Links */
48 +.prose a {
49 + color: var(--primary);
50 + text-decoration: underline;
51 + text-decoration-color: var(--text-tertiary);
52 + transition: text-decoration-color 0.2s ease-out;
53 +}
54 +
55 +.prose a:hover {
56 + color: var(--primary);
57 + text-decoration-color: var(--text-primary);
58 +}
59 +
60 +/* Paragraphs */
61 +.prose p {
62 + line-height: 1.75;
63 + margin-bottom: 1.25em;
64 +}
65 +
66 +/* Tables */
67 +.prose table {
68 + table-layout: fixed;
69 + width: 100%;
70 + border-collapse: separate;
71 + border-spacing: 0;
72 + margin: 1.25em 0;
73 + font-size: var(--font-size-m);
74 + border: 1px solid var(--border);
75 + border-radius: 8px;
76 + overflow: hidden;
77 +}
78 +
79 +/* Table cells */
80 +.prose th,
81 +.prose td {
82 + border: none;
83 + border-right: 1px solid var(--border);
84 + border-bottom: 1px solid var(--border);
85 + padding: 0.5em 1em;
86 + text-align: left;
87 +}
88 +
89 +.prose th:last-child,
90 +.prose td:last-child {
91 + border-right: none;
92 +}
93 +
94 +.prose tr:last-child td {
95 + border-bottom: none;
96 +}
97 +
98 +.prose th {
99 + background: var(--astro-code-background);
100 + font-weight: var(--font-weight-bold);
101 +}
102 +
103 +/* Images */
104 +.prose img {
105 + max-width: 100%;
106 + height: auto;
107 + display: block;
108 + margin: 1.25em 0;
109 +}
110 +
111 +.prose figure {
112 + margin-bottom: 1.25em;
113 + text-align: center;
114 +}
115 +
116 +.prose figure img {
117 + margin-bottom: 0.75em;
118 +}
119 +
120 +.prose figure figcaption {
121 + color: var(--text-secondary);
122 + font-size: var(--font-size-s);
123 + text-align: center;
124 +}
125 +
126 +.prose p > img {
127 + position: relative;
128 + margin-bottom: 1.25em;
129 +}
130 +
131 +.prose p > img::after {
132 + content: attr(alt);
133 + display: block;
134 + position: absolute;
135 + left: 0;
136 + width: 100%;
137 + text-align: center;
138 + color: var(--text-secondary);
139 + font-size: var(--font-size-s);
140 + margin-top: 0.75em;
141 +}
142 +
143 +.prose .img-caption {
144 + display: block;
145 + text-align: center;
146 + color: var(--text-secondary);
147 + font-size: var(--font-size-s);
148 + margin-bottom: 1.25em;
149 +}
150 +
151 +/* Inline code */
152 +.prose code {
153 + padding: 3px 4px;
154 + border-radius: 5px;
155 + background-color: var(--code-bg);
156 + font-family: var(--font-mono);
157 + font-size: 0.9em;
158 + font-feature-settings:
159 + 'liga' 0,
160 + 'calt' 0;
161 + -webkit-font-feature-settings:
162 + 'liga' 0,
163 + 'calt' 0;
164 +}
165 +
166 +/* Blockquotes */
167 +.prose blockquote {
168 + border-left: 2px solid var(--border);
169 + margin: 0 0 1.25em 0;
170 + padding: 0 0 0 1em;
171 + text-align: left;
172 +}
173 +
174 +.prose blockquote p {
175 + margin: 0;
176 +}
177 +
178 +.prose blockquote cite {
179 + display: inline-block;
180 + margin-top: 0.5em;
181 +}
182 +
183 +/* Unordered lists */
184 +.prose ul {
185 + list-style-type: none;
186 + padding-left: 0;
187 + margin-left: 1rem;
188 + margin-bottom: 1.25em;
189 + line-height: 1.75;
190 +}
191 +
192 +.prose ul ul {
193 + margin-left: 0.75rem;
194 + margin-top: 0.5em;
195 + margin-bottom: 0.5em;
196 +}
197 +
198 +.prose ul li {
199 + position: relative;
200 + padding-left: 0.25rem;
201 + margin-bottom: 0.5em;
202 +}
203 +
204 +.prose ul li:last-child {
205 + margin-bottom: 0;
206 +}
207 +
208 +.prose ul li > ul {
209 + margin-top: 0.5em;
210 + margin-bottom: 0.5em;
211 +}
212 +
213 +.prose ul li::before {
214 + content: '•';
215 + position: absolute;
216 + left: -1.375rem;
217 + top: -0.05em;
218 + width: 1.5rem;
219 + text-align: center;
220 + color: var(--text-tertiary);
221 +}
222 +
223 +/* Ordered lists */
224 +.prose ol {
225 + list-style-position: outside;
226 + padding-left: 0;
227 + margin-left: 1.25rem;
228 + counter-reset: item;
229 +}
230 +
231 +.prose ol li {
232 + display: block;
233 + position: relative;
234 + margin-bottom: 0.5em;
235 +}
236 +
237 +.prose ol li:last-child {
238 + margin-bottom: 0;
239 +}
240 +
241 +.prose ol li::before {
242 + content: counter(item) '.';
243 + counter-increment: item;
244 + position: absolute;
245 + left: -1.15rem;
246 + width: 1.5rem;
247 + text-align: left;
248 + color: var(--text-secondary);
249 + font-variant-numeric: tabular-nums;
250 + font-feature-settings:
251 + 'tnum' 1,
252 + 'zero' 0,
253 + 'cv01' 1,
254 + 'cv02' 1,
255 + 'calt' 1,
256 + 'ss03' 1,
257 + 'liga' 1,
258 + 'ordn' 1;
259 +}
260 +
261 +/* Task lists */
262 +.prose ul.contains-task-list {
263 + list-style: none;
264 + margin-left: 0;
265 + white-space: nowrap;
266 +}
267 +
268 +.prose ul.contains-task-list li::before {
269 + content: none;
270 +}
271 +
272 +.prose ul.contains-task-list li.task-list-item {
273 + padding-left: 0.125em;
274 + margin-bottom: 0.5em;
275 +}
276 +
277 +.prose ul.contains-task-list li.task-list-item:last-child {
278 + margin-bottom: 0;
279 +}
280 +
281 +/* Task list checkboxes */
282 +.prose ul.contains-task-list li.task-list-item input[type='checkbox'] {
283 + margin-right: 0.375em;
284 + position: relative;
285 + top: 0.175em;
286 + width: 1em;
287 + height: 1em;
288 + border: 1.35px solid var(--text-tertiary);
289 + border-radius: 4px;
290 + background: transparent;
291 + appearance: none;
292 + -webkit-appearance: none;
293 +}
294 +
295 +.prose ul.contains-task-list li.task-list-item input[type='checkbox']:checked {
296 + position: relative;
297 + background: var(--code-bg);
298 + border: 1.35px solid var(--text-tertiary);
299 + opacity: 0.75;
300 +}
301 +
302 +.prose ul.contains-task-list li.task-list-item input[type='checkbox']:checked::before {
303 + content: '✓';
304 + font-family: var(--font-sans);
305 + color: var(--text-primary);
306 + opacity: 0.75;
307 + font-weight: var(--font-weight-bold);
308 + position: absolute;
309 + left: 0.15em;
310 + top: 0.05em;
311 + font-size: 0.75em;
312 + line-height: 1;
313 +}
314 +
315 +.prose ul.contains-task-list li.task-list-item input[type='checkbox'] + * {
316 + display: inline;
317 + margin-left: 0;
318 + line-height: 1.75;
319 + white-space: nowrap;
320 +}
321 +
322 +/* .prose ul.contains-task-list li.task-list-item:has(input[type='checkbox']:checked) {
323 + text-decoration: line-through;
324 +} */
325 +
326 +/* Subscript and superscript */
327 +.prose sup,
328 +.prose sub,
329 +.prose sup a {
330 + margin: 0 0.125em;
331 + font-size: 0.875em;
332 + line-height: 1;
333 +}
334 +
335 +/* Horizontal rule */
336 +.prose hr {
337 + margin: 2.5em 0;
338 + height: auto;
339 + border: none;
340 + background: none;
341 + text-align: center;
342 + position: relative;
343 +}
344 +
345 +.prose hr::before {
346 + content: '***';
347 + font-family: var(--font-mono);
348 + color: var(--text-tertiary);
349 + font-size: 0.875em;
350 + letter-spacing: 0.25em;
351 +}
352 +
353 +/* Keyboard input */
354 +.prose kbd {
355 + font-family: var(--font-mono);
356 + font-size: var(--font-size-s);
357 + border: 1px solid var(--text-tertiary);
358 + padding: 1px 4px;
359 + border-radius: 5px;
360 + min-width: 1.75em;
361 + display: inline-block;
362 + text-align: center;
363 + /* box-shadow: inset 0 -2.5px 0 var(--border); */
364 +}
365 +
366 +/* Highlighted text */
367 +.prose mark {
368 + background-color: var(--mark);
369 + color: var(--text-primary);
370 + padding: 3px 1px;
371 +}
372 +
373 +/* Footnotes */
374 +.prose .footnotes {
375 + margin-top: 4rem;
376 + padding-top: 1.75rem;
377 + position: relative;
378 +}
379 +
380 +.prose .footnotes::before {
381 + content: '';
382 + position: absolute;
383 + top: 0;
384 + left: 0;
385 + width: 4rem;
386 + height: 1px;
387 + background-color: var(--border);
388 +}
389 +
390 +.prose cite {
391 + font-style: normal;
392 +}
393 +
394 +/* Footnote references */
395 +.prose [data-footnote-backref] {
396 + position: relative;
397 + font-family: var(--font-mono);
398 + font-size: var(--font-size-l);
399 + top: -0.05em;
400 +}
401 +
402 +.prose [data-footnote-ref] {
403 + font-size: 1em;
404 + font-variant-numeric: tabular-nums;
405 + font-feature-settings:
406 + 'tnum' 1,
407 + 'zero' 0,
408 + 'cv01' 1,
409 + 'cv02' 1,
410 + 'calt' 1,
411 + 'ss03' 1,
412 + 'liga' 1,
413 + 'ordn' 1;
414 +}
415 +
416 +.prose [data-footnote-ref],
417 +.prose [data-footnote-backref] {
418 + color: var(--text-secondary);
419 + text-decoration: none;
420 + transition: color 0.2s ease-out;
421 + padding-right: 0.5em;
422 +}
423 +
424 +.prose [data-footnote-ref]:hover,
425 +.prose [data-footnote-backref]:hover {
426 + color: var(--text-primary);
427 +}
428 +
429 +/* Code blocks */
430 +.prose pre {
431 + background-color: var(--astro-code-background);
432 + border-radius: 8px;
433 + padding: 1.25em 1.5em;
434 + margin: 1.25em 0;
435 + overflow-x: auto;
436 +}
437 +
438 +@media (max-width: 768px) {
439 + .prose pre {
440 + padding: 1em 1.25em;
441 + }
442 +}
443 +
444 +.prose pre > code {
445 + font-family: var(--font-mono);
446 + font-feature-settings:
447 + 'liga' 0,
448 + 'calt' 0;
449 + display: block;
450 + white-space: pre-wrap;
451 + word-break: break-word;
452 + overflow-wrap: anywhere;
453 + padding: 0;
454 + margin: 0;
455 + background: none;
456 + border: none;
457 + line-height: 1.5;
458 + border-radius: 0;
459 +}
460 +
461 +.prose pre > code * {
462 + font-size: var(--font-size-s);
463 +}
464 +
465 +/* KaTeX Math Rendering */
466 +
467 +/* Hide MathML fallback to prevent duplication */
468 +.katex-mathml {
469 + display: none !important;
470 +}
471 +
472 +/* Ensure display math is centered */
473 +.katex-display {
474 + text-align: center;
475 + margin: 1.5em 0;
476 +}
477 +
478 +/* Reset any conflicting styles that might interfere with KaTeX */
479 +.katex * {
480 + box-sizing: content-box;
481 +}
482 +
483 +/* Ensure KaTeX elements inherit color properly */
484 +.katex,
485 +.katex * {
486 + color: inherit;
487 +}
488 +
489 +/* Specific fixes for common CSS framework conflicts */
490 +.katex .base,
491 +.katex .strut,
492 +.katex .mathit,
493 +.katex .mathrm,
494 +.katex .mathbf,
495 +.katex .mathsf,
496 +.katex .mathtt {
497 + line-height: initial;
498 + vertical-align: baseline;
499 +}
500 +
501 +/* Dark mode support */
502 +@media (prefers-color-scheme: dark) {
503 + .katex,
504 + .katex * {
505 + color: inherit;
506 + }
507 +}
508 +
509 +/* Reading Time */
510 +.reading-time {
511 + color: var(--text-secondary);
512 + letter-spacing: -0.025em;
513 +}
514 +
515 +.reading-time .separator {
516 + margin: 0 0.25em;
517 +}
518 +
519 +/* Video */
520 +.prose iframe {
521 + width: 100%;
522 + aspect-ratio: 16/9;
523 + border: none;
524 + border-radius: 6px;
525 + margin: 0.25em 0 0 0;
526 +}
527 +
528 +/* Spotify */
529 +.prose iframe[src*='spotify.com'] {
530 + aspect-ratio: auto;
531 +}
src/types/index.ts new
+28
@@ -0,0 +1,28 @@
1 +export * from './layout.types'
2 +
3 +// Date format types
4 +export type DateFormat =
5 + | 'YYYY-MM-DD'
6 + | 'MM-DD-YYYY'
7 + | 'DD-MM-YYYY'
8 + | 'MONTH DAY YYYY'
9 + | 'DAY MONTH YYYY'
10 +
11 +// Site configuration type
12 +export interface SiteConfig {
13 + website: string
14 + title: string
15 + author: string
16 + description: string
17 + language: string
18 + contentWidth: string
19 + centeredLayout: boolean
20 + favicon: boolean
21 + footer: boolean
22 + fadeAnimation: boolean
23 + dateFormat: DateFormat
24 + dateSeparator: string
25 + readingTime: boolean
26 + imageViewer: boolean
27 + copyCode: boolean
28 +}
src/types/layout.types.ts new
+9
@@ -0,0 +1,9 @@
1 +export interface TransitionProps {
2 + type: 'post' | 'page'
3 + class?: string
4 +}
5 +
6 +export interface LayoutProps extends TransitionProps {
7 + title?: string
8 + description?: string
9 +}
src/utils/date.ts new
+67
@@ -0,0 +1,67 @@
1 +import { SITE } from '@/config'
2 +
3 +const MONTHS_EN = [
4 + 'Jan',
5 + 'Feb',
6 + 'Mar',
7 + 'Apr',
8 + 'May',
9 + 'Jun',
10 + 'Jul',
11 + 'Aug',
12 + 'Sep',
13 + 'Oct',
14 + 'Nov',
15 + 'Dec'
16 +]
17 +
18 +const VALID_SEPARATORS = ['.', '-', '/']
19 +
20 +/**
21 + * @param date
22 + * @param format
23 + * @returns
24 + */
25 +export function formatDate(date: Date, format?: string): string {
26 + const formatStr = (format || SITE.dateFormat).trim()
27 + const configSeparator = SITE.dateSeparator || '-'
28 +
29 + const separator = VALID_SEPARATORS.includes(configSeparator.trim()) ? configSeparator.trim() : '.'
30 +
31 + const year = date.getFullYear()
32 + const month = date.getMonth() + 1
33 + const day = date.getDate()
34 + const monthName = MONTHS_EN[date.getMonth()]
35 +
36 + const pad = (num: number) => String(num).padStart(2, '0')
37 +
38 + switch (formatStr) {
39 + case 'YYYY-MM-DD':
40 + return `${year}${separator}${pad(month)}${separator}${pad(day)}`
41 +
42 + case 'MM-DD-YYYY':
43 + return `${pad(month)}${separator}${pad(day)}${separator}${year}`
44 +
45 + case 'DD-MM-YYYY':
46 + return `${pad(day)}${separator}${pad(month)}${separator}${year}`
47 +
48 + case 'MONTH DAY YYYY':
49 + return `<span class="month">${monthName}</span> ${day} ${year}`
50 +
51 + case 'DAY MONTH YYYY':
52 + return `${day} <span class="month">${monthName}</span> ${year}`
53 +
54 + default:
55 + return `${year}${separator}${pad(month)}${separator}${pad(day)}`
56 + }
57 +}
58 +
59 +export const SUPPORTED_DATE_FORMATS = [
60 + 'YYYY-MM-DD',
61 + 'MM-DD-YYYY',
62 + 'DD-MM-YYYY',
63 + 'MONTH DAY YYYY',
64 + 'DAY MONTH YYYY'
65 +] as const
66 +
67 +export type DateFormat = (typeof SUPPORTED_DATE_FORMATS)[number]
src/utils/draft.ts new
+20
@@ -0,0 +1,20 @@
1 +import { getCollection, type CollectionEntry } from 'astro:content'
2 +
3 +/**
4 + * Get all posts, filtering out posts whose filenames start with _
5 + */
6 +export async function getFilteredPosts() {
7 + const posts = await getCollection('posts')
8 + return posts.filter((post) => !post.id.startsWith('_'))
9 +}
10 +
11 +/**
12 + * Get all posts sorted by publication date, filtering out posts whose filenames start with _
13 + */
14 +export async function getSortedFilteredPosts() {
15 + const posts = await getFilteredPosts()
16 + return posts.sort(
17 + (a: CollectionEntry<'posts'>, b: CollectionEntry<'posts'>) =>
18 + b.data.pubDate.valueOf() - a.data.pubDate.valueOf()
19 + )
20 +}
src/utils/feed.ts new
+81
@@ -0,0 +1,81 @@
1 +import { getCollection, type CollectionEntry } from 'astro:content'
2 +import { SITE } from '@/config'
3 +import type { APIContext } from 'astro'
4 +
5 +export async function generateRSS(context: APIContext) {
6 + const posts = await getCollection('posts')
7 + const filteredPosts = posts.filter((post) => !post.id.startsWith('_'))
8 + const sortedPosts = filteredPosts.sort(
9 + (a: CollectionEntry<'posts'>, b: CollectionEntry<'posts'>) =>
10 + b.data.pubDate.valueOf() - a.data.pubDate.valueOf()
11 + )
12 +
13 + const rss = `<?xml version="1.0" encoding="UTF-8" ?>
14 +<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom">
15 + <channel>
16 + <title>${SITE.title}</title>
17 + <link>${context.site}</link>
18 + <description>${SITE.description}</description>
19 + <language>zh-CN</language>
20 + <lastBuildDate>${new Date().toUTCString()}</lastBuildDate>
21 + <atom:link href="${context.site}/rss.xml" rel="self" type="application/rss+xml" />
22 + ${sortedPosts
23 + .map(
24 + (post: CollectionEntry<'posts'>) => `
25 + <item>
26 + <title><![CDATA[${post.data.title}]]></title>
27 + <link>${context.site}/${post.id}/</link>
28 + <guid>${context.site}/${post.id}/</guid>
29 + <pubDate>${post.data.pubDate.toUTCString()}</pubDate>
30 + <content:encoded><![CDATA[${post.body}]]></content:encoded>
31 + </item>
32 + `
33 + )
34 + .join('')}
35 + </channel>
36 +</rss>`
37 +
38 + return new Response(rss, {
39 + headers: {
40 + 'Content-Type': 'application/xml; charset=utf-8'
41 + }
42 + })
43 +}
44 +
45 +export async function generateAtom(context: APIContext) {
46 + const posts = await getCollection('posts')
47 + const filteredPosts = posts.filter((post) => !post.id.startsWith('_'))
48 + const sortedPosts = filteredPosts.sort(
49 + (a: CollectionEntry<'posts'>, b: CollectionEntry<'posts'>) =>
50 + b.data.pubDate.valueOf() - a.data.pubDate.valueOf()
51 + )
52 +
53 + const atom = `<?xml version="1.0" encoding="utf-8"?>
54 +<feed xmlns="http://www.w3.org/2005/Atom">
55 + <title>${SITE.title}</title>
56 + <subtitle>${SITE.description}</subtitle>
57 + <link href="${context.site}/atom.xml" rel="self" type="application/atom+xml" />
58 + <link href="${context.site}" />
59 + <id>${context.site}</id>
60 + <updated>${new Date().toISOString()}</updated>
61 + ${sortedPosts
62 + .map(
63 + (post: CollectionEntry<'posts'>) => `
64 + <entry>
65 + <title>${post.data.title}</title>
66 + <link href="${context.site}/${post.id}/" />
67 + <id>${context.site}/${post.id}/</id>
68 + <published>${post.data.pubDate.toISOString()}</published>
69 + <content type="html"><![CDATA[${post.body}]]></content>
70 + </entry>
71 + `
72 + )
73 + .join('')}
74 +</feed>`
75 +
76 + return new Response(atom, {
77 + headers: {
78 + 'Content-Type': 'application/xml; charset=utf-8'
79 + }
80 + })
81 +}
tsconfig.json new
+12
@@ -0,0 +1,12 @@
1 +{
2 + "extends": "astro/tsconfigs/strict",
3 + "include": [".astro/types.d.ts", "**/*"],
4 + "exclude": ["dist"],
5 + "compilerOptions": {
6 + "strictNullChecks": true,
7 + "baseUrl": ".",
8 + "paths": {
9 + "@/*": ["src/*"]
10 + }
11 + }
12 +}