diff --git a/.deploy_subdir b/.deploy_subdir new file mode 100644 index 0000000..2018f4f --- /dev/null +++ b/.deploy_subdir @@ -0,0 +1,4 @@ +.config/ghostty +.config/karabiner +.config/micro +.config/sheldon diff --git a/.deploy_subdir-windows b/.deploy_subdir-windows deleted file mode 100644 index 5032d6c..0000000 --- a/.deploy_subdir-windows +++ /dev/null @@ -1,2 +0,0 @@ -Documents/PowerShell -Documents/kanata diff --git a/.editorconfig b/.editorconfig index 4100b79..382e5aa 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,16 +4,19 @@ root = true [*] -indent_style = space +# indent_style = space indent_size = 2 end_of_line = lf charset = utf-8 # trim_trailing_whitespace = false insert_final_newline = true +[justfile] +indent_size = 4 + [install, *.{sh,zsh}] indent_size = 4 [*.md] trim_trailing_whitespace = false -insert_final_newline = true +insert_final_newline = true \ No newline at end of file diff --git a/.miserc.toml b/.miserc.toml deleted file mode 100644 index 19c1f64..0000000 --- a/.miserc.toml +++ /dev/null @@ -1,9 +0,0 @@ -# Early-init settings (read before mise.toml). -# Enables mise.linux.toml / mise.macos.toml / mise.unix.toml discovery. -# See https://mise.jdx.dev/configuration/environments.html - -auto_env = true - -# Always-on env so the cross-platform [dotfiles] allowlist can live in -# its own file (mise.dotfiles.toml) instead of cluttering mise.toml. -env = ["dotfiles"] diff --git a/.vscode/extensions.json b/.vscode/extensions.json index a676b68..f4ea6b9 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -2,6 +2,7 @@ "recommendations": [ "shellomo.enhanced-toml", "editorconfig.editorconfig", - "artlaman.chalice-icon-theme" + "artlaman.chalice-icon-theme", + "nefrob.vscode-just-syntax" ] } \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index ad6a7e0..a44e8a5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -28,9 +28,8 @@ This document is a guide for safe and productive collaboration between AI agents - Only change global OS/tool settings with explicit consent ## Coding and Structure Guidelines -- Symlinks for `home/` are declared in `[dotfiles]` (`mise.dotfiles.toml` / `mise.macos.toml`); deploy with `mise run deploy` -- Dirs that receive runtime writes (karabiner, micro, lazygit, hammerspoon) get per-file entries — never whole-dir symlinks -- Fresh Unix setup converges via `mise bootstrap` (see `docs/content/docs/mise-bootstrap.mdx`) +- Use GNU Stow for symlink deployment +- Before deploy, read `/.deploy_subdir` and create required directories with `mkdir -p` - Use `README.md` as an entry point; put detailed steps/background in `docs/` - Follow existing style (frontmatter, naming, hierarchy) when creating files @@ -40,17 +39,15 @@ This document is a guide for safe and productive collaboration between AI agents ## How to Request (Human → Agent) - State what you want to do and where (e.g., "Add AGENTS.md", "Add to docs") -- Indicate consistency with existing implementation (e.g., use `[dotfiles]` entries, use mise tasks) +- Indicate consistency with existing implementation (e.g., use stow, use justfile recipes) - Specify output language (Japanese/English) and location (README or docs) ## Repository-Specific Knowledge -- Main operations are mise tasks in root `mise.toml` (`mise tasks` / `mise run …`) -- Machine bootstrap (packages, login shell, deploy) uses `mise bootstrap` -- `.miserc.toml` sets `auto_env = true` so `mise.linux.toml` / `mise.macos.toml` load +- Main operations are summarized in the root `justfile` - Documentation is managed as MDX in `docs/content/docs` and published on the site - Navigation is auto-completed by `meta.json` (usually just add a page) ## References -- mise: https://mise.jdx.dev/ -- mise bootstrap: https://mise.jdx.dev/bootstrap.html +- GNU Stow: https://www.gnu.org/software/stow/ +- just: https://github.com/casey/just - sheldon: https://github.com/rossmacarthur/sheldon diff --git a/README.md b/README.md index ec67afa..a27d85b 100644 --- a/README.md +++ b/README.md @@ -2,30 +2,8 @@ ## install -### macOS / Linux - -```bash -bash -c "$(curl -fsSL https://dot.umeru.ma/install)" -``` - -This clones to `~/Codes/dotfiles`, installs mise if needed, then runs `mise bootstrap` (packages, login shell, deploy). Optional GUI/CLI apps: `mise run install-apps`. - -### Windows - -On a fresh / reset Windows, install **App Installer** (winget) from the Microsoft Store first — it is the prerequisite for everything else. Git, PowerShell 7 and mise are then installed automatically by the script. (If winget is missing, the script opens the Store page for you and stops so you can install it.) - -Before running the install script, enable **Developer Mode** (required for symlink creation). - -You can open the Settings page directly with this command in PowerShell: - -```powershell -Start-Process "ms-settings:developers" ``` - -In **PowerShell**: - -```powershell -irm https://dot.umeru.ma/install-win | iex +bash -c "$(curl -fsSL https://dot.umeru.ma/install)" ``` This will clone the repository to `~/Codes/dotfiles` and set up your dotfiles. diff --git a/docs/.gitignore b/docs/.gitignore index 8c31b3b..e89fe36 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1,27 +1,31 @@ -node_modules/ -dist/ -.astro/ -.nimbus/ -.wrangler/ +# deps +/node_modules -# install scripts are copied in from the repo root at build time -# (see copyInstallScripts in astro.config.ts); the root is the source of truth -public/install -public/install-win +# generated content +.contentlayer +.content-collections +.source -.env -.env.local -.env.*.local -.env.production -.dev.vars -.dev.vars.* +# test & build +/coverage +/.next/ +/out/ +/build +*.tsbuildinfo +# misc +.DS_Store +*.pem +/.pnp +.pnp.js npm-debug.log* yarn-debug.log* yarn-error.log* -pnpm-debug.log* -.DS_Store -.idea/ -.vscode/* -!.vscode/extensions.json +# others +.env*.local +.vercel +next-env.d.ts + +# +public/install \ No newline at end of file diff --git a/docs/AGENT.md b/docs/AGENT.md deleted file mode 100644 index 0ddcd58..0000000 --- a/docs/AGENT.md +++ /dev/null @@ -1,100 +0,0 @@ -# This Nimbus docs site - -Astro-based docs. The `nimbus-docs` package handles content schemas, sidebar/TOC, MDX→markdown, build hooks, and the `nimbus` CLI. Everything in `src/` is yours to edit. - -## File layout - -``` -astro.config.ts # imports nimbus + defineNimbusConfig -src/ -├── components.ts # MDX globals registry — every component used in .mdx must be listed -├── components/ # AgentDirective, Header, Render + ui// -├── content/ -│ ├── docs/*.mdx -│ └── partials/*.mdx # referenced via -├── content.config.ts # registers docsCollection() + partialsCollection() -├── layouts/ # BaseLayout (NimbusHead), DocsLayout (sidebar/TOC/breadcrumbs) -├── lib/cn.ts # Tailwind className merger -├── pages/ -│ ├── [...slug].astro -│ ├── [...slug]/index.md.ts # per-page markdown alternate -│ ├── llms.txt.ts -│ ├── og.png.ts # site-level OG card -│ ├── og/ -│ │ ├── _og-card-config.ts # shared OG theme tokens (underscore = not a route) -│ │ └── [...slug].ts # per-page OG cards -│ └── robots.txt.ts -└── styles/ # globals.css, prose.css -``` - -Cloudflare deploys also have `wrangler.jsonc` at the project root. - -## Writing docs - -Frontmatter validates against `docsSchema` (`nimbus-docs/schemas`). Required: `title`. - -```mdx ---- -title: My page -description: One-line summary. ---- - -Content here. The page H1 comes from `title` — don't repeat it in the body. - -## Section heading -``` - -Rules: - -- **Components must be PascalCase and registered in `src/components.ts`.** A pre-build validator catches typos with a "did you mean" hint. -- **Partials use ``.** Don't import `.mdx` directly. Shared content lives in `src/content/partials/.mdx`. -- **Icons use `astro-icon` + Phosphor.** `` from `astro-icon/components`. Glyphs: [phosphoricons.com](https://phosphoricons.com). -- **Don't remove `` from `BaseLayout.astro`.** It points agents at `/llms.txt`. - -## Adding things - -| Goal | Action | -|---|---| -| New doc page | Create `src/content/docs/.mdx`. Sidebar picks it up. | -| New partial | Create `src/content/partials/.mdx`. Use via ``. | -| UI from registry | `pnpm exec nimbus-docs add `. Register in `src/components.ts` if used in MDX. | -| Feature recipe | `pnpm exec nimbus-docs add `. Pipe the printed brief to your agent. | -| Custom page route | Add a file under `src/pages/`. | -| Custom OG style | Edit `src/pages/og/_og-card-config.ts`. | -| Check for updates | `pnpm exec nimbus-docs outdated` — starter files behind their tag + registry components behind. | -| Upgrade a starter file | `pnpm exec nimbus-docs diff ` to review, `diff --apply ` to pull a clean upstream change. | -| Upgrade a registry component | `pnpm exec nimbus-docs add --overwrite`, then review with `git diff`. | - -List installable items: `pnpm exec nimbus-docs list`. - -## Audit this site - -When asked to audit, walk the categories below. Emit findings as: - -``` -- [error|warn|info] FILE:LINE — what + why + fix. -``` - -End with `Summary: N errors, N warnings.` - -- **Config** — `astro.config.ts` calls `nimbus(defineNimbusConfig({ ... }))`; `site` is set; `editPattern` (if set) contains `{path}`; `output:` matches the deploy target. -- **Content** — `content.config.ts` registers `docsCollection()` (and `partialsCollection()` if used); every `.mdx` is inside a registered collection; frontmatter validates. -- **Sidebar** — every sidebar ref resolves to a content entry; no orphans; no slug collisions. -- **MDX** — every PascalCase component in `*.mdx` is registered; every `` resolves; code-fence languages are valid. -- **Routes** — `llms.txt.ts`, `robots.txt.ts`, `[...slug]/index.md.ts`, `og.png.ts`, `og/[...slug].ts` all exist. -- **Registry hygiene** — every `src/components/ui//` is either MDX-registered or imported in `src/`; transitive deps (`lib/cn.ts`, etc.) exist. -- **AI surface** — `` renders in `BaseLayout.astro`; doc `` has ``. -- **Search** — `data-pagefind-body` is on the docs main wrapper; after `pnpm build`, `dist/pagefind/` exists with ≥1 indexed page. -- **Cloudflare** (if applicable) — `wrangler.jsonc` has `name`, `compatibility_date`, `assets.directory = "./dist"`, `not_found_handling`. - -## Don't - -- Hand-add components under `src/components/ui/` that exists in the nimbus-docs registry — use `nimbus-docs add` so deps resolve. -- Import `.mdx` files directly — use ``. -- Attach remark/rehype plugins via `mdx({ remarkPlugins })` — Sätteri silently drops them. Framework-side transformations run as content passes. -- Remove `` unless asked. -- Edit `src/components.ts` to bypass registration — if a component is used in `.mdx`, register it. - -## Project home - -[nimbus-docs.com](https://nimbus-docs.com) diff --git a/docs/README.md b/docs/README.md index 3d16616..9b7bba9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,40 +1,45 @@ # docs -Documentation site for [dot.umeru.ma](https://dot.umeru.ma), built with -[Nimbus](https://nimbus-docs.com) (Astro) and deployed to Cloudflare Workers. +This is a Next.js application generated with +[Create Fumadocs](https://github.com/fuma-nama/fumadocs). -## Develop +Run development server: ```bash -mise run dev # or: bun run dev +npm run dev +# or +pnpm dev +# or +yarn dev ``` -Open http://localhost:4321. +Open http://localhost:3000 with your browser to see the result. -## Content +## Explore -- `src/pages/index.astro` — the landing page at `/` (hero, install one-liner, - and cards linking into the docs). -- `src/content/docs/*.{md,mdx}` — documentation pages. The sidebar is derived - from frontmatter (`sidebar.order`, `sidebar.group.label`). -- `astro.config.ts` — site config via `defineNimbusConfig` (`site`, `title`, - `github`) and the `copyInstallScripts` integration that copies the repo-root - `install` / `install-win` scripts into `public/` so they are served at - `/install` and `/install-win`. -- `public/_headers` — Cloudflare asset headers (immutable `/_astro/*`, - plain-text installers). +In the project, you can see: -Nimbus ships OG images, `/llms.txt`, `/llms-full.txt`, per-page `.md`/`.mdx` -twins, `robots.txt`, sitemap, and Pagefind search out of the box — see -`src/pages/`. `AGENT.md` documents the layout and authoring rules. +- `lib/source.ts`: Code for content source adapter, [`loader()`](https://fumadocs.dev/docs/headless/source-api) provides the interface to access your content. +- `lib/layout.shared.tsx`: Shared options for layouts, optional but preferred to keep. -## Build & deploy +| Route | Description | +| ------------------------- | ------------------------------------------------------ | +| `app/(home)` | The route group for your landing page and other pages. | +| `app/docs` | The documentation layout and pages. | +| `app/api/search/route.ts` | The Route Handler for search. | -```bash -bun run build # astro build → dist/ -bun run preview:cf # local Cloudflare Workers preview (wrangler dev) -bun run deploy # astro check && astro build && wrangler deploy -``` +### Fumadocs MDX + +A `source.config.ts` config file has been included, you can customise different options like frontmatter schema. + +Read the [Introduction](https://fumadocs.dev/docs/mdx) for further details. + +## Learn More + +To learn more about Next.js and Fumadocs, take a look at the following +resources: -The Worker is named `dotfiles` (`wrangler.jsonc`), which is bound to -`dot.umeru.ma`. +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js + features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. +- [Fumadocs](https://fumadocs.dev) - learn about Fumadocs diff --git a/docs/app/(docs)/[[...slug]]/page.tsx b/docs/app/(docs)/[[...slug]]/page.tsx new file mode 100644 index 0000000..4d19a82 --- /dev/null +++ b/docs/app/(docs)/[[...slug]]/page.tsx @@ -0,0 +1,54 @@ +import { getPageImage, source } from '@/lib/source'; +import { + DocsBody, + DocsDescription, + DocsPage, + DocsTitle, +} from 'fumadocs-ui/page'; +import { notFound } from 'next/navigation'; +import { getMDXComponents } from '@/mdx-components'; +import type { Metadata } from 'next'; +import { createRelativeLink } from 'fumadocs-ui/mdx'; + +export default async function Page(props: PageProps<'/[[...slug]]'>) { + const params = await props.params; + const page = source.getPage(params.slug); + if (!page) notFound(); + + const MDX = page.data.body; + + return ( + + {page.data.title} + {page.data.description} + + + + + ); +} + +export async function generateStaticParams() { + return source.generateParams(); +} + +export async function generateMetadata( + props: PageProps<'/[[...slug]]'>, +): Promise { + const params = await props.params; + const page = source.getPage(params.slug); + if (!page) notFound(); + + return { + title: page.data.title, + description: page.data.description, + openGraph: { + images: getPageImage(page).url, + }, + }; +} diff --git a/docs/app/(docs)/layout.tsx b/docs/app/(docs)/layout.tsx new file mode 100644 index 0000000..cdac70f --- /dev/null +++ b/docs/app/(docs)/layout.tsx @@ -0,0 +1,11 @@ +import { DocsLayout } from 'fumadocs-ui/layouts/docs'; +import { baseOptions } from '@/lib/layout.shared'; +import { source } from '@/lib/source'; + +export default function Layout({ children }: LayoutProps<'/'>) { + return ( + + {children} + + ); +} diff --git a/docs/app/api/search/route.ts b/docs/app/api/search/route.ts new file mode 100644 index 0000000..7ba7e82 --- /dev/null +++ b/docs/app/api/search/route.ts @@ -0,0 +1,7 @@ +import { source } from '@/lib/source'; +import { createFromSource } from 'fumadocs-core/search/server'; + +export const { GET } = createFromSource(source, { + // https://docs.orama.com/docs/orama-js/supported-languages + language: 'english', +}); diff --git a/docs/app/global.css b/docs/app/global.css new file mode 100644 index 0000000..69e4cb5 --- /dev/null +++ b/docs/app/global.css @@ -0,0 +1,61 @@ +@import 'tailwindcss'; +@import 'fumadocs-ui/css/neutral.css'; +@import 'fumadocs-ui/css/preset.css'; + +/** +* https://github.com/zen-browser/docs/blob/main/src/app/global.css +*/ +:root { + --color-fd-background: #F2F0E3; + --color-fd-foreground: #2E2E2E; + --color-fd-primary: #F76F53; + --color-fd-accent: #E6E4D7; + --color-fd-accent-foreground: #2E2E2E; + --color-fd-card: #F7F6EE; + --color-fd-card-foreground: #2E2E2E; + --color-fd-muted: #2e2e2e0b; + --color-fd-muted-foreground: #2e2e2ec5; + --color-fd-secondary: #E6E4D7; + --color-fd-secondary-foreground: #2E2E2E; + --color-fd-popover: #F2F0E3; + --color-fd-popover-foreground: #2E2E2E; + --color-fd-border: #EAE9E2; +} + +.dark { + --color-fd-background: #1F1F1F; + --color-fd-foreground: #D1CFC0; + --color-fd-primary: #F76F53; + --color-fd-accent: #363636; + --color-fd-accent-foreground: #D1CFC0; + --color-fd-card: #161616; + --color-fd-card-foreground: #D1CFC0; + --color-fd-muted: #d1cfc00b; + --color-fd-muted-foreground: #D1CFC0c5; + --color-fd-secondary: #363636; + --color-fd-secondary-foreground: #2E2E2E; + --color-fd-popover: #1F1F1F; + --color-fd-popover-foreground: #D1CFC0; + --color-fd-border: #2E2E2E; +} + +aside { + background-color: var(--color-fd-background) !important; +} + +aside a[data-active="true"] { + color: var(--color-fd-foreground) !important; + background-color: var(--color-fd-accent) !important; +} + +.prose :where(code):not(:where([class~="not-prose"], [class~="not-prose"] *)) { + font-size: 14px; +} + +g.main:has(> g.plot) > rect { + display: none; +} + +video { + border-radius: 40px; +} \ No newline at end of file diff --git a/docs/app/layout.tsx b/docs/app/layout.tsx new file mode 100644 index 0000000..db55a54 --- /dev/null +++ b/docs/app/layout.tsx @@ -0,0 +1,17 @@ +import '@/app/global.css'; +import { RootProvider } from 'fumadocs-ui/provider/next'; +import { Inter } from 'next/font/google'; + +const inter = Inter({ + subsets: ['latin'], +}); + +export default function Layout({ children }: LayoutProps<'/'>) { + return ( + + + {children} + + + ); +} diff --git a/docs/app/llms-full.txt/route.ts b/docs/app/llms-full.txt/route.ts new file mode 100644 index 0000000..d494d2c --- /dev/null +++ b/docs/app/llms-full.txt/route.ts @@ -0,0 +1,10 @@ +import { getLLMText, source } from '@/lib/source'; + +export const revalidate = false; + +export async function GET() { + const scan = source.getPages().map(getLLMText); + const scanned = await Promise.all(scan); + + return new Response(scanned.join('\n\n')); +} diff --git a/docs/app/og/docs/[...slug]/route.tsx b/docs/app/og/docs/[...slug]/route.tsx new file mode 100644 index 0000000..f5df96d --- /dev/null +++ b/docs/app/og/docs/[...slug]/route.tsx @@ -0,0 +1,36 @@ +import { getPageImage, source } from '@/lib/source'; +import { notFound } from 'next/navigation'; +import { ImageResponse } from 'next/og'; +import { generate as DefaultImage } from 'fumadocs-ui/og'; + +export const revalidate = false; + +export async function GET( + _req: Request, + { params }: RouteContext<'/og/docs/[...slug]'>, +) { + const { slug } = await params; + const page = source.getPage(slug.slice(0, -1)); + if (!page) notFound(); + + return new ImageResponse( + ( + + ), + { + width: 1200, + height: 630, + }, + ); +} + +export function generateStaticParams() { + return source.getPages().map((page) => ({ + lang: page.locale, + slug: getPageImage(page).segments, + })); +} diff --git a/docs/astro.config.ts b/docs/astro.config.ts deleted file mode 100644 index 3db9cb7..0000000 --- a/docs/astro.config.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { cpSync, mkdirSync } from "node:fs"; -import { fileURLToPath } from "node:url"; -import { defineConfig } from "astro/config"; -import icon from "astro-icon"; -import tailwindcss from "@tailwindcss/vite"; -import nimbus, { defineConfig as defineNimbusConfig } from "@cloudflare/nimbus-docs"; -import { tableScroll } from "@cloudflare/nimbus-docs/markdown"; - -// The curl/irm installers are the repo-root `install` / `install-win` scripts. -// They must be served verbatim at /install and /install-win (referenced from -// the docs and from the outside world), so copy them into `public/` before -// dev and build. They stay gitignored under public/ — the repo root is the -// single source of truth. -function copyInstallScripts() { - return { - name: "copy-install-scripts", - hooks: { - "astro:config:setup": () => { - const publicDir = fileURLToPath(new URL("./public/", import.meta.url)); - mkdirSync(publicDir, { recursive: true }); - for (const name of ["install", "install-win"]) { - cpSync( - fileURLToPath(new URL(`../${name}`, import.meta.url)), - `${publicDir}${name}`, - ); - } - }, - }, - }; -} - -const nimbusConfig = defineNimbusConfig({ - // Canonical origin (no trailing slash). Drives canonical URLs, absolute OG - // image URLs, robots.txt, sitemap, and the links in /llms.txt. - site: "https://dot.umeru.ma", - // Used for , the home H1, the header brand, and OG cards. - title: "dotfiles", - description: "umeruma の dotfiles — macOS / Linux / Windows へのインストールとデプロイ。", - locale: "ja", - github: "https://github.com/umeruma/dotfiles", - socialImageAlt: "dotfiles documentation preview", -}); - -export default defineConfig({ - site: "https://dot.umeru.ma", - output: "static", - // Tailwind v4 via its Vite plugin (the integration Astro recommends for - // Tailwind v4 — replaces the PostCSS plugin, which doesn't build under - // Astro 7's Vite 8 bundler). - vite: { - plugins: [tailwindcss()], - }, - // Hover-prefetch link targets so full-page navigations feel instant without - // a client-side router. - prefetch: { - prefetchAll: true, - defaultStrategy: "hover", - }, - integrations: [ - copyInstallScripts(), - icon(), - nimbus(nimbusConfig, { - // Frontmatter must validate against the content schema, and broken - // internal links are 404s for readers — enforce both. - rules: { - "nimbus/frontmatter-shape": "error", - "nimbus/internal-link": "error", - }, - // Wrap wide tables so they scroll instead of overflowing the page - // (styled by `.nb-table-scroll` in src/styles/prose.css). - markdown: { - hastPlugins: [tableScroll()], - }, - }), - ], -}); diff --git a/docs/biome.json b/docs/biome.json new file mode 100644 index 0000000..95df3a1 --- /dev/null +++ b/docs/biome.json @@ -0,0 +1,34 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.2.0/schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, + "files": { + "ignoreUnknown": true, + "includes": ["**", "!node_modules", "!.next", "!dist", "!build", "!.source"] + }, + "formatter": { + "enabled": true, + "indentStyle": "space", + "indentWidth": 2 + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true + }, + "domains": { + "next": "recommended", + "react": "recommended" + } + }, + "assist": { + "actions": { + "source": { + "organizeImports": "on" + } + } + } +} diff --git a/docs/bun.lock b/docs/bun.lock index 8c05241..14f2b60 100644 --- a/docs/bun.lock +++ b/docs/bun.lock @@ -1,269 +1,165 @@ { "lockfileVersion": 1, - "configVersion": 1, + "configVersion": 0, "workspaces": { "": { - "name": "nimbus-probe", + "name": "docs", "dependencies": { - "@cloudflare/nimbus-docs": "^0.8.1", - "@fontsource-variable/inter": "^5.2.8", - "@fontsource-variable/jetbrains-mono": "^5.2.8", - "@iconify-json/ph": "^1.2.0", - "astro": "^7.0.0", - "astro-icon": "^1.1.0", - "astro-og-canvas": "^0.13.0", - "canvaskit-wasm": "^0.41.1", - "clsx": "^2.1.1", - "tailwind-merge": "^3.5.0", + "fumadocs-core": "16.4.5", + "fumadocs-mdx": "14.2.4", + "fumadocs-ui": "16.4.5", + "lucide-react": "^0.562.0", + "next": "16.1.1", + "react": "^19.2.3", + "react-dom": "^19.2.3", }, "devDependencies": { - "@astrojs/check": "^0.9.8", - "@tailwindcss/vite": "^4.1.4", - "pagefind": "^1.5.2", - "tailwindcss": "^4.1.4", - "typescript": "^5.8.3", - "wrangler": "^4.95.0", + "@biomejs/biome": "^2.3.11", + "@tailwindcss/postcss": "^4.1.18", + "@types/mdx": "^2.0.13", + "@types/node": "25.0.3", + "@types/react": "^19.2.7", + "@types/react-dom": "^19.2.3", + "postcss": "^8.5.6", + "tailwindcss": "^4.1.18", + "typescript": "^5.9.3", }, }, }, "packages": { - "@antfu/install-pkg": ["@antfu/install-pkg@1.1.0", "", { "dependencies": { "package-manager-detector": "^1.3.0", "tinyexec": "^1.0.1" } }, "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ=="], + "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], - "@antfu/utils": ["@antfu/utils@8.1.1", "", {}, "sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ=="], + "@biomejs/biome": ["@biomejs/biome@2.3.11", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.3.11", "@biomejs/cli-darwin-x64": "2.3.11", "@biomejs/cli-linux-arm64": "2.3.11", "@biomejs/cli-linux-arm64-musl": "2.3.11", "@biomejs/cli-linux-x64": "2.3.11", "@biomejs/cli-linux-x64-musl": "2.3.11", "@biomejs/cli-win32-arm64": "2.3.11", "@biomejs/cli-win32-x64": "2.3.11" }, "bin": { "biome": "bin/biome" } }, "sha512-/zt+6qazBWguPG6+eWmiELqO+9jRsMZ/DBU3lfuU2ngtIQYzymocHhKiZRyrbra4aCOoyTg/BmY+6WH5mv9xmQ=="], - "@astrojs/check": ["@astrojs/check@0.9.9", "", { "dependencies": { "@astrojs/language-server": "^2.16.7", "chokidar": "^4.0.3", "kleur": "^4.1.5", "yargs": "^17.7.2" }, "peerDependencies": { "typescript": "^5.0.0 || ^6.0.0" }, "bin": { "astro-check": "bin/astro-check.js" } }, "sha512-A5UW8uIuErLWEoRQvzgXpO1gTjUFtK8r7nU2Z7GewAMxUb7bPvpk11qaKKgxqXlHJWlAvaaxy+Xg28A6bmQ1Tg=="], + "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.3.11", "", { "os": "darwin", "cpu": "arm64" }, "sha512-/uXXkBcPKVQY7rc9Ys2CrlirBJYbpESEDme7RKiBD6MmqR2w3j0+ZZXRIL2xiaNPsIMMNhP1YnA+jRRxoOAFrA=="], - "@astrojs/compiler": ["@astrojs/compiler@2.13.1", "", {}, "sha512-f3FN83d2G/v32ipNClRKgYv30onQlMZX1vCeZMjPsMMPl1mDpmbl0+N5BYo4S/ofzqJyS5hvwacEo0CCVDn/Qg=="], + "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.3.11", "", { "os": "darwin", "cpu": "x64" }, "sha512-fh7nnvbweDPm2xEmFjfmq7zSUiox88plgdHF9OIW4i99WnXrAC3o2P3ag9judoUMv8FCSUnlwJCM1B64nO5Fbg=="], - "@astrojs/compiler-binding": ["@astrojs/compiler-binding@0.3.1", "", { "optionalDependencies": { "@astrojs/compiler-binding-darwin-arm64": "0.3.1", "@astrojs/compiler-binding-darwin-x64": "0.3.1", "@astrojs/compiler-binding-linux-arm64-gnu": "0.3.1", "@astrojs/compiler-binding-linux-arm64-musl": "0.3.1", "@astrojs/compiler-binding-linux-x64-gnu": "0.3.1", "@astrojs/compiler-binding-linux-x64-musl": "0.3.1", "@astrojs/compiler-binding-wasm32-wasi": "0.3.1", "@astrojs/compiler-binding-win32-arm64-msvc": "0.3.1", "@astrojs/compiler-binding-win32-x64-msvc": "0.3.1" } }, "sha512-DaAUj29AIBU2XdJ8uwcab8lW5O2pk9pY8AXkcMw0sw77nVa3oeTYRcO+Dvbbpoexf6ThMc0FMWYCQ/wN1/T7oQ=="], + "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.3.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-l4xkGa9E7Uc0/05qU2lMYfN1H+fzzkHgaJoy98wO+b/7Gl78srbCRRgwYSW+BTLixTBrM6Ede5NSBwt7rd/i6g=="], - "@astrojs/compiler-binding-darwin-arm64": ["@astrojs/compiler-binding-darwin-arm64@0.3.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-IEmEF2fUIlTHtpeE/isyEGVOB14cEyh/LZOFYt6wn3jNyVpdC8aR5OZ+RzFUR/f+8ZDM1LaMwZKvoA7eMyJeFw=="], + "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.3.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-XPSQ+XIPZMLaZ6zveQdwNjbX+QdROEd1zPgMwD47zvHV+tCGB88VH+aynyGxAHdzL+Tm/+DtKST5SECs4iwCLg=="], - "@astrojs/compiler-binding-darwin-x64": ["@astrojs/compiler-binding-darwin-x64@0.3.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-GF2kIxjpPDLsn94zbZNMsxEmkU828QqnmM7kiQJnaooS3jmI+I7kk6+oI6EpwOsK3femCMdcm+wmOsEqtGrmjQ=="], + "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.3.11", "", { "os": "linux", "cpu": "x64" }, "sha512-/1s9V/H3cSe0r0Mv/Z8JryF5x9ywRxywomqZVLHAoa/uN0eY7F8gEngWKNS5vbbN/BsfpCG5yeBT5ENh50Frxg=="], - "@astrojs/compiler-binding-linux-arm64-gnu": ["@astrojs/compiler-binding-linux-arm64-gnu@0.3.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-XJL3SDmOtVrqFhCirNcHwE91+IesJqlgNo23I4qW9QUYfwzm/TBZuH61fgqsb1ttgR1mMYz6ooPWs0JDhwMqpQ=="], + "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.3.11", "", { "os": "linux", "cpu": "x64" }, "sha512-vU7a8wLs5C9yJ4CB8a44r12aXYb8yYgBn+WeyzbMjaCMklzCv1oXr8x+VEyWodgJt9bDmhiaW/I0RHbn7rsNmw=="], - "@astrojs/compiler-binding-linux-arm64-musl": ["@astrojs/compiler-binding-linux-arm64-musl@0.3.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-xqE8BVbDoBueK/B47w30PtkVofUWJKGkwoMVE+EOMLf11rnoANxIAdA9FPqY+rng4oNI5ndHGsri1yPj2k8vZQ=="], + "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.3.11", "", { "os": "win32", "cpu": "arm64" }, "sha512-PZQ6ElCOnkYapSsysiTy0+fYX+agXPlWugh6+eQ6uPKI3vKAqNp6TnMhoM3oY2NltSB89hz59o8xIfOdyhi9Iw=="], - "@astrojs/compiler-binding-linux-x64-gnu": ["@astrojs/compiler-binding-linux-x64-gnu@0.3.1", "", { "os": "linux", "cpu": "x64" }, "sha512-1y0StU1qiCuDFH3rmbRJXcxdfHxFPrES1Rd+RLffosvUR7I2cH5SF5SFnBN9vXpzpkmyElZm3Yr47iJBPN7vVA=="], + "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.3.11", "", { "os": "win32", "cpu": "x64" }, "sha512-43VrG813EW+b5+YbDbz31uUsheX+qFKCpXeY9kfdAx+ww3naKxeVkTD9zLIWxUPfJquANMHrmW3wbe/037G0Qg=="], - "@astrojs/compiler-binding-linux-x64-musl": ["@astrojs/compiler-binding-linux-x64-musl@0.3.1", "", { "os": "linux", "cpu": "x64" }, "sha512-16q0fYf7kpbmdObZEeZJEup8hQv/whgNwVjrSvT8umrKwLDSnNIWiQpm09lQQu6bweZB0XyIvHwlPitvJhC+hg=="], + "@emnapi/runtime": ["@emnapi/runtime@1.5.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ=="], - "@astrojs/compiler-binding-wasm32-wasi": ["@astrojs/compiler-binding-wasm32-wasi@0.3.1", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.6" }, "cpu": "none" }, "sha512-cB456shIwDv/PrVT+2QG7LFndpHkVge5HjqADKZgGaAc9JHVktCtjSrcdkRQ+3tbkPazNKaTLRjXLIiz2NIx9g=="], + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw=="], - "@astrojs/compiler-binding-win32-arm64-msvc": ["@astrojs/compiler-binding-win32-arm64-msvc@0.3.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-ur/9+If/yTE69mmeX5MqSZndL0HOyx67GeNZUy3N7wVdWpLz9UTJXwyWS4UR2PUQHitghjsM5xoX0Ge56WRVQQ=="], + "@esbuild/android-arm": ["@esbuild/android-arm@0.27.2", "", { "os": "android", "cpu": "arm" }, "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA=="], - "@astrojs/compiler-binding-win32-x64-msvc": ["@astrojs/compiler-binding-win32-x64-msvc@0.3.1", "", { "os": "win32", "cpu": "x64" }, "sha512-k0W+kDBzDkNZOqu4kElDvCOIbKw5Ut9S1WZ1Krj3KTgNuBERNKXsMMsRLLcbgfdMdbe7bTekQLshZrrvmYpmwA=="], + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.2", "", { "os": "android", "cpu": "arm64" }, "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA=="], - "@astrojs/compiler-rs": ["@astrojs/compiler-rs@0.3.1", "", { "dependencies": { "@astrojs/compiler-binding": "0.3.1" } }, "sha512-aT7xkgsbNoS6nriY5qKpbihK43slFHO41iqgHCTdOvn1ifaQxLCc5yXy+6GzAtiafoaC1zA7OwVXCXMsvUZOkg=="], + "@esbuild/android-x64": ["@esbuild/android-x64@0.27.2", "", { "os": "android", "cpu": "x64" }, "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A=="], - "@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.10.1", "", { "dependencies": { "@types/hast": "^3.0.4", "@types/mdast": "^4.0.4", "js-yaml": "^4.1.1", "picomatch": "^4.0.4", "retext-smartypants": "^6.2.0", "shiki": "^4.0.2", "smol-toml": "^1.6.0", "unified": "^11.0.5" } }, "sha512-5phcroT/vmOOrYuuAxtkbPixy5hePtlz9i8K4OeDv3dNK6/UQRuXPOSRTxIOBbUY5Sonw2UaxjbuVc43Mcir6Q=="], + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg=="], - "@astrojs/language-server": ["@astrojs/language-server@2.16.13", "", { "dependencies": { "@astrojs/compiler": "^2.13.1", "@astrojs/yaml2ts": "^0.2.4", "@jridgewell/sourcemap-codec": "^1.5.5", "@volar/kit": "~2.4.28", "@volar/language-core": "~2.4.28", "@volar/language-server": "~2.4.28", "@volar/language-service": "~2.4.28", "muggle-string": "^0.4.1", "tinyglobby": "^0.2.16", "volar-service-css": "0.0.71", "volar-service-emmet": "0.0.71", "volar-service-html": "0.0.71", "volar-service-prettier": "0.0.71", "volar-service-typescript": "0.0.71", "volar-service-typescript-twoslash-queries": "0.0.71", "volar-service-yaml": "0.0.71", "vscode-html-languageservice": "^5.6.2", "vscode-uri": "^3.1.0" }, "peerDependencies": { "prettier": "^3.0.0", "prettier-plugin-astro": ">=0.11.0" }, "optionalPeers": ["prettier", "prettier-plugin-astro"], "bin": { "astro-ls": "./bin/nodeServer.js" } }, "sha512-ekOa+CYprEq5n4EJC1qTIAhLk49HZIUQuFwrEuF+3JK/pdMaYnWoREFUI2A0KEPOJiFA2kamBzKzbYljDvUxLg=="], + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA=="], - "@astrojs/markdown-remark": ["@astrojs/markdown-remark@7.2.1", "", { "dependencies": { "@astrojs/internal-helpers": "0.10.1", "@astrojs/prism": "4.0.2", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-smartypants": "^3.0.2", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.1.0", "unist-util-visit-parents": "^6.0.2", "vfile": "^6.0.3" } }, "sha512-jPVNIqTvk+yKviikszv/Y1U4jGUSKpp/Nw48QZV4qjWgp70j4Lkq3lhSDRbWwCfgKvEyO9GHuVbV1dM2WYXy1w=="], + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g=="], - "@astrojs/markdown-satteri": ["@astrojs/markdown-satteri@0.3.4", "", { "dependencies": { "@astrojs/internal-helpers": "0.10.1", "@astrojs/prism": "4.0.2", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "satteri": "^0.9.1" } }, "sha512-6Lvt/bQZEBW+zzdhPblvfZEy5PGEYJaUsUqaCgwHeRPxZJL1gc9I+DRLKWJjjYTWDzVUTzXlMq4WwSK+X34CVw=="], + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA=="], - "@astrojs/mdx": ["@astrojs/mdx@7.0.3", "", { "dependencies": { "@astrojs/internal-helpers": "0.10.1", "@astrojs/markdown-remark": "7.2.1", "@mdx-js/mdx": "^3.1.1", "acorn": "^8.16.0", "es-module-lexer": "^2.0.0", "estree-util-visit": "^2.0.0", "hast-util-to-html": "^9.0.5", "piccolore": "^0.1.3", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.1", "remark-smartypants": "^3.0.2", "source-map": "^0.7.6", "unist-util-visit": "^5.1.0", "vfile": "^6.0.3" }, "peerDependencies": { "@astrojs/markdown-satteri": "^0.3.1", "astro": "^7.0.0" }, "optionalPeers": ["@astrojs/markdown-satteri"] }, "sha512-RxyIwU0uFam5ftwqKOjpIdhnFxZ/kEikeimLyQy3eGXbHT8WgRGzzesOIHVU8+m9TY8ag5WVOyvV24/GyqPdPQ=="], + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.2", "", { "os": "linux", "cpu": "arm" }, "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw=="], - "@astrojs/prism": ["@astrojs/prism@4.0.2", "", { "dependencies": { "prismjs": "^1.30.0" } }, "sha512-KTivpmnz6lDsC6o9H4+DNm2SrE/GHzw8cNAvEJwAvUT+eoaEnn/4NtbDNfRRaxaJHdp15gf+tfHAWiXR4wB3BA=="], + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw=="], - "@astrojs/sitemap": ["@astrojs/sitemap@3.7.3", "", { "dependencies": { "sitemap": "^9.0.0", "stream-replace-string": "^2.0.0", "zod": "^4.3.6" } }, "sha512-f8euLVsyeAmAkSm/1M2Kb8sL8byQmfgbvBNaHFItCheTj/IpiJYSEWVcqDHZ/yEHxiS7+w87mQkzwZaPHmk5GA=="], + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.2", "", { "os": "linux", "cpu": "ia32" }, "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w=="], - "@astrojs/telemetry": ["@astrojs/telemetry@3.3.3", "", { "dependencies": { "ci-info": "^4.4.0", "dset": "^3.1.4", "is-docker": "^4.0.0", "package-manager-detector": "^1.6.0" } }, "sha512-C1TLn5sPJr0x4vk56piHWKbnqlEB8BKyte5Y45V02U+D7BGO5eMqZDH5aPjnkXQWJggvmsTXxH03QMZ9NgWLzQ=="], + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.2", "", { "os": "linux", "cpu": "none" }, "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg=="], - "@astrojs/yaml2ts": ["@astrojs/yaml2ts@0.2.4", "", { "dependencies": { "yaml": "^2.8.3" } }, "sha512-8oddpOae35pJsXPQXhTkM0ypfKPskVsh2bCxRtbf7e+/Epw2nReakFYpLKjZMEr75CsoF203PMnCocpfz0s69A=="], + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.2", "", { "os": "linux", "cpu": "none" }, "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw=="], - "@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="], + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ=="], - "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.2", "", { "os": "linux", "cpu": "none" }, "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA=="], - "@babel/parser": ["@babel/parser@7.29.7", "", { "dependencies": { "@babel/types": "^7.29.7" }, "bin": "./bin/babel-parser.js" }, "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg=="], + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w=="], - "@babel/types": ["@babel/types@7.29.7", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA=="], + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.2", "", { "os": "linux", "cpu": "x64" }, "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA=="], - "@bruits/satteri-darwin-arm64": ["@bruits/satteri-darwin-arm64@0.9.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-iw4nZgx9v30lWo/MTngQqi1pI78KI0DnkSm+lVJGYdmPLgAyDNJigVhpG42/Iq55A6c1Ll8q66ljyyRiQUxwow=="], + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.2", "", { "os": "none", "cpu": "arm64" }, "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw=="], - "@bruits/satteri-darwin-x64": ["@bruits/satteri-darwin-x64@0.9.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-6T26Z5Kf3cFW2PSlk9p7zT7yVxvuBSiJvYyz9u8KjYwMTqZyIDOj2wDyNpxKV4+6yUVG7rddq2QwvG/8LJA2+Q=="], + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.2", "", { "os": "none", "cpu": "x64" }, "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA=="], - "@bruits/satteri-linux-arm64-gnu": ["@bruits/satteri-linux-arm64-gnu@0.9.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-u51id17uJwNEMK9nBlICsq6U31c+XVqQueVBkwRIzZG+gMpS8TOJctt5h5Wz33Z8xnMdTd+adtACVz0yHgGuOA=="], + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA=="], - "@bruits/satteri-linux-arm64-musl": ["@bruits/satteri-linux-arm64-musl@0.9.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-v39HxiwGC5Rqm01HksP6+5Y+xKLPlsuVFgIgpEAo+SiQ22c+mJVhS3u7Z6ePAKdhL5NJoK1xq70kLz3L13AhpQ=="], + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg=="], - "@bruits/satteri-linux-x64-gnu": ["@bruits/satteri-linux-x64-gnu@0.9.5", "", { "os": "linux", "cpu": "x64" }, "sha512-F3uO8uFp3pAP5ZGXttwvh57GS7s0lL953tnNdyI2gRyP4kOOkp6pyGojNJzCjkDvWI2Cvb9iNrKok3aqQPauAw=="], + "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.2", "", { "os": "none", "cpu": "arm64" }, "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag=="], - "@bruits/satteri-linux-x64-musl": ["@bruits/satteri-linux-x64-musl@0.9.5", "", { "os": "linux", "cpu": "x64" }, "sha512-bicEqglLlz++mWyADaZoP0JY20s4vDfLjaPYgQqC+NI4zZLTOOg1T4GB8aqtc822Pqji8SQBmSrTb7CrP8i08Q=="], + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg=="], - "@bruits/satteri-wasm32-wasi": ["@bruits/satteri-wasm32-wasi@0.9.5", "", { "dependencies": { "@emnapi/core": "1.11.1", "@emnapi/runtime": "1.11.1", "@napi-rs/wasm-runtime": "^1.1.6" }, "cpu": "none" }, "sha512-zauAuMwfPnKPUkd4AFixRFpXdgKwP2mKgxrIIo2gJzW0/ZneF9dbHnLkojSpaBnCCp7VUL1hIi5WWZvB1CqmAQ=="], + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg=="], - "@bruits/satteri-win32-arm64-msvc": ["@bruits/satteri-win32-arm64-msvc@0.9.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-SrfE7NEsgZjBvU3c+RR6oQRu0ToXY5uVJEbieXEF0YTctIV2zAVlbaMjWLts074QCgh3a+XHWkR/lWh2VH2LUg=="], + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ=="], - "@bruits/satteri-win32-x64-msvc": ["@bruits/satteri-win32-x64-msvc@0.9.5", "", { "os": "win32", "cpu": "x64" }, "sha512-5Kw9ZAtTGS8WHizyn+CJhjjfIQrw+7jcZodpmpXJjefnO15M8UexIi6JR2E5thyvsmHyhL6ZDDMUNR4bKJPd4g=="], + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.2", "", { "os": "win32", "cpu": "x64" }, "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ=="], - "@capsizecss/unpack": ["@capsizecss/unpack@4.0.1", "", { "dependencies": { "fontkitten": "^1.0.3" } }, "sha512-CuNiSqg7+e1cO/GjffyMOm5Tt2jUF9CWHHnvQ/UkqvtkGfHdgwEC0wpmq7fkN3gxwpRnrAN0WzO3vREKmNolMQ=="], + "@floating-ui/core": ["@floating-ui/core@1.7.3", "", { "dependencies": { "@floating-ui/utils": "^0.2.10" } }, "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w=="], - "@clack/core": ["@clack/core@0.4.1", "", { "dependencies": { "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-Pxhij4UXg8KSr7rPek6Zowm+5M22rbd2g1nfojHJkxp5YkFqiZ2+YLEM/XGVIzvGOcM0nqjIFxrpDwWRZYWYjA=="], + "@floating-ui/dom": ["@floating-ui/dom@1.7.4", "", { "dependencies": { "@floating-ui/core": "^1.7.3", "@floating-ui/utils": "^0.2.10" } }, "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA=="], - "@clack/prompts": ["@clack/prompts@0.9.1", "", { "dependencies": { "@clack/core": "0.4.1", "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-JIpyaboYZeWYlyP0H+OoPPxd6nqueG/CmN6ixBiNFsIDHREevjIf0n0Ohh5gr5C8pEDknzgvz+pIJ8dMhzWIeg=="], + "@floating-ui/react-dom": ["@floating-ui/react-dom@2.1.6", "", { "dependencies": { "@floating-ui/dom": "^1.7.4" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw=="], - "@cloudflare/kv-asset-handler": ["@cloudflare/kv-asset-handler@0.5.0", "", {}, "sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg=="], + "@floating-ui/utils": ["@floating-ui/utils@0.2.10", "", {}, "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="], - "@cloudflare/nimbus-docs": ["@cloudflare/nimbus-docs@0.8.2", "", { "dependencies": { "@astrojs/markdown-satteri": "^0.3.4", "@astrojs/mdx": "^7.0.3", "@astrojs/sitemap": "^3.7.2", "@clack/prompts": "^0.9.1", "@shikijs/transformers": "^4.2.0", "@shikijs/types": "^4.2.0", "@vercel/detect-agent": "^1.2.3", "clsx": "^2.1.1", "giget": "^3.3.0", "github-slugger": "^2.0.0", "mri": "^1.2.0", "picomatch": "^4.0.5", "remark-lint-emphasis-marker": "^4.0.1", "remark-lint-fenced-code-flag": "^4.2.0", "remark-lint-heading-increment": "^4.0.1", "remark-lint-no-duplicate-headings": "^4.0.1", "remark-lint-no-heading-punctuation": "^4.0.1", "remark-lint-no-literal-urls": "^4.0.1", "remark-lint-no-multiple-toplevel-headings": "^4.0.1", "remark-lint-unordered-list-marker-style": "^4.0.1", "satteri": "^0.9.1", "shiki": "^4.0.0", "tailwind-merge": "^3.5.0", "unified": "^11.0.5", "vfile": "^6.0.3", "yaml": "^2.7.1" }, "peerDependencies": { "astro": "^7.0.0", "react": ">=19.0.0", "react-dom": ">=19.0.0" }, "optionalPeers": ["react", "react-dom"], "bin": { "nimbus-docs": "dist/cli/index.js" } }, "sha512-SLrU2xeXIHQYxhZAivpQWqEHk+egwPAuCPffdEMI4qUANAccP9jV6MPdP4s57xwXaD3TP2URSMI28fGH9kkywg=="], + "@formatjs/fast-memoize": ["@formatjs/fast-memoize@3.0.3", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-CArYtQKGLAOruCMeq5/RxCg6vUXFx3OuKBdTm30Wn/+gCefehmZ8Y2xSMxMrO2iel7hRyE3HKfV56t3vAU6D4Q=="], - "@cloudflare/unenv-preset": ["@cloudflare/unenv-preset@2.16.1", "", { "peerDependencies": { "unenv": "2.0.0-rc.24", "workerd": ">1.20260305.0 <2.0.0-0" }, "optionalPeers": ["workerd"] }, "sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw=="], + "@formatjs/intl-localematcher": ["@formatjs/intl-localematcher@0.7.5", "", { "dependencies": { "@formatjs/fast-memoize": "3.0.3", "tslib": "^2.8.0" } }, "sha512-7/nd90cn5CT7SVF71/ybUKAcnvBlr9nZlJJp8O8xIZHXFgYOC4SXExZlSdgHv2l6utjw1byidL06QzChvQMHwA=="], - "@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20260722.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-vZOP8vIS3NwnuaO+gz0FZ7kIGeiO3bZmxV35Ph9zOXKSREhDFlH7wQ7mkCdhW3O4jnXsew+XT7b+DNEI2CcJGQ=="], + "@fumadocs/ui": ["@fumadocs/ui@16.4.5", "", { "dependencies": { "fumadocs-core": "16.4.5", "next-themes": "^0.4.6", "postcss-selector-parser": "^7.1.1", "tailwind-merge": "^3.4.0" }, "peerDependencies": { "@types/react": "*", "next": "16.x.x", "react": "^19.2.0", "react-dom": "^19.2.0", "tailwindcss": "^4.0.0" }, "optionalPeers": ["@types/react", "next", "tailwindcss"] }, "sha512-YnQLQp6TVPib6kuRCdIUTsL5vW7vfrkvde68OILn1CEMDd+WLX666WUenCwvZWfk/lwxgW5b5GuQfH57YNRq0w=="], - "@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20260722.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-EmIQymihDq6WNdER4+LF8Qn80yqayBUpJ+tkOO7wmY8pmgfyXjIUFNXotl21AHovTeu2seR7HdVUgeN/BilCWw=="], + "@img/colour": ["@img/colour@1.0.0", "", {}, "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw=="], - "@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20260722.1", "", { "os": "linux", "cpu": "x64" }, "sha512-jvZ3k9fxcnEn04s80CgIYxQfpOyAiz/8qC42DP8EBa9tR27qWyg9wmm31zIobVlrgBZn/+8NfdP73avRGcQOjQ=="], + "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.3" }, "os": "darwin", "cpu": "arm64" }, "sha512-sitdlPzDVyvmINUdJle3TNHl+AG9QcwiAMsXmccqsCOMZNIdW2/7S26w0LyU8euiLVzFBL3dXPwVCq/ODnf2vA=="], - "@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20260722.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-BOSB55SMNdy+DA5uj2WirgiNanpHGis5PVvXH1wSfvjRKr4JGgWK+EZzxz0RFUo6QjjQQC/NimEzNZ7va7jmKg=="], + "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.3" }, "os": "darwin", "cpu": "x64" }, "sha512-rZheupWIoa3+SOdF/IcUe1ah4ZDpKBGWcsPX6MT0lYniH9micvIU7HQkYTfrx5Xi8u+YqwLtxC/3vl8TQN6rMg=="], - "@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20260722.1", "", { "os": "win32", "cpu": "x64" }, "sha512-sYM8YgUpKnRz2xjvdJLX1Ojzoi4MlA4gk8WTTExhGydjYB2UTs5NIbv0ZmpKgMoK9io3ixgmiW56ZnTbcWOdiA=="], + "@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-QzWAKo7kpHxbuHqUC28DZ9pIKpSi2ts2OJnoIGI26+HMgq92ZZ4vk8iJd4XsxN+tYfNJxzH6W62X5eTcsBymHw=="], - "@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="], + "@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-Ju+g2xn1E2AKO6YBhxjj+ACcsPQRHT0bhpglxcEf+3uyPY+/gL8veniKoo96335ZaPo03bdDXMv0t+BBFAbmRA=="], - "@emmetio/abbreviation": ["@emmetio/abbreviation@2.3.3", "", { "dependencies": { "@emmetio/scanner": "^1.0.4" } }, "sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA=="], + "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.3", "", { "os": "linux", "cpu": "arm" }, "sha512-x1uE93lyP6wEwGvgAIV0gP6zmaL/a0tGzJs/BIDDG0zeBhMnuUPm7ptxGhUbcGs4okDJrk4nxgrmxpib9g6HpA=="], - "@emmetio/css-abbreviation": ["@emmetio/css-abbreviation@2.1.8", "", { "dependencies": { "@emmetio/scanner": "^1.0.4" } }, "sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw=="], + "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-I4RxkXU90cpufazhGPyVujYwfIm9Nk1QDEmiIsaPwdnm013F7RIceaCc87kAH+oUB1ezqEvC6ga4m7MSlqsJvQ=="], - "@emmetio/css-parser": ["@emmetio/css-parser@0.4.1", "", { "dependencies": { "@emmetio/stream-reader": "^2.2.0", "@emmetio/stream-reader-utils": "^0.1.0" } }, "sha512-2bC6m0MV/voF4CTZiAbG5MWKbq5EBmDPKu9Sb7s7nVcEzNQlrZP6mFFFlIaISM8X6514H9shWMme1fCm8cWAfQ=="], + "@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-Y2T7IsQvJLMCBM+pmPbM3bKT/yYJvVtLJGfCs4Sp95SjvnFIjynbjzsa7dY1fRJX45FTSfDksbTp6AGWudiyCg=="], - "@emmetio/html-matcher": ["@emmetio/html-matcher@1.3.0", "", { "dependencies": { "@emmetio/scanner": "^1.0.0" } }, "sha512-NTbsvppE5eVyBMuyGfVu2CRrLvo7J4YHb6t9sBFLyY03WYhXET37qA4zOYUjBWFCRHO7pS1B9khERtY0f5JXPQ=="], + "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-RgWrs/gVU7f+K7P+KeHFaBAJlNkD1nIZuVXdQv6S+fNA6syCcoboNjsV2Pou7zNlVdNQoQUpQTk8SWDHUA3y/w=="], - "@emmetio/scanner": ["@emmetio/scanner@1.0.4", "", {}, "sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA=="], + "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.3", "", { "os": "linux", "cpu": "x64" }, "sha512-3JU7LmR85K6bBiRzSUc/Ff9JBVIFVvq6bomKE0e63UXGeRw2HPVEjoJke1Yx+iU4rL7/7kUjES4dZ/81Qjhyxg=="], - "@emmetio/stream-reader": ["@emmetio/stream-reader@2.2.0", "", {}, "sha512-fXVXEyFA5Yv3M3n8sUGT7+fvecGrZP4k6FnWWMSZVQf69kAq0LLpaBQLGcPR30m3zMmKYhECP4k/ZkzvhEW5kw=="], + "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-F9q83RZ8yaCwENw1GieztSfj5msz7GGykG/BA+MOUefvER69K/ubgFHNeSyUu64amHIYKGDs4sRCMzXVj8sEyw=="], - "@emmetio/stream-reader-utils": ["@emmetio/stream-reader-utils@0.1.0", "", {}, "sha512-ZsZ2I9Vzso3Ho/pjZFsmmZ++FWeEd/txqybHTm4OgaZzdS8V9V/YYWQwg5TC38Z7uLWUV1vavpLLbjJtKubR1A=="], + "@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.3", "", { "os": "linux", "cpu": "x64" }, "sha512-U5PUY5jbc45ANM6tSJpsgqmBF/VsL6LnxJmIf11kB7J5DctHgqm0SkuXzVWtIY90GnJxKnC/JT251TDnk1fu/g=="], - "@emnapi/core": ["@emnapi/core@1.11.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" } }, "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ=="], + "@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.3" }, "os": "linux", "cpu": "arm" }, "sha512-Xyam4mlqM0KkTHYVSuc6wXRmM7LGN0P12li03jAnZ3EJWZqj83+hi8Y9UxZUbxsgsK1qOEwg7O0Bc0LjqQVtxA=="], - "@emnapi/runtime": ["@emnapi/runtime@1.11.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw=="], + "@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.3" }, "os": "linux", "cpu": "arm64" }, "sha512-YXU1F/mN/Wu786tl72CyJjP/Ngl8mGHN1hST4BGl+hiW5jhCnV2uRVTNOcaYPs73NeT/H8Upm3y9582JVuZHrQ=="], - "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA=="], + "@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.3" }, "os": "linux", "cpu": "ppc64" }, "sha512-F4PDtF4Cy8L8hXA2p3TO6s4aDt93v+LKmpcYFLAVdkkD3hSxZzee0rh6/+94FpAynsuMpLX5h+LRsSG3rIciUQ=="], - "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.28.1", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ=="], + "@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.3" }, "os": "linux", "cpu": "s390x" }, "sha512-qVrZKE9Bsnzy+myf7lFKvng6bQzhNUAYcVORq2P7bDlvmF6u2sCmK2KyEQEBdYk+u3T01pVsPrkj943T1aJAsw=="], - "@esbuild/android-arm": ["@esbuild/android-arm@0.28.1", "", { "os": "android", "cpu": "arm" }, "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ=="], + "@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.3" }, "os": "linux", "cpu": "x64" }, "sha512-ZfGtcp2xS51iG79c6Vhw9CWqQC8l2Ot8dygxoDoIQPTat/Ov3qAa8qpxSrtAEAJW+UjTXc4yxCjNfxm4h6Xm2A=="], - "@esbuild/android-arm64": ["@esbuild/android-arm64@0.28.1", "", { "os": "android", "cpu": "arm64" }, "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg=="], + "@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.3" }, "os": "linux", "cpu": "arm64" }, "sha512-8hDVvW9eu4yHWnjaOOR8kHVrew1iIX+MUgwxSuH2XyYeNRtLUe4VNioSqbNkB7ZYQJj9rUTT4PyRscyk2PXFKA=="], - "@esbuild/android-x64": ["@esbuild/android-x64@0.28.1", "", { "os": "android", "cpu": "x64" }, "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng=="], + "@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.3" }, "os": "linux", "cpu": "x64" }, "sha512-lU0aA5L8QTlfKjpDCEFOZsTYGn3AEiO6db8W5aQDxj0nQkVrZWmN3ZP9sYKWJdtq3PWPhUNlqehWyXpYDcI9Sg=="], - "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.28.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q=="], + "@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.4", "", { "dependencies": { "@emnapi/runtime": "^1.5.0" }, "cpu": "none" }, "sha512-33QL6ZO/qpRyG7woB/HUALz28WnTMI2W1jgX3Nu2bypqLIKx/QKMILLJzJjI+SIbvXdG9fUnmrxR7vbi1sTBeA=="], - "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.28.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ=="], + "@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-2Q250do/5WXTwxW3zjsEuMSv5sUU4Tq9VThWKlU2EYLm4MB7ZeMwF+SFJutldYODXF6jzc6YEOC+VfX0SZQPqA=="], - "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.28.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw=="], + "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-3ZeLue5V82dT92CNL6rsal6I2weKw1cYu+rGKm8fOCCtJTR2gYeUfY3FqUnIJsMUPIH68oS5jmZ0NiJ508YpEw=="], - "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.28.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ=="], - - "@esbuild/linux-arm": ["@esbuild/linux-arm@0.28.1", "", { "os": "linux", "cpu": "arm" }, "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ=="], - - "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.28.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g=="], - - "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.28.1", "", { "os": "linux", "cpu": "ia32" }, "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w=="], - - "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg=="], - - "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ=="], - - "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.28.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ=="], - - "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ=="], - - "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.28.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag=="], - - "@esbuild/linux-x64": ["@esbuild/linux-x64@0.28.1", "", { "os": "linux", "cpu": "x64" }, "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA=="], - - "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.28.1", "", { "os": "none", "cpu": "arm64" }, "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw=="], - - "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.28.1", "", { "os": "none", "cpu": "x64" }, "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg=="], - - "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.28.1", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q=="], - - "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.28.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw=="], - - "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.28.1", "", { "os": "none", "cpu": "arm64" }, "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg=="], - - "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.28.1", "", { "os": "sunos", "cpu": "x64" }, "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ=="], - - "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.28.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA=="], - - "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.28.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg=="], - - "@esbuild/win32-x64": ["@esbuild/win32-x64@0.28.1", "", { "os": "win32", "cpu": "x64" }, "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A=="], - - "@fontsource-variable/inter": ["@fontsource-variable/inter@5.3.0", "", {}, "sha512-OupL48va4JNofb97w6NYeF9S7W/kHNKM0Er8Dem5nqi4jeOLrVJDoE8tZEpnMJmtkvNbB1EIPPwHcdkF6b1oUA=="], - - "@fontsource-variable/jetbrains-mono": ["@fontsource-variable/jetbrains-mono@5.3.0", "", {}, "sha512-F32xpS2NsGYoQi2ADSkKTgpJj7ozajsGgDJ8woTnqjmIB+dxDIqImjl4pXZVEExu8UFZ2ndhmX18EBS/hdz3Lw=="], - - "@iconify-json/ph": ["@iconify-json/ph@1.2.2", "", { "dependencies": { "@iconify/types": "*" } }, "sha512-PgkEZNtqa8hBGjHXQa4pMwZa93hmfu8FUSjs/nv4oUU6yLsgv+gh9nu28Kqi8Fz9CCVu4hj1MZs9/60J57IzFw=="], - - "@iconify/tools": ["@iconify/tools@4.2.0", "", { "dependencies": { "@iconify/types": "^2.0.0", "@iconify/utils": "^2.3.0", "cheerio": "^1.1.2", "domhandler": "^5.0.3", "extract-zip": "^2.0.1", "local-pkg": "^1.1.2", "pathe": "^2.0.3", "svgo": "^3.3.2", "tar": "^7.5.2" } }, "sha512-WRxPva/ipxYkqZd1+CkEAQmd86dQmrwH0vwK89gmp2Kh2WyyVw57XbPng0NehP3x4V1LzLsXUneP1uMfTMZmUA=="], - - "@iconify/types": ["@iconify/types@2.0.0", "", {}, "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="], - - "@iconify/utils": ["@iconify/utils@2.3.0", "", { "dependencies": { "@antfu/install-pkg": "^1.0.0", "@antfu/utils": "^8.1.0", "@iconify/types": "^2.0.0", "debug": "^4.4.0", "globals": "^15.14.0", "kolorist": "^1.8.0", "local-pkg": "^1.0.0", "mlly": "^1.7.4" } }, "sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA=="], - - "@img/colour": ["@img/colour@1.1.0", "", {}, "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ=="], - - "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.35.2", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.3.1" }, "os": "darwin", "cpu": "arm64" }, "sha512-eEieHsMksAW4IiO5NzauESRl2D2qz3J/kwUxUrSfV06A93eEaRfMpHXyUb1mAqrR7i8U9A0GRqE9pjn6u1Jjpg=="], - - "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.35.2", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.3.1" }, "os": "darwin", "cpu": "x64" }, "sha512-BaktuGPCeHJMARpodR8jK4uKiZrPAy9WrfQW0sdI37clracq8Bp01AYS3SZgi5FS/y5twa9t4+LIuuxQjqRrWw=="], - - "@img/sharp-freebsd-wasm32": ["@img/sharp-freebsd-wasm32@0.35.2", "", { "dependencies": { "@img/sharp-wasm32": "0.35.2" }, "os": "freebsd" }, "sha512-YoAxdnd8hPUkvLHd3bWY+YA8nw3xM/RyRopYucNsWHVSan8NLVM3X2volsfoRDcXdUJPg6tXahSd7HXPK7lRnw=="], - - "@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.3.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-4V/M3roRMTYjiwZY9IOVQOE8OyeCxFAkYmyZDrZl51uOKjibm3oeEJ4WAmLxutAfzFbC9jqUiPs2gbnGflH+7g=="], - - "@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.3.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-c0/DxItpJv2+dGhgycJBBgotdqruGYDvA79drdh0MD1dFpy7JzJ/PlXwi1H4rFf0eTy8tgbI91aHDnZIceY3jQ=="], - - "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.3.1", "", { "os": "linux", "cpu": "arm" }, "sha512-aGGy9aWzXgHBG7HNyQPWorZthlp7+x6fDRoPAQbGO3ThcttuTyKIx3NuSHb6zb4gBNq6/yNn9f1cy9nFKS/Vmg=="], - - "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.3.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-JznefmcK9j1JKPz8AkQDh89kjojubyfOasWBPKfzMIhPwsgDy9evpE/naJTXXXmghS1iFwR8u/kTwh/I2/+GCw=="], - - "@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.3.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-1EkwGNCZk6iWNCMWqrvdJ+r1j0PT1zIz60CNPhYnJlK/zyeWqlsPZIe+ocBVqPF8k/Ssee/NCk+tE9Ryrko6ng=="], - - "@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.3.1", "", { "os": "linux", "cpu": "none" }, "sha512-Ilays+w2bXdnxzxtQdmXR62u8o8GYa3eL4+Gr+1KiE4xperMZUslRaVPJwwPkzlHEjGfXAfRVAa/7CYCtSqsBw=="], - - "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.3.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-VfBwVHQTbRoj4XlpA/KLZ7ltgMpz+4WSejFzQ+GnoImjo1PtEJ59QB2qR1xQEeRPYIkNrPIm2L4cICMvz4C2ew=="], - - "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.3.1", "", { "os": "linux", "cpu": "x64" }, "sha512-+c8ukgwU62DS54nCAjw7keOfHUkmr0B5QHEdcOqRnodF/MNXJbVI8Eopoj4B/0H8Asr65I+A4Amrn7a85/md6A=="], - - "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.3.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-qlKb/pwbkAi1WMsJrYHk7CuDrd12s27U2QnRhFYUoJNrRCmkosMTttuRFat/DDB3IlDm5qE1TJgZ4JDnHX8Ldw=="], - - "@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.3.1", "", { "os": "linux", "cpu": "x64" }, "sha512-yO21HwoUVLN8Qa+/SBjQLMYwBWAVJjeGPNe+hc0OUeMeifEtJqu5a1c4HayE1nNpDih9y3/KkoltfkDodmKAlg=="], - - "@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.35.2", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.3.1" }, "os": "linux", "cpu": "arm" }, "sha512-SE4kzF2mepn6z+6E7L6lsV8FzuLL6IPQdyX8ZiwROAG/G8td+hP/m7FsFPwidtrF19gvajuC9l6TxAVcsA4S7A=="], - - "@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.35.2", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.3.1" }, "os": "linux", "cpu": "arm64" }, "sha512-af12Pnd0ZGu2HfP8NayB0kk6eC/lrfbQE6HlR4jD+34wdJ1Vw9TF6TMn6ZvffT+WgqVsl0hRbmNvz2u/23VmwA=="], - - "@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.35.2", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.3.1" }, "os": "linux", "cpu": "ppc64" }, "sha512-hYSBm7zcNtDCozCxQHYZJiu63b/bXsgRZuOxCIBZsStMM9Vap47iFHdbX4kCvQsblPB/k+clhELpdQJHQLSHvg=="], - - "@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.35.2", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.3.1" }, "os": "linux", "cpu": "none" }, "sha512-qQt0Kc13+Hoan/Awq/qMSQw3L+RI1NCRPgD5cUJ/1WSSmIoysLOc72jlRM3E0OHN9Yr313jgeQ2T+zW+F03QFA=="], - - "@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.35.2", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.3.1" }, "os": "linux", "cpu": "s390x" }, "sha512-E4fLLfRPzDLlEeDaTzI98OFLcv++WL5ChLLMwPoVd0CIoZQqupBSNbOisPL5am9XsbQ9T84+iiMpUvbFtkunbA=="], - - "@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.35.2", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.3.1" }, "os": "linux", "cpu": "x64" }, "sha512-gi0zFJJRLswfCZmHtJdikXPOc5u7qamSOS3NHedLqLd4W8Q0NqjdBr6TTRIgsfFjqfTsHFgdfvJ9LwqSgcHiAA=="], - - "@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.35.2", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.3.1" }, "os": "linux", "cpu": "arm64" }, "sha512-siWbOW1u6HFnFLrp0waKyW7VEf7jYvcDWdrXEFa8AkdAQgEvuu5Fz8/Y70w9EeqAdwDtfU012BhEHHaDqvQNzg=="], - - "@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.35.2", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.3.1" }, "os": "linux", "cpu": "x64" }, "sha512-YBqMMcjDi4QGYiSn4vNOYBhmlC4z5AXqkOUUqI2e0AFA4urNv4ESgOgwNl3K+4etQhha0twXlzeF20bbULm9Yg=="], - - "@img/sharp-wasm32": ["@img/sharp-wasm32@0.35.2", "", { "dependencies": { "@emnapi/runtime": "^1.11.1" } }, "sha512-Mrv4JQNYVQ94xH+jzZ9r+gowleN8mv2FTgKT+PI6bx5C0G8TdNYndu161pg2i7uoBwxy2ImPMHrJOM2LZef7Bw=="], - - "@img/sharp-webcontainers-wasm32": ["@img/sharp-webcontainers-wasm32@0.35.2", "", { "dependencies": { "@img/sharp-wasm32": "0.35.2" }, "cpu": "none" }, "sha512-QNV27pxs9wpApEiCfvHM1RDoP1w1+2KrUWWDPEhEwg+latvOrfuhWrHWZKwdSFwU6jh3myjw/yOCRsUIuOft3g=="], - - "@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.35.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-BiVRYc/t6/Vl3e1hBx0hugG4oN9Pydf4fgMSpxTQJmwGUg/YoXTWHiFeRymHfCZzifxu4F4rpk/I67D0LQ20wQ=="], - - "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.35.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-YYEhx9PImCC7T0tI8JDMi4DB9LwLCXCU5OWNYEXAxh5Q1ShKkyC6byxzoBJ3gEFDnH2lQckWuDe70G7mB2XJog=="], - - "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.35.2", "", { "os": "win32", "cpu": "x64" }, "sha512-imoOyBcoM/iiUr4J6VPpCNjPnjvP/Gks95898yB8YqoGGYmHYbOyCuNv9FMhFgtaiHFGbHW8bxKqRV6VjtXThQ=="], - - "@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="], + "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.4", "", { "os": "win32", "cpu": "x64" }, "sha512-xIyj4wpYs8J18sVN3mSQjwrw7fKUqRw+Z5rnHNCy5fYTxigBz81u5mOMPmFumwjcn8+ld1ppptMBCLic1nz6ig=="], "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], @@ -277,213 +173,185 @@ "@mdx-js/mdx": ["@mdx-js/mdx@3.1.1", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdx": "^2.0.0", "acorn": "^8.0.0", "collapse-white-space": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "estree-util-scope": "^1.0.0", "estree-walker": "^3.0.0", "hast-util-to-jsx-runtime": "^2.0.0", "markdown-extensions": "^2.0.0", "recma-build-jsx": "^1.0.0", "recma-jsx": "^1.0.0", "recma-stringify": "^1.0.0", "rehype-recma": "^1.0.0", "remark-mdx": "^3.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.0.0", "source-map": "^0.7.0", "unified": "^11.0.0", "unist-util-position-from-estree": "^2.0.0", "unist-util-stringify-position": "^4.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ=="], - "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.6", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg=="], + "@next/env": ["@next/env@16.1.1", "", {}, "sha512-3oxyM97Sr2PqiVyMyrZUtrtM3jqqFxOQJVuKclDsgj/L728iZt/GyslkN4NwarledZATCenbk4Offjk1hQmaAA=="], - "@oslojs/encoding": ["@oslojs/encoding@1.1.0", "", {}, "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ=="], + "@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.1.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-JS3m42ifsVSJjSTzh27nW+Igfha3NdBOFScr9C80hHGrWx55pTrVL23RJbqir7k7/15SKlrLHhh/MQzqBBYrQA=="], - "@oxc-project/types": ["@oxc-project/types@0.139.0", "", {}, "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw=="], + "@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.1.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-hbyKtrDGUkgkyQi1m1IyD3q4I/3m9ngr+V93z4oKHrPcmxwNL5iMWORvLSGAf2YujL+6HxgVvZuCYZfLfb4bGw=="], - "@pagefind/darwin-arm64": ["@pagefind/darwin-arm64@1.5.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-MXpI+7HsAdPkvJ0gk9xj9g541BCqBZOBbdwj9g6lB5LCj6kSV6nqDSjzcAJwvOsfu0fjwvC8hQU+ecfhp+MpiQ=="], + "@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.1.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-/fvHet+EYckFvRLQ0jPHJCUI5/B56+2DpI1xDSvi80r/3Ez+Eaa2Yq4tJcRTaB1kqj/HrYKn8Yplm9bNoMJpwQ=="], - "@pagefind/darwin-x64": ["@pagefind/darwin-x64@1.5.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-IojxFWMEJe0RQ7PQ3KXQsPIImNsbpPYpoZ+QUDrL8fAl/O27IX+LVLs74/UzEZy5uA2LD8Nz1AiwKr72vrkZQw=="], + "@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.1.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-MFHrgL4TXNQbBPzkKKur4Fb5ICEJa87HM7fczFs2+HWblM7mMLdco3dvyTI+QmLBU9xgns/EeeINSZD6Ar+oLg=="], - "@pagefind/freebsd-x64": ["@pagefind/freebsd-x64@1.5.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-7EVzo9+0w+2cbe671BtMj10UlNo83I+HrLVLfRxO731svHRJKUfJ/mo05gU14pe9PCfpKNQT8FS3Xc/oDN6pOA=="], + "@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.1.1", "", { "os": "linux", "cpu": "x64" }, "sha512-20bYDfgOQAPUkkKBnyP9PTuHiJGM7HzNBbuqmD0jiFVZ0aOldz+VnJhbxzjcSabYsnNjMPsE0cyzEudpYxsrUQ=="], - "@pagefind/linux-arm64": ["@pagefind/linux-arm64@1.5.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-Ovt9+K35sqzn8H3ZMXGwls4TD/wMJuvRtShHIsmUQREmaxjrDEX7gHckRCrwYJ4XE1H1p6HkLz3wukrAnsfXQw=="], + "@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.1.1", "", { "os": "linux", "cpu": "x64" }, "sha512-9pRbK3M4asAHQRkwaXwu601oPZHghuSC8IXNENgbBSyImHv/zY4K5udBusgdHkvJ/Tcr96jJwQYOll0qU8+fPA=="], - "@pagefind/linux-x64": ["@pagefind/linux-x64@1.5.2", "", { "os": "linux", "cpu": "x64" }, "sha512-V+tFqHKXhQKq/WqPBD67AFy7scn1/aZID00ws4fSDd+1daSi5UHR9VVlRrOUYKxn3VuFQYRD7lYXdZK1WED1YA=="], + "@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.1.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-bdfQkggaLgnmYrFkSQfsHfOhk/mCYmjnrbRCGgkMcoOBZ4n+TRRSLmT/CU5SATzlBJ9TpioUyBW/vWFXTqQRiA=="], - "@pagefind/windows-arm64": ["@pagefind/windows-arm64@1.5.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-hN9Nh90fNW61nNRCW9ZyQrAj/mD0eRvmJ8NlTUzkbuW8kIzGJUi3cxjFkEcMZ5h/8FsKWD/VcouZl4yo1F7B6g=="], + "@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.1.1", "", { "os": "win32", "cpu": "x64" }, "sha512-Ncwbw2WJ57Al5OX0k4chM68DKhEPlrXBaSXDCi2kPi5f4d8b3ejr3RRJGfKBLrn2YJL5ezNS7w2TZLHSti8CMw=="], - "@pagefind/windows-x64": ["@pagefind/windows-x64@1.5.2", "", { "os": "win32", "cpu": "x64" }, "sha512-Fa2Iyw7kaDRzGMfNYNUXNW2zbL5FQVDgSOcbDHdzBrDEdpqOqg8TcZ68F22ol6NJ9IGzvUdmeyZypLW5dyhqsg=="], + "@orama/orama": ["@orama/orama@3.1.18", "", {}, "sha512-a61ljmRVVyG5MC/698C8/FfFDw5a8LOIvyOLW5fztgUXqUpc1jOfQzOitSCbge657OgXXThmY3Tk8fpiDb4UcA=="], - "@poppinss/colors": ["@poppinss/colors@4.1.6", "", { "dependencies": { "kleur": "^4.1.5" } }, "sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg=="], + "@radix-ui/number": ["@radix-ui/number@1.1.1", "", {}, "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g=="], - "@poppinss/dumper": ["@poppinss/dumper@0.6.5", "", { "dependencies": { "@poppinss/colors": "^4.1.5", "@sindresorhus/is": "^7.0.2", "supports-color": "^10.0.0" } }, "sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw=="], + "@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="], - "@poppinss/exception": ["@poppinss/exception@1.2.3", "", {}, "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw=="], + "@radix-ui/react-accordion": ["@radix-ui/react-accordion@1.2.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collapsible": "1.1.12", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA=="], - "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.1.5", "", { "os": "android", "cpu": "arm64" }, "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ=="], + "@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w=="], - "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.1.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw=="], + "@radix-ui/react-collapsible": ["@radix-ui/react-collapsible@1.1.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA=="], - "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.1.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g=="], + "@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw=="], - "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.1.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA=="], + "@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg=="], - "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.1.5", "", { "os": "linux", "cpu": "arm" }, "sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw=="], + "@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="], - "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.1.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q=="], + "@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw=="], - "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.1.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA=="], + "@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw=="], - "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.1.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg=="], + "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg=="], - "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.1.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA=="], + "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw=="], - "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.1.5", "", { "os": "linux", "cpu": "x64" }, "sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ=="], + "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw=="], - "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.1.5", "", { "os": "linux", "cpu": "x64" }, "sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg=="], + "@radix-ui/react-id": ["@radix-ui/react-id@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg=="], - "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.1.5", "", { "os": "none", "cpu": "arm64" }, "sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw=="], + "@radix-ui/react-navigation-menu": ["@radix-ui/react-navigation-menu@1.2.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w=="], - "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.1.5", "", { "dependencies": { "@emnapi/core": "1.11.1", "@emnapi/runtime": "1.11.1", "@napi-rs/wasm-runtime": "^1.1.6" }, "cpu": "none" }, "sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA=="], + "@radix-ui/react-popover": ["@radix-ui/react-popover@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA=="], - "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.1.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw=="], + "@radix-ui/react-popper": ["@radix-ui/react-popper@1.2.8", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-rect": "1.1.1", "@radix-ui/react-use-size": "1.1.1", "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw=="], - "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.1.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA=="], + "@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ=="], - "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.1", "", {}, "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw=="], + "@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.5", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ=="], - "@rollup/pluginutils": ["@rollup/pluginutils@5.4.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg=="], + "@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="], - "@shikijs/core": ["@shikijs/core@4.3.1", "", { "dependencies": { "@shikijs/primitive": "4.3.1", "@shikijs/types": "4.3.1", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-ANMDxuaPsNMdDC1m4vfvhlDmJweMwkE5XitTwrq2rWHx5jM+dlm4MmHt2PP6t0uejfR77SuhrhJ0zEijIF/uhA=="], + "@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA=="], - "@shikijs/engine-javascript": ["@shikijs/engine-javascript@4.3.1", "", { "dependencies": { "@shikijs/types": "4.3.1", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.6" } }, "sha512-JBItcnPuYq7jVJdZo/vMj94r+szT7XEjHFX+mvFDGSEIbVAXAGyHAHzhbWzpGOwYidCZrErJLLgn2PVeiokHnQ=="], + "@radix-ui/react-scroll-area": ["@radix-ui/react-scroll-area@1.2.10", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A=="], - "@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@4.3.1", "", { "dependencies": { "@shikijs/types": "4.3.1", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-OXyNMzg0pews+msMj4cHeqT4xiYKKvbnn6VbdAXxfoFl3SSx4fJTc8FadECuc5/H9p3BzhNAoAUXKwAu9rWYhg=="], + "@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.4", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA=="], - "@shikijs/langs": ["@shikijs/langs@4.3.1", "", { "dependencies": { "@shikijs/types": "4.3.1" } }, "sha512-m0l9nsDqgBHvbZbk7A0/kXz/impK3uB/c6rAn6Gpg/uPtdZRQ+alsN/17MU5thb68XTj/4DxkZAotrM0GGSpDQ=="], + "@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A=="], - "@shikijs/primitive": ["@shikijs/primitive@4.3.1", "", { "dependencies": { "@shikijs/types": "4.3.1", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-CXQRQOYy1leqQ8ceTeJdmXv/bsUY++6QyLpXJ94LZAAYj5X2SKRdc5ipguv4NPyGVKItB2PPwUpRNe0Sjh5S1A=="], + "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="], - "@shikijs/themes": ["@shikijs/themes@4.3.1", "", { "dependencies": { "@shikijs/types": "4.3.1" } }, "sha512-dgpoJ4WqNi2yTmizQHBJ5zcX6j2lE6icN/0yt4l1kkf16jrY/pwPLoTb1ETsWMz0OBLf9ZNvwmxft+cH+N9qSA=="], + "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.2", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg=="], - "@shikijs/transformers": ["@shikijs/transformers@4.3.1", "", { "dependencies": { "@shikijs/core": "4.3.1", "@shikijs/types": "4.3.1" } }, "sha512-z6ir0bGDgWcF2FduktEfPgIsdOtIlDiLAjFBgBzE42Q9xHbkkIXZtORHzlLVB71iZP9elEcqKg6keajvOUwE2A=="], + "@radix-ui/react-use-effect-event": ["@radix-ui/react-use-effect-event@0.0.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA=="], - "@shikijs/types": ["@shikijs/types@4.3.1", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-CHFxE0jztBIZRHH6gxXE7DXUCFXjReEGxZ/j0rfSLGKZuwp2xBYycEP14875DSa9KLL/6700oxIq6oO6ef9K2g=="], + "@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.1", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g=="], - "@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="], + "@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ=="], - "@sindresorhus/is": ["@sindresorhus/is@7.2.0", "", {}, "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw=="], + "@radix-ui/react-use-previous": ["@radix-ui/react-use-previous@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ=="], - "@speed-highlight/core": ["@speed-highlight/core@1.2.17", "", {}, "sha512-Z92FwKpCtfaW1V0jTU/fh3QzYEZN8wDwrzRIBoADCJfn4mJCNcJN/XegifX7BDrQ8/h9Xh/JnbyMchL0FqXrkg=="], + "@radix-ui/react-use-rect": ["@radix-ui/react-use-rect@1.1.1", "", { "dependencies": { "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w=="], - "@tailwindcss/node": ["@tailwindcss/node@4.3.3", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "^5.24.1", "jiti": "^2.7.0", "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.3.3" } }, "sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg=="], + "@radix-ui/react-use-size": ["@radix-ui/react-use-size@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ=="], - "@tailwindcss/oxide": ["@tailwindcss/oxide@4.3.3", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.3.3", "@tailwindcss/oxide-darwin-arm64": "4.3.3", "@tailwindcss/oxide-darwin-x64": "4.3.3", "@tailwindcss/oxide-freebsd-x64": "4.3.3", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.3", "@tailwindcss/oxide-linux-arm64-gnu": "4.3.3", "@tailwindcss/oxide-linux-arm64-musl": "4.3.3", "@tailwindcss/oxide-linux-x64-gnu": "4.3.3", "@tailwindcss/oxide-linux-x64-musl": "4.3.3", "@tailwindcss/oxide-wasm32-wasi": "4.3.3", "@tailwindcss/oxide-win32-arm64-msvc": "4.3.3", "@tailwindcss/oxide-win32-x64-msvc": "4.3.3" } }, "sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA=="], + "@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.2.3", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug=="], - "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.3.3", "", { "os": "android", "cpu": "arm64" }, "sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw=="], + "@radix-ui/rect": ["@radix-ui/rect@1.1.1", "", {}, "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw=="], - "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.3.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw=="], + "@shikijs/core": ["@shikijs/core@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-AXSQu/2n1UIQekY8euBJlvFYZIw0PHY63jUzGbrOma4wPxzznJXTXkri+QcHeBNaFxiiOljKxxJkVSoB3PjbyA=="], - "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.3.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw=="], + "@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-ATwv86xlbmfD9n9gKRiwuPpWgPENAWCLwYCGz9ugTJlsO2kOzhOkvoyV/UD+tJ0uT7YRyD530x6ugNSffmvIiQ=="], - "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.3.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw=="], + "@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-OYknTCct6qiwpQDqDdf3iedRdzj6hFlOPv5hMvI+hkWfCKs5mlJ4TXziBG9nyabLwGulrUjHiCq3xCspSzErYQ=="], - "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3", "", { "os": "linux", "cpu": "arm" }, "sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ=="], + "@shikijs/langs": ["@shikijs/langs@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0" } }, "sha512-g6mn5m+Y6GBJ4wxmBYqalK9Sp0CFkUqfNzUy2pJglUginz6ZpWbaWjDB4fbQ/8SHzFjYbtU6Ddlp1pc+PPNDVA=="], - "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w=="], + "@shikijs/rehype": ["@shikijs/rehype@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0", "@types/hast": "^3.0.4", "hast-util-to-string": "^3.0.1", "shiki": "3.21.0", "unified": "^11.0.5", "unist-util-visit": "^5.0.0" } }, "sha512-fTQvwsZL67QdosMFdTgQ5SNjW3nxaPplRy//312hqOctRbIwviTV0nAbhv3NfnztHXvFli2zLYNKsTz/f9tbpQ=="], - "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA=="], + "@shikijs/themes": ["@shikijs/themes@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0" } }, "sha512-BAE4cr9EDiZyYzwIHEk7JTBJ9CzlPuM4PchfcA5ao1dWXb25nv6hYsoDiBq2aZK9E3dlt3WB78uI96UESD+8Mw=="], - "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w=="], + "@shikijs/transformers": ["@shikijs/transformers@3.21.0", "", { "dependencies": { "@shikijs/core": "3.21.0", "@shikijs/types": "3.21.0" } }, "sha512-CZwvCWWIiRRiFk9/JKzdEooakAP8mQDtBOQ1TKiCaS2E1bYtyBCOkUzS8akO34/7ufICQ29oeSfkb3tT5KtrhA=="], - "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img=="], + "@shikijs/types": ["@shikijs/types@3.21.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-zGrWOxZ0/+0ovPY7PvBU2gIS9tmhSUUt30jAcNV0Bq0gb2S98gwfjIs1vxlmH5zM7/4YxLamT6ChlqqAJmPPjA=="], - "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.3.3", "", { "dependencies": { "@emnapi/core": "^1.11.1", "@emnapi/runtime": "^1.11.1", "@emnapi/wasi-threads": "^1.2.2", "@napi-rs/wasm-runtime": "^1.1.4", "@tybys/wasm-util": "^0.10.2", "tslib": "^2.8.1" }, "cpu": "none" }, "sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ=="], + "@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="], - "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.3.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ=="], + "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.3.3", "", { "os": "win32", "cpu": "x64" }, "sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw=="], + "@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="], - "@tailwindcss/vite": ["@tailwindcss/vite@4.3.3", "", { "dependencies": { "@tailwindcss/node": "4.3.3", "@tailwindcss/oxide": "4.3.3", "tailwindcss": "4.3.3" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, "sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw=="], + "@tailwindcss/node": ["@tailwindcss/node@4.1.18", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.6.1", "lightningcss": "1.30.2", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.1.18" } }, "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ=="], - "@tybys/wasm-util": ["@tybys/wasm-util@0.10.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="], + "@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.18", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.18", "@tailwindcss/oxide-darwin-arm64": "4.1.18", "@tailwindcss/oxide-darwin-x64": "4.1.18", "@tailwindcss/oxide-freebsd-x64": "4.1.18", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18", "@tailwindcss/oxide-linux-arm64-musl": "4.1.18", "@tailwindcss/oxide-linux-x64-gnu": "4.1.18", "@tailwindcss/oxide-linux-x64-musl": "4.1.18", "@tailwindcss/oxide-wasm32-wasi": "4.1.18", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18", "@tailwindcss/oxide-win32-x64-msvc": "4.1.18" } }, "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A=="], - "@types/debug": ["@types/debug@4.1.13", "", { "dependencies": { "@types/ms": "*" } }, "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw=="], + "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.18", "", { "os": "android", "cpu": "arm64" }, "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q=="], - "@types/estree": ["@types/estree@1.0.9", "", {}, "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg=="], + "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.18", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A=="], - "@types/estree-jsx": ["@types/estree-jsx@1.0.5", "", { "dependencies": { "@types/estree": "*" } }, "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg=="], + "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.18", "", { "os": "darwin", "cpu": "x64" }, "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw=="], - "@types/hast": ["@types/hast@3.0.5", "", { "dependencies": { "@types/unist": "*" } }, "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g=="], + "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.18", "", { "os": "freebsd", "cpu": "x64" }, "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA=="], - "@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="], + "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18", "", { "os": "linux", "cpu": "arm" }, "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA=="], - "@types/mdx": ["@types/mdx@2.0.14", "", {}, "sha512-T48PeuJtvLosNTPVhfnIp3i/n3a4g4Bad7YCq5k64D4u7NwDrAotikQ+5+sjtUvBmxCMlbo3dVL+C2dP0rWHzg=="], + "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.18", "", { "os": "linux", "cpu": "arm64" }, "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw=="], - "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], + "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.18", "", { "os": "linux", "cpu": "arm64" }, "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg=="], - "@types/nlcst": ["@types/nlcst@2.0.3", "", { "dependencies": { "@types/unist": "*" } }, "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA=="], - - "@types/node": ["@types/node@24.13.3", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q=="], - - "@types/sax": ["@types/sax@1.2.7", "", { "dependencies": { "@types/node": "*" } }, "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A=="], - - "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.18", "", { "os": "linux", "cpu": "x64" }, "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g=="], - "@types/yauzl": ["@types/yauzl@2.10.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q=="], + "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.18", "", { "os": "linux", "cpu": "x64" }, "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ=="], - "@ungap/structured-clone": ["@ungap/structured-clone@1.3.3", "", {}, "sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg=="], + "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.18", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.1.0", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.4.0" }, "cpu": "none" }, "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA=="], - "@vercel/detect-agent": ["@vercel/detect-agent@1.2.3", "", {}, "sha512-VYNCgUc0nOmC4WJmWw9GkrKdfr8Zl4/rxhC5SvgacBgxiW9W/9NRttUoHHXV8xdII3MaRgkZZVX8Ikzc/Jmjag=="], + "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.18", "", { "os": "win32", "cpu": "arm64" }, "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA=="], - "@volar/kit": ["@volar/kit@2.4.28", "", { "dependencies": { "@volar/language-service": "2.4.28", "@volar/typescript": "2.4.28", "typesafe-path": "^0.2.2", "vscode-languageserver-textdocument": "^1.0.11", "vscode-uri": "^3.0.8" }, "peerDependencies": { "typescript": "*" } }, "sha512-cKX4vK9dtZvDRaAzeoUdaAJEew6IdxHNCRrdp5Kvcl6zZOqb6jTOfk3kXkIkG3T7oTFXguEMt5+9ptyqYR84Pg=="], + "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.18", "", { "os": "win32", "cpu": "x64" }, "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q=="], - "@volar/language-core": ["@volar/language-core@2.4.28", "", { "dependencies": { "@volar/source-map": "2.4.28" } }, "sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ=="], + "@tailwindcss/postcss": ["@tailwindcss/postcss@4.1.18", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.1.18", "@tailwindcss/oxide": "4.1.18", "postcss": "^8.4.41", "tailwindcss": "4.1.18" } }, "sha512-Ce0GFnzAOuPyfV5SxjXGn0CubwGcuDB0zcdaPuCSzAa/2vII24JTkH+I6jcbXLb1ctjZMZZI6OjDaLPJQL1S0g=="], - "@volar/language-server": ["@volar/language-server@2.4.28", "", { "dependencies": { "@volar/language-core": "2.4.28", "@volar/language-service": "2.4.28", "@volar/typescript": "2.4.28", "path-browserify": "^1.0.1", "request-light": "^0.7.0", "vscode-languageserver": "^9.0.1", "vscode-languageserver-protocol": "^3.17.5", "vscode-languageserver-textdocument": "^1.0.11", "vscode-uri": "^3.0.8" } }, "sha512-NqcLnE5gERKuS4PUFwlhMxf6vqYo7hXtbMFbViXcbVkbZ905AIVWhnSo0ZNBC2V127H1/2zP7RvVOVnyITFfBw=="], + "@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="], - "@volar/language-service": ["@volar/language-service@2.4.28", "", { "dependencies": { "@volar/language-core": "2.4.28", "vscode-languageserver-protocol": "^3.17.5", "vscode-languageserver-textdocument": "^1.0.11", "vscode-uri": "^3.0.8" } }, "sha512-Rh/wYCZJrI5vCwMk9xyw/Z+MsWxlJY1rmMZPsxUoJKfzIRjS/NF1NmnuEcrMbEVGja00aVpCsInJfixQTMdvLw=="], + "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], - "@volar/source-map": ["@volar/source-map@2.4.28", "", {}, "sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ=="], - - "@volar/typescript": ["@volar/typescript@2.4.28", "", { "dependencies": { "@volar/language-core": "2.4.28", "path-browserify": "^1.0.1", "vscode-uri": "^3.0.8" } }, "sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw=="], - - "@vscode/emmet-helper": ["@vscode/emmet-helper@2.11.0", "", { "dependencies": { "emmet": "^2.4.3", "jsonc-parser": "^2.3.0", "vscode-languageserver-textdocument": "^1.0.1", "vscode-languageserver-types": "^3.15.1", "vscode-uri": "^3.0.8" } }, "sha512-QLxjQR3imPZPQltfbWRnHU6JecWTF1QSWhx3GAKQpslx7y3Dp6sIIXhKjiUJ/BR9FX8PVthjr9PD6pNwOJfAzw=="], - - "@vscode/l10n": ["@vscode/l10n@0.0.18", "", {}, "sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ=="], + "@types/estree-jsx": ["@types/estree-jsx@1.0.5", "", { "dependencies": { "@types/estree": "*" } }, "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg=="], - "@webgpu/types": ["@webgpu/types@0.1.21", "", {}, "sha512-pUrWq3V5PiSGFLeLxoGqReTZmiiXwY3jRkIG5sLLKjyqNxrwm/04b4nw7LSmGWJcKk59XOM/YRTUwOzo4MMlow=="], + "@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="], - "acorn": ["acorn@8.17.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg=="], + "@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="], - "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], + "@types/mdx": ["@types/mdx@2.0.13", "", {}, "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw=="], - "ajv": ["ajv@8.20.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA=="], + "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], - "ajv-draft-04": ["ajv-draft-04@1.0.0", "", { "peerDependencies": { "ajv": "^8.5.0" }, "optionalPeers": ["ajv"] }, "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw=="], + "@types/node": ["@types/node@25.0.3", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA=="], - "ajv-i18n": ["ajv-i18n@4.2.0", "", { "peerDependencies": { "ajv": "^8.0.0-beta.0" } }, "sha512-v/ei2UkCEeuKNXh8RToiFsUclmU+G57LO1Oo22OagNMENIw+Yb8eMwvHu7Vn9fmkjJyv6XclhJ8TbuigSglPkg=="], + "@types/react": ["@types/react@19.2.7", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg=="], - "am-i-vibing": ["am-i-vibing@0.4.0", "", { "dependencies": { "process-ancestry": "^0.1.0" }, "bin": { "am-i-vibing": "dist/cli.mjs" } }, "sha512-MxT4XZL7pzLHpuvhDKdMaQHMGGkJDLluKBLsbstn+8wv9sWcFT6h+0ve9qkml95amVTZtZV83gQe2hY+ojgHLg=="], + "@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="], - "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], - "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], - "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="], + "acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], - "arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="], + "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], - "aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="], - - "array-iterate": ["array-iterate@2.0.1", "", {}, "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg=="], + "aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="], "astring": ["astring@1.9.0", "", { "bin": { "astring": "bin/astring" } }, "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg=="], - "astro": ["astro@7.1.3", "", { "dependencies": { "@astrojs/compiler-rs": "^0.3.1", "@astrojs/internal-helpers": "0.10.1", "@astrojs/markdown-satteri": "0.3.4", "@astrojs/telemetry": "3.3.3", "@capsizecss/unpack": "^4.0.0", "@clack/prompts": "^1.1.0", "@oslojs/encoding": "^1.1.0", "@rollup/pluginutils": "^5.3.0", "am-i-vibing": "^0.4.0", "aria-query": "^5.3.2", "axobject-query": "^4.1.0", "ci-info": "^4.4.0", "clsx": "^2.1.1", "common-ancestor-path": "^2.0.0", "cookie": "^2.0.1", "devalue": "^5.8.1", "diff": "^8.0.3", "dset": "^3.1.4", "es-module-lexer": "^2.0.0", "esbuild": "^0.28.0", "flattie": "^1.1.1", "fontace": "~0.4.1", "get-tsconfig": "5.0.0-beta.4", "github-slugger": "^2.0.0", "html-escaper": "3.0.3", "http-cache-semantics": "^4.2.0", "js-yaml": "^4.1.1", "jsonc-parser": "^3.3.1", "magic-string": "^0.30.21", "magicast": "^0.5.2", "mrmime": "^2.0.1", "neotraverse": "^1.0.1", "obug": "^2.1.1", "p-limit": "^7.3.0", "p-queue": "^9.1.0", "package-manager-detector": "^1.6.0", "piccolore": "^0.1.3", "picomatch": "^4.0.4", "semver": "^7.7.4", "shiki": "^4.0.2", "smol-toml": "^1.6.0", "svgo": "^4.0.1", "tinyclip": "^0.1.12", "tinyexec": "^1.0.4", "tinyglobby": "^0.2.15", "ultrahtml": "^1.6.0", "unifont": "~0.7.4", "unstorage": "^1.17.5", "vite": "^8.0.13", "vitefu": "^1.1.2", "xxhash-wasm": "^1.1.0", "yargs-parser": "^22.0.0", "zod": "^4.3.6" }, "optionalDependencies": { "sharp": "^0.34.0 || ^0.35.0" }, "peerDependencies": { "@astrojs/markdown-remark": "7.2.1" }, "optionalPeers": ["@astrojs/markdown-remark"], "bin": { "astro": "./bin/astro.mjs" } }, "sha512-4dhPyAAXthf3xLEYnG8SeL7yr/nTPPABfY7e9YF0yuO+vK9Xp+8Q5j4xzsmL3GueukQv4oNwGNTBepLOiDGeJA=="], - - "astro-icon": ["astro-icon@1.1.5", "", { "dependencies": { "@iconify/tools": "^4.0.5", "@iconify/types": "^2.0.0", "@iconify/utils": "^2.1.30" } }, "sha512-CJYS5nWOw9jz4RpGWmzNQY7D0y2ZZacH7atL2K9DeJXJVaz7/5WrxeyIxO8KASk1jCM96Q4LjRx/F3R+InjJrw=="], - - "astro-og-canvas": ["astro-og-canvas@0.13.0", "", { "dependencies": { "canvaskit-wasm": "^0.41.1", "deterministic-object-hash": "^2.0.2", "entities": "^8.0.0" }, "peerDependencies": { "astro": "^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-jcIDhE9OGIbd7LstZQ4CyzOpbbEKAlxJqEgdkVu6r26m7yJKlQjKysszfDxlox717cnCLPXKivyFjsufcq8sYA=="], - - "axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="], - "bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="], - "base-64": ["base-64@1.0.0", "", {}, "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg=="], - - "blake3-wasm": ["blake3-wasm@2.1.5", "", {}, "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g=="], - - "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], - - "buffer-crc32": ["buffer-crc32@0.2.13", "", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="], + "baseline-browser-mapping": ["baseline-browser-mapping@2.9.13", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-WhtvB2NG2wjr04+h77sg3klAIwrgOqnjS49GGudnUPGFFgg7G17y7Qecqp+2Dr5kUDxNRBca0SK7cG8JwzkWDQ=="], - "canvaskit-wasm": ["canvaskit-wasm@0.41.1", "", { "dependencies": { "@webgpu/types": "0.1.21" } }, "sha512-gO2rNMIE0lOQ8MaarM4qNeq2zZAEknAObKP2XAKidMSAY8P5sURGdFkrx1TSdHuBFqTf5w35JqjuUzjibqkD5g=="], + "caniuse-lite": ["caniuse-lite@1.0.30001749", "", {}, "sha512-0rw2fJOmLfnzCRbkm8EyHL8SvI2Apu5UbnQuTsJ0ClgrH8hcwFooJ1s5R0EP8o8aVrFu8++ae29Kt9/gZAZp/Q=="], "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], @@ -495,101 +363,43 @@ "character-reference-invalid": ["character-reference-invalid@2.0.1", "", {}, "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw=="], - "cheerio": ["cheerio@1.2.0", "", { "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", "domhandler": "^5.0.3", "domutils": "^3.2.2", "encoding-sniffer": "^0.2.1", "htmlparser2": "^10.1.0", "parse5": "^7.3.0", "parse5-htmlparser2-tree-adapter": "^7.1.0", "parse5-parser-stream": "^7.1.2", "undici": "^7.19.0", "whatwg-mimetype": "^4.0.0" } }, "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg=="], + "chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], - "cheerio-select": ["cheerio-select@2.1.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", "css-what": "^6.1.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1" } }, "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g=="], + "class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="], - "chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], - - "chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], - - "ci-info": ["ci-info@4.4.0", "", {}, "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg=="], - - "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], + "client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="], "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], "collapse-white-space": ["collapse-white-space@2.1.0", "", {}, "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw=="], - "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], - - "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], - "comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="], - "commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="], - - "common-ancestor-path": ["common-ancestor-path@2.0.0", "", {}, "sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng=="], - - "confbox": ["confbox@0.2.4", "", {}, "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ=="], - - "cookie": ["cookie@2.0.1", "", {}, "sha512-yuToqVvRrj6pfDXREyQAAv8SkAEk/8GS3jQRTiUMm66TVtBYmqQeoEjL2Lmq8Rpo6271vH76InTChTitEAm65w=="], + "compute-scroll-into-view": ["compute-scroll-into-view@3.1.1", "", {}, "sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw=="], - "cookie-es": ["cookie-es@1.2.3", "", {}, "sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw=="], + "cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="], - "crossws": ["crossws@0.3.5", "", { "dependencies": { "uncrypto": "^0.1.3" } }, "sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA=="], - - "css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="], - - "css-tree": ["css-tree@3.2.1", "", { "dependencies": { "mdn-data": "2.27.1", "source-map-js": "^1.2.1" } }, "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA=="], - - "css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="], - - "csso": ["csso@5.0.5", "", { "dependencies": { "css-tree": "~2.2.0" } }, "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ=="], + "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], - "decode-named-character-reference": ["decode-named-character-reference@1.3.0", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q=="], - - "defu": ["defu@6.1.7", "", {}, "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ=="], + "decode-named-character-reference": ["decode-named-character-reference@1.2.0", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q=="], "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], - "destr": ["destr@2.0.5", "", {}, "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA=="], - "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], - "deterministic-object-hash": ["deterministic-object-hash@2.0.2", "", { "dependencies": { "base-64": "^1.0.0" } }, "sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ=="], - - "devalue": ["devalue@5.8.2", "", {}, "sha512-DObPPAfdtFbXjxLqK8s2Xk9ZuWz5+ZoFEhC7J76es4GU/rEiXwHTmbImoCdyoCOcBH1UF3+Cz6Z2sYD4hyl5TA=="], + "detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="], "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], - "diff": ["diff@8.0.4", "", {}, "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw=="], - - "dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="], - - "domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="], - - "domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="], - - "domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="], - - "dset": ["dset@3.1.4", "", {}, "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA=="], - - "emmet": ["emmet@2.4.11", "", { "dependencies": { "@emmetio/abbreviation": "^2.3.3", "@emmetio/css-abbreviation": "^2.1.8" } }, "sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ=="], - - "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], - - "encoding-sniffer": ["encoding-sniffer@0.2.1", "", { "dependencies": { "iconv-lite": "^0.6.3", "whatwg-encoding": "^3.1.1" } }, "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw=="], - - "end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="], - - "enhanced-resolve": ["enhanced-resolve@5.24.3", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.3" } }, "sha512-PwKooW9JUzh5chmYfHM3IQl5OkK2u2Nm011MgeZrss3JmFraUx/fqrf78kk8GUMYoibx/14MdwTl/1WKkG7TpQ=="], - - "entities": ["entities@8.0.0", "", {}, "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA=="], - - "error-stack-parser-es": ["error-stack-parser-es@1.0.5", "", {}, "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA=="], - - "es-module-lexer": ["es-module-lexer@2.3.1", "", {}, "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA=="], + "enhanced-resolve": ["enhanced-resolve@5.18.3", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww=="], "esast-util-from-estree": ["esast-util-from-estree@2.0.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "devlop": "^1.0.0", "estree-util-visit": "^2.0.0", "unist-util-position-from-estree": "^2.0.0" } }, "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ=="], "esast-util-from-js": ["esast-util-from-js@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "acorn": "^8.0.0", "esast-util-from-estree": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw=="], - "esbuild": ["esbuild@0.28.1", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.28.1", "@esbuild/android-arm": "0.28.1", "@esbuild/android-arm64": "0.28.1", "@esbuild/android-x64": "0.28.1", "@esbuild/darwin-arm64": "0.28.1", "@esbuild/darwin-x64": "0.28.1", "@esbuild/freebsd-arm64": "0.28.1", "@esbuild/freebsd-x64": "0.28.1", "@esbuild/linux-arm": "0.28.1", "@esbuild/linux-arm64": "0.28.1", "@esbuild/linux-ia32": "0.28.1", "@esbuild/linux-loong64": "0.28.1", "@esbuild/linux-mips64el": "0.28.1", "@esbuild/linux-ppc64": "0.28.1", "@esbuild/linux-riscv64": "0.28.1", "@esbuild/linux-s390x": "0.28.1", "@esbuild/linux-x64": "0.28.1", "@esbuild/netbsd-arm64": "0.28.1", "@esbuild/netbsd-x64": "0.28.1", "@esbuild/openbsd-arm64": "0.28.1", "@esbuild/openbsd-x64": "0.28.1", "@esbuild/openharmony-arm64": "0.28.1", "@esbuild/sunos-x64": "0.28.1", "@esbuild/win32-arm64": "0.28.1", "@esbuild/win32-ia32": "0.28.1", "@esbuild/win32-x64": "0.28.1" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw=="], - - "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], + "esbuild": ["esbuild@0.27.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.2", "@esbuild/android-arm": "0.27.2", "@esbuild/android-arm64": "0.27.2", "@esbuild/android-x64": "0.27.2", "@esbuild/darwin-arm64": "0.27.2", "@esbuild/darwin-x64": "0.27.2", "@esbuild/freebsd-arm64": "0.27.2", "@esbuild/freebsd-x64": "0.27.2", "@esbuild/linux-arm": "0.27.2", "@esbuild/linux-arm64": "0.27.2", "@esbuild/linux-ia32": "0.27.2", "@esbuild/linux-loong64": "0.27.2", "@esbuild/linux-mips64el": "0.27.2", "@esbuild/linux-ppc64": "0.27.2", "@esbuild/linux-riscv64": "0.27.2", "@esbuild/linux-s390x": "0.27.2", "@esbuild/linux-x64": "0.27.2", "@esbuild/netbsd-arm64": "0.27.2", "@esbuild/netbsd-x64": "0.27.2", "@esbuild/openbsd-arm64": "0.27.2", "@esbuild/openbsd-x64": "0.27.2", "@esbuild/openharmony-arm64": "0.27.2", "@esbuild/sunos-x64": "0.27.2", "@esbuild/win32-arm64": "0.27.2", "@esbuild/win32-ia32": "0.27.2", "@esbuild/win32-x64": "0.27.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw=="], "escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], @@ -603,93 +413,43 @@ "estree-util-to-js": ["estree-util-to-js@2.0.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "astring": "^1.8.0", "source-map": "^0.7.0" } }, "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg=="], - "estree-util-visit": ["estree-util-visit@2.0.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/unist": "^3.0.0" } }, "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww=="], + "estree-util-value-to-estree": ["estree-util-value-to-estree@3.5.0", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-aMV56R27Gv3QmfmF1MY12GWkGzzeAezAX+UplqHVASfjc9wNzI/X6hC0S9oxq61WT4aQesLGslWP9tKk6ghRZQ=="], - "estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], - - "eventemitter3": ["eventemitter3@5.0.4", "", {}, "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw=="], + "estree-util-visit": ["estree-util-visit@2.0.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/unist": "^3.0.0" } }, "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww=="], - "exsolve": ["exsolve@1.1.0", "", {}, "sha512-D+42+T12DdIlJM3uepa55qGiL3sYdLBOxIl2ifQCzCHz4c7eiolaHsi3BIqEr7JxBzxv2pYZQX9kw16ziMcEmw=="], + "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], - "extract-zip": ["extract-zip@2.0.1", "", { "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", "yauzl": "^2.10.0" }, "optionalDependencies": { "@types/yauzl": "^2.9.1" }, "bin": { "extract-zip": "cli.js" } }, "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg=="], - - "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], - - "fast-string-truncated-width": ["fast-string-truncated-width@3.0.3", "", {}, "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g=="], - - "fast-string-width": ["fast-string-width@3.0.2", "", { "dependencies": { "fast-string-truncated-width": "^3.0.2" } }, "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg=="], - - "fast-uri": ["fast-uri@3.1.4", "", {}, "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw=="], - - "fast-wrap-ansi": ["fast-wrap-ansi@0.2.2", "", { "dependencies": { "fast-string-width": "^3.0.2" } }, "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q=="], - - "fd-slicer": ["fd-slicer@1.1.0", "", { "dependencies": { "pend": "~1.2.0" } }, "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g=="], - "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], - "flattie": ["flattie@1.1.1", "", {}, "sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ=="], - - "fontace": ["fontace@0.4.1", "", { "dependencies": { "fontkitten": "^1.0.2" } }, "sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw=="], - - "fontkitten": ["fontkitten@1.0.3", "", { "dependencies": { "tiny-inflate": "^1.0.3" } }, "sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw=="], - - "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + "fumadocs-core": ["fumadocs-core@16.4.5", "", { "dependencies": { "@formatjs/intl-localematcher": "^0.7.4", "@orama/orama": "^3.1.18", "@shikijs/rehype": "^3.20.0", "@shikijs/transformers": "^3.20.0", "estree-util-value-to-estree": "^3.5.0", "github-slugger": "^2.0.0", "hast-util-to-estree": "^3.1.3", "hast-util-to-jsx-runtime": "^2.3.6", "image-size": "^2.0.2", "negotiator": "^1.0.0", "npm-to-yarn": "^3.0.1", "path-to-regexp": "^8.3.0", "remark": "^15.0.1", "remark-gfm": "^4.0.1", "remark-rehype": "^11.1.2", "scroll-into-view-if-needed": "^3.1.0", "shiki": "^3.20.0", "tinyglobby": "^0.2.15", "unist-util-visit": "^5.0.0" }, "peerDependencies": { "@mixedbread/sdk": "^0.46.0", "@orama/core": "1.x.x", "@oramacloud/client": "2.x.x", "@tanstack/react-router": "1.x.x", "@types/react": "*", "algoliasearch": "5.x.x", "lucide-react": "*", "next": "16.x.x", "react": "^19.2.0", "react-dom": "^19.2.0", "react-router": "7.x.x", "waku": "^0.26.0 || ^0.27.0", "zod": "4.x.x" }, "optionalPeers": ["@mixedbread/sdk", "@orama/core", "@oramacloud/client", "@tanstack/react-router", "@types/react", "algoliasearch", "lucide-react", "next", "react", "react-dom", "react-router", "waku", "zod"] }, "sha512-TiolQpn22URwhR3HB2uahKtUFYu4HFjBdKIReG76ONguNUor7BVaF6yq4Ysx58UmvpNa2mfaUYSi5jCmdDfr6g=="], - "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], + "fumadocs-mdx": ["fumadocs-mdx@14.2.4", "", { "dependencies": { "@mdx-js/mdx": "^3.1.1", "@standard-schema/spec": "^1.1.0", "chokidar": "^5.0.0", "esbuild": "^0.27.2", "estree-util-value-to-estree": "^3.5.0", "js-yaml": "^4.1.1", "mdast-util-to-markdown": "^2.1.2", "picocolors": "^1.1.1", "picomatch": "^4.0.3", "remark-mdx": "^3.1.1", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.3", "zod": "^4.2.1" }, "peerDependencies": { "@fumadocs/mdx-remote": "^1.4.0", "@types/react": "*", "fumadocs-core": "^15.0.0 || ^16.0.0", "next": "^15.3.0 || ^16.0.0", "react": "*", "vite": "6.x.x || 7.x.x" }, "optionalPeers": ["@fumadocs/mdx-remote", "@types/react", "next", "react", "vite"], "bin": { "fumadocs-mdx": "dist/bin.js" } }, "sha512-YuDgzTopMuOOQmOhvOUfmXn2RryZY5Ev+9uwAzTBEYcLIpxIBxZl0/jHaLoYdlOMBM65AO6OBngA2SucC2hkIQ=="], - "get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="], + "fumadocs-ui": ["fumadocs-ui@16.4.5", "", { "dependencies": { "@fumadocs/ui": "16.4.5", "@radix-ui/react-accordion": "^1.2.12", "@radix-ui/react-collapsible": "^1.1.12", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-direction": "^1.1.1", "@radix-ui/react-navigation-menu": "^1.2.14", "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-presence": "^1.1.5", "@radix-ui/react-scroll-area": "^1.2.10", "@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-tabs": "^1.1.13", "class-variance-authority": "^0.7.1", "fumadocs-core": "16.4.5", "lucide-react": "^0.562.0", "next-themes": "^0.4.6", "react-medium-image-zoom": "^5.4.0", "scroll-into-view-if-needed": "^3.1.0" }, "peerDependencies": { "@types/react": "*", "react": "^19.2.0", "react-dom": "^19.2.0", "tailwindcss": "^4.0.0" }, "optionalPeers": ["@types/react", "tailwindcss"] }, "sha512-I+eQkkBk2uOmpxe2w1jyucJ9uOHyfhkCDfskeqmeJzzEYq0vDP4urbvF4OPXfZv1WoH1tq6PbSzE3oIFX1lbhg=="], - "get-tsconfig": ["get-tsconfig@5.0.0-beta.4", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-7nF7C9fIPFEMHgEMEfgIlO9wDdZ8CyHw27rWciFZfHvHDReIiPhsYuzPRXsfvBCqFy1l8RRyyWV7QLM+ZhUJsQ=="], - - "giget": ["giget@3.3.1", "", { "bin": { "giget": "dist/cli.mjs" } }, "sha512-r+mvuDjrjMpsdw46Kmeydb8bdHm7wOKw8wNBtTndkjbPjgAp5oUJUxRE76wZFknxIPokfWvep2qSXK37aXE6zg=="], + "get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="], "github-slugger": ["github-slugger@2.0.0", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="], - "globals": ["globals@15.15.0", "", {}, "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg=="], - "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], - "h3": ["h3@1.15.11", "", { "dependencies": { "cookie-es": "^1.2.3", "crossws": "^0.3.5", "defu": "^6.1.6", "destr": "^2.0.5", "iron-webcrypto": "^1.2.1", "node-mock-http": "^1.0.4", "radix3": "^1.1.2", "ufo": "^1.6.3", "uncrypto": "^0.1.3" } }, "sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg=="], - - "hast-util-from-html": ["hast-util-from-html@2.0.3", "", { "dependencies": { "@types/hast": "^3.0.0", "devlop": "^1.1.0", "hast-util-from-parse5": "^8.0.0", "parse5": "^7.0.0", "vfile": "^6.0.0", "vfile-message": "^4.0.0" } }, "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw=="], - - "hast-util-from-parse5": ["hast-util-from-parse5@8.0.3", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "devlop": "^1.0.0", "hastscript": "^9.0.0", "property-information": "^7.0.0", "vfile": "^6.0.0", "vfile-location": "^5.0.0", "web-namespaces": "^2.0.0" } }, "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg=="], - - "hast-util-is-element": ["hast-util-is-element@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g=="], - - "hast-util-parse-selector": ["hast-util-parse-selector@4.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A=="], - - "hast-util-raw": ["hast-util-raw@9.1.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "@ungap/structured-clone": "^1.0.0", "hast-util-from-parse5": "^8.0.0", "hast-util-to-parse5": "^8.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "parse5": "^7.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0", "web-namespaces": "^2.0.0", "zwitch": "^2.0.0" } }, "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw=="], - "hast-util-to-estree": ["hast-util-to-estree@3.1.3", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "estree-util-attach-comments": "^3.0.0", "estree-util-is-identifier-name": "^3.0.0", "hast-util-whitespace": "^3.0.0", "mdast-util-mdx-expression": "^2.0.0", "mdast-util-mdx-jsx": "^3.0.0", "mdast-util-mdxjs-esm": "^2.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "style-to-js": "^1.0.0", "unist-util-position": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w=="], "hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="], "hast-util-to-jsx-runtime": ["hast-util-to-jsx-runtime@2.3.6", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "hast-util-whitespace": "^3.0.0", "mdast-util-mdx-expression": "^2.0.0", "mdast-util-mdx-jsx": "^3.0.0", "mdast-util-mdxjs-esm": "^2.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "style-to-js": "^1.0.0", "unist-util-position": "^5.0.0", "vfile-message": "^4.0.0" } }, "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg=="], - "hast-util-to-parse5": ["hast-util-to-parse5@8.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "web-namespaces": "^2.0.0", "zwitch": "^2.0.0" } }, "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA=="], - - "hast-util-to-text": ["hast-util-to-text@4.0.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "hast-util-is-element": "^3.0.0", "unist-util-find-after": "^5.0.0" } }, "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A=="], + "hast-util-to-string": ["hast-util-to-string@3.0.1", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A=="], "hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="], - "hastscript": ["hastscript@9.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-parse-selector": "^4.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0" } }, "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w=="], - - "html-escaper": ["html-escaper@3.0.3", "", {}, "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ=="], - "html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="], - "htmlparser2": ["htmlparser2@10.1.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.2.2", "entities": "^7.0.1" } }, "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ=="], - - "http-cache-semantics": ["http-cache-semantics@4.2.0", "", {}, "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="], - - "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], + "image-size": ["image-size@2.0.2", "", { "bin": { "image-size": "bin/image-size.js" } }, "sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w=="], - "inline-style-parser": ["inline-style-parser@0.2.7", "", {}, "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA=="], - - "iron-webcrypto": ["iron-webcrypto@1.2.1", "", {}, "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg=="], + "inline-style-parser": ["inline-style-parser@0.2.4", "", {}, "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q=="], "is-alphabetical": ["is-alphabetical@2.0.1", "", {}, "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ=="], @@ -697,69 +457,51 @@ "is-decimal": ["is-decimal@2.0.1", "", {}, "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A=="], - "is-docker": ["is-docker@4.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-LHE+wROyG/Y/0ZnbktRCoTix2c1RhgWaZraMZ8o1Q7zCh0VSrICJQO5oqIIISrcSBtrXv0o233w1IYwsWCjTzA=="], - - "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], - "is-hexadecimal": ["is-hexadecimal@2.0.1", "", {}, "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg=="], "is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="], - "jiti": ["jiti@2.7.0", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ=="], - - "js-yaml": ["js-yaml@4.3.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q=="], + "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], - "json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], - "jsonc-parser": ["jsonc-parser@3.3.1", "", {}, "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ=="], + "lightningcss": ["lightningcss@1.30.2", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.30.2", "lightningcss-darwin-arm64": "1.30.2", "lightningcss-darwin-x64": "1.30.2", "lightningcss-freebsd-x64": "1.30.2", "lightningcss-linux-arm-gnueabihf": "1.30.2", "lightningcss-linux-arm64-gnu": "1.30.2", "lightningcss-linux-arm64-musl": "1.30.2", "lightningcss-linux-x64-gnu": "1.30.2", "lightningcss-linux-x64-musl": "1.30.2", "lightningcss-win32-arm64-msvc": "1.30.2", "lightningcss-win32-x64-msvc": "1.30.2" } }, "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ=="], - "kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="], + "lightningcss-android-arm64": ["lightningcss-android-arm64@1.30.2", "", { "os": "android", "cpu": "arm64" }, "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A=="], - "kolorist": ["kolorist@1.8.0", "", {}, "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ=="], + "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA=="], - "lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="], + "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ=="], - "lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="], + "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA=="], - "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="], + "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.2", "", { "os": "linux", "cpu": "arm" }, "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA=="], - "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.32.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w=="], + "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A=="], - "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.32.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig=="], + "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA=="], - "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.32.0", "", { "os": "linux", "cpu": "arm" }, "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw=="], + "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w=="], - "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ=="], + "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA=="], - "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg=="], + "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ=="], - "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA=="], - - "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg=="], - - "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.32.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="], - - "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="], - - "local-pkg": ["local-pkg@1.2.1", "", { "dependencies": { "mlly": "^1.7.4", "pkg-types": "^2.3.0", "quansync": "^0.2.11" } }, "sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q=="], + "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw=="], "longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="], - "lru-cache": ["lru-cache@11.5.2", "", {}, "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g=="], + "lucide-react": ["lucide-react@0.562.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-82hOAu7y0dbVuFfmO4bYF1XEwYk/mEbM5E+b1jgci/udUBEE/R7LF5Ip0CCEmXe8AybRM8L+04eP+LGZeDvkiw=="], "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], - "magicast": ["magicast@0.5.3", "", { "dependencies": { "@babel/parser": "^7.29.3", "@babel/types": "^7.29.0", "source-map-js": "^1.2.1" } }, "sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw=="], - "markdown-extensions": ["markdown-extensions@2.0.0", "", {}, "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q=="], "markdown-table": ["markdown-table@3.0.4", "", {}, "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw=="], - "mdast-util-definitions": ["mdast-util-definitions@6.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ=="], - "mdast-util-find-and-replace": ["mdast-util-find-and-replace@3.0.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "escape-string-regexp": "^5.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg=="], - "mdast-util-from-markdown": ["mdast-util-from-markdown@2.0.3", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "mdast-util-to-string": "^4.0.0", "micromark": "^4.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q=="], + "mdast-util-from-markdown": ["mdast-util-from-markdown@2.0.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "mdast-util-to-string": "^4.0.0", "micromark": "^4.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA=="], "mdast-util-gfm": ["mdast-util-gfm@3.1.0", "", { "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-gfm-autolink-literal": "^2.0.0", "mdast-util-gfm-footnote": "^2.0.0", "mdast-util-gfm-strikethrough": "^2.0.0", "mdast-util-gfm-table": "^2.0.0", "mdast-util-gfm-task-list-item": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ=="], @@ -783,14 +525,12 @@ "mdast-util-phrasing": ["mdast-util-phrasing@4.1.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "unist-util-is": "^6.0.0" } }, "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w=="], - "mdast-util-to-hast": ["mdast-util-to-hast@13.2.1", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@ungap/structured-clone": "^1.0.0", "devlop": "^1.0.0", "micromark-util-sanitize-uri": "^2.0.0", "trim-lines": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA=="], + "mdast-util-to-hast": ["mdast-util-to-hast@13.2.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@ungap/structured-clone": "^1.0.0", "devlop": "^1.0.0", "micromark-util-sanitize-uri": "^2.0.0", "trim-lines": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA=="], "mdast-util-to-markdown": ["mdast-util-to-markdown@2.1.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "longest-streak": "^3.0.0", "mdast-util-phrasing": "^4.0.0", "mdast-util-to-string": "^4.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA=="], "mdast-util-to-string": ["mdast-util-to-string@4.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0" } }, "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg=="], - "mdn-data": ["mdn-data@2.27.1", "", {}, "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ=="], - "micromark": ["micromark@4.0.2", "", { "dependencies": { "@types/debug": "^4.0.0", "debug": "^4.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA=="], "micromark-core-commonmark": ["micromark-core-commonmark@2.0.3", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-destination": "^2.0.0", "micromark-factory-label": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-factory-title": "^2.0.0", "micromark-factory-whitespace": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-html-tag-name": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg=="], @@ -861,103 +601,49 @@ "micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="], - "miniflare": ["miniflare@4.20260722.0", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "sharp": "0.35.2", "undici": "7.28.0", "workerd": "1.20260722.1", "ws": "8.21.0", "youch": "4.1.0-beta.10" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-LW6ABMhCx/yIEFBLC/DO4yAhdm2T/G7jp7pr5T2kj895+CCIaHZqpMXdW9O6YE48LcYcCJChwWc8aEs1vpbTXw=="], - - "minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], - - "minizlib": ["minizlib@3.1.0", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw=="], - - "mlly": ["mlly@1.8.2", "", { "dependencies": { "acorn": "^8.16.0", "pathe": "^2.0.3", "pkg-types": "^1.3.1", "ufo": "^1.6.3" } }, "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA=="], - - "mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="], - - "mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="], - "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], - "muggle-string": ["muggle-string@0.4.1", "", {}, "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ=="], - - "nanoid": ["nanoid@3.3.16", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q=="], - - "neotraverse": ["neotraverse@1.0.1", "", {}, "sha512-WmmLty1YWwJl9yZi77v2dVIV6X2kuYV8YYBI/G3LWGKdGHmHUvL1z7FW0iDvEvGAwNEoc5x1tOOOyDnf5jJw/w=="], - - "nlcst-to-string": ["nlcst-to-string@4.0.0", "", { "dependencies": { "@types/nlcst": "^2.0.0" } }, "sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA=="], - - "node-fetch-native": ["node-fetch-native@1.6.7", "", {}, "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q=="], + "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], - "node-mock-http": ["node-mock-http@1.0.4", "", {}, "sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ=="], + "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], - "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], + "next": ["next@16.1.1", "", { "dependencies": { "@next/env": "16.1.1", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.8.3", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.1.1", "@next/swc-darwin-x64": "16.1.1", "@next/swc-linux-arm64-gnu": "16.1.1", "@next/swc-linux-arm64-musl": "16.1.1", "@next/swc-linux-x64-gnu": "16.1.1", "@next/swc-linux-x64-musl": "16.1.1", "@next/swc-win32-arm64-msvc": "16.1.1", "@next/swc-win32-x64-msvc": "16.1.1", "sharp": "^0.34.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-QI+T7xrxt1pF6SQ/JYFz95ro/mg/1Znk5vBebsWwbpejj1T0A23hO7GYEaVac9QUOT2BIMiuzm0L99ooq7k0/w=="], - "nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="], + "next-themes": ["next-themes@0.4.6", "", { "peerDependencies": { "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA=="], - "obug": ["obug@2.1.4", "", {}, "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA=="], + "npm-to-yarn": ["npm-to-yarn@3.0.1", "", {}, "sha512-tt6PvKu4WyzPwWUzy/hvPFqn+uwXO0K1ZHka8az3NnrhWJDmSqI8ncWq0fkL0k/lmmi5tAC11FXwXuh0rFbt1A=="], - "ofetch": ["ofetch@1.5.1", "", { "dependencies": { "destr": "^2.0.5", "node-fetch-native": "^1.6.7", "ufo": "^1.6.1" } }, "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA=="], + "oniguruma-parser": ["oniguruma-parser@0.12.1", "", {}, "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w=="], - "ohash": ["ohash@2.0.11", "", {}, "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ=="], - - "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], - - "oniguruma-parser": ["oniguruma-parser@0.12.2", "", {}, "sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw=="], - - "oniguruma-to-es": ["oniguruma-to-es@4.3.6", "", { "dependencies": { "oniguruma-parser": "^0.12.2", "regex": "^6.1.0", "regex-recursion": "^6.0.2" } }, "sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA=="], - - "p-limit": ["p-limit@7.3.1", "", { "dependencies": { "yocto-queue": "^1.2.1" } }, "sha512-0trZaiG7Y7kN/Egy9a8j47t9osC0Tch4PaIWd9yGF6bvmlk7muExRvGNYb8sXBwEKMoNKsbNN9P8EefuQekE4Q=="], - - "p-queue": ["p-queue@9.3.3", "", { "dependencies": { "eventemitter3": "^5.0.4", "p-timeout": "^7.0.0" } }, "sha512-NXAOdnEe5FsZJfT4oK84lE1Y5cFFdWlRuOo5tww8DyNMxyRXwn39fIkUtNLKppcPC+UYU/bXujNCUGDv01y7CA=="], - - "p-timeout": ["p-timeout@7.0.1", "", {}, "sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg=="], - - "package-manager-detector": ["package-manager-detector@1.8.0", "", {}, "sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A=="], - - "pagefind": ["pagefind@1.5.2", "", { "optionalDependencies": { "@pagefind/darwin-arm64": "1.5.2", "@pagefind/darwin-x64": "1.5.2", "@pagefind/freebsd-x64": "1.5.2", "@pagefind/linux-arm64": "1.5.2", "@pagefind/linux-x64": "1.5.2", "@pagefind/windows-arm64": "1.5.2", "@pagefind/windows-x64": "1.5.2" }, "bin": { "pagefind": "lib/runner/bin.cjs" } }, "sha512-XTUaK0hXMCu2jszWE584JGQT7y284TmMV9l/HX3rnG5uo3rHI/uHU56XTyyyPFjeWEBxECbAi0CaFDJOONtG0Q=="], + "oniguruma-to-es": ["oniguruma-to-es@4.3.4", "", { "dependencies": { "oniguruma-parser": "^0.12.1", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA=="], "parse-entities": ["parse-entities@4.0.2", "", { "dependencies": { "@types/unist": "^2.0.0", "character-entities-legacy": "^3.0.0", "character-reference-invalid": "^2.0.0", "decode-named-character-reference": "^1.0.0", "is-alphanumerical": "^2.0.0", "is-decimal": "^2.0.0", "is-hexadecimal": "^2.0.0" } }, "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw=="], - "parse-latin": ["parse-latin@7.0.0", "", { "dependencies": { "@types/nlcst": "^2.0.0", "@types/unist": "^3.0.0", "nlcst-to-string": "^4.0.0", "unist-util-modify-children": "^4.0.0", "unist-util-visit-children": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ=="], - - "parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="], - - "parse5-htmlparser2-tree-adapter": ["parse5-htmlparser2-tree-adapter@7.1.0", "", { "dependencies": { "domhandler": "^5.0.3", "parse5": "^7.0.0" } }, "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g=="], - - "parse5-parser-stream": ["parse5-parser-stream@7.1.2", "", { "dependencies": { "parse5": "^7.0.0" } }, "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow=="], - - "path-browserify": ["path-browserify@1.0.1", "", {}, "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g=="], - - "path-to-regexp": ["path-to-regexp@6.3.0", "", {}, "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ=="], - - "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], - - "pend": ["pend@1.2.0", "", {}, "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="], - - "piccolore": ["piccolore@0.1.3", "", {}, "sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw=="], + "path-to-regexp": ["path-to-regexp@8.3.0", "", {}, "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA=="], "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], - "picomatch": ["picomatch@4.0.5", "", {}, "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A=="], - - "pkg-types": ["pkg-types@2.3.1", "", { "dependencies": { "confbox": "^0.2.4", "exsolve": "^1.0.8", "pathe": "^2.0.3" } }, "sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg=="], + "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], - "postcss": ["postcss@8.5.23", "", { "dependencies": { "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg=="], + "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="], - "prettier": ["prettier@3.9.6", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g=="], + "postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="], - "prismjs": ["prismjs@1.30.0", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="], + "property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], - "process-ancestry": ["process-ancestry@0.1.0", "", {}, "sha512-tGqJW/UnclpYASFcM6Xh8D8l/BMtaQ9+CSG0vlJSJTcdMM4lDRv4c6H0Pdcsfted+bVczdYSfk2fdukg2gQkZg=="], + "react": ["react@19.2.3", "", {}, "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA=="], - "property-information": ["property-information@7.2.0", "", {}, "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg=="], + "react-dom": ["react-dom@19.2.3", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.3" } }, "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg=="], - "pump": ["pump@3.0.4", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA=="], + "react-medium-image-zoom": ["react-medium-image-zoom@5.4.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-BsE+EnFVQzFIlyuuQrZ9iTwyKpKkqdFZV1ImEQN573QPqGrIUuNni7aF+sZwDcxlsuOMayCr6oO/PZR/yJnbRg=="], - "quansync": ["quansync@0.2.11", "", {}, "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA=="], + "react-remove-scroll": ["react-remove-scroll@2.7.1", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA=="], - "quotation": ["quotation@2.0.3", "", {}, "sha512-yEc24TEgCFLXx7D4JHJJkK4JFVtatO8fziwUxY4nB/Jbea9o9CVS3gt22mA0W7rPYAGW2fWzYDSOtD94PwOyqA=="], + "react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="], - "radix3": ["radix3@1.1.2", "", {}, "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA=="], + "react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="], - "readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], + "readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], "recma-build-jsx": ["recma-build-jsx@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-util-build-jsx": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew=="], @@ -967,81 +653,35 @@ "recma-stringify": ["recma-stringify@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-util-to-js": "^2.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g=="], - "regex": ["regex@6.1.0", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg=="], + "regex": ["regex@6.0.1", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA=="], "regex-recursion": ["regex-recursion@6.0.2", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg=="], "regex-utilities": ["regex-utilities@2.3.0", "", {}, "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng=="], - "rehype-raw": ["rehype-raw@7.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-raw": "^9.0.0", "vfile": "^6.0.0" } }, "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww=="], - "rehype-recma": ["rehype-recma@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", "hast-util-to-estree": "^3.0.0" } }, "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw=="], - "rehype-stringify": ["rehype-stringify@10.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-to-html": "^9.0.0", "unified": "^11.0.0" } }, "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA=="], + "remark": ["remark@15.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.0" } }, "sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A=="], "remark-gfm": ["remark-gfm@4.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-gfm": "^3.0.0", "micromark-extension-gfm": "^3.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.0" } }, "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg=="], - "remark-lint-emphasis-marker": ["remark-lint-emphasis-marker@4.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "unified-lint-rule": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit-parents": "^6.0.0", "vfile-message": "^4.0.0" } }, "sha512-BF1WWsAxai3XoKk48sfiqT3L8m02AZLj3BnipWkHDRXuLfz6VwsHVaHWyNvvE0p6b2B3A5dSYbcfJu5RmPx4tQ=="], - - "remark-lint-fenced-code-flag": ["remark-lint-fenced-code-flag@4.2.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-phrasing": "^4.0.0", "quotation": "^2.0.0", "unified-lint-rule": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-QWGTrnYbcopOFZR98djDREmKApLonJ7hmXE7pEcOGee9JY/EUIVS7Lq54Hy9CtU3cVIvQQmiMTxCwUhfddDJFA=="], - - "remark-lint-heading-increment": ["remark-lint-heading-increment@4.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-mdx": "^3.0.0", "unified-lint-rule": "^3.0.0", "unist-util-visit-parents": "^6.0.0", "vfile-message": "^4.0.0" } }, "sha512-uat7RTQn0hGlMv62p7yjLlg3tO3RljFbH6C+0M+5BNEF+s3NrA8jJgqW0UwLLNdCd3EABCKaWloHumT57ND7PQ=="], - - "remark-lint-no-duplicate-headings": ["remark-lint-no-duplicate-headings@4.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-mdx": "^3.0.0", "mdast-util-to-string": "^4.0.0", "unified-lint-rule": "^3.0.0", "unist-util-visit-parents": "^6.0.0", "vfile-message": "^4.0.0" } }, "sha512-6lggqnpIe5FepikjYF2me3ovKV4oD/rAz8WmwVbLR2cLkce1iH+PB7jyxk/A2gQQqrDcIlRMA5Ct2Yj56cEwhQ=="], - - "remark-lint-no-heading-punctuation": ["remark-lint-no-heading-punctuation@4.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-mdx": "^3.0.0", "mdast-util-to-string": "^4.0.0", "unified-lint-rule": "^3.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-lpSVFEHPDKGWi8YPeO51xmLNVON5A2cGz0Y8VRkW0f2l6LvEkPTMjQAvA84AQu/10TrxTbIzU/tQlRLpG96QUA=="], - - "remark-lint-no-literal-urls": ["remark-lint-no-literal-urls@4.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-to-string": "^4.0.0", "micromark-util-character": "^2.0.0", "unified-lint-rule": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-RhTANFkFFXE6bM+WxWcPo2TTPEfkWG3lJZU50ycW7tJJmxUzDNzRed/z80EVJIdGwFa0NntVooLUJp3xrogalQ=="], - - "remark-lint-no-multiple-toplevel-headings": ["remark-lint-no-multiple-toplevel-headings@4.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-mdx": "^3.0.0", "unified-lint-rule": "^3.0.0", "unist-util-visit-parents": "^6.0.0", "vfile-message": "^4.0.0" } }, "sha512-8sepobIOu3PlDOuMH7jtri+LH4tFNVQU+aqKSkrlNRdp831fYz9S+jA2crTVqWqxVbTwiF96uJWePv8/9qmHnA=="], - - "remark-lint-unordered-list-marker-style": ["remark-lint-unordered-list-marker-style@4.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-phrasing": "^4.0.0", "unified-lint-rule": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit-parents": "^6.0.0", "vfile-message": "^4.0.0" } }, "sha512-HMrVQC0Qbr8ktSy+1lJGRGU10qecL3T14L6s/THEQXR5Tk0wcsLLG0auNvB4r2+H+ClhVO/Vnm1TEosh1OCsfw=="], - "remark-mdx": ["remark-mdx@3.1.1", "", { "dependencies": { "mdast-util-mdx": "^3.0.0", "micromark-extension-mdxjs": "^3.0.0" } }, "sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg=="], "remark-parse": ["remark-parse@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", "micromark-util-types": "^2.0.0", "unified": "^11.0.0" } }, "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA=="], "remark-rehype": ["remark-rehype@11.1.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "mdast-util-to-hast": "^13.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw=="], - "remark-smartypants": ["remark-smartypants@3.0.3", "", { "dependencies": { "retext": "^9.0.0", "retext-smartypants": "^6.0.0", "unified": "^11.0.4", "unist-util-visit": "^5.0.0" } }, "sha512-gCaK+ndZ0hYezlqFegHFCVh2CQemsi0Npdh1qVM9bxlUFknjkbP6VmojWhddOCrbK0PbbacmYLWfTULRiT1eWA=="], - "remark-stringify": ["remark-stringify@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-to-markdown": "^2.0.0", "unified": "^11.0.0" } }, "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw=="], - "request-light": ["request-light@0.7.0", "", {}, "sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q=="], - - "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], - - "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="], - - "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="], - - "retext": ["retext@9.0.0", "", { "dependencies": { "@types/nlcst": "^2.0.0", "retext-latin": "^4.0.0", "retext-stringify": "^4.0.0", "unified": "^11.0.0" } }, "sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA=="], - - "retext-latin": ["retext-latin@4.0.0", "", { "dependencies": { "@types/nlcst": "^2.0.0", "parse-latin": "^7.0.0", "unified": "^11.0.0" } }, "sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA=="], - - "retext-smartypants": ["retext-smartypants@6.2.0", "", { "dependencies": { "@types/nlcst": "^2.0.0", "nlcst-to-string": "^4.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ=="], - - "retext-stringify": ["retext-stringify@4.0.0", "", { "dependencies": { "@types/nlcst": "^2.0.0", "nlcst-to-string": "^4.0.0", "unified": "^11.0.0" } }, "sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA=="], + "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], - "rolldown": ["rolldown@1.1.5", "", { "dependencies": { "@oxc-project/types": "=0.139.0", "@rolldown/pluginutils": "^1.0.0" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.1.5", "@rolldown/binding-darwin-arm64": "1.1.5", "@rolldown/binding-darwin-x64": "1.1.5", "@rolldown/binding-freebsd-x64": "1.1.5", "@rolldown/binding-linux-arm-gnueabihf": "1.1.5", "@rolldown/binding-linux-arm64-gnu": "1.1.5", "@rolldown/binding-linux-arm64-musl": "1.1.5", "@rolldown/binding-linux-ppc64-gnu": "1.1.5", "@rolldown/binding-linux-s390x-gnu": "1.1.5", "@rolldown/binding-linux-x64-gnu": "1.1.5", "@rolldown/binding-linux-x64-musl": "1.1.5", "@rolldown/binding-openharmony-arm64": "1.1.5", "@rolldown/binding-wasm32-wasi": "1.1.5", "@rolldown/binding-win32-arm64-msvc": "1.1.5", "@rolldown/binding-win32-x64-msvc": "1.1.5" }, "bin": { "rolldown": "./bin/cli.mjs" } }, "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA=="], + "scroll-into-view-if-needed": ["scroll-into-view-if-needed@3.1.0", "", { "dependencies": { "compute-scroll-into-view": "^3.0.2" } }, "sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ=="], - "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + "semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], - "satteri": ["satteri@0.9.5", "", { "dependencies": { "@types/estree-jsx": "^1.0.5", "@types/hast": "^3.0.4", "@types/mdast": "^4.0.4", "@types/unist": "^3.0.3" }, "optionalDependencies": { "@bruits/satteri-darwin-arm64": "0.9.5", "@bruits/satteri-darwin-x64": "0.9.5", "@bruits/satteri-linux-arm64-gnu": "0.9.5", "@bruits/satteri-linux-arm64-musl": "0.9.5", "@bruits/satteri-linux-x64-gnu": "0.9.5", "@bruits/satteri-linux-x64-musl": "0.9.5", "@bruits/satteri-wasm32-wasi": "0.9.5", "@bruits/satteri-win32-arm64-msvc": "0.9.5", "@bruits/satteri-win32-x64-msvc": "0.9.5" } }, "sha512-ZuWVl+vnM64y+/TtX8Kosv2c00W+hLQiiwnEL6H0UKVVrxFqMw4D2CJHHQaouVd89OAhtBBfjWLqhKi3TVUV4w=="], + "sharp": ["sharp@0.34.4", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.0", "semver": "^7.7.2" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.4", "@img/sharp-darwin-x64": "0.34.4", "@img/sharp-libvips-darwin-arm64": "1.2.3", "@img/sharp-libvips-darwin-x64": "1.2.3", "@img/sharp-libvips-linux-arm": "1.2.3", "@img/sharp-libvips-linux-arm64": "1.2.3", "@img/sharp-libvips-linux-ppc64": "1.2.3", "@img/sharp-libvips-linux-s390x": "1.2.3", "@img/sharp-libvips-linux-x64": "1.2.3", "@img/sharp-libvips-linuxmusl-arm64": "1.2.3", "@img/sharp-libvips-linuxmusl-x64": "1.2.3", "@img/sharp-linux-arm": "0.34.4", "@img/sharp-linux-arm64": "0.34.4", "@img/sharp-linux-ppc64": "0.34.4", "@img/sharp-linux-s390x": "0.34.4", "@img/sharp-linux-x64": "0.34.4", "@img/sharp-linuxmusl-arm64": "0.34.4", "@img/sharp-linuxmusl-x64": "0.34.4", "@img/sharp-wasm32": "0.34.4", "@img/sharp-win32-arm64": "0.34.4", "@img/sharp-win32-ia32": "0.34.4", "@img/sharp-win32-x64": "0.34.4" } }, "sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA=="], - "sax": ["sax@1.6.1", "", {}, "sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q=="], - - "semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], - - "sharp": ["sharp@0.35.2", "", { "dependencies": { "@img/colour": "^1.1.0", "detect-libc": "^2.1.2", "semver": "^7.8.4" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.35.2", "@img/sharp-darwin-x64": "0.35.2", "@img/sharp-freebsd-wasm32": "0.35.2", "@img/sharp-libvips-darwin-arm64": "1.3.1", "@img/sharp-libvips-darwin-x64": "1.3.1", "@img/sharp-libvips-linux-arm": "1.3.1", "@img/sharp-libvips-linux-arm64": "1.3.1", "@img/sharp-libvips-linux-ppc64": "1.3.1", "@img/sharp-libvips-linux-riscv64": "1.3.1", "@img/sharp-libvips-linux-s390x": "1.3.1", "@img/sharp-libvips-linux-x64": "1.3.1", "@img/sharp-libvips-linuxmusl-arm64": "1.3.1", "@img/sharp-libvips-linuxmusl-x64": "1.3.1", "@img/sharp-linux-arm": "0.35.2", "@img/sharp-linux-arm64": "0.35.2", "@img/sharp-linux-ppc64": "0.35.2", "@img/sharp-linux-riscv64": "0.35.2", "@img/sharp-linux-s390x": "0.35.2", "@img/sharp-linux-x64": "0.35.2", "@img/sharp-linuxmusl-arm64": "0.35.2", "@img/sharp-linuxmusl-x64": "0.35.2", "@img/sharp-webcontainers-wasm32": "0.35.2", "@img/sharp-win32-arm64": "0.35.2", "@img/sharp-win32-ia32": "0.35.2", "@img/sharp-win32-x64": "0.35.2" } }, "sha512-FVtFjtBCMiJS6yb5CX7Sop45WFMpeGw6oRKuJnXYgf/f1ms/D7LE/ZUSNxnW7rZ/dbslQWYkoqFHGPaDBtaK4w=="], - - "shiki": ["shiki@4.3.1", "", { "dependencies": { "@shikijs/core": "4.3.1", "@shikijs/engine-javascript": "4.3.1", "@shikijs/engine-oniguruma": "4.3.1", "@shikijs/langs": "4.3.1", "@shikijs/themes": "4.3.1", "@shikijs/types": "4.3.1", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-oR+qDVi2OjX1tmDpyv+3KviX01KzO6Af+0NNnKnsp9491UEGz2YpxTuJboS/6VhYpTdqzmuJBuiTlrAWWJAssw=="], - - "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="], - - "sitemap": ["sitemap@9.0.1", "", { "dependencies": { "@types/node": "^24.9.2", "@types/sax": "^1.2.1", "arg": "^5.0.0", "sax": "^1.4.1" }, "bin": { "sitemap": "dist/esm/cli.js" } }, "sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ=="], - - "smol-toml": ["smol-toml@1.7.0", "", {}, "sha512-aqVvWoyO21L23mb+drl4RmMXbf6N7FdHjAhTRA9ZBL7apWBgfWC16KjrASI+1p9GAroljyMHj6fK67i0UiTNvQ=="], + "shiki": ["shiki@3.21.0", "", { "dependencies": { "@shikijs/core": "3.21.0", "@shikijs/engine-javascript": "3.21.0", "@shikijs/engine-oniguruma": "3.21.0", "@shikijs/langs": "3.21.0", "@shikijs/themes": "3.21.0", "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-N65B/3bqL/TI2crrXr+4UivctrAGEjmsib5rPMMPpFp1xAx/w03v8WZ9RDDFYteXoEgY7qZ4HGgl5KBIu1153w=="], "source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="], @@ -1049,37 +689,23 @@ "space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="], - "stream-replace-string": ["stream-replace-string@2.0.0", "", {}, "sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w=="], - - "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], - "stringify-entities": ["stringify-entities@4.0.4", "", { "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" } }, "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="], - "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - - "style-to-js": ["style-to-js@1.1.21", "", { "dependencies": { "style-to-object": "1.0.14" } }, "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ=="], + "style-to-js": ["style-to-js@1.1.17", "", { "dependencies": { "style-to-object": "1.0.9" } }, "sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA=="], - "style-to-object": ["style-to-object@1.0.14", "", { "dependencies": { "inline-style-parser": "0.2.7" } }, "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw=="], + "style-to-object": ["style-to-object@1.0.9", "", { "dependencies": { "inline-style-parser": "0.2.4" } }, "sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw=="], - "supports-color": ["supports-color@10.2.2", "", {}, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="], + "styled-jsx": ["styled-jsx@5.1.6", "", { "dependencies": { "client-only": "0.0.1" }, "peerDependencies": { "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" } }, "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA=="], - "svgo": ["svgo@4.0.2", "", { "dependencies": { "commander": "^11.1.0", "css-select": "^5.1.0", "css-tree": "^3.0.1", "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.1.1", "sax": "^1.5.0" }, "bin": "./bin/svgo.js" }, "sha512-ekx94z1rRc5LDi6oSUaeRnYhd0UOJxdtQCL2rF8xpWxD3TPAsISWOrxezqGovqS38GRZOdpDfvQe3ts6F7nsng=="], + "tailwind-merge": ["tailwind-merge@3.4.0", "", {}, "sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g=="], - "tailwind-merge": ["tailwind-merge@3.6.0", "", {}, "sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w=="], + "tailwindcss": ["tailwindcss@4.1.18", "", {}, "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw=="], - "tailwindcss": ["tailwindcss@4.3.3", "", {}, "sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ=="], + "tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="], - "tapable": ["tapable@2.3.3", "", {}, "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A=="], + "tinyexec": ["tinyexec@1.0.2", "", {}, "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg=="], - "tar": ["tar@7.5.22", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" } }, "sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA=="], - - "tiny-inflate": ["tiny-inflate@1.0.3", "", {}, "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="], - - "tinyclip": ["tinyclip@0.1.15", "", {}, "sha512-uo33abH+Ays0xYaDysoBt494Hb3hsEczMpcC0MwFl773pazORx4fmvKhclhR1wonUbB6vvpRsvVMwnhfqeMc+A=="], - - "tinyexec": ["tinyexec@1.2.4", "", {}, "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg=="], - - "tinyglobby": ["tinyglobby@0.2.17", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g=="], + "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], "trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="], @@ -1087,35 +713,13 @@ "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "typesafe-path": ["typesafe-path@0.2.2", "", {}, "sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA=="], - "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], - "typescript-auto-import-cache": ["typescript-auto-import-cache@0.3.6", "", { "dependencies": { "semver": "^7.3.8" } }, "sha512-RpuHXrknHdVdK7wv/8ug3Fr0WNsNi5l5aB8MYYuXhq2UH5lnEB1htJ1smhtD5VeCsGr2p8mUDtd83LCQDFVgjQ=="], - - "ufo": ["ufo@1.6.4", "", {}, "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA=="], - - "ultrahtml": ["ultrahtml@1.7.0", "", {}, "sha512-2xRd0VHoAQE4M+vF/DvFFB7pUV0ZxTW1TLi7lHQWnF/Sb5TPeEUV/l+hxcNnGO00ZXGnR0voCMmYRKQf+rvJ2g=="], - - "uncrypto": ["uncrypto@0.1.3", "", {}, "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q=="], - - "undici": ["undici@7.28.0", "", {}, "sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA=="], - - "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="], - - "unenv": ["unenv@2.0.0-rc.24", "", { "dependencies": { "pathe": "^2.0.3" } }, "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw=="], + "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], "unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", "devlop": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", "vfile": "^6.0.0" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="], - "unified-lint-rule": ["unified-lint-rule@3.0.1", "", { "dependencies": { "@types/unist": "^3.0.0", "trough": "^2.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-HxIeQOmwL19DGsxHXbeyzKHBsoSCFO7UtRVUvT2v61ptw/G+GbysWcrpHdfs5jqbIFDA11MoKngIhQK0BeTVjA=="], - - "unifont": ["unifont@0.7.4", "", { "dependencies": { "css-tree": "^3.1.0", "ofetch": "^1.5.1", "ohash": "^2.0.11" } }, "sha512-oHeis4/xl42HUIeHuNZRGEvxj5AaIKR+bHPNegRq5LV1gdc3jundpONbjglKpihmJf+dswygdMJn3eftGIMemg=="], - - "unist-util-find-after": ["unist-util-find-after@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ=="], - - "unist-util-is": ["unist-util-is@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g=="], - - "unist-util-modify-children": ["unist-util-modify-children@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "array-iterate": "^2.0.0" } }, "sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw=="], + "unist-util-is": ["unist-util-is@6.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw=="], "unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="], @@ -1125,164 +729,46 @@ "unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="], - "unist-util-visit": ["unist-util-visit@5.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="], + "unist-util-visit": ["unist-util-visit@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg=="], - "unist-util-visit-children": ["unist-util-visit-children@3.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA=="], + "unist-util-visit-parents": ["unist-util-visit-parents@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw=="], - "unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="], + "use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="], - "unstorage": ["unstorage@1.17.5", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^5.0.0", "destr": "^2.0.5", "h3": "^1.15.10", "lru-cache": "^11.2.7", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.3" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6 || ^7 || ^8", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1 || ^2 || ^3", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg=="], + "use-sidecar": ["use-sidecar@1.1.3", "", { "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ=="], - "vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="], + "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], - "vfile-location": ["vfile-location@5.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg=="], + "vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="], "vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], - "vite": ["vite@8.1.5", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.5", "postcss": "^8.5.17", "rolldown": "~1.1.5", "tinyglobby": "^0.2.17" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.3.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-7ULLwsCdYx/nRyrpiEwvqb5TFHrMVZyBt+rg/OAXT7rgj/z+DtTDyKFeLAdDkubDVDKD8jOsndmy7m55XcfUsw=="], - - "vitefu": ["vitefu@1.1.3", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["vite"] }, "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg=="], - - "volar-service-css": ["volar-service-css@0.0.71", "", { "dependencies": { "vscode-css-languageservice": "^6.3.0", "vscode-languageserver-textdocument": "^1.0.11", "vscode-uri": "^3.0.8" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-wRRFt9BpjMKCazcgOh67MSjUjiWUCAh99DyYSDIOTuxaRjEtDC7PpB0k1Y1wbJIW/pVtMUSVbpPo3UGSm0Byxw=="], - - "volar-service-emmet": ["volar-service-emmet@0.0.71", "", { "dependencies": { "@emmetio/css-parser": "^0.4.1", "@emmetio/html-matcher": "^1.3.0", "@vscode/emmet-helper": "^2.9.3", "vscode-uri": "^3.0.8" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-zqjzt6bN95e3CUstBm0PBFAJnrfz0ZAARka87fart46/gNCLLuP3Vujy8V/J8HEziTFLnfkgIASLFYPUhonJcA=="], - - "volar-service-html": ["volar-service-html@0.0.71", "", { "dependencies": { "vscode-html-languageservice": "^5.3.0", "vscode-languageserver-textdocument": "^1.0.11", "vscode-uri": "^3.0.8" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-e8tHPhgQ7ooLfudAEIku+kgd9pWkq3SSz8RbnQDI1+Eb8wbenkLGHqoirLqz5ORLV6wIMr2Iv08RWBG5eOcgpw=="], - - "volar-service-prettier": ["volar-service-prettier@0.0.71", "", { "dependencies": { "vscode-uri": "^3.0.8" }, "peerDependencies": { "@volar/language-service": "~2.4.0", "prettier": "^2.2 || ^3.0" }, "optionalPeers": ["@volar/language-service", "prettier"] }, "sha512-Rz7JVH3qD108UCdmIEiZvOBNljMt2nLFdbN8AXcDfn7xD9F5I2aCIsDVqBbXw21PsnxG0b7MfwtNF+zPS/NKUg=="], - - "volar-service-typescript": ["volar-service-typescript@0.0.71", "", { "dependencies": { "path-browserify": "^1.0.1", "semver": "^7.6.2", "typescript-auto-import-cache": "^0.3.5", "vscode-languageserver-textdocument": "^1.0.11", "vscode-nls": "^5.2.0", "vscode-uri": "^3.0.8" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-yTtM/BVT6hoyEYnDtaCyAtNhdNeS/mhTTABlBOdw3NNiRBUin3IznFJpgfjer4c6RYopiPjjQjc9VFhxVl1mLw=="], - - "volar-service-typescript-twoslash-queries": ["volar-service-typescript-twoslash-queries@0.0.71", "", { "dependencies": { "vscode-uri": "^3.0.8" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-9K2k72s4n7rV9s4bX0MyjbX9iBribvKZbBJKuEmTCZfeWJXs6Yh7bGpY4eoc7UufAjvpheBqwyZCOIPBvxCv0A=="], - - "volar-service-yaml": ["volar-service-yaml@0.0.71", "", { "dependencies": { "vscode-uri": "^3.0.8", "yaml-language-server": "~1.23.0" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-qYGWGuVpUTnZGu5P/CR4KLK4aIR8RrcVnmfZ2eRcj9q/I8VZCoC5yy9FtEvfNvnDp4MU17yhdJcvpQPIqhJS2Q=="], - - "vscode-css-languageservice": ["vscode-css-languageservice@6.3.10", "", { "dependencies": { "@vscode/l10n": "^0.0.18", "vscode-languageserver-textdocument": "^1.0.12", "vscode-languageserver-types": "3.17.5", "vscode-uri": "^3.1.0" } }, "sha512-eq5N9Er3fC4vA9zd9EFhyBG90wtCCuXgRSpAndaOgXMh1Wgep5lBgRIeDgjZBW9pa+332yC9+49cZMW8jcL3MA=="], - - "vscode-html-languageservice": ["vscode-html-languageservice@5.6.2", "", { "dependencies": { "@vscode/l10n": "^0.0.18", "vscode-languageserver-textdocument": "^1.0.12", "vscode-languageserver-types": "^3.17.5", "vscode-uri": "^3.1.0" } }, "sha512-ulCrSnFnfQ16YzvwnYUgEbUEl/ZG7u2eV27YhvLObSHKkb8fw1Z9cgsnUwjTEeDIdJDoTDTDpxuhQwoenoLNMg=="], - - "vscode-json-languageservice": ["vscode-json-languageservice@4.1.8", "", { "dependencies": { "jsonc-parser": "^3.0.0", "vscode-languageserver-textdocument": "^1.0.1", "vscode-languageserver-types": "^3.16.0", "vscode-nls": "^5.0.0", "vscode-uri": "^3.0.2" } }, "sha512-0vSpg6Xd9hfV+eZAaYN63xVVMOTmJ4GgHxXnkLCh+9RsQBkWKIghzLhW2B9ebfG+LQQg8uLtsQ2aUKjTgE+QOg=="], - - "vscode-jsonrpc": ["vscode-jsonrpc@8.2.0", "", {}, "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA=="], - - "vscode-languageserver": ["vscode-languageserver@9.0.1", "", { "dependencies": { "vscode-languageserver-protocol": "3.17.5" }, "bin": { "installServerIntoExtension": "bin/installServerIntoExtension" } }, "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g=="], - - "vscode-languageserver-protocol": ["vscode-languageserver-protocol@3.17.5", "", { "dependencies": { "vscode-jsonrpc": "8.2.0", "vscode-languageserver-types": "3.17.5" } }, "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg=="], - - "vscode-languageserver-textdocument": ["vscode-languageserver-textdocument@1.0.12", "", {}, "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA=="], - - "vscode-languageserver-types": ["vscode-languageserver-types@3.18.0", "", {}, "sha512-8TsGPNMIMiiBdkORgRSvLjuiEIiAFtO+KssmYWxQ+uSVvlf7RjK8YKCOjPzZ+YA04jXEV7+7LvkSmHkhpNS99g=="], - - "vscode-nls": ["vscode-nls@5.2.0", "", {}, "sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng=="], - - "vscode-uri": ["vscode-uri@3.1.0", "", {}, "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ=="], - - "web-namespaces": ["web-namespaces@2.0.1", "", {}, "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ=="], - - "whatwg-encoding": ["whatwg-encoding@3.1.1", "", { "dependencies": { "iconv-lite": "0.6.3" } }, "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ=="], - - "whatwg-mimetype": ["whatwg-mimetype@4.0.0", "", {}, "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg=="], - - "workerd": ["workerd@1.20260722.1", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20260722.1", "@cloudflare/workerd-darwin-arm64": "1.20260722.1", "@cloudflare/workerd-linux-64": "1.20260722.1", "@cloudflare/workerd-linux-arm64": "1.20260722.1", "@cloudflare/workerd-windows-64": "1.20260722.1" }, "bin": { "workerd": "bin/workerd" } }, "sha512-NycKuc1x2onvsRfGGpM093vRlLFU2zHDAM0+APpccfg4+gZxDGCH27RmdDvkeBuoZyYqgLo3oAfF6re4mvC3vQ=="], - - "wrangler": ["wrangler@4.114.0", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.5.0", "@cloudflare/unenv-preset": "2.16.1", "blake3-wasm": "2.1.5", "esbuild": "0.28.1", "miniflare": "4.20260722.0", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.24", "workerd": "1.20260722.1" }, "optionalDependencies": { "fsevents": "2.3.3" }, "peerDependencies": { "@cloudflare/workers-types": "^5.20260722.1" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "cf-wrangler": "bin/cf-wrangler.js", "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-M65P25t5UHA1TIJfgZXDcj+YzVobgKdRguM2QPz0xnxLFuOcuE3ErgllDht0iaho7MS4o0g/Bb4YK2+GT+bibg=="], - - "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], - - "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], - - "ws": ["ws@8.21.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g=="], - - "xxhash-wasm": ["xxhash-wasm@1.1.0", "", {}, "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA=="], - - "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], - - "yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], - - "yaml": ["yaml@2.8.3", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg=="], - - "yaml-language-server": ["yaml-language-server@1.23.0", "", { "dependencies": { "@vscode/l10n": "^0.0.18", "ajv": "^8.17.1", "ajv-draft-04": "^1.0.0", "ajv-i18n": "^4.2.0", "prettier": "^3.8.1", "request-light": "^0.5.7", "vscode-json-languageservice": "4.1.8", "vscode-languageserver": "^9.0.0", "vscode-languageserver-textdocument": "^1.0.1", "vscode-languageserver-types": "^3.16.0", "vscode-uri": "^3.0.2", "yaml": "2.8.3" }, "bin": { "yaml-language-server": "bin/yaml-language-server" } }, "sha512-3qVyCOexLCWw06PQa5kRPwvMWMZ/eZeCRWUvgD6a0OkqL/4iCnxy2WumbWifa937Uo5xhyWJ0uxlU39ljhNh7A=="], - - "yargs": ["yargs@17.7.3", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g=="], - - "yargs-parser": ["yargs-parser@22.0.0", "", {}, "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw=="], - - "yauzl": ["yauzl@2.10.0", "", { "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } }, "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g=="], - - "yocto-queue": ["yocto-queue@1.2.2", "", {}, "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ=="], - - "youch": ["youch@4.1.0-beta.10", "", { "dependencies": { "@poppinss/colors": "^4.1.5", "@poppinss/dumper": "^0.6.4", "@speed-highlight/core": "^1.2.7", "cookie": "^1.0.2", "youch-core": "^0.3.3" } }, "sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ=="], - - "youch-core": ["youch-core@0.3.3", "", { "dependencies": { "@poppinss/exception": "^1.2.2", "error-stack-parser-es": "^1.0.5" } }, "sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA=="], - - "zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="], + "zod": ["zod@4.3.5", "", {}, "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g=="], "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], - "@cspotcode/source-map-support/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.9", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ=="], + "@radix-ui/react-collection/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], - "@iconify/tools/svgo": ["svgo@3.3.4", "", { "dependencies": { "commander": "^7.2.0", "css-select": "^5.1.0", "css-tree": "^2.3.1", "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.0.0", "sax": "^1.5.0" }, "bin": "./bin/svgo" }, "sha512-GsNRis4e8jxn2Y9ENz/8lbJ93CstG8svtMnuRaHbiF2LTJ5tK0/q3t/URPq9Zc7zVWBJnNnJMIp6bevK7bSmNg=="], + "@radix-ui/react-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], - "@img/sharp-wasm32/@emnapi/runtime": ["@emnapi/runtime@1.11.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="], + "@radix-ui/react-popover/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], - "@mdx-js/mdx/estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], + "@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], - "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.11.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" }, "bundled": true }, "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ=="], + "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.8.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg=="], - "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.11.3", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="], + "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="], - "@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.2", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA=="], + "@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="], - "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.6", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" }, "bundled": true }, "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg=="], + "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.1", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" }, "bundled": true }, "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A=="], - "@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.3", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="], + "@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@vscode/emmet-helper/jsonc-parser": ["jsonc-parser@2.3.1", "", {}, "sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg=="], - - "anymatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], - - "astro/@clack/prompts": ["@clack/prompts@1.7.0", "", { "dependencies": { "@clack/core": "1.4.3", "fast-string-width": "^3.0.2", "fast-wrap-ansi": "^0.2.0", "sisteransi": "^1.0.5" } }, "sha512-y7/yvZ2TPAnR9+jnc00klvNNLkJiXFFrQA/hlLCcxA9a2A4zQIOimyFQ9XfwYKiGD1fb5GY8vbKIIgO8d5Tb2A=="], - - "csso/css-tree": ["css-tree@2.2.1", "", { "dependencies": { "mdn-data": "2.0.28", "source-map-js": "^1.0.1" } }, "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA=="], - - "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], - - "estree-util-build-jsx/estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], - - "htmlparser2/entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], - - "mlly/pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="], + "next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="], "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], - - "parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], - - "unstorage/chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], - - "vscode-css-languageservice/vscode-languageserver-types": ["vscode-languageserver-types@3.17.5", "", {}, "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg=="], - - "vscode-languageserver-protocol/vscode-languageserver-types": ["vscode-languageserver-types@3.17.5", "", {}, "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg=="], - - "yaml-language-server/request-light": ["request-light@0.5.8", "", {}, "sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg=="], - - "yargs/yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], - - "youch/cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="], - - "@iconify/tools/svgo/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="], - - "@iconify/tools/svgo/css-tree": ["css-tree@2.3.1", "", { "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" } }, "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw=="], - - "astro/@clack/prompts/@clack/core": ["@clack/core@1.4.3", "", { "dependencies": { "fast-wrap-ansi": "^0.2.0", "sisteransi": "^1.0.5" } }, "sha512-/kr3UWNtdJfxZtPgDqUOmG2pvwlmcLGheex5yiZKdwbzZJxhV+HMNR9QNmyY5cGwTNV6LrR7Jtp+KjhUAP1qBQ=="], - - "csso/css-tree/mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="], - - "mlly/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], - - "unstorage/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], - - "@iconify/tools/svgo/css-tree/mdn-data": ["mdn-data@2.0.30", "", {}, "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA=="], } } diff --git a/docs/content/docs/index.mdx b/docs/content/docs/index.mdx new file mode 100644 index 0000000..89b1976 --- /dev/null +++ b/docs/content/docs/index.mdx @@ -0,0 +1,116 @@ +--- +title: dotfiles +--- + + +## install +This dotfiles repository is designed to be installed at `~/Codes/dotfiles`. + +Review the contents of the script before running it: +[https://dot.umeru.ma/install](https://dot.umeru.ma/install) + +Open Terminal.app, and run: + +``` +bash -c "$(curl -fsSL https://dot.umeru.ma/install)" +``` +This will clone the repository to `~/Codes/dotfiles` and set up your dotfiles. + +Notes on bash and curl options: + +bash: +- `-c`: Execute the given string as a bash command (e.g., `bash -c "echo hello"` outputs `hello`). + +curl: +- `-f` (`--fail`): Fail silently on server errors (no output, exit non-zero). +- `-s` (`--silent`): Silent mode — do not show progress meter or error messages. +- `-S` (`--show-error`): When used with `-s`, show error messages on failure (since `-s` alone is fully silent). +- `-L` (`--location`): Follow HTTP redirects automatically. + +## jump to dotfiles + +In Terminal, you can quickly jump to the dotfiles directory by running: +``` +dot +``` + +.zshenv & .zshrc contains: +``` +# on .zshenv +export DOTFILES="$HOME/Codes/dotfiles" + +# on .zshrc +alias dot='cd $DOTFILES' +``` + +## Deploy dotfiles + +To deploy your dotfiles to your home directory, simply run: + +``` +dot && just deploy +``` + +### Pre-create subdirectories + +Before deploying with GNU Stow, this repository can automatically create any required subdirectories in your home directory, based on a plain text list in `.deploy_subdir`. + +**How it works:** +- Reads `.deploy_subdir` line by line + - Ignores blank lines and lines starting with `#` + - Trims whitespace +- Runs `mkdir -p "$HOME/<path>"` for each valid line +- Then deploys `home/` using Stow + +This process runs automatically as part of `just deploy` via the `prepare-subdirs` recipe. + +#### Usage +1. Add the directories you need to `.deploy_subdir` (one path per line): + + ``` + # editors + .config/micro + .config/nvim + + # tools + .local/share/fzf + ``` + +2. Deploy your dotfiles: + + ``` + just deploy + ``` + +This ensures all listed directories (e.g. `~/.config/micro`) exist before Stow creates symlinks, making deployment more reliable. + +**Notes:** +- Implementation is in the `justfile` under the `prepare-subdirs` recipe +- Input is tolerant of whitespace and comments + +## macOS defaults +To update macOS defaults setting, run: + +``` +dot && just defaults +``` + +## macOS Terminal theme +To apply theme for macOS Terminal, run: +``` +dot && just theme +``` + +then looks like this: + +<img alt="" src="https://i.gyazo.com/e6b46b2e0332ecbbf1e2fcf859533f3c.jpg"/> + +## tech stack + +- [just](https://github.com/casey/just#readme) as command runner +- [sheldon](https://github.com/rossmacarthur/sheldon#readme) as zsh plugin manager +- [Homebrew](https://docs.brew.sh/Manpage) as package manager + +## website + +[dot.umeru.ma](https://dot.umeru.ma) diff --git a/docs/src/content/docs/lean-zsh.md b/docs/content/docs/lean-zsh.md similarity index 69% rename from docs/src/content/docs/lean-zsh.md rename to docs/content/docs/lean-zsh.md index cc18d93..ea76f83 100644 --- a/docs/src/content/docs/lean-zsh.md +++ b/docs/content/docs/lean-zsh.md @@ -1,8 +1,5 @@ --- title: Lean zsh -description: この lean な zsh 設定の参考資料とインスピレーション元。 -sidebar: - order: 7 --- reading: diff --git a/docs/content/docs/meta.json b/docs/content/docs/meta.json new file mode 100644 index 0000000..bce81fb --- /dev/null +++ b/docs/content/docs/meta.json @@ -0,0 +1,11 @@ +{ + "title": ".um", + "root": true, + "href": "/", + "pages": [ + "---Introduction---", + "index", + "---etc---", + "..." + ] +} \ No newline at end of file diff --git a/docs/src/content/docs/setup-hard/index.md b/docs/content/docs/setup-hard.md similarity index 79% rename from docs/src/content/docs/setup-hard/index.md rename to docs/content/docs/setup-hard.md index 11e5d4f..8583098 100644 --- a/docs/src/content/docs/setup-hard/index.md +++ b/docs/content/docs/setup-hard.md @@ -1,16 +1,11 @@ --- title: Setup Hardware -description: このセットアップで使っているキーボード・マウス・オーディオ機材。 -sidebar: - order: 6 --- ## keyboard: [HHKB ANSI layout](https://hhkb.io/layout/) -IME 切り替えの設定(macOS: Karabiner / Windows: kanata)は [IME Switching](/setup-hard/ime-switching/) を参照。 - <img width="320" alt="" src="https://i.gyazo.com/1eaad11921cce165baed6c8b222f77cc.jpg"/> ## mouse: diff --git a/docs/lib/layout.shared.tsx b/docs/lib/layout.shared.tsx new file mode 100644 index 0000000..ee20148 --- /dev/null +++ b/docs/lib/layout.shared.tsx @@ -0,0 +1,31 @@ +import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared'; + +/** + * Shared layout configurations + * + * you can customise layouts individually from: + * Home Layout: app/(home)/layout.tsx + * Docs Layout: app/docs/layout.tsx + */ +export function baseOptions(): BaseLayoutProps { + return { + nav: { + title: ( + <> + <svg + width="24" + height="24" + xmlns="http://www.w3.org/2000/svg" + aria-label="Logo" + > + <circle cx={12} cy={12} r={12} fill="currentColor" /> + </svg> + dot.umeru.ma + </> + ), + }, + // see https://fumadocs.dev/docs/ui/navigation/links + links: [], + githubUrl: 'https://github.com/umeruma/dotfiles', + }; +} diff --git a/docs/lib/source.ts b/docs/lib/source.ts new file mode 100644 index 0000000..f5be714 --- /dev/null +++ b/docs/lib/source.ts @@ -0,0 +1,27 @@ +import { docs } from 'fumadocs-mdx:collections/server'; +import { type InferPageType, loader } from 'fumadocs-core/source'; +import { lucideIconsPlugin } from 'fumadocs-core/source/lucide-icons'; + +// See https://fumadocs.dev/docs/headless/source-api for more info +export const source = loader({ + baseUrl: '/', + source: docs.toFumadocsSource(), + plugins: [lucideIconsPlugin()], +}); + +export function getPageImage(page: InferPageType<typeof source>) { + const segments = [...page.slugs, 'image.png']; + + return { + segments, + url: `/og/docs/${segments.join('/')}`, + }; +} + +export async function getLLMText(page: InferPageType<typeof source>) { + const processed = await page.data.getText('processed'); + + return `# ${page.data.title} (${page.url}) + +${processed}`; +} diff --git a/docs/mdx-components.tsx b/docs/mdx-components.tsx new file mode 100644 index 0000000..d3fbb13 --- /dev/null +++ b/docs/mdx-components.tsx @@ -0,0 +1,10 @@ +import defaultMdxComponents from 'fumadocs-ui/mdx'; +import type { MDXComponents } from 'mdx/types'; + +// use this function to get MDX components, you will need it for rendering MDX +export function getMDXComponents(components?: MDXComponents): MDXComponents { + return { + ...defaultMdxComponents, + ...components, + }; +} diff --git a/docs/mise.toml b/docs/mise.toml index 7183495..f6db502 100644 --- a/docs/mise.toml +++ b/docs/mise.toml @@ -1,2 +1,2 @@ [tools] -bun = "1.3.14" +bun = "1.3.5" diff --git a/docs/next.config.mjs b/docs/next.config.mjs new file mode 100644 index 0000000..457dcf2 --- /dev/null +++ b/docs/next.config.mjs @@ -0,0 +1,10 @@ +import { createMDX } from 'fumadocs-mdx/next'; + +const withMDX = createMDX(); + +/** @type {import('next').NextConfig} */ +const config = { + reactStrictMode: true, +}; + +export default withMDX(config); diff --git a/docs/nimbus.json b/docs/nimbus.json deleted file mode 100644 index ac2f611..0000000 --- a/docs/nimbus.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "https://nimbus-docs.com/schema/nimbus.json", - "version": "0.6.3", - "templatesTag": "templates-v0.6.3", - "variant": "starter", - "registry": "https://nimbus-docs.com/registry", - "install": { - "root": "src", - "aliases": { - "@/*": "src/*" - } - }, - "components": [] -} diff --git a/docs/package.json b/docs/package.json index 4bfc074..b30e256 100644 --- a/docs/package.json +++ b/docs/package.json @@ -2,38 +2,33 @@ "name": "docs", "version": "0.0.0", "private": true, - "type": "module", - "packageManager": "bun@1.3.14", "scripts": { - "dev": "astro dev", - "build": "astro build", - "preview": "astro preview", - "typecheck": "astro check", - "lint:docs": "nimbus-docs lint", - "lint:docs:fix": "nimbus-docs lint --fix", - "prepreview:cf": "astro build", - "preview:cf": "wrangler dev", - "predeploy": "astro check && astro build", - "deploy": "wrangler deploy" + "prebuild": "bun scripts/copy-files.mjs", + "build": "next build", + "dev": "next dev --turbo", + "start": "next start", + "postinstall": "fumadocs-mdx", + "lint": "biome check", + "format": "biome format --write" }, "dependencies": { - "@fontsource-variable/inter": "^5.2.8", - "@fontsource-variable/jetbrains-mono": "^5.2.8", - "@iconify-json/ph": "^1.2.0", - "astro": "^7.0.0", - "astro-icon": "^1.1.0", - "astro-og-canvas": "^0.13.0", - "canvaskit-wasm": "^0.41.1", - "clsx": "^2.1.1", - "@cloudflare/nimbus-docs": "^0.8.1", - "tailwind-merge": "^3.5.0" + "next": "16.1.5", + "react": "^19.2.3", + "react-dom": "^19.2.3", + "lucide-react": "^0.562.0", + "fumadocs-ui": "16.4.5", + "fumadocs-core": "16.4.5", + "fumadocs-mdx": "14.2.4" }, "devDependencies": { - "@astrojs/check": "^0.9.8", - "@tailwindcss/vite": "^4.1.4", - "pagefind": "^1.5.2", - "tailwindcss": "^4.1.4", - "typescript": "^5.8.3", - "wrangler": "^4.95.0" + "@types/node": "25.0.3", + "@types/react": "^19.2.7", + "@types/react-dom": "^19.2.3", + "typescript": "^5.9.3", + "@types/mdx": "^2.0.13", + "@tailwindcss/postcss": "^4.1.18", + "tailwindcss": "^4.1.18", + "postcss": "^8.5.6", + "@biomejs/biome": "^2.3.11" } } diff --git a/docs/postcss.config.mjs b/docs/postcss.config.mjs new file mode 100644 index 0000000..a34a3d5 --- /dev/null +++ b/docs/postcss.config.mjs @@ -0,0 +1,5 @@ +export default { + plugins: { + '@tailwindcss/postcss': {}, + }, +}; diff --git a/docs/public/_headers b/docs/public/_headers deleted file mode 100644 index 50759e4..0000000 --- a/docs/public/_headers +++ /dev/null @@ -1,15 +0,0 @@ -# Cloudflare Workers static-asset headers. - -# Astro emits content-hashed assets under /_astro/* — safe to cache forever. -/_astro/* - Cache-Control: public, max-age=31536000, immutable - -# Serve the installers as plain text (so `curl`/`irm` and browsers render them -# instead of downloading), always revalidated so a new script ships instantly. -/install - Content-Type: text/plain; charset=utf-8 - Cache-Control: public, max-age=0, must-revalidate - -/install-win - Content-Type: text/plain; charset=utf-8 - Cache-Control: public, max-age=0, must-revalidate diff --git a/docs/public/favicon.ico b/docs/public/favicon.ico deleted file mode 100644 index 5ba3ef4..0000000 Binary files a/docs/public/favicon.ico and /dev/null differ diff --git a/docs/public/fonts/Inter-Bold.ttf b/docs/public/fonts/Inter-Bold.ttf deleted file mode 100644 index 9fb9b75..0000000 Binary files a/docs/public/fonts/Inter-Bold.ttf and /dev/null differ diff --git a/docs/public/fonts/NotoSansJP-Bold.otf b/docs/public/fonts/NotoSansJP-Bold.otf deleted file mode 100644 index 4026277..0000000 Binary files a/docs/public/fonts/NotoSansJP-Bold.otf and /dev/null differ diff --git a/docs/scripts/copy-files.mjs b/docs/scripts/copy-files.mjs new file mode 100644 index 0000000..ecc1eef --- /dev/null +++ b/docs/scripts/copy-files.mjs @@ -0,0 +1,22 @@ +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const websiteRoot = path.resolve(__dirname, ".."); +const repoRoot = path.resolve(websiteRoot, ".."); + +const src = path.join(repoRoot, "install"); +const dest = path.join(websiteRoot, "public", "install"); + +/** + * Copy install script to website public directory + */ +fs.mkdirSync(path.dirname(dest), { recursive: true }); +if (!fs.existsSync(src)) { + console.error("install not found:", src); + process.exit(1); +} +fs.copyFileSync(src, dest); + +console.log("copied:", src, "->", dest); \ No newline at end of file diff --git a/docs/source.config.ts b/docs/source.config.ts new file mode 100644 index 0000000..8aecd54 --- /dev/null +++ b/docs/source.config.ts @@ -0,0 +1,27 @@ +import { + defineConfig, + defineDocs, + frontmatterSchema, + metaSchema, +} from 'fumadocs-mdx/config'; + +// You can customise Zod schemas for frontmatter and `meta.json` here +// see https://fumadocs.dev/docs/mdx/collections +export const docs = defineDocs({ + docs: { + schema: frontmatterSchema, + postprocess: { + includeProcessedMarkdown: true, + }, + }, + // dir: 'content/docs', + meta: { + schema: metaSchema, + }, +}); + +export default defineConfig({ + mdxOptions: { + // MDX options + }, +}); diff --git a/docs/src/components.ts b/docs/src/components.ts deleted file mode 100644 index a3434fc..0000000 --- a/docs/src/components.ts +++ /dev/null @@ -1,25 +0,0 @@ -/** - * MDX globals registry — components available inside MDX without `import`. - * Wired via `<Content components={components} />` in `[...slug].astro`. - * Add new components here as you build (or install) them. - */ - -import { Aside } from "./components/ui/aside"; -import Render from "./components/Render.astro"; -import { Card } from "./components/ui/card"; -import { CardGrid } from "./components/ui/card-grid"; -import { PackageManagers } from "./components/ui/package-managers"; -import { Step, Steps } from "./components/ui/steps"; -import { Tabs, TabItem } from "./components/ui/tabs"; - -export const components = { - Aside, - Card, - CardGrid, - PackageManagers, - Render, - Step, - Steps, - TabItem, - Tabs, -}; diff --git a/docs/src/components/AgentDirective.astro b/docs/src/components/AgentDirective.astro deleted file mode 100644 index c2617df..0000000 --- a/docs/src/components/AgentDirective.astro +++ /dev/null @@ -1,16 +0,0 @@ ---- -interface Props { - /** Absolute or site-relative URL for this page's markdown version. */ - markdownUrl: string; - /** Absolute or site-relative URL for the top-level llms.txt index. */ - llmsUrl: string; -} - -const { markdownUrl, llmsUrl } = Astro.props; ---- - -<aside class="sr-only" data-ai-agent-directive> - This page is available in Markdown format. Markdown is recommended for AI - consumption. See <a href={markdownUrl}>{markdownUrl}</a> for this page, or - <a href={llmsUrl}>{llmsUrl}</a> for the full documentation index. -</aside> diff --git a/docs/src/components/Header.astro b/docs/src/components/Header.astro deleted file mode 100644 index e06b861..0000000 --- a/docs/src/components/Header.astro +++ /dev/null @@ -1,93 +0,0 @@ ---- -import { Icon } from "astro-icon/components"; -import { Button } from "./ui/button"; -import { LinkButton } from "./ui/link-button"; -import { ThemeToggle } from "./ui/theme-toggle"; -import { SearchTrigger } from "./ui/search"; -import { config } from "virtual:nimbus/config"; -import { getSidebarSections } from "@cloudflare/nimbus-docs"; - -interface Props { - /** Astro collection id for the current page, forwarded from DocsLayout. */ - collection?: string; - /** Astro entry id for the current page, forwarded from DocsLayout. */ - entryId?: string; - /** - * Whether the page has a sidebar to open. When `false`, the mobile - * menu button is hidden — pages that opted out via `sidebar: false` - * shouldn't show a button that opens an empty dialog. Default `true`. - */ - showSidebar?: boolean; -} - -// `entryId` is part of Props as a forward-compat hook (the version-switcher -// recipe reads it) but the base Header doesn't use it — leave it off the -// destructure to avoid an unused-var warning. -const { collection, showSidebar = true } = Astro.props; - -// Normalize trailing slash so isActive matches sidebar hrefs. -const currentSlug = Astro.url.pathname.replace(/\/$/, "") || "/"; -const sections = await getSidebarSections(currentSlug, { collection }); -const showSections = sections.length >= 2; ---- - -<header class="sticky top-0 z-30 border-b border-border bg-card/80 backdrop-blur-lg"> - <div class="mx-auto flex items-center justify-between h-14 px-4 lg:px-6"> - <div class="flex items-center gap-3"> - <a href="/" class="group"> - <span class="font-semibold text-sm text-foreground group-hover:text-primary transition-colors"> - {config.title} - </span> - </a> - - {showSections && ( - <nav aria-label="Sections" class="hidden md:flex items-center gap-1 ml-4 pl-4 border-l border-border h-6"> - {sections.map((section) => ( - <a - href={section.href} - aria-current={section.isActive ? "page" : undefined} - class:list={[ - "px-2 py-1 rounded-md text-[0.8125rem] font-medium no-underline transition-colors", - section.isActive - ? "text-foreground bg-accent" - : "text-muted-foreground hover:text-foreground hover:bg-accent/60", - ]} - > - {section.label} - </a> - ))} - </nav> - )} - </div> - - <div class="flex items-center gap-2"> - {config.search !== false && <SearchTrigger />} - {config.github && ( - <LinkButton - href={config.github} - variant="minimal" - shape="square" - size="sm" - aria-label="GitHub" - target="_blank" - rel="noopener" - class="text-muted-foreground" - > - <Icon name="ph:github-logo" class="w-4 h-4" /> - </LinkButton> - )} - <ThemeToggle /> - {showSidebar && ( - <Button - variant="ghost" - shape="square" - size="sm" - icon="ph:list" - aria-label="Open navigation" - data-menu-btn - class="lg:hidden text-muted-foreground" - /> - )} - </div> - </div> -</header> diff --git a/docs/src/components/Render.astro b/docs/src/components/Render.astro deleted file mode 100644 index 4ec3eef..0000000 --- a/docs/src/components/Render.astro +++ /dev/null @@ -1,106 +0,0 @@ ---- -/** - * Render — include a reusable partial in any docs page. - * - * <Render file="quickstart" /> - * <Render file="workers/setup" params={{ runtime: "node" }} /> - * - * Partials live in `src/content/partials/` as MDX. Declare params in - * partial frontmatter (`params: [runtime, version?]`); required params - * fail at build time, optional use a `?` suffix. - */ -import { getCollection, getEntry, render } from "astro:content"; -import { components } from "../components"; - -interface Props { - /** Partial ID — path relative to src/content/partials/ without extension. */ - file: string; - /** Parameters passed to the partial as props. */ - params?: Record<string, unknown>; -} - -const { file, params } = Astro.props; -const page = Astro.url.pathname; -const partial = await getEntry("partials", file); - -if (!partial) { - const allPartials = await getCollection("partials"); - const partialIds = allPartials.map((p) => p.id); - const hint = closest(file, partialIds); - const shortList = partialIds.sort().slice(0, 10).join(", "); - const tail = - partialIds.length > 10 - ? ` (and ${partialIds.length - 10} more)` - : partialIds.length === 0 - ? "none" - : ""; - throw new Error( - `[Render] Partial "${file}" not found, included on "${page}".` + - (hint ? ` Did you mean "${hint}"?` : "") + - ` Available: ${shortList}${tail}`, - ); -} - -const declaredParams = partial.data.params; -if (declaredParams) { - const required = declaredParams.filter((param: string) => !param.endsWith("?")); - const optional = declaredParams.filter((param: string) => param.endsWith("?")); - const allNames = [...required, ...optional.map((param: string) => param.slice(0, -1))]; - const received = Object.keys(params ?? {}); - - const missing = required.filter((param: string) => !received.includes(param)); - if (missing.length > 0) { - throw new Error( - `[Render] Missing required params ${JSON.stringify(missing)} for "${file}" on "${page}". ` + - `Expected: ${JSON.stringify(declaredParams)}, received: ${JSON.stringify(received)}`, - ); - } - - const unexpected = received.filter((param) => !allNames.includes(param)); - if (unexpected.length > 0) { - const unexpectedHints = unexpected - .map((u) => { - const h = closest(u, allNames); - return h ? `"${u}" (did you mean "${h}"?)` : `"${u}"`; - }) - .join(", "); - throw new Error( - `[Render] Unexpected params ${unexpectedHints} for "${file}" on "${page}". ` + - `Declared: ${JSON.stringify(declaredParams)}`, - ); - } -} - -const { Content } = await render(partial); - -/** Levenshtein distance — inlined to keep this component dep-free. */ -function distance(a: string, b: string): number { - if (a === b) return 0; - if (!a.length) return b.length; - if (!b.length) return a.length; - const v0 = new Array<number>(b.length + 1); - const v1 = new Array<number>(b.length + 1); - for (let i = 0; i <= b.length; i++) v0[i] = i; - for (let i = 0; i < a.length; i++) { - v1[0] = i + 1; - for (let j = 0; j < b.length; j++) { - const cost = a[i] === b[j] ? 0 : 1; - v1[j + 1] = Math.min(v1[j] + 1, v0[j + 1] + 1, v0[j] + cost); - } - for (let j = 0; j <= b.length; j++) v0[j] = v1[j]; - } - return v1[b.length]; -} - -function closest(target: string, candidates: string[], maxDist = 3): string | null { - const t = target.toLowerCase(); - let best: { name: string; dist: number } | null = null; - for (const c of candidates) { - const d = distance(t, c.toLowerCase()); - if (d <= maxDist && (!best || d < best.dist)) best = { name: c, dist: d }; - } - return best?.name ?? null; -} ---- - -<Content components={components} {...(params ?? {})} /> diff --git a/docs/src/components/ui/aside/Aside.astro b/docs/src/components/ui/aside/Aside.astro deleted file mode 100644 index 23ac082..0000000 --- a/docs/src/components/ui/aside/Aside.astro +++ /dev/null @@ -1,76 +0,0 @@ ---- -import { Icon } from "astro-icon/components"; -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; - -interface Props extends HTMLAttributes<"aside"> { - // Keeps `type` (not `variant`) for Starlight compatibility — Starlight's <Aside> uses `type`. - type?: "note" | "tip" | "caution" | "danger"; - title?: string; -} - -const { type = "note", title, class: className, ...attrs } = Astro.props; - -const config: Record<string, { label: string; color: string; tint: string }> = { - note: { label: "Note", color: "var(--nb-info)", tint: "var(--nb-info-muted)" }, - tip: { label: "Tip", color: "var(--nb-success)", tint: "var(--nb-success-muted)" }, - caution: { label: "Caution", color: "var(--nb-warning)", tint: "var(--nb-warning-muted)" }, - danger: { label: "Danger", color: "var(--nb-danger)", tint: "var(--nb-danger-muted)" }, -}; - -const c = config[type] ?? config.note; -const displayTitle = title ?? c.label; ---- - -<aside - role="note" - aria-label={displayTitle} - class={cn("aside-card flex items-start gap-3 rounded-lg px-4 py-3 my-4", className)} - style={`--_c: ${c.color}; --_t: ${c.tint};`} - {...attrs} -> - <span class="shrink-0 flex items-center h-[1.375em]" aria-hidden="true"> - {type === "note" && <Icon name="ph:info" class="w-[1em] h-[1em]" />} - {type === "tip" && <Icon name="ph:lightbulb" class="w-[1em] h-[1em]" />} - {type === "caution" && <Icon name="ph:warning" class="w-[1em] h-[1em]" />} - {type === "danger" && <Icon name="ph:warning-circle" class="w-[1em] h-[1em]" />} - </span> - <div class="flex min-w-0 flex-1 flex-col gap-0.5"> - <p class="m-0 text-base font-semibold leading-snug">{displayTitle}</p> - <div class="aside-card-body text-sm leading-normal"> - <slot /> - </div> - </div> -</aside> - -<style> - .aside-card { - border: 1px solid color-mix(in oklch, var(--_c) 25%, transparent); - background: var(--_t); - } - - /* Icon + title stay in semantic color; body text stays readable */ - .aside-card > :global(:first-child) { color: var(--_c); } - .aside-card > :global(:last-child) > :global(:first-child) { color: var(--_c); } - .aside-card-body { color: var(--nb-foreground); } - - .aside-card-body :global(p) { margin: 0; } - .aside-card-body :global(p + p) { margin-top: 0.375rem; } - .aside-card-body :global(a) { text-decoration: underline; text-underline-offset: 2px; } - - /* Inline code only — exclude code inside Expressive Code pre blocks */ - .aside-card-body :global(code:not(:where(pre *))) { - font-family: var(--nb-font-mono); - font-size: 0.8125em; - background: color-mix(in oklch, var(--_c) 10%, transparent); - border: 1px solid color-mix(in oklch, var(--_c) 15%, transparent); - border-radius: 0.25rem; - padding: 0.0625rem 0.3125rem; - } - .aside-card-body :global(strong) { font-weight: 600; color: inherit; } - - /* Shiki code blocks inside Asides */ - .aside-card-body :global(.astro-code) { - margin: 0.75rem 0; - } -</style> diff --git a/docs/src/components/ui/aside/index.ts b/docs/src/components/ui/aside/index.ts deleted file mode 100644 index 816ef78..0000000 --- a/docs/src/components/ui/aside/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as Aside } from "./Aside.astro"; diff --git a/docs/src/components/ui/badge/Badge.astro b/docs/src/components/ui/badge/Badge.astro deleted file mode 100644 index d6c5f56..0000000 --- a/docs/src/components/ui/badge/Badge.astro +++ /dev/null @@ -1,43 +0,0 @@ ---- -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; - -interface Props extends HTMLAttributes<"span"> { - /** Badge text. When omitted, slotted children render instead. */ - text?: string; - variant?: "default" | "info" | "note" | "success" | "tip" | "warning" | "caution" | "danger"; - size?: "small" | "medium" | "large"; -} - -const { text, variant = "default", size = "small", class: className, ...attrs } = Astro.props; - -// note→info, tip→success, caution→warning: variant aliases -const variantClass: Record<string, string> = { - default: "bg-accent text-muted-foreground", - info: "bg-info-muted text-info", - note: "bg-info-muted text-info", - success: "bg-success-muted text-success", - tip: "bg-success-muted text-success", - warning: "bg-warning-muted text-warning", - caution: "bg-warning-muted text-warning", - danger: "bg-danger-muted text-danger", -}; - -const sizeClass: Record<string, string> = { - small: "px-2 py-0.5 text-xs", - medium: "px-2.5 py-0.5 text-[0.8125rem]", - large: "px-3 py-1 text-sm", -}; ---- - -<span - class={cn( - "inline-flex items-center rounded-full font-medium whitespace-nowrap leading-none", - variantClass[variant] ?? variantClass.default, - sizeClass[size] ?? sizeClass.small, - className, - )} - {...attrs} -> - {text ?? <slot />} -</span> diff --git a/docs/src/components/ui/badge/index.ts b/docs/src/components/ui/badge/index.ts deleted file mode 100644 index 2a0ea5d..0000000 --- a/docs/src/components/ui/badge/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as Badge } from "./Badge.astro"; diff --git a/docs/src/components/ui/banner/Banner.astro b/docs/src/components/ui/banner/Banner.astro deleted file mode 100644 index 924c32e..0000000 --- a/docs/src/components/ui/banner/Banner.astro +++ /dev/null @@ -1,83 +0,0 @@ ---- -/** - * Banner — announcement strip. Pass `dismissible: { id, days? }` to - * show a close button that persists to localStorage. - */ -import { Icon } from "astro-icon/components"; -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; - -interface Props extends HTMLAttributes<"div"> { - content: string; - variant?: "note" | "tip" | "caution" | "danger"; - dismissible?: { id: string; days?: number }; -} - -const { content, variant = "note", dismissible, class: className, ...attrs } = Astro.props; - -function sanitizeBannerHtml(value: string): string { - return value - .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "") - .replace(/\s+on[a-z]+\s*=\s*("[^"]*"|'[^']*'|[^\s>]+)/gi, "") - .replace(/\s+(href|src)\s*=\s*(["'])\s*javascript:[\s\S]*?\2/gi, ""); -} - -const config: Record<string, { color: string; tint: string }> = { - note: { color: "var(--nb-info)", tint: "var(--nb-info-muted)" }, - tip: { color: "var(--nb-success)", tint: "var(--nb-success-muted)" }, - caution: { color: "var(--nb-warning)", tint: "var(--nb-warning-muted)" }, - danger: { color: "var(--nb-danger)", tint: "var(--nb-danger-muted)" }, -}; - -const c = config[variant] ?? config.note; -const safeContent = sanitizeBannerHtml(content); ---- - -<div - role={variant === "danger" || variant === "caution" ? "alert" : "status"} - class={cn("banner-card my-4 flex w-full items-start gap-3 rounded-lg px-4 py-3 text-sm leading-normal text-foreground", className)} - style={`--_c: ${c.color}; --_t: ${c.tint};`} - {...(dismissible - ? { "data-nb-banner-dismiss": dismissible.id, "data-nb-banner-days": dismissible.days } - : {})} - {...attrs} -> - <div class="banner-card-body min-w-0 flex-1"> - <Fragment set:html={safeContent} /> - </div> - {dismissible && ( - <button - type="button" - data-nb-banner-close - class="-my-1 -mr-2 flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-current opacity-60 transition-[background-color,opacity] hover:bg-card/60 hover:opacity-100" - aria-label="Dismiss banner" - > - <Icon name="ph:x" class="w-3.5 h-3.5" /> - </button> - )} -</div> - -<script> - import "./banner.client"; -</script> - -<style> - .banner-card { - border: 1px solid color-mix(in oklch, var(--_c) 25%, transparent); - background: var(--_t); - } - - .banner-card-body { min-width: 0; overflow-wrap: break-word; } - .banner-card-body :global(p) { margin: 0; } - .banner-card-body :global(p + p) { margin-top: 0.375rem; } - .banner-card-body :global(a) { text-decoration: underline; text-underline-offset: 2px; } - - .banner-card-body :global(code:not(:where(pre *))) { - font-family: var(--nb-font-mono); - font-size: 0.8125em; - background: color-mix(in oklch, var(--_c) 10%, transparent); - border: 1px solid color-mix(in oklch, var(--_c) 15%, transparent); - border-radius: 0.25rem; - padding: 0.0625rem 0.3125rem; - } -</style> diff --git a/docs/src/components/ui/banner/banner.client.ts b/docs/src/components/ui/banner/banner.client.ts deleted file mode 100644 index 4ab68c3..0000000 --- a/docs/src/components/ui/banner/banner.client.ts +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Storage key: `nb-banner-dismissed-{id}`. Value is "0" for permanent, - * or a future timestamp (ms) for time-limited dismissal. - */ - -import { mount } from "@cloudflare/nimbus-docs/client"; - -const KEY_PREFIX = "nb-banner-dismissed-"; - -function initBanner(banner: HTMLElement): () => void { - const id = banner.dataset.nbBannerDismiss; - if (!id) return () => {}; - - const key = `${KEY_PREFIX}${id}`; - - try { - const stored = localStorage.getItem(key); - if (stored) { - const expiry = Number(stored); - if (expiry === 0 || expiry > Date.now()) { - banner.remove(); - return () => {}; - } - localStorage.removeItem(key); - } - } catch { - // localStorage unavailable; show without persistence. - } - - const btn = banner.querySelector<HTMLButtonElement>("[data-nb-banner-close]"); - if (!btn) return () => {}; - - function handleClick() { - const days = Number(banner.dataset.nbBannerDays) || 0; - const value = days > 0 ? String(Date.now() + days * 86400000) : "0"; - try { - localStorage.setItem(key, value); - } catch { - // localStorage unavailable; dismissal is session-only. - } - banner.remove(); - } - - btn.addEventListener("click", handleClick); - - return () => btn.removeEventListener("click", handleClick); -} - -mount("[data-nb-banner-dismiss]", initBanner); diff --git a/docs/src/components/ui/banner/index.ts b/docs/src/components/ui/banner/index.ts deleted file mode 100644 index 9b90dcf..0000000 --- a/docs/src/components/ui/banner/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as Banner } from "./Banner.astro"; diff --git a/docs/src/components/ui/breadcrumbs/Breadcrumbs.astro b/docs/src/components/ui/breadcrumbs/Breadcrumbs.astro deleted file mode 100644 index 8b035bc..0000000 --- a/docs/src/components/ui/breadcrumbs/Breadcrumbs.astro +++ /dev/null @@ -1,84 +0,0 @@ ---- -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; -import type { Breadcrumb } from "@cloudflare/nimbus-docs/types"; - -interface Props extends HTMLAttributes<"nav"> { - items: Breadcrumb[]; - /** Max visible crumbs before collapsing middle items (default: 4) */ - maxVisible?: number; -} - -const { items, maxVisible = 4, class: className, ...attrs } = Astro.props; - -// Determine if we need to collapse the middle -const shouldCollapse = items.length > maxVisible; -// When collapsed: Home + first segment + ... + last 2 (parent + current) -const headCount = 2; // Home + first segment -const tailCount = 2; // parent + current page -const headItems = shouldCollapse ? items.slice(0, headCount) : items; -const collapsedItems = shouldCollapse ? items.slice(headCount, items.length - tailCount) : []; -const tailItems = shouldCollapse ? items.slice(items.length - tailCount) : []; ---- - -{items.length > 1 && ( - <nav aria-label="Breadcrumb" class={cn("text-xs font-medium", className)} {...attrs}> - <ol class="flex flex-wrap items-center gap-y-0.5 text-muted-foreground"> - {headItems.map((crumb, i) => ( - <li class="flex items-center"> - {i > 0 && <span class="mx-1.5 text-muted-foreground/50">/</span>} - {(!shouldCollapse && i === items.length - 1) || !crumb.href ? ( - <span class="text-foreground truncate max-w-[12rem]">{crumb.label}</span> - ) : ( - <a href={crumb.href} class="hover:text-foreground transition-colors truncate max-w-[12rem]"> - {crumb.label} - </a> - )} - </li> - ))} - - {shouldCollapse && collapsedItems.length > 0 && ( - <li class="flex items-center"> - <span class="mx-1.5 text-muted-foreground/50">/</span> - <details class="relative group"> - <summary - class="list-none cursor-pointer select-none rounded px-1 py-0.5 transition-colors hover:bg-accent hover:text-foreground [&::-webkit-details-marker]:hidden group-open:before:fixed group-open:before:inset-0 group-open:before:z-[39] group-open:before:cursor-default group-open:before:content-['']" - aria-label={`Show ${collapsedItems.length} more path segments`} - > - <span class="tracking-widest">…</span> - </summary> - <div class="absolute left-0 top-full z-40 mt-1 min-w-[10rem] max-w-[16rem] rounded-lg border border-border bg-card p-1 shadow-lg"> - {collapsedItems.map((crumb) => ( - crumb.href ? ( - <a - href={crumb.href} - class="block truncate rounded-md px-2.5 py-1.5 text-xs text-muted-foreground hover:bg-accent hover:text-foreground transition-colors" - > - {crumb.label} - </a> - ) : ( - <span class="block truncate rounded-md px-2.5 py-1.5 text-xs text-muted-foreground"> - {crumb.label} - </span> - ) - ))} - </div> - </details> - </li> - )} - - {shouldCollapse && tailItems.map((crumb, i) => ( - <li class="flex items-center"> - <span class="mx-1.5 text-muted-foreground/50">/</span> - {i === tailItems.length - 1 || !crumb.href ? ( - <span class="text-foreground truncate max-w-[12rem]">{crumb.label}</span> - ) : ( - <a href={crumb.href} class="hover:text-foreground transition-colors truncate max-w-[12rem]"> - {crumb.label} - </a> - )} - </li> - ))} - </ol> - </nav> -)} diff --git a/docs/src/components/ui/breadcrumbs/index.ts b/docs/src/components/ui/breadcrumbs/index.ts deleted file mode 100644 index 734e208..0000000 --- a/docs/src/components/ui/breadcrumbs/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as Breadcrumbs } from "./Breadcrumbs.astro"; diff --git a/docs/src/components/ui/button/Button.astro b/docs/src/components/ui/button/Button.astro deleted file mode 100644 index 4503785..0000000 --- a/docs/src/components/ui/button/Button.astro +++ /dev/null @@ -1,69 +0,0 @@ ---- -/** - * Button — primary action trigger. - * - * <Button variant="primary">Save</Button> - * <Button variant="secondary" icon="ph:plus">Create</Button> - * <Button variant="ghost" loading>Saving…</Button> - * <Button variant="outline" shape="square" icon="ph:gear" aria-label="Settings" /> - * - * Variants: primary · secondary (default) · ghost · destructive · - * secondary-destructive · outline. - * Sizes: xs · sm · base (default) · lg. - * Shapes: base (default) · square · circle (icon-only — pass `aria-label`). - * - * `icon` takes an iconify name (astro-icon) rendered before the label; - * `loading` swaps it for a spinner and disables the button. - * - * Styling lives in `./variants` (shared with LinkButton). For an anchor - * styled as a button, use `~/components/ui/link-button`. - */ -import { cn } from "@/lib/cn"; -import { Icon } from "astro-icon/components"; -import type { HTMLAttributes } from "astro/types"; -import { - buttonVariants, - buttonIconSize, - type ButtonVariant, - type ButtonSize, - type ButtonShape, -} from "./variants"; - -interface Props extends Omit<HTMLAttributes<"button">, "size"> { - variant?: ButtonVariant; - size?: ButtonSize; - shape?: ButtonShape; - /** Iconify name rendered before the label, e.g. "ph:plus". */ - icon?: string; - /** Show a spinner and disable interaction. */ - loading?: boolean; -} - -const { - variant = "secondary", - size = "base", - shape = "base", - icon, - loading = false, - type = "button", - disabled, - class: className, - ...attrs -} = Astro.props; ---- - -<button - type={type} - disabled={disabled || loading} - class={cn(buttonVariants({ variant, size, shape }), className)} - {...attrs} -> - { - loading ? ( - <Icon name="ph:circle-notch" class={cn("animate-spin", buttonIconSize[size])} /> - ) : ( - icon && <Icon name={icon} class={buttonIconSize[size]} /> - ) - } - <slot /> -</button> diff --git a/docs/src/components/ui/button/index.ts b/docs/src/components/ui/button/index.ts deleted file mode 100644 index 32440d6..0000000 --- a/docs/src/components/ui/button/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -export { default as Button } from "./Button.astro"; -export { - buttonVariants, - buttonBase, - buttonVariantClasses, - buttonSizeText, - buttonSizeCompact, - buttonIconSize, - type ButtonVariant, - type ButtonSize, - type ButtonShape, - type ButtonVariantsOptions, -} from "./variants"; diff --git a/docs/src/components/ui/button/variants.ts b/docs/src/components/ui/button/variants.ts deleted file mode 100644 index afe03b1..0000000 --- a/docs/src/components/ui/button/variants.ts +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Shared button styling — the single source of truth for both <Button> - * (a real button) and <LinkButton> (an anchor styled as a button), so the - * two stay visually identical. - * - * Token-mapped to Nimbus. Import `buttonVariants()` to compose the trigger - * classes for a button-shaped element; `buttonIconSize` sizes a leading/ - * trailing icon for a given size. - */ -import { cn } from "@/lib/cn"; - -export type ButtonVariant = - | "primary" - | "secondary" - | "ghost" - | "destructive" - | "secondary-destructive" - | "outline"; -export type ButtonSize = "xs" | "sm" | "base" | "lg"; -export type ButtonShape = "base" | "square" | "circle"; - -// `rounded-lg` is the default radius for every button; `circle` overrides -// it to `rounded-full` (see `buttonVariants`), `square` keeps it. -export const buttonBase = - "group inline-flex w-max shrink-0 items-center justify-center rounded-lg font-medium whitespace-nowrap no-underline transition-all cursor-pointer select-none focus-visible:outline-2 focus-visible:outline-ring focus-visible:outline-offset-2 disabled:cursor-not-allowed disabled:opacity-50"; - -export const buttonVariantClasses: Record<ButtonVariant, string> = { - primary: - "bg-primary text-primary-foreground shadow-sm hover:bg-primary-hover hover:shadow", - secondary: - "bg-card text-foreground ring ring-border shadow-sm hover:bg-accent hover:ring-border-strong", - ghost: "bg-transparent text-foreground shadow-none hover:bg-accent", - destructive: "bg-danger text-white shadow-sm hover:bg-danger/90", - "secondary-destructive": - "bg-card text-danger ring ring-border shadow-sm hover:bg-accent hover:ring-danger/40", - outline: - "bg-transparent text-foreground ring ring-border hover:ring-border-strong", -}; - -// Rectangular sizing (shape="base"). Radius comes from `buttonBase`. -export const buttonSizeText: Record<ButtonSize, string> = { - xs: "gap-1 px-2 py-1 text-xs", - sm: "gap-1 px-3 py-1.5 text-xs", - base: "gap-1.5 px-4 py-2 text-sm", - lg: "gap-2 px-5 py-2.5 text-sm", -}; - -// Square/circle sizing (icon-only): equal dimensions, no padding. -export const buttonSizeCompact: Record<ButtonSize, string> = { - xs: "size-7", - sm: "size-8", - base: "size-9", - lg: "size-10", -}; - -export const buttonIconSize: Record<ButtonSize, string> = { - xs: "h-3.5 w-3.5", - sm: "h-3.5 w-3.5", - base: "h-4 w-4", - lg: "h-[1.125rem] w-[1.125rem]", -}; - -export interface ButtonVariantsOptions { - variant?: ButtonVariant; - size?: ButtonSize; - shape?: ButtonShape; -} - -/** Compose the base + variant + size/shape classes for a button-shaped element. */ -export function buttonVariants({ - variant = "secondary", - size = "base", - shape = "base", -}: ButtonVariantsOptions = {}): string { - // base + square inherit `rounded-lg` from buttonBase; circle overrides it - // to a full pill. - const dims = - shape === "base" - ? buttonSizeText[size] - : cn(buttonSizeCompact[size], "p-0", shape === "circle" && "rounded-full"); - return cn(buttonBase, buttonVariantClasses[variant], dims); -} diff --git a/docs/src/components/ui/card-grid/CardGrid.astro b/docs/src/components/ui/card-grid/CardGrid.astro deleted file mode 100644 index a7c50fb..0000000 --- a/docs/src/components/ui/card-grid/CardGrid.astro +++ /dev/null @@ -1,15 +0,0 @@ ---- -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; - -type Props = HTMLAttributes<"div">; - -const { class: className, ...attrs } = Astro.props; ---- - -<div - class={cn("grid grid-cols-1 gap-4 my-4 sm:grid-cols-2 [&>*]:my-0", className)} - {...attrs} -> - <slot /> -</div> diff --git a/docs/src/components/ui/card-grid/index.ts b/docs/src/components/ui/card-grid/index.ts deleted file mode 100644 index 417cc1f..0000000 --- a/docs/src/components/ui/card-grid/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as CardGrid } from "./CardGrid.astro"; diff --git a/docs/src/components/ui/card/Card.astro b/docs/src/components/ui/card/Card.astro deleted file mode 100644 index f4f268a..0000000 --- a/docs/src/components/ui/card/Card.astro +++ /dev/null @@ -1,21 +0,0 @@ ---- -import { Icon } from "astro-icon/components"; -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; - -interface Props extends HTMLAttributes<"article"> { - title: string; - /** Iconify icon name, e.g. `ph:lightning`. */ - icon?: string; -} - -const { title, icon, class: className, ...attrs } = Astro.props; ---- - -<article class={cn("my-4 rounded-lg bg-card p-5 shadow-sm ring ring-border", className)} {...attrs}> - {icon && <Icon name={icon} class="mb-2.5 block w-6 h-6 text-foreground" />} - <h3 class="m-0 text-base font-semibold leading-snug text-foreground">{title}</h3> - <div class="mt-1.5 text-sm leading-normal text-muted-foreground"> - <slot /> - </div> -</article> diff --git a/docs/src/components/ui/card/index.ts b/docs/src/components/ui/card/index.ts deleted file mode 100644 index b491741..0000000 --- a/docs/src/components/ui/card/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as Card } from "./Card.astro"; diff --git a/docs/src/components/ui/code/Code.astro b/docs/src/components/ui/code/Code.astro deleted file mode 100644 index 34feef7..0000000 --- a/docs/src/components/ui/code/Code.astro +++ /dev/null @@ -1,36 +0,0 @@ ---- -/** - * Code — syntax-highlighted code block from a string prop. - * - * <Code code={generated} lang="ts" /> - * <Code code={...} lang="ts" meta='title="src/foo.ts" {1,3-5}' /> - */ -import { Code as AstroCode } from "astro:components"; -import { defaultCodeTransformers } from "@cloudflare/nimbus-docs"; - -type Props = Parameters<typeof AstroCode>[0]; -const rawProps = Astro.props as Props; -const usesNimbusDefaultThemes = !("theme" in rawProps) && !("themes" in rawProps); -const themed = usesNimbusDefaultThemes - ? { - ...rawProps, - themes: { light: "github-light", dark: "github-dark" }, - defaultColor: false, - } - : rawProps; -const userTransformers = themed.transformers ?? []; -const props = { - ...themed, - transformers: defaultCodeTransformers({ - beforeTitleTransformers: userTransformers, - }), -}; -// One boundary cast back to Astro's own `<Code>` props. Everything above is -// runtime-valid; the only type friction is nominal — nimbus-docs and Astro -// can resolve different `@shikijs/types` copies (e.g. 4.2.x vs 4.1.x), so the -// `ShikiTransformer`/`ThemePresets` shapes differ on paper while matching at -// runtime. `Astro.props` was already `as Props`; re-asserting here keeps the -// component compiling regardless of which shiki types version dedupes in. ---- - -<AstroCode {...(props as Props)} /> diff --git a/docs/src/components/ui/code/index.ts b/docs/src/components/ui/code/index.ts deleted file mode 100644 index 152859d..0000000 --- a/docs/src/components/ui/code/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as Code } from "./Code.astro"; diff --git a/docs/src/components/ui/collapsible/Collapsible.astro b/docs/src/components/ui/collapsible/Collapsible.astro deleted file mode 100644 index 24b51c2..0000000 --- a/docs/src/components/ui/collapsible/Collapsible.astro +++ /dev/null @@ -1,25 +0,0 @@ ---- -/** Collapsible — disclosure. Compose with CollapsibleTrigger + CollapsibleContent. */ -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; - -interface Props extends HTMLAttributes<"div"> { - /** Start open. Default false. */ - open?: boolean; -} - -const { open = false, class: className, ...attrs } = Astro.props; ---- - -<div - data-nb-collapsible - data-nb-default-open={open ? "true" : undefined} - class={cn(className)} - {...attrs} -> - <slot /> -</div> - -<script> - import "./collapsible.client"; -</script> diff --git a/docs/src/components/ui/collapsible/CollapsibleContent.astro b/docs/src/components/ui/collapsible/CollapsibleContent.astro deleted file mode 100644 index e8b7686..0000000 --- a/docs/src/components/ui/collapsible/CollapsibleContent.astro +++ /dev/null @@ -1,27 +0,0 @@ ---- -/** - * CollapsibleContent — the panel that animates open/closed. - * Uses `grid-template-rows: 0fr → 1fr` for smooth height transition. - */ -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; - -interface Props extends HTMLAttributes<"div"> {} - -const { class: className, ...attrs } = Astro.props; ---- - -<div - data-nb-collapsible-content - class={cn( - "grid grid-rows-[0fr] transition-[grid-template-rows] duration-250 ease-[cubic-bezier(0.87,0,0.13,1)]", - "data-[nb-state=open]:grid-rows-[1fr]", - "motion-reduce:transition-none", - className, - )} - {...attrs} -> - <div class="overflow-hidden min-h-0"> - <slot /> - </div> -</div> diff --git a/docs/src/components/ui/collapsible/CollapsibleTrigger.astro b/docs/src/components/ui/collapsible/CollapsibleTrigger.astro deleted file mode 100644 index d5f8cea..0000000 --- a/docs/src/components/ui/collapsible/CollapsibleTrigger.astro +++ /dev/null @@ -1,21 +0,0 @@ ---- -/** - * CollapsibleTrigger — the button that toggles the Collapsible. - * Slot accepts arbitrary content; component author provides full visuals. - */ -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; - -interface Props extends HTMLAttributes<"button"> {} - -const { class: className, type, ...attrs } = Astro.props; ---- - -<button - type={type ?? "button"} - data-nb-collapsible-trigger - class={cn("w-full text-left cursor-pointer select-none", className)} - {...attrs} -> - <slot /> -</button> diff --git a/docs/src/components/ui/collapsible/collapsible.client.ts b/docs/src/components/ui/collapsible/collapsible.client.ts deleted file mode 100644 index 71a1af4..0000000 --- a/docs/src/components/ui/collapsible/collapsible.client.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** Wires Collapsible via the disclosure module. */ - -import { mount, makeDisclosure } from "@cloudflare/nimbus-docs/client"; - -function initCollapsible(root: HTMLElement): () => void { - const trigger = root.querySelector<HTMLElement>("[data-nb-collapsible-trigger]"); - const content = root.querySelector<HTMLElement>("[data-nb-collapsible-content]"); - - if (!trigger || !content) return () => {}; - - const defaultOpen = root.dataset.nbDefaultOpen === "true"; - - const disclosure = makeDisclosure({ - trigger, - content, - defaultOpen, - }); - - return () => disclosure.destroy(); -} - -mount("[data-nb-collapsible]", initCollapsible); diff --git a/docs/src/components/ui/collapsible/index.ts b/docs/src/components/ui/collapsible/index.ts deleted file mode 100644 index a4c4221..0000000 --- a/docs/src/components/ui/collapsible/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { default as Collapsible } from "./Collapsible.astro"; -export { default as CollapsibleTrigger } from "./CollapsibleTrigger.astro"; -export { default as CollapsibleContent } from "./CollapsibleContent.astro"; diff --git a/docs/src/components/ui/dialog/Dialog.astro b/docs/src/components/ui/dialog/Dialog.astro deleted file mode 100644 index 509b5b7..0000000 --- a/docs/src/components/ui/dialog/Dialog.astro +++ /dev/null @@ -1,33 +0,0 @@ ---- -/** - * Dialog — modal overlay built on the native <dialog>. - * - * Open with `el.showModal()`, close with `el.close()` or Escape. - * Scroll-lock and backdrop-click-to-close are handled automatically. - * - * <Dialog id="confirm"> - * <DialogContent> - * <div>Are you sure?</div> - * <DialogClose>Cancel</DialogClose> - * </DialogContent> - * </Dialog> - */ -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; - -interface Props extends HTMLAttributes<"dialog"> {} - -const { class: className, ...attrs } = Astro.props; ---- - -<dialog - data-dialog - class={cn("fixed inset-0 z-50 m-0 h-full w-full max-h-full max-w-full bg-transparent p-0 backdrop:bg-black/40", className)} - {...attrs} -> - <slot /> -</dialog> - -<script> - import "./dialog.client"; -</script> diff --git a/docs/src/components/ui/dialog/DialogClose.astro b/docs/src/components/ui/dialog/DialogClose.astro deleted file mode 100644 index 9d62d99..0000000 --- a/docs/src/components/ui/dialog/DialogClose.astro +++ /dev/null @@ -1,25 +0,0 @@ ---- -/** - * DialogClose — button that closes the nearest ancestor <dialog>. - * Consumer provides the visual (icon, text, kbd hint) via default slot. - */ -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; - -interface Props extends HTMLAttributes<"button"> {} - -const { class: className, ...attrs } = Astro.props; ---- - -<button - data-dialog-close - type="button" - class={cn(className)} - {...attrs} -> - <slot /> -</button> - -<script> - import "./dialog-close.client"; -</script> diff --git a/docs/src/components/ui/dialog/DialogContent.astro b/docs/src/components/ui/dialog/DialogContent.astro deleted file mode 100644 index 429a537..0000000 --- a/docs/src/components/ui/dialog/DialogContent.astro +++ /dev/null @@ -1,21 +0,0 @@ ---- -/** - * DialogContent — inner frame of a Dialog. Centered, constrained, styled. - * Consumer controls max-width/height via class override. - */ -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; - -interface Props extends HTMLAttributes<"div"> {} - -const { class: className, ...attrs } = Astro.props; ---- - -<div class="flex items-start justify-center pt-[10vh] px-4 pointer-events-none"> - <div - class={cn("pointer-events-auto flex max-h-[70vh] w-full flex-col overflow-y-auto rounded-lg bg-muted shadow-lg ring-1 ring-border", className)} - {...attrs} - > - <slot /> - </div> -</div> diff --git a/docs/src/components/ui/dialog/dialog-close.client.ts b/docs/src/components/ui/dialog/dialog-close.client.ts deleted file mode 100644 index 3b5ac7b..0000000 --- a/docs/src/components/ui/dialog/dialog-close.client.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { mount } from "@cloudflare/nimbus-docs/client"; - -mount("[data-dialog-close]", (btn) => { - const close = () => btn.closest("dialog")?.close(); - btn.addEventListener("click", close); - return () => btn.removeEventListener("click", close); -}); diff --git a/docs/src/components/ui/dialog/dialog.client.ts b/docs/src/components/ui/dialog/dialog.client.ts deleted file mode 100644 index 1a68d67..0000000 --- a/docs/src/components/ui/dialog/dialog.client.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { lockScroll, mount, unlockScroll } from "@cloudflare/nimbus-docs/client"; - -mount("[data-dialog]", (root) => { - if (!(root instanceof HTMLDialogElement)) return () => {}; - const dialog = root; - - const sync = () => (dialog.open ? lockScroll() : unlockScroll()); - const observer = new MutationObserver(sync); - observer.observe(dialog, { attributes: true, attributeFilter: ["open"] }); - - const onClose = () => unlockScroll(); - const onBackdrop = (e: MouseEvent) => { - if (e.target === dialog) dialog.close(); - }; - dialog.addEventListener("close", onClose); - dialog.addEventListener("click", onBackdrop); - - return () => { - observer.disconnect(); - dialog.removeEventListener("close", onClose); - dialog.removeEventListener("click", onBackdrop); - // A swap while open never fires `close`; balance the scroll lock. - if (dialog.open) unlockScroll(); - }; -}); diff --git a/docs/src/components/ui/dialog/index.ts b/docs/src/components/ui/dialog/index.ts deleted file mode 100644 index fe7fb64..0000000 --- a/docs/src/components/ui/dialog/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { default as Dialog } from "./Dialog.astro"; -export { default as DialogContent } from "./DialogContent.astro"; -export { default as DialogClose } from "./DialogClose.astro"; diff --git a/docs/src/components/ui/layer-card/LayerCard.astro b/docs/src/components/ui/layer-card/LayerCard.astro deleted file mode 100644 index 8473c7b..0000000 --- a/docs/src/components/ui/layer-card/LayerCard.astro +++ /dev/null @@ -1,23 +0,0 @@ ---- -/** - * LayerCard — two-layer card (recessed header + raised content). - * - * <LayerCard> - * <LayerCardHeader>Title or tabs</LayerCardHeader> - * <LayerCardContent>Main content</LayerCardContent> - * </LayerCard> - */ -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; - -interface Props extends HTMLAttributes<"div"> {} - -const { class: className, ...attrs } = Astro.props; ---- - -<div - class={cn("flex w-full flex-col overflow-hidden rounded-lg bg-muted text-sm ring ring-border", className)} - {...attrs} -> - <slot /> -</div> diff --git a/docs/src/components/ui/layer-card/LayerCardContent.astro b/docs/src/components/ui/layer-card/LayerCardContent.astro deleted file mode 100644 index 12bdaea..0000000 --- a/docs/src/components/ui/layer-card/LayerCardContent.astro +++ /dev/null @@ -1,16 +0,0 @@ ---- -/** LayerCardContent — raised content layer of a LayerCard. */ -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; - -interface Props extends HTMLAttributes<"div"> {} - -const { class: className, ...attrs } = Astro.props; ---- - -<div - class={cn("relative flex flex-col gap-2 overflow-hidden rounded-lg bg-card p-4 pr-3 text-sm leading-6 text-foreground ring ring-border", className)} - {...attrs} -> - <slot /> -</div> diff --git a/docs/src/components/ui/layer-card/LayerCardHeader.astro b/docs/src/components/ui/layer-card/LayerCardHeader.astro deleted file mode 100644 index b9be404..0000000 --- a/docs/src/components/ui/layer-card/LayerCardHeader.astro +++ /dev/null @@ -1,16 +0,0 @@ ---- -/** LayerCardHeader — recessed header layer of a LayerCard. */ -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; - -interface Props extends HTMLAttributes<"div"> {} - -const { class: className, ...attrs } = Astro.props; ---- - -<div - class={cn("flex items-center gap-2 bg-muted px-3 py-2 text-[0.8125rem] font-medium leading-5 text-muted-foreground", className)} - {...attrs} -> - <slot /> -</div> diff --git a/docs/src/components/ui/layer-card/index.ts b/docs/src/components/ui/layer-card/index.ts deleted file mode 100644 index dd347fe..0000000 --- a/docs/src/components/ui/layer-card/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { default as LayerCard } from "./LayerCard.astro"; -export { default as LayerCardHeader } from "./LayerCardHeader.astro"; -export { default as LayerCardContent } from "./LayerCardContent.astro"; diff --git a/docs/src/components/ui/link-button/LinkButton.astro b/docs/src/components/ui/link-button/LinkButton.astro deleted file mode 100644 index c023437..0000000 --- a/docs/src/components/ui/link-button/LinkButton.astro +++ /dev/null @@ -1,76 +0,0 @@ ---- -/** - * LinkButton — an anchor styled as a button. - * - * <LinkButton href="/start" variant="primary">Get started</LinkButton> - * <LinkButton href="/docs" variant="secondary">Read the docs</LinkButton> - * <LinkButton href="#" variant="minimal" icon>Learn more</LinkButton> - * <LinkButton href="/x" shape="square" aria-label="Open"> … </LinkButton> - * - * The `icon` prop appends a right-caret that nudges on hover. - * - * Styling is delegated to the shared `ui/button/variants`, so LinkButton and - * Button stay visually identical. The original props are preserved (used by - * MDX): the LinkButton-only aliases map onto the shared vocabulary — - * `minimal → ghost`, `md → base`. - */ -import { cn } from "@/lib/cn"; -import { Icon } from "astro-icon/components"; -import type { HTMLAttributes } from "astro/types"; -import { - buttonVariants, - buttonIconSize, - type ButtonVariant, - type ButtonSize, - type ButtonShape, -} from "../button/variants"; - -interface Props extends HTMLAttributes<"a"> { - href: string; - /** Original `primary | secondary | minimal`, plus Button's variants. */ - variant?: ButtonVariant | "minimal"; - /** Original `sm | md | lg`, plus Button's `xs | base`. */ - size?: ButtonSize | "md"; - /** `base` (default) · `square` · `circle` (icon-only — pass `aria-label`). */ - shape?: ButtonShape; - /** Append a caret-right that nudges on hover. */ - icon?: boolean; -} - -const { - href, - variant = "primary", - size = "md", - shape = "base", - icon = false, - class: className, - ...attrs -} = Astro.props; - -// Map the LinkButton-only aliases onto the shared Button vocabulary. -const resolvedVariant: ButtonVariant = variant === "minimal" ? "ghost" : variant; -const resolvedSize: ButtonSize = size === "md" ? "base" : size; ---- - -<a - href={href} - class={cn( - buttonVariants({ variant: resolvedVariant, size: resolvedSize, shape }), - className, - )} - {...attrs} -> - <slot /> - { - icon && ( - <Icon - name="ph:caret-right" - class={cn( - "transition-transform group-hover:translate-x-0.5", - buttonIconSize[resolvedSize], - )} - is:inline - /> - ) - } -</a> diff --git a/docs/src/components/ui/link-button/index.ts b/docs/src/components/ui/link-button/index.ts deleted file mode 100644 index 71411b5..0000000 --- a/docs/src/components/ui/link-button/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as LinkButton } from "./LinkButton.astro"; diff --git a/docs/src/components/ui/package-managers/PackageManagers.astro b/docs/src/components/ui/package-managers/PackageManagers.astro deleted file mode 100644 index 62821fe..0000000 --- a/docs/src/components/ui/package-managers/PackageManagers.astro +++ /dev/null @@ -1,129 +0,0 @@ ---- -/** - * PackageManagers — code block with a tab per package manager (npm, - * pnpm, yarn, bun). Selection syncs across instances via sessionStorage; - * an inline custom element restores the saved tab before paint. - */ -import { createHash } from "node:crypto"; -import { Icon } from "astro-icon/components"; -import { getTabs } from "@cloudflare/nimbus-docs/lib/pkgm"; -import type { CommandType, CommandOptions } from "@cloudflare/nimbus-docs/lib/pkgm"; -import { LayerCard, LayerCardHeader } from "@/components/ui/layer-card"; - -interface Props extends CommandOptions { - pkg?: string; - type?: CommandType; -} - -const { pkg, type = "add", args, dev, comment } = Astro.props; -const tabs = getTabs(type, pkg, { args, dev, comment }); -// Prop hash + a per-page counter (on Astro.locals) so two blocks with -// identical props still get distinct ids. Counter order is stable within a -// render, so incremental/warm builds match cold — unlike crypto.randomUUID(). -const localsAny = Astro.locals as Record<string, unknown>; -const counters = - (localsAny.__nbCounters as Map<string, number>) ?? - (localsAny.__nbCounters = new Map<string, number>()); -const n = (counters.get("package-managers") ?? 0) + 1; -counters.set("package-managers", n); -const uid = - "pm-" + - createHash("sha256") - .update(JSON.stringify({ pkg, type, args, dev, comment })) - .digest("hex") - .slice(0, 12) + - "-" + - n.toString(16).padStart(4, "0"); ---- - -<script is:inline> - if (!customElements.get("nb-pm-restore")) { - customElements.define( - "nb-pm-restore", - class extends HTMLElement { - connectedCallback() { - const card = this.closest("[data-nb-pm]"); - if (!card) return; - let saved; - try { - saved = sessionStorage.getItem("ui-pm-tab"); - } catch { - return; - } - if (!saved) return; - const tabs = card.querySelectorAll("[data-nb-pm-tab]"); - let idx = -1; - tabs.forEach(function (t, i) { - if (t.textContent.trim() === saved) idx = i; - }); - if (idx < 1) return; - tabs.forEach(function (t, i) { - t.setAttribute("aria-selected", String(i === idx)); - }); - card.querySelectorAll("[data-nb-pm-panel]").forEach(function (p, i) { - p.hidden = i !== idx; - }); - } - }, - ); - } -</script> - -<div data-nb-pm class="w-full"> - <LayerCard> - <LayerCardHeader role="tablist" aria-label="Package manager"> - {tabs.map((tab, i) => ( - <button - role="tab" - type="button" - aria-selected={i === 0 ? "true" : "false"} - aria-controls={`pm-panel-${uid}-${tab.mgr}`} - id={`pm-tab-${uid}-${tab.mgr}`} - data-nb-pm-tab - class="m-0 cursor-pointer rounded-md border-0 bg-transparent px-2 py-0.5 text-xs leading-5 font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-foreground aria-selected:bg-selected aria-selected:text-foreground" - > - {tab.mgr} - </button> - ))} - </LayerCardHeader> - - {tabs.map((tab, i) => { - const cmdLines = tab.cmd.split("\n"); - const commentPrefix = cmdLines.length > 1 ? cmdLines.slice(0, -1).join("\n") + "\n" : ""; - const codeLine = cmdLines[cmdLines.length - 1]; - const spaceIdx = codeLine.indexOf(" "); - const codeFirst = spaceIdx === -1 ? codeLine : codeLine.slice(0, spaceIdx); - const codeRest = spaceIdx === -1 ? "" : codeLine.slice(spaceIdx); - return ( - <div - role="tabpanel" - id={`pm-panel-${uid}-${tab.mgr}`} - aria-labelledby={`pm-tab-${uid}-${tab.mgr}`} - hidden={i !== 0} - data-nb-pm-panel - class="relative overflow-hidden rounded-lg bg-card text-inherit ring ring-border" - > - <div class="flex items-stretch"> - <pre class="my-0 min-w-0 grow overflow-x-auto border-0 bg-transparent px-4 py-3 text-sm leading-relaxed whitespace-pre font-mono text-foreground"><code data-nb-pm-code>{commentPrefix && <span class="text-muted-foreground">{commentPrefix}</span>}<span class="text-success">{codeFirst}</span><span class="text-warning">{codeRest}</span></code></pre> - <button - type="button" - data-nb-pm-copy - data-nb-command={tab.cmd} - aria-label="Copy to clipboard" - class="m-0 flex shrink-0 cursor-pointer items-center justify-center border-0 border-l border-solid border-border bg-transparent px-3 text-muted-foreground transition-colors hover:text-foreground" - > - <Icon name="ph:copy" class="w-[18px] h-[18px]" is:inline /> - </button> - </div> - </div> - ); - })} - <nb-pm-restore style="display:contents"></nb-pm-restore> - </LayerCard> - <template data-nb-pm-icon-copy><Icon name="ph:copy" class="w-[18px] h-[18px]" is:inline /></template> - <template data-nb-pm-icon-check><Icon name="ph:check" class="w-[18px] h-[18px]" is:inline /></template> -</div> - -<script> - import "./package-managers.client"; -</script> diff --git a/docs/src/components/ui/package-managers/index.ts b/docs/src/components/ui/package-managers/index.ts deleted file mode 100644 index 248021d..0000000 --- a/docs/src/components/ui/package-managers/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as PackageManagers } from "./PackageManagers.astro"; diff --git a/docs/src/components/ui/package-managers/package-managers.client.ts b/docs/src/components/ui/package-managers/package-managers.client.ts deleted file mode 100644 index 28b33f8..0000000 --- a/docs/src/components/ui/package-managers/package-managers.client.ts +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Sync key `ui-pm-tab` (sessionStorage) is shared with the - * `<nb-pm-restore>` early-paint element to avoid flash across navigations. - */ - -import { mount, initTabs } from "@cloudflare/nimbus-docs/client"; - -function cloneIcon(tpl: HTMLTemplateElement | null): Node { - return tpl ? tpl.content.cloneNode(true) : document.createTextNode(""); -} - -function initPackageManager(container: HTMLElement): () => void { - const copyTpl = container.querySelector<HTMLTemplateElement>("[data-nb-pm-icon-copy]"); - const checkTpl = container.querySelector<HTMLTemplateElement>("[data-nb-pm-icon-check]"); - - const tabs = initTabs({ - container, - tabSelector: "[data-nb-pm-tab]", - panelSelector: "[data-nb-pm-panel]", - rovingTabindex: true, - sync: { key: "ui-pm-tab", storage: "session" }, - }); - - const copyHandlers: Array<{ btn: HTMLButtonElement; handler: () => void; timer?: number }> = []; - - container.querySelectorAll<HTMLButtonElement>("[data-nb-pm-copy]").forEach((btn) => { - const handlerInfo: { btn: HTMLButtonElement; handler: () => void; timer?: number } = { - btn, - handler: async () => { - try { - await navigator.clipboard.writeText(btn.dataset.nbCommand ?? ""); - } catch { - return; - } - btn.replaceChildren(cloneIcon(checkTpl)); - if (handlerInfo.timer) window.clearTimeout(handlerInfo.timer); - handlerInfo.timer = window.setTimeout(() => { - btn.replaceChildren(cloneIcon(copyTpl)); - }, 1500); - }, - }; - btn.addEventListener("click", handlerInfo.handler); - copyHandlers.push(handlerInfo); - }); - - return () => { - tabs.destroy(); - copyHandlers.forEach(({ btn, handler, timer }) => { - btn.removeEventListener("click", handler); - if (timer) window.clearTimeout(timer); - }); - }; -} - -mount("[data-nb-pm]", initPackageManager); diff --git a/docs/src/components/ui/page-actions/PageActions.astro b/docs/src/components/ui/page-actions/PageActions.astro deleted file mode 100644 index 7654f0d..0000000 --- a/docs/src/components/ui/page-actions/PageActions.astro +++ /dev/null @@ -1,65 +0,0 @@ ---- -import { Icon } from "astro-icon/components"; -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; - -interface Props extends HTMLAttributes<"div"> { - markdownUrl?: string; - lastUpdated?: Date; -} - -const { markdownUrl, lastUpdated, class: className, ...attrs } = Astro.props; - -const baseBtn = - "inline-flex cursor-pointer items-center gap-1.5 rounded-md bg-transparent px-2 py-1 text-muted-foreground no-underline transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-2 focus-visible:outline-ring focus-visible:outline-offset-2"; - -const formattedDate = lastUpdated - ? new Intl.DateTimeFormat(undefined, { year: "numeric", month: "short", day: "numeric" }).format(lastUpdated) - : null; ---- - -{(markdownUrl || lastUpdated) && ( - <div - data-nb-page-actions - data-md-url={markdownUrl} - class={cn("not-prose -ml-2 flex flex-wrap items-center gap-y-1 text-[0.8125rem]", className)} - {...attrs} - > - {lastUpdated && ( - <span class="inline-flex items-center gap-1.5 px-2 py-1 text-muted-foreground"> - <Icon name="ph:clock" class="w-3.5 h-3.5" /> - Updated <time datetime={lastUpdated.toISOString()}>{formattedDate}</time> - </span> - )} - - {markdownUrl && lastUpdated && ( - <span aria-hidden="true" class="select-none text-muted-foreground/40">|</span> - )} - - {markdownUrl && ( - <> - <button type="button" data-nb-page-actions-copy class={baseBtn}> - <Icon name="ph:copy" class="w-3.5 h-3.5" data-nb-page-actions-copy-icon is:inline /> - <Icon name="ph:check" class="hidden w-3.5 h-3.5 text-success" data-nb-page-actions-check-icon is:inline /> - <span data-nb-page-actions-label aria-live="polite">Copy page</span> - </button> - - <span aria-hidden="true" class="select-none text-muted-foreground/40">|</span> - - <a - href={markdownUrl} - target="_blank" - rel="noopener noreferrer" - class={baseBtn} - > - <Icon name="ph:markdown-logo" class="w-3.5 h-3.5" /> - View as Markdown - </a> - </> - )} - </div> -)} - -<script> - import "./page-actions.client"; -</script> diff --git a/docs/src/components/ui/page-actions/index.ts b/docs/src/components/ui/page-actions/index.ts deleted file mode 100644 index 3d7bcd1..0000000 --- a/docs/src/components/ui/page-actions/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as PageActions } from "./PageActions.astro"; diff --git a/docs/src/components/ui/page-actions/page-actions.client.ts b/docs/src/components/ui/page-actions/page-actions.client.ts deleted file mode 100644 index 0f4d9a4..0000000 --- a/docs/src/components/ui/page-actions/page-actions.client.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { mount } from "@cloudflare/nimbus-docs/client"; - -function initPageActions(root: HTMLElement): () => void { - const copyBtn = root.querySelector<HTMLButtonElement>("[data-nb-page-actions-copy]"); - const copyIcon = root.querySelector<SVGElement>("[data-nb-page-actions-copy-icon]"); - const checkIcon = root.querySelector<SVGElement>("[data-nb-page-actions-check-icon]"); - const label = root.querySelector<HTMLSpanElement>("[data-nb-page-actions-label]"); - const mdUrl = root.dataset.mdUrl; - - if (!copyBtn || !mdUrl) return () => {}; - - let resetTimer: number | undefined; - - function showState(state: "copied" | "error") { - if (!copyIcon || !checkIcon || !label) return; - if (state === "copied") { - copyIcon.classList.add("hidden"); - checkIcon.classList.remove("hidden"); - label.textContent = "Copied"; - } else { - label.textContent = "Couldn't copy"; - } - if (resetTimer) window.clearTimeout(resetTimer); - resetTimer = window.setTimeout(() => { - copyIcon.classList.remove("hidden"); - checkIcon.classList.add("hidden"); - label.textContent = "Copy page"; - }, 1500); - } - - async function handleCopyPage() { - try { - const res = await fetch(mdUrl!); - if (!res.ok) { - showState("error"); - return; - } - const text = await res.text(); - await navigator.clipboard.writeText(text); - showState("copied"); - } catch { - showState("error"); - } - } - - copyBtn.addEventListener("click", handleCopyPage); - - return () => { - if (resetTimer) window.clearTimeout(resetTimer); - copyBtn.removeEventListener("click", handleCopyPage); - }; -} - -mount("[data-nb-page-actions]", initPageActions); diff --git a/docs/src/components/ui/pagination/Pagination.astro b/docs/src/components/ui/pagination/Pagination.astro deleted file mode 100644 index 11811f9..0000000 --- a/docs/src/components/ui/pagination/Pagination.astro +++ /dev/null @@ -1,36 +0,0 @@ ---- -import { Icon } from "astro-icon/components"; -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; -import type { PrevNext } from "@cloudflare/nimbus-docs/types"; - -interface Props extends HTMLAttributes<"nav"> { - prevNext: PrevNext; -} - -const { prevNext, class: className, ...attrs } = Astro.props; -const { prev, next } = prevNext; ---- - -{(prev || next) && ( - <nav aria-label="Pagination" class={cn("flex items-center justify-between mt-12 pt-6 border-t border-border", className)} {...attrs}> - {prev ? ( - <a href={prev.href} class="group flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground transition-colors"> - <Icon name="ph:caret-left" class="w-4 h-4 transition-transform group-hover:-translate-x-0.5" /> - <span> - <span class="block text-xs text-muted-foreground">Previous</span> - <span class="font-medium text-foreground">{prev.label}</span> - </span> - </a> - ) : <span />} - {next ? ( - <a href={next.href} class="group flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground transition-colors text-right"> - <span> - <span class="block text-xs text-muted-foreground">Next</span> - <span class="font-medium text-foreground">{next.label}</span> - </span> - <Icon name="ph:caret-right" class="w-4 h-4 transition-transform group-hover:translate-x-0.5" is:inline /> - </a> - ) : <span />} - </nav> -)} diff --git a/docs/src/components/ui/pagination/index.ts b/docs/src/components/ui/pagination/index.ts deleted file mode 100644 index 8972ed7..0000000 --- a/docs/src/components/ui/pagination/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as Pagination } from "./Pagination.astro"; diff --git a/docs/src/components/ui/search/SearchDialog.astro b/docs/src/components/ui/search/SearchDialog.astro deleted file mode 100644 index 5c16840..0000000 --- a/docs/src/components/ui/search/SearchDialog.astro +++ /dev/null @@ -1,54 +0,0 @@ ---- -import { Icon } from "astro-icon/components"; -import { Dialog, DialogClose, DialogContent } from "@/components/ui/dialog"; ---- - -<Dialog aria-label="Search documentation" data-search-dialog> - <DialogContent class="max-w-xl bg-muted shadow-xl ring-border"> - <div class="overflow-hidden rounded-t-lg bg-card border-b border-border"> - <div class="flex items-center gap-3 border-b border-border px-4 py-3"> - <Icon name="ph:magnifying-glass" class="h-4 w-4 shrink-0 text-muted-foreground" /> - <input - data-search-input - role="combobox" - aria-expanded="false" - aria-haspopup="listbox" - aria-autocomplete="list" - aria-controls="search-listbox" - type="text" - placeholder="Search documentation…" - class="min-w-0 flex-1 border-0 bg-transparent text-sm text-foreground placeholder:text-muted-foreground focus:outline-none" - autocomplete="off" - spellcheck="false" - autocorrect="off" - autocapitalize="none" - /> - <DialogClose class="rounded border border-border bg-muted px-1.5 py-0.5 text-xs font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-foreground"> - Esc - </DialogClose> - </div> - - <div - data-search-results - role="listbox" - id="search-listbox" - aria-orientation="vertical" - class="min-h-40 overflow-y-auto p-2" - > - <p data-search-empty class="py-8 text-center text-sm text-muted-foreground"> - Type to search… - </p> - </div> - </div> - - <div class="flex items-center gap-4 px-4 py-2.5 text-xs text-muted-foreground/80"> - <span>↑↓ navigate</span> - <span>↵ select</span> - <span>Esc close</span> - </div> - </DialogContent> -</Dialog> - -<script> - import "./search.client"; -</script> diff --git a/docs/src/components/ui/search/SearchTrigger.astro b/docs/src/components/ui/search/SearchTrigger.astro deleted file mode 100644 index 8c79579..0000000 --- a/docs/src/components/ui/search/SearchTrigger.astro +++ /dev/null @@ -1,22 +0,0 @@ ---- -/** Button that opens the search dialog. Cmd+K on macOS, Ctrl+K elsewhere. */ -import { Icon } from "astro-icon/components"; ---- - -<button - data-search-trigger - type="button" - class="flex items-center gap-2 rounded-md border border-border bg-card text-sm text-muted-foreground transition-colors hover:border-border-strong hover:text-foreground p-2 sm:px-2.5 sm:py-1.5" - aria-label="Search documentation" - aria-keyshortcuts="Control+K" -> - <Icon name="ph:magnifying-glass" class="h-4 w-4" /> - <span class="hidden md:inline">Search</span> - <kbd class="hidden sm:inline-flex items-center gap-0.5 rounded border border-border bg-muted px-1.5 py-0.5 text-[0.625rem] font-medium text-muted-foreground"> - <span data-shortcut-key>Ctrl</span>K - </kbd> -</button> - -<script> - import "./search-trigger.client"; -</script> diff --git a/docs/src/components/ui/search/index.ts b/docs/src/components/ui/search/index.ts deleted file mode 100644 index 9f7c86a..0000000 --- a/docs/src/components/ui/search/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default as SearchDialog } from "./SearchDialog.astro"; -export { default as SearchTrigger } from "./SearchTrigger.astro"; diff --git a/docs/src/components/ui/search/providers/pagefind.ts b/docs/src/components/ui/search/providers/pagefind.ts deleted file mode 100644 index 3e9dc49..0000000 --- a/docs/src/components/ui/search/providers/pagefind.ts +++ /dev/null @@ -1,80 +0,0 @@ -import type { SearchProvider, SearchResult } from "@cloudflare/nimbus-docs/types"; -import { config } from "virtual:nimbus/config"; - -interface PagefindSubResult { - title?: string; - url?: string; -} - -interface PagefindResultData { - url: string; - excerpt?: string; - meta?: { title?: string }; - sub_results?: PagefindSubResult[]; -} - -interface PagefindSearchResponse { - results: Array<{ data(): Promise<PagefindResultData> }>; -} - -interface PagefindFilters { - [key: string]: string | string[] | { none?: string | string[]; any?: string | string[] }; -} - -interface PagefindApi { - init(): Promise<void>; - search(query: string, options?: { filters?: PagefindFilters }): Promise<PagefindSearchResponse>; -} - -let pagefind: PagefindApi | undefined; - -/** - * Default Pagefind filters applied to every search. - * - * Versioning: when the site has a `versions.deprecated` list, the - * layout emits `data-pagefind-filter="status:deprecated"` on every - * deprecated-version page. Search defaults to excluding those results - * (readers searching for "auth" want the current version's auth page, - * not the deprecated one). Future UI work can expose a "include - * deprecated" toggle; for now the default is current + non-deprecated. - * - * Versions are still searchable individually — readers on a v0 page - * who explicitly search from there can opt the UI into a version-scoped - * filter. The default exclusion is just for the top-level search. - * - * Computed at module-import time so we don't pay the config lookup on - * every keystroke. - */ -const defaultFilters: PagefindFilters | undefined = - config.versions && config.versions.deprecated && config.versions.deprecated.length > 0 - ? { status: { none: "deprecated" } } - : undefined; - -export const provider: SearchProvider = { - async init() { - if (pagefind) return; - const baseUrl = new URL(import.meta.env.BASE_URL ?? "/", window.location.origin); - const pagefindUrl = new URL("pagefind/pagefind.js", baseUrl); - pagefind = (await import(/* @vite-ignore */ pagefindUrl.href)) as PagefindApi; - await pagefind.init(); - }, - - async search(query) { - if (!pagefind) await this.init?.(); - if (!pagefind) return []; - - const search = await pagefind.search( - query, - defaultFilters ? { filters: defaultFilters } : undefined, - ); - const results = await Promise.all(search.results.slice(0, 10).map((result) => result.data())); - return results.map((result): SearchResult => ({ - title: result.meta?.title ?? "Untitled", - url: result.url, - snippet: result.excerpt, - subResults: result.sub_results - ?.filter((sub): sub is Required<PagefindSubResult> => Boolean(sub.title && sub.url)) - .map((sub) => ({ title: sub.title, url: sub.url })), - })); - }, -}; diff --git a/docs/src/components/ui/search/search-trigger.client.ts b/docs/src/components/ui/search/search-trigger.client.ts deleted file mode 100644 index 7e75f01..0000000 --- a/docs/src/components/ui/search/search-trigger.client.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** Sets the platform-correct shortcut hint on the search trigger (⌘ on macOS, Ctrl elsewhere). */ - -import { mount } from "@cloudflare/nimbus-docs/client"; - -mount("[data-search-trigger]", (btn) => { - const nav = navigator as Navigator & { userAgentData?: { platform?: string } }; - const platform = nav.userAgentData?.platform ?? ""; - const isMac = platform - ? /mac/i.test(platform) - : /mac|iphone|ipod|ipad/i.test(navigator.userAgent); - if (isMac) { - btn.setAttribute("aria-keyshortcuts", "Meta+K"); - const key = btn.querySelector("[data-shortcut-key]"); - if (key) key.textContent = "⌘"; - } - return () => {}; -}); diff --git a/docs/src/components/ui/search/search.client.ts b/docs/src/components/ui/search/search.client.ts deleted file mode 100644 index 95d1b19..0000000 --- a/docs/src/components/ui/search/search.client.ts +++ /dev/null @@ -1,275 +0,0 @@ -import { mount } from "@cloudflare/nimbus-docs/client"; -import type { SearchProvider, SearchResult } from "@cloudflare/nimbus-docs/types"; -import { provider } from "./providers/pagefind"; - -export interface SearchConfig { - input: HTMLInputElement; - resultsContainer: HTMLElement; - emptyState: HTMLElement; - provider: SearchProvider; - onNavigate?: () => void; -} - -export interface SearchInstance { - reset(): Promise<void>; - destroy(): void; -} - -export function initSearch(config: SearchConfig): SearchInstance { - const { input, resultsContainer, emptyState, provider, onNavigate } = config; - - let initialized = false; - let activeIndex = -1; - let resultIdCounter = 0; - let debounceTimer: ReturnType<typeof setTimeout> | undefined; - let activeController: AbortController | undefined; - - function getOptions(): HTMLElement[] { - return Array.from(resultsContainer.querySelectorAll<HTMLElement>("[role='option']")); - } - - function updateActive(newIndex: number): void { - const options = getOptions(); - if (options.length === 0) { - activeIndex = -1; - input.removeAttribute("aria-activedescendant"); - return; - } - activeIndex = Math.max(-1, Math.min(newIndex, options.length - 1)); - options.forEach((option, index) => { - if (index === activeIndex) { - option.setAttribute("data-highlighted", ""); - option.scrollIntoView({ block: "nearest" }); - input.setAttribute("aria-activedescendant", option.id); - } else { - option.removeAttribute("data-highlighted"); - } - }); - if (activeIndex < 0) input.removeAttribute("aria-activedescendant"); - } - - function clearResults(): void { - for (const result of resultsContainer.querySelectorAll("[role='option']")) result.remove(); - input.setAttribute("aria-expanded", "false"); - input.removeAttribute("aria-activedescendant"); - } - - function resultLink(title: string, href: string, className: string): HTMLAnchorElement { - const link = document.createElement("a"); - link.href = href; - link.className = className; - link.textContent = title; - link.addEventListener("click", () => onNavigate?.()); - return link; - } - - function buildResult(result: SearchResult): HTMLElement { - const option = document.createElement("div"); - option.id = `search-result-${resultIdCounter++}`; - option.setAttribute("role", "option"); - option.className = "rounded-lg px-2 py-2 transition-colors cursor-pointer hover:bg-accent focus-within:bg-accent data-[highlighted]:bg-accent"; - - const link = resultLink(result.title, result.url, "block truncate text-sm font-medium text-foreground no-underline focus-visible:outline-none"); - option.appendChild(link); - - if (result.snippet) { - const snippet = document.createElement("p"); - snippet.className = "mt-1 line-clamp-2 text-xs leading-relaxed text-muted-foreground"; - snippet.innerHTML = result.snippet; - option.appendChild(snippet); - } - - if (result.subResults?.length) { - const subList = document.createElement("div"); - subList.className = "mt-2 border-l border-border pl-3"; - for (const sub of result.subResults.slice(0, 3)) { - subList.appendChild(resultLink(sub.title, sub.url, "block truncate py-0.5 text-xs text-muted-foreground no-underline hover:text-foreground")); - } - option.appendChild(subList); - } - - option.addEventListener("click", (event) => { - if ((event.target as Element | null)?.closest("a")) return; - link.click(); - }); - - return option; - } - - async function ensureInitialized(): Promise<boolean> { - if (initialized) return true; - try { - await provider.init?.(); - initialized = true; - return true; - } catch { - emptyState.textContent = "Search is available after a production build."; - return false; - } - } - - async function runSearch(query: string): Promise<void> { - activeController?.abort(); - activeController = new AbortController(); - const signal = activeController.signal; - - emptyState.style.display = ""; - emptyState.textContent = "Searching…"; - clearResults(); - - if (!(await ensureInitialized()) || signal.aborted) return; - - try { - const results = await provider.search(query, { signal }); - if (signal.aborted) return; - - clearResults(); - activeIndex = -1; - - if (results.length === 0) { - emptyState.style.display = ""; - emptyState.textContent = "No results found."; - return; - } - - emptyState.style.display = "none"; - input.setAttribute("aria-expanded", "true"); - for (const result of results) resultsContainer.appendChild(buildResult(result)); - } catch { - if (signal.aborted) return; - clearResults(); - emptyState.style.display = ""; - emptyState.textContent = "Search is temporarily unavailable."; - } - } - - function handleInput(): void { - if (debounceTimer) clearTimeout(debounceTimer); - debounceTimer = setTimeout(() => { - const query = input.value.trim(); - if (!query) { - activeController?.abort(); - clearResults(); - emptyState.style.display = ""; - emptyState.textContent = "Type to search…"; - return; - } - void runSearch(query); - }, 150); - } - - function handleKeydown(event: KeyboardEvent): void { - const options = getOptions(); - if (event.key === "ArrowDown") { - event.preventDefault(); - updateActive(activeIndex + 1); - } else if (event.key === "ArrowUp") { - event.preventDefault(); - updateActive(activeIndex - 1); - } else if (event.key === "Home") { - event.preventDefault(); - updateActive(0); - } else if (event.key === "End") { - event.preventDefault(); - updateActive(options.length - 1); - } else if (event.key === "Enter" && activeIndex >= 0) { - event.preventDefault(); - options[activeIndex]?.querySelector<HTMLAnchorElement>("a")?.click(); - } - } - - input.addEventListener("input", handleInput); - input.closest("dialog")?.addEventListener("keydown", handleKeydown); - - return { - async reset() { - activeController?.abort(); - if (debounceTimer) clearTimeout(debounceTimer); - input.value = ""; - input.focus(); - activeIndex = -1; - clearResults(); - emptyState.style.display = ""; - emptyState.textContent = "Type to search…"; - await ensureInitialized(); - }, - destroy() { - activeController?.abort(); - if (debounceTimer) clearTimeout(debounceTimer); - input.removeEventListener("input", handleInput); - input.closest("dialog")?.removeEventListener("keydown", handleKeydown); - }, - }; -} - -// --------------------------------------------------------------------------- -// Bootstrap — imported for its side effects by SearchDialog.astro -// (`import "./search.client"`). Wires each dialog through mount() and binds the -// global open shortcut once. -// --------------------------------------------------------------------------- - -type SearchDialogElement = HTMLDialogElement & { - __openSearchDialog?: () => void; -}; - -function primaryDialog(): SearchDialogElement | null { - return document.querySelector<SearchDialogElement>("[data-search-dialog][data-search-ready]"); -} - -// The open shortcut and trigger delegation live on `document`, which survives -// view transitions, so they are bound once for the page's lifetime — never -// through mount()'s per-element setup/teardown. A module-scoped boolean (not an -// <html> attribute) is the guard: ClientRouter resets <html> on every swap but -// keeps document listeners, so an attribute guard would stack a duplicate -// keydown handler each navigation (Cmd+K then toggles twice). -let globalsBound = false; - -function bindGlobals() { - if (globalsBound) return; - globalsBound = true; - - document.addEventListener("click", (event) => { - const trigger = (event.target as Element | null)?.closest("[data-search-trigger]"); - if (!trigger) return; - primaryDialog()?.__openSearchDialog?.(); - }); - - document.addEventListener("keydown", (event) => { - if (!(event.metaKey || event.ctrlKey) || event.key.toLowerCase() !== "k") return; - const dialog = primaryDialog(); - if (!dialog) return; - event.preventDefault(); - if (dialog.open) dialog.close(); - else dialog.__openSearchDialog?.(); - }); -} - -// Per-element wiring: idempotent discovery now and on astro:page-load, teardown -// on astro:before-swap. Replaces the hand-rolled data-search-ready init loop; -// data-search-ready is now just the "wired" marker primaryDialog() selects on. -mount("[data-search-dialog]", (root) => { - const dialog = root as SearchDialogElement; - dialog.setAttribute("data-search-ready", "true"); - - const input = dialog.querySelector<HTMLInputElement>("[data-search-input]"); - const resultsContainer = dialog.querySelector<HTMLElement>("[data-search-results]"); - const emptyState = dialog.querySelector<HTMLElement>("[data-search-empty]"); - if (!input || !resultsContainer || !emptyState) return () => {}; - - const search = initSearch({ - input, - resultsContainer, - emptyState, - provider, - onNavigate: () => dialog.close(), - }); - - dialog.__openSearchDialog = () => { - if (!dialog.open) dialog.showModal(); - void search.reset(); - }; - - return () => search.destroy(); -}); - -bindGlobals(); diff --git a/docs/src/components/ui/sidebar/Sidebar.astro b/docs/src/components/ui/sidebar/Sidebar.astro deleted file mode 100644 index 5795b0b..0000000 --- a/docs/src/components/ui/sidebar/Sidebar.astro +++ /dev/null @@ -1,65 +0,0 @@ ---- -/** - * Sidebar — recursive navigation tree from a `SidebarItem[]`. Composes - * SidebarGroup + SidebarLink. Pass `persist` to opt into sessionStorage - * for open/scroll state (desktop only). - */ -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; -import SidebarGroup from "./SidebarGroup.astro"; -import SidebarLink from "./SidebarLink.astro"; -import type { SidebarItem } from "@cloudflare/nimbus-docs/types"; -import { sidebarHash } from "@cloudflare/nimbus-docs"; - -interface Props extends HTMLAttributes<"div"> { - items: SidebarItem[]; - /** Persist open/scroll state to sessionStorage. Desktop sidebar only. */ - persist?: boolean; -} - -const { items, persist = false, class: className, ...attrs } = Astro.props; -const hash = sidebarHash(items); ---- - -<div - data-nb-sidebar - data-nb-sidebar-hash={hash} - data-nb-sidebar-persist={persist ? "" : undefined} - class={cn(className)} - {...attrs} -> - <ul class="top-level flex list-none flex-col gap-0.5 p-0"> - {items.map((item) => - item.type === "group" ? ( - <li> - <SidebarGroup - label={item.label} - items={item.children} - collapsed={item.collapsed} - badge={item.badge} - icon={item.icon} - indexHref={item.indexHref} - indexIsCurrent={item.indexIsCurrent} - indexIsExternal={item.indexIsExternal} - /> - </li> - ) : item.type === "external" ? ( - <li> - <SidebarLink label={item.label} href={item.href} badge={item.badge} target="_blank" rel="noopener" /> - </li> - ) : ( - <li> - <SidebarLink label={item.label} href={item.href} isCurrent={item.isCurrent} badge={item.badge} /> - </li> - ), - )} - </ul> -</div> - -<script> - import "./sidebar.client"; -</script> - -<style is:global> - [data-nb-sidebar-hidden] { display: none; } -</style> diff --git a/docs/src/components/ui/sidebar/SidebarFilter.astro b/docs/src/components/ui/sidebar/SidebarFilter.astro deleted file mode 100644 index 1f56920..0000000 --- a/docs/src/components/ui/sidebar/SidebarFilter.astro +++ /dev/null @@ -1,28 +0,0 @@ ---- -/** SidebarFilter — text input that filters the adjacent Sidebar. Press "/" to focus. */ -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; - -interface Props extends HTMLAttributes<"div"> { - placeholder?: string; -} - -const { class: className, placeholder = "Filter…", ...attrs } = Astro.props; ---- - -<div class={cn("relative mb-3", className)} {...attrs}> - <input - data-nb-sidebar-filter-input - type="search" - placeholder={placeholder} - class="peer w-full rounded-md border border-border bg-card py-1.5 pl-3 pr-9 text-sm text-foreground placeholder:text-muted-foreground transition-colors focus-visible:border-brand focus-visible:outline-2 focus-visible:outline-ring [&:not(:placeholder-shown)]:pr-2" - aria-label="Filter navigation" - autocomplete="off" - /> - {/* Shortcut hint — press "/" to focus. Hidden once the input is focused or has a value. */} - <kbd - aria-hidden="true" - class="pointer-events-none absolute right-2 top-1/2 flex h-5 min-w-5 -translate-y-1/2 items-center justify-center rounded border border-border bg-muted px-1 font-mono text-[0.6875rem] font-semibold leading-none text-muted-foreground transition-opacity duration-150 peer-focus:opacity-0 peer-[:not(:placeholder-shown)]:opacity-0 motion-reduce:transition-none" - >/</kbd - > -</div> diff --git a/docs/src/components/ui/sidebar/SidebarGroup.astro b/docs/src/components/ui/sidebar/SidebarGroup.astro deleted file mode 100644 index a7bdda4..0000000 --- a/docs/src/components/ui/sidebar/SidebarGroup.astro +++ /dev/null @@ -1,198 +0,0 @@ ---- -/** - * SidebarGroup — autogenerated section header in the sidebar rail. - * - * Renders in one of two shapes depending on whether the group has a - * landing page (`indexHref`): - * - * - Has landing: the label is an `<a>` linking to indexHref. The - * collapse caret sits next to it as a separate `<button>`. The - * group label IS the link to the landing page; children are listed - * separately below. - * - No landing: the entire row is a single `<button>` that toggles - * the collapse. Label is non-interactive. Used for directories - * without an `index.mdx`, where the group is a pure visual section - * divider over its children. - */ -import { Icon } from "astro-icon/components"; -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; -import { Collapsible, CollapsibleTrigger, CollapsibleContent } from "@/components/ui/collapsible"; -import SidebarLink from "./SidebarLink.astro"; -import { Badge } from "@/components/ui/badge"; -import type { SidebarItem, SidebarBadge } from "@cloudflare/nimbus-docs/types"; - -interface Props extends HTMLAttributes<"div"> { - label: string; - items: SidebarItem[]; - collapsed?: boolean; - badge?: SidebarBadge; - /** Landing-page URL when the group has an `index.mdx`. Renders the label as a link. */ - indexHref?: string; - /** True when the landing page is the current route. */ - indexIsCurrent?: boolean; - /** True when `indexHref` is an off-site URL — render with target="_blank" rel="noopener". */ - indexIsExternal?: boolean; - /** Optional leading icon (astro-icon name) rendered before the label. */ - icon?: string; -} - -const { - label, - items, - collapsed, - badge, - indexHref, - indexIsCurrent, - indexIsExternal, - icon, - class: className, - ...attrs -} = Astro.props; - -function hasActiveDescendant(items: SidebarItem[]): boolean { - return items.some((item) => - item.type === "link" - ? Boolean(item.isCurrent) - : item.type === "group" - ? Boolean(item.indexIsCurrent) || hasActiveDescendant(item.children) - : false, - ); -} - -const hasActive = Boolean(indexIsCurrent) || hasActiveDescendant(items); -const isOpen = Boolean(hasActive || collapsed === false || collapsed === undefined); - -// Shared classes for the row that holds the label + caret in both -// rendering modes (landing-as-link vs. label-as-trigger). -const rowClass = cn( - "group/expander flex min-h-[2rem] items-center rounded-lg px-3 py-1 text-[0.8125rem] no-underline transition-colors duration-150 focus-visible:outline-offset-[-2px]", - "hover:bg-accent hover:text-foreground", - hasActive ? "font-semibold text-foreground" : "font-medium text-muted-foreground", -); -// Chevron icon classes. Rotation is driven by an explicit CSS rule in -// `<style is:global>` at the bottom of this file. -const caretClass = - "ml-auto -mr-px shrink-0 w-5 h-5 text-muted-foreground opacity-50 transition-[rotate,color] duration-[250ms] ease-[cubic-bezier(0.87,0,0.13,1)] group-hover/expander:text-foreground"; ---- - -<Collapsible - class={cn("group/accordion", className)} - open={isOpen} - data-nb-sidebar-group - {...attrs} -> - {indexHref ? ( - <div - class={cn( - rowClass, - "p-0", - // Active state covers the WHOLE row (label-link + chevron), - // not just the link half. - indexIsCurrent ? "bg-accent text-foreground font-semibold" : "", - )} - data-nb-state={isOpen ? "open" : "closed"} - data-nb-sidebar-group-label - > - <a - href={indexHref} - aria-current={indexIsCurrent ? "page" : undefined} - target={indexIsExternal ? "_blank" : undefined} - rel={indexIsExternal ? "noopener" : undefined} - class={cn( - "flex flex-1 min-w-0 items-center min-h-[2rem] px-3 py-1 rounded-l-lg focus-visible:outline-offset-[-2px]", - )} - > - <span class="flex items-center gap-2 flex-1 min-w-0"> - {icon && <Icon name={icon} class="shrink-0 h-4 w-4 text-muted-foreground" />} - <span class="break-words">{label}</span> - {badge && - (typeof badge === "string" ? ( - <Badge text={badge} /> - ) : ( - <Badge text={badge.text} variant={badge.variant} /> - ))} - </span> - </a> - <CollapsibleTrigger - class={cn( - // `w-auto` overrides CollapsibleTrigger's default `w-full`, - // which would otherwise compete with the label-link's - // `flex-1` and starve the label's width. - "w-auto flex items-center shrink-0 min-h-[2rem] px-1.5 py-1 rounded-r-lg", - "hover:bg-accent hover:text-foreground focus-visible:outline-offset-[-2px]", - // The chevron icon uses `group-data-[nb-state=open]/expander:rotate-90` - // to rotate on toggle. That variant resolves to the nearest - // ancestor with `group/expander` *AND* `data-nb-state="open"`. - // The disclosure JS only updates `data-nb-state` on the - // trigger and content elements (not the outer row container), - // so the trigger itself must carry `group/expander` — - // otherwise the icon's class would match the outer row, - // whose `data-nb-state` is stale after the first click. - "group/expander", - )} - data-nb-state={isOpen ? "open" : "closed"} - aria-expanded={isOpen ? "true" : "false"} - aria-label={`Toggle ${label} section`} - > - <Icon name="ph:caret-right" class={caretClass} data-nb-caret is:inline /> - </CollapsibleTrigger> - </div> - ) : ( - <CollapsibleTrigger - class={cn(rowClass, "justify-between w-full")} - data-nb-sidebar-group-label - data-nb-state={isOpen ? "open" : "closed"} - aria-expanded={isOpen ? "true" : "false"} - > - <span class="flex items-center gap-2 flex-1 min-w-0"> - {icon && <Icon name={icon} class="shrink-0 h-4 w-4 text-muted-foreground" />} - <span class="break-words">{label}</span> - {badge && - (typeof badge === "string" ? ( - <Badge text={badge} /> - ) : ( - <Badge text={badge.text} variant={badge.variant} /> - ))} - </span> - <Icon name="ph:caret-right" class={caretClass} data-nb-caret is:inline /> - </CollapsibleTrigger> - )} - - <CollapsibleContent data-nb-state={isOpen ? "open" : "closed"}> - <ul class="mt-0.5 ml-3 list-none border-l border-border p-0 pl-2 flex flex-col gap-px"> - {items.map((item) => ( - <li class="break-words"> - {item.type === "group" ? ( - <Astro.self - label={item.label} - items={item.children} - collapsed={item.collapsed} - badge={item.badge} - icon={item.icon} - indexHref={item.indexHref} - indexIsCurrent={item.indexIsCurrent} - indexIsExternal={item.indexIsExternal} - /> - ) : item.type === "external" ? ( - <SidebarLink label={item.label} href={item.href} badge={item.badge} target="_blank" rel="noopener" /> - ) : ( - <SidebarLink label={item.label} href={item.href} isCurrent={item.isCurrent} badge={item.badge} /> - )} - </li> - ))} - </ul> - </CollapsibleContent> -</Collapsible> - -<style is:global> - /* - * Chevron rotation, driven by the trigger's `data-nb-state`. The - * disclosure runtime (`@/components/ui/collapsible/collapsible.client`) - * keeps this attribute in sync on toggle; this rule turns the - * attribute change into the visual rotation. - */ - [data-nb-collapsible-trigger][data-nb-state="open"] [data-nb-caret] { - rotate: 90deg; - } -</style> diff --git a/docs/src/components/ui/sidebar/SidebarLink.astro b/docs/src/components/ui/sidebar/SidebarLink.astro deleted file mode 100644 index 64e8849..0000000 --- a/docs/src/components/ui/sidebar/SidebarLink.astro +++ /dev/null @@ -1,37 +0,0 @@ ---- -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; -import { Badge } from "@/components/ui/badge"; -import type { SidebarBadge } from "@cloudflare/nimbus-docs/types"; - -interface Props extends HTMLAttributes<"a"> { - label: string; - href: string; - isCurrent?: boolean; - badge?: SidebarBadge; -} - -const { label, href, isCurrent, badge, class: className, ...attrs } = Astro.props; ---- - -<a - href={href} - aria-current={isCurrent ? "page" : undefined} - data-nb-sidebar-link - class={cn( - "flex min-h-[2rem] items-center gap-2 rounded-lg px-3 py-1 text-[0.8125rem] font-medium no-underline focus-visible:outline-offset-[-2px]", - isCurrent - ? "bg-accent font-semibold text-foreground" - : "text-muted-foreground transition-colors duration-150 hover:bg-accent hover:text-foreground", - className, - )} - {...attrs} -> - <span class="break-words">{label}</span> - {badge && - (typeof badge === "string" ? ( - <Badge text={badge} /> - ) : ( - <Badge text={badge.text} variant={badge.variant} /> - ))} -</a> diff --git a/docs/src/components/ui/sidebar/index.ts b/docs/src/components/ui/sidebar/index.ts deleted file mode 100644 index 8b4c73a..0000000 --- a/docs/src/components/ui/sidebar/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { default as Sidebar } from "./Sidebar.astro"; -export { default as SidebarFilter } from "./SidebarFilter.astro"; -export { default as SidebarGroup } from "./SidebarGroup.astro"; -export { default as SidebarLink } from "./SidebarLink.astro"; diff --git a/docs/src/components/ui/sidebar/sidebar.client.ts b/docs/src/components/ui/sidebar/sidebar.client.ts deleted file mode 100644 index 27aad7c..0000000 --- a/docs/src/components/ui/sidebar/sidebar.client.ts +++ /dev/null @@ -1,209 +0,0 @@ -/** Sidebar runtime: filter, persistence, "/" shortcut. */ - -import { mount } from "@cloudflare/nimbus-docs/client"; - -const STORAGE_KEY = "sidebar-state"; - -interface SidebarState { - hash: string; - open: boolean[]; - scroll: number; -} - -function initSidebar(root: HTMLElement): () => void { - const teardowns: Array<() => void> = []; - const persist = root.hasAttribute("data-nb-sidebar-persist"); - - const filterTeardown = initFilter(root); - if (filterTeardown) teardowns.push(filterTeardown); - - if (persist) { - const persistTeardown = initPersistence(root); - if (persistTeardown) teardowns.push(persistTeardown); - } - - return () => teardowns.forEach((t) => t()); -} - -// --------------------------------------------------------------------------- -// Filter -// --------------------------------------------------------------------------- - -function initFilter(root: HTMLElement): (() => void) | null { - const input = root.querySelector<HTMLInputElement>("[data-nb-sidebar-filter-input]"); - // SidebarFilter is rendered *next to* Sidebar (sibling), so also look in - // the parent — preserves the existing layout where filter sits above. - const inputElement = - input ?? root.parentElement?.querySelector<HTMLInputElement>("[data-nb-sidebar-filter-input]") ?? null; - if (!inputElement) return null; - - function handleInput() { - const query = inputElement!.value.trim().toLowerCase(); - if (!query) { - resetFilter(root); - return; - } - applyFilter(root, query); - } - - function handleKeydown(e: KeyboardEvent) { - if (e.key === "Escape") { - inputElement!.value = ""; - handleInput(); - inputElement!.blur(); - } - } - - inputElement.addEventListener("input", handleInput); - inputElement.addEventListener("keydown", handleKeydown); - - return () => { - inputElement.removeEventListener("input", handleInput); - inputElement.removeEventListener("keydown", handleKeydown); - resetFilter(root); - }; -} - -function resetFilter(root: HTMLElement): void { - root.querySelectorAll<HTMLElement>("[data-nb-sidebar-hidden]").forEach((el) => { - el.removeAttribute("data-nb-sidebar-hidden"); - }); - // Reset groups opened by the filter back to their saved state. - root - .querySelectorAll<HTMLElement>("[data-nb-sidebar-group][data-nb-opened-by-filter]") - .forEach((group) => { - const trigger = group.querySelector<HTMLElement>("[data-nb-collapsible-trigger]"); - trigger?.click(); - group.removeAttribute("data-nb-opened-by-filter"); - }); -} - -function applyFilter(root: HTMLElement, query: string): void { - const links = root.querySelectorAll<HTMLElement>("[data-nb-sidebar-link]"); - const groups = root.querySelectorAll<HTMLElement>("[data-nb-sidebar-group]"); - - links.forEach((link) => link.setAttribute("data-nb-sidebar-hidden", "")); - groups.forEach((group) => group.setAttribute("data-nb-sidebar-hidden", "")); - - links.forEach((link) => { - const text = link.textContent?.toLowerCase() ?? ""; - if (!text.includes(query)) return; - link.removeAttribute("data-nb-sidebar-hidden"); - revealAncestors(link, root); - }); - - groups.forEach((group) => { - const label = group.querySelector("[data-nb-sidebar-group-label]"); - const text = label?.textContent?.toLowerCase() ?? ""; - if (!text.includes(query)) return; - group.removeAttribute("data-nb-sidebar-hidden"); - openGroup(group); - group.querySelectorAll<HTMLElement>("[data-nb-sidebar-link], [data-nb-sidebar-group]") - .forEach((child) => child.removeAttribute("data-nb-sidebar-hidden")); - }); -} - -function revealAncestors(el: HTMLElement, scope: Element): void { - let parent: HTMLElement | null = el.parentElement; - while (parent && parent !== scope) { - if (parent.hasAttribute("data-nb-sidebar-group")) { - parent.removeAttribute("data-nb-sidebar-hidden"); - openGroup(parent); - } - parent = parent.parentElement; - } -} - -function openGroup(group: HTMLElement): void { - const trigger = group.querySelector<HTMLElement>("[data-nb-collapsible-trigger]"); - if (!trigger) return; - if (trigger.getAttribute("data-nb-state") === "open") return; - group.setAttribute("data-nb-opened-by-filter", ""); - trigger.click(); -} - -// --------------------------------------------------------------------------- -// Persistence (open state + scroll) -// --------------------------------------------------------------------------- - -function initPersistence(root: HTMLElement): (() => void) | null { - // The scrollable container is the closest <aside> or the root itself. - const scrollHost: HTMLElement = root.closest("aside") ?? root; - const hash = root.dataset.nbSidebarHash ?? ""; - - function readState(): SidebarState { - const groups = root.querySelectorAll<HTMLElement>("[data-nb-sidebar-group]"); - const open: boolean[] = []; - groups.forEach((group) => { - const trigger = group.querySelector<HTMLElement>("[data-nb-collapsible-trigger]"); - open.push(trigger?.getAttribute("data-nb-state") === "open"); - }); - return { hash, open, scroll: scrollHost.scrollTop }; - } - - function save() { - try { - sessionStorage.setItem(STORAGE_KEY, JSON.stringify(readState())); - } catch {} - } - - // Observe state changes on each group's trigger. - const observer = new MutationObserver(save); - root.querySelectorAll<HTMLElement>("[data-nb-collapsible-trigger]").forEach((trigger) => { - observer.observe(trigger, { - attributes: true, - attributeFilter: ["data-nb-state"], - }); - }); - - function handleVisibility() { - if (document.visibilityState === "hidden") save(); - } - document.addEventListener("visibilitychange", handleVisibility); - window.addEventListener("pagehide", save); - - let raf = 0; - function handleScroll() { - cancelAnimationFrame(raf); - raf = requestAnimationFrame(save); - } - scrollHost.addEventListener("scroll", handleScroll); - - return () => { - observer.disconnect(); - document.removeEventListener("visibilitychange", handleVisibility); - window.removeEventListener("pagehide", save); - scrollHost.removeEventListener("scroll", handleScroll); - cancelAnimationFrame(raf); - }; -} - -// --------------------------------------------------------------------------- -// Global `/` shortcut — bound once at module load -// --------------------------------------------------------------------------- - -(function bindFilterShortcut() { - if (document.documentElement.hasAttribute("data-nb-sidebar-shortcut-bound")) return; - document.documentElement.setAttribute("data-nb-sidebar-shortcut-bound", ""); - - document.addEventListener("keydown", (e) => { - if (e.key !== "/") return; - const active = document.activeElement as HTMLElement | null; - if ( - active && - (active.tagName === "INPUT" || - active.tagName === "TEXTAREA" || - active.isContentEditable) - ) { - return; - } - const desktopInput = document.querySelector<HTMLInputElement>( - "[data-nb-sidebar-persist] ~ * [data-nb-sidebar-filter-input], [data-nb-desktop-sidebar] [data-nb-sidebar-filter-input]", - ); - if (!desktopInput) return; - e.preventDefault(); - desktopInput.focus(); - }); -})(); - -mount("[data-nb-sidebar]", initSidebar); diff --git a/docs/src/components/ui/steps/Step.astro b/docs/src/components/ui/steps/Step.astro deleted file mode 100644 index e63869d..0000000 --- a/docs/src/components/ui/steps/Step.astro +++ /dev/null @@ -1,26 +0,0 @@ ---- -/** - * Step — a single step inside <Steps>. Alternative to authoring an - * <ol><li> directly. - * - * <Steps> - * <Step title="Install">Run <code>npm install</code>.</Step> - * <Step title="Configure">Edit <code>config.json</code>.</Step> - * </Steps> - */ -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; - -interface Props extends HTMLAttributes<"div"> { - title?: string; -} - -const { title, class: className, ...attrs } = Astro.props; ---- - -<div data-step class={cn(className)} {...attrs}> - {title && <p class="m-0 font-semibold text-foreground">{title}</p>} - <div class="mt-1 text-sm leading-snug text-foreground [&_p:first-child]:mt-0 [&_p:last-child]:mb-0"> - <slot /> - </div> -</div> diff --git a/docs/src/components/ui/steps/Steps.astro b/docs/src/components/ui/steps/Steps.astro deleted file mode 100644 index 10bb330..0000000 --- a/docs/src/components/ui/steps/Steps.astro +++ /dev/null @@ -1,115 +0,0 @@ ---- -/** - * Steps — ordered list with numbered circles and connecting lines. - * Wrap a markdown ordered list. Set `start` to offset the counter. - */ -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; - -interface Props extends HTMLAttributes<"div"> { - start?: number; -} - -const { start, class: className, ...attrs } = Astro.props; ---- - -<div - data-steps - class={cn("steps", className)} - style={start !== undefined ? `--steps-start: ${start};` : undefined} - {...attrs} -> - <slot /> -</div> - -<script> - import "./steps.client"; -</script> - -<style> - .steps { - --_start: var(--steps-start, 1); - margin: 1.5rem 0; - counter-reset: step calc(var(--_start) - 1); - } - - .steps :global(ol) { - counter-reset: step calc(var(--_start) - 1); - list-style: none; - margin: 0; - padding: 0; - } - - /* Markdown mode (ol > li) AND component mode ([data-step]) share styling. - Grid layout so the circle (col 1) lines up with the first row of column 2 - via `align-items: center` — no font-metric guesswork. */ - .steps :global(ol > li), - .steps :global([data-step]) { - display: grid; - grid-template-columns: 1.75rem 1fr; - column-gap: 0.75rem; - row-gap: 0.5rem; - align-items: center; - counter-increment: step; - position: relative; - min-height: 1.75rem; - /* Cancel the prose li margin — step rhythm comes from padding/row-gap. */ - margin: 0; - padding-bottom: 1.5rem; - } - - .steps :global(ol > li:last-child), - .steps :global([data-step]:last-child) { - padding-bottom: 0; - } - - /* All non-marker content lives in column 2 — prevents the second+ child - from falling into column 1 (which is reserved for the circle). The - child selector lives inside :global() so Astro's scope hash doesn't - skip elements coming from Step.astro. */ - .steps :global(ol > li > *), - .steps :global([data-step] > *) { - grid-column: 2; - min-width: 0; - } - - /* Number marker — auto-placed in row 1 col 1, centered with col 2's first row. */ - .steps :global(ol > li)::before, - .steps :global([data-step])::before { - content: counter(step); - grid-row: 1; - grid-column: 1; - width: 1.75rem; - height: 1.75rem; - border-radius: 0.5rem; - background: var(--nb-accent); - color: var(--nb-foreground); - border: 1px solid var(--nb-border-strong); - font-size: 0.6875rem; - font-weight: 600; - display: grid; - place-items: center; - z-index: 1; - } - - /* Connecting line — runs from below the circle to the bottom of the step. */ - .steps :global(ol > li:not(:last-child))::after, - .steps :global([data-step]:not(:last-child))::after { - content: ""; - position: absolute; - left: calc(1.75rem / 2 - 0.75px); - top: 1.75rem; - bottom: 0; - width: 1.5px; - background: var(--nb-border); - } - - .steps :global(ol > li > p:first-child > strong:only-child) { - color: var(--nb-foreground); - } - - /* Vertical rhythm comes from the grid row-gap, not p margins. */ - .steps :global(ol > li > p) { - margin: 0; - } -</style> diff --git a/docs/src/components/ui/steps/index.ts b/docs/src/components/ui/steps/index.ts deleted file mode 100644 index ae327b2..0000000 --- a/docs/src/components/ui/steps/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default as Steps } from "./Steps.astro"; -export { default as Step } from "./Step.astro"; diff --git a/docs/src/components/ui/steps/steps.client.ts b/docs/src/components/ui/steps/steps.client.ts deleted file mode 100644 index c0b727a..0000000 --- a/docs/src/components/ui/steps/steps.client.ts +++ /dev/null @@ -1,32 +0,0 @@ -/** - * steps.client.ts — Safari list-role restoration. - * - * Safari strips list semantics when `list-style: none` is applied - * (which we do for the numbered counter styling). Restoring `role="list"` - * on the inner `<ol>` makes VoiceOver announce the item count again. - */ - -import { mount } from "@cloudflare/nimbus-docs/client"; - -function initSteps(root: HTMLElement): () => void { - const lists = root.querySelectorAll<HTMLOListElement>("ol"); - if ( - import.meta.env.DEV && - lists.length === 0 && - root.querySelector("[data-step]") === null && - root.children.length > 0 - ) { - console.warn( - "[nimbus] <Steps> expects an ordered list (`1.` items) or <Step> " + - "children. A bullet list renders with no numbers or connectors — " + - "use an ordered list.", - ); - } - lists.forEach((ol) => ol.setAttribute("role", "list")); - - return () => { - lists.forEach((ol) => ol.removeAttribute("role")); - }; -} - -mount("[data-steps]", initSteps); diff --git a/docs/src/components/ui/tabs/TabItem.astro b/docs/src/components/ui/tabs/TabItem.astro deleted file mode 100644 index 52e9195..0000000 --- a/docs/src/components/ui/tabs/TabItem.astro +++ /dev/null @@ -1,30 +0,0 @@ ---- -/** - * TabItem — single tab panel in the `<Tabs>` component. - * - * The `label` prop is read by `tabs.client.ts` to synthesize the matching - * trigger button. Each TabItem becomes one `[data-nb-tabs-content]` panel. - */ -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; - -interface Props extends HTMLAttributes<"div"> { - label: string; -} - -const { label, class: className, ...attrs } = Astro.props; - -if (!label) { - throw new Error("Missing required `label` prop on `<TabItem>` component."); -} ---- - -<div - role="tabpanel" - data-nb-tabs-content - data-nb-tab-label={label} - class={cn(className)} - {...attrs} -> - <slot /> -</div> diff --git a/docs/src/components/ui/tabs/Tabs.astro b/docs/src/components/ui/tabs/Tabs.astro deleted file mode 100644 index e5c356f..0000000 --- a/docs/src/components/ui/tabs/Tabs.astro +++ /dev/null @@ -1,36 +0,0 @@ ---- -/** - * <Tabs syncKey="pkg"> - * <TabItem label="npm">npm install</TabItem> - * <TabItem label="pnpm">pnpm install</TabItem> - * </Tabs> - * - * For manual control: TabsList, TabsTrigger, TabsContent. - */ -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; -import TabsList from "./TabsList.astro"; - -interface Props extends HTMLAttributes<"div"> { - /** Sync tab selection across instances with the same key via localStorage */ - syncKey?: string; -} - -const { syncKey, class: className, ...attrs } = Astro.props; ---- - -<div - data-nb-tabs - data-nb-sync-key={syncKey} - class={cn(className)} - {...attrs} -> - <TabsList /> - <div class="mt-3"> - <slot /> - </div> -</div> - -<script> - import "./tabs.client"; -</script> diff --git a/docs/src/components/ui/tabs/TabsContent.astro b/docs/src/components/ui/tabs/TabsContent.astro deleted file mode 100644 index 6e6d5c4..0000000 --- a/docs/src/components/ui/tabs/TabsContent.astro +++ /dev/null @@ -1,24 +0,0 @@ ---- -/** - * TabsContent — individual tab panel matched to a TabsTrigger by value. - */ -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; - -interface Props extends HTMLAttributes<"div"> { - /** Value matching a TabsTrigger. */ - value: string; -} - -const { value, class: className, ...attrs } = Astro.props; ---- - -<div - role="tabpanel" - data-nb-tabs-content - data-nb-value={value} - class={cn(className)} - {...attrs} -> - <slot /> -</div> diff --git a/docs/src/components/ui/tabs/TabsList.astro b/docs/src/components/ui/tabs/TabsList.astro deleted file mode 100644 index 8a1bc3c..0000000 --- a/docs/src/components/ui/tabs/TabsList.astro +++ /dev/null @@ -1,34 +0,0 @@ ---- -/** - * TabsList — container for tab triggers with animated indicator bar. - * Renders `role="tablist"` with a sliding underline indicator. - */ -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; - -interface Props extends HTMLAttributes<"div"> {} - -const { class: className, ...attrs } = Astro.props; ---- - -<div - class={cn( - // Scroll horizontally when the triggers exceed the column instead of - // leaking past the page. Scrollbar hidden so it doesn't collide with the - // underline/indicator on classic-scrollbar platforms; the strip stays - // scrollable via wheel/touch and the tabs remain keyboard-navigable. - "relative flex overflow-x-auto overscroll-x-contain border-b border-border", - "[scrollbar-width:none] [&::-webkit-scrollbar]:hidden", - className, - )} - role="tablist" - data-nb-tabs-list - {...attrs} -> - <span - class="pointer-events-none absolute bottom-0 h-0.5 rounded-t-sm bg-primary transition-[left,width] duration-200 ease-out" - data-nb-tabs-indicator - aria-hidden="true" - ></span> - <slot /> -</div> diff --git a/docs/src/components/ui/tabs/TabsTrigger.astro b/docs/src/components/ui/tabs/TabsTrigger.astro deleted file mode 100644 index dd61d9b..0000000 --- a/docs/src/components/ui/tabs/TabsTrigger.astro +++ /dev/null @@ -1,31 +0,0 @@ ---- -/** - * TabsTrigger — individual tab button within a TabsList. - * Use `value` to match with a TabsContent of the same value. - */ -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; - -interface Props extends HTMLAttributes<"button"> { - /** Value matching a TabsContent. */ - value: string; -} - -const { value, class: className, ...attrs } = Astro.props; ---- - -<button - role="tab" - type="button" - data-nb-tabs-trigger - data-nb-value={value} - class={cn( - "shrink-0 cursor-pointer px-4 py-2 text-sm font-medium leading-6 whitespace-nowrap text-muted-foreground transition-colors", - "hover:text-foreground aria-selected:text-primary", - "focus-visible:rounded-sm focus-visible:outline-2 focus-visible:outline-ring focus-visible:outline-offset-[-2px]", - className, - )} - {...attrs} -> - <slot /> -</button> diff --git a/docs/src/components/ui/tabs/index.ts b/docs/src/components/ui/tabs/index.ts deleted file mode 100644 index 07214f6..0000000 --- a/docs/src/components/ui/tabs/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export { default as Tabs } from "./Tabs.astro"; -export { default as TabItem } from "./TabItem.astro"; -export { default as TabsList } from "./TabsList.astro"; -export { default as TabsTrigger } from "./TabsTrigger.astro"; -export { default as TabsContent } from "./TabsContent.astro"; diff --git a/docs/src/components/ui/tabs/tabs.client.ts b/docs/src/components/ui/tabs/tabs.client.ts deleted file mode 100644 index b8ec414..0000000 --- a/docs/src/components/ui/tabs/tabs.client.ts +++ /dev/null @@ -1,109 +0,0 @@ -/** Wires <Tabs>; auto-detects manual triggers vs. synthesized-from-TabItem mode. */ - -import { mount, initTabs } from "@cloudflare/nimbus-docs/client"; - -const TRIGGER_CLASS = - "shrink-0 cursor-pointer px-4 py-2 text-sm font-medium leading-6 whitespace-nowrap text-muted-foreground transition-colors hover:text-foreground aria-selected:text-primary focus-visible:rounded-sm focus-visible:outline-2 focus-visible:outline-ring focus-visible:outline-offset-[-2px]"; - -let counter = 0; - -function initTabContainer(container: HTMLElement): () => void { - const id = `nb-tabs-${counter++}`; - const syncKey = container.dataset.nbSyncKey; - const tablist = container.querySelector<HTMLElement>("[role=tablist]"); - const indicator = container.querySelector<HTMLElement>("[data-nb-tabs-indicator]"); - - // Scope to this container so a nested <Tabs>'s triggers don't flip the - // parent into manual mode (or vice-versa), independent of mount order. - const existingTriggers = Array.from( - container.querySelectorAll("[data-nb-tabs-trigger]"), - ).filter((t) => (t as HTMLElement).closest("[data-nb-tabs]") === container); - const synthesize = existingTriggers.length === 0; - - if (synthesize && tablist) { - // Only this container's own panels — exclude a nested <Tabs>'s panels, - // whose nearest [data-nb-tabs] ancestor is the inner container. - const panels = Array.from( - container.querySelectorAll<HTMLElement>("[data-nb-tabs-content]"), - ).filter((p) => p.closest("[data-nb-tabs]") === container); - - panels.forEach((panel, i) => { - const label = panel.dataset.nbTabLabel ?? "Tab"; - const btn = document.createElement("button"); - btn.role = "tab"; - btn.type = "button"; - btn.className = TRIGGER_CLASS; - btn.textContent = label; - btn.setAttribute("data-nb-tabs-trigger", ""); - - const panelId = `${id}-panel-${i}`; - const tabId = `${id}-tab-${i}`; - btn.id = tabId; - btn.setAttribute("aria-controls", panelId); - panel.id = panelId; - panel.setAttribute("aria-labelledby", tabId); - - if (indicator) { - tablist.insertBefore(btn, indicator); - } else { - tablist.appendChild(btn); - } - }); - } - - const instance = initTabs({ - container, - tabSelector: "[data-nb-tabs-trigger]", - panelSelector: "[data-nb-tabs-content]", - boundarySelector: "[data-nb-tabs]", - indicator, - sync: syncKey ? { key: `ui-synced-tabs__${syncKey}` } : undefined, - // Keep the active tab within the horizontally-scrollable (scrollbar-hidden) - // strip's visible range. Fires on every activate() — including the initial - // paint and a synced/restored selection — so a right-edge active tab can't - // render off-screen with no affordance. scrollLeft directly (not - // scrollIntoView, which would also scroll the page vertically). - onActivate: (index) => { - if (!tablist) return; - const trigger = - tablist.querySelectorAll<HTMLElement>("[data-nb-tabs-trigger]")[index]; - if (!trigger) return; - const left = trigger.offsetLeft; - const right = left + trigger.offsetWidth; - if (left < tablist.scrollLeft) { - tablist.scrollLeft = left; - } else if (right > tablist.scrollLeft + tablist.clientWidth) { - tablist.scrollLeft = right - tablist.clientWidth; - } - }, - }); - - // Cross-instance sync is keyed by trigger label; duplicate labels in a group - // resolve by first-match and activate the wrong panel. Surface it in dev. - if (import.meta.env.DEV && syncKey && tablist) { - const labels = Array.from( - tablist.querySelectorAll<HTMLElement>("[data-nb-tabs-trigger]"), - ) - .filter((t) => t.closest("[data-nb-tabs]") === container) - .map((t) => (t.textContent ?? "").trim()); - const dupes = [...new Set(labels.filter((l, i) => labels.indexOf(l) !== i))]; - if (dupes.length) { - console.warn( - `[nimbus] <Tabs syncKey="${syncKey}"> has duplicate tab labels (${dupes - .map((d) => `"${d}"`) - .join(", ")}). Sync is keyed by label, so a duplicate activates the ` + - `first match. Give each tab a unique label.`, - ); - } - } - - return () => { - instance.destroy(); - // Remove synthesized triggers so re-mount doesn't double up. - if (synthesize && tablist) { - tablist.querySelectorAll("[data-nb-tabs-trigger]").forEach((b) => b.remove()); - } - }; -} - -mount("[data-nb-tabs]", initTabContainer); diff --git a/docs/src/components/ui/theme-toggle/ThemeToggle.astro b/docs/src/components/ui/theme-toggle/ThemeToggle.astro deleted file mode 100644 index 1aded43..0000000 --- a/docs/src/components/ui/theme-toggle/ThemeToggle.astro +++ /dev/null @@ -1,32 +0,0 @@ ---- -/** - * ThemeToggle — light/dark switcher. Persists to localStorage; theme - * applies to `<html data-mode="dark">` via the inline script in BaseLayout - * (no FOUC). - */ -import { Icon } from "astro-icon/components"; -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; - -interface Props extends HTMLAttributes<"button"> {} - -const { class: className, ...attrs } = Astro.props; ---- - -<button - data-nb-theme-toggle - class={cn( - "group flex items-center justify-center w-8 h-8 rounded-md text-muted-foreground hover:text-foreground hover:bg-accent transition-colors", - className, - )} - {...attrs} - aria-label="Toggle dark mode" - data-nb-state="light" -> - <Icon name="ph:sun" class="w-[1.125rem] h-[1.125rem] hidden group-data-[nb-state=dark]:block" /> - <Icon name="ph:moon" class="w-[1.125rem] h-[1.125rem] group-data-[nb-state=dark]:hidden" /> -</button> - -<script> - import "./theme-toggle.client"; -</script> diff --git a/docs/src/components/ui/theme-toggle/index.ts b/docs/src/components/ui/theme-toggle/index.ts deleted file mode 100644 index 23685f5..0000000 --- a/docs/src/components/ui/theme-toggle/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as ThemeToggle } from "./ThemeToggle.astro"; diff --git a/docs/src/components/ui/theme-toggle/theme-toggle.client.ts b/docs/src/components/ui/theme-toggle/theme-toggle.client.ts deleted file mode 100644 index a7a143a..0000000 --- a/docs/src/components/ui/theme-toggle/theme-toggle.client.ts +++ /dev/null @@ -1,31 +0,0 @@ -/** - * theme-toggle.client.ts — light/dark toggle. Writes pref to localStorage - * ("ui-mode"); BaseLayout's pre-paint script owns DOM application so view - * transitions, OS changes, and cross-tab edits stay in sync. - */ - -import { mount } from "@cloudflare/nimbus-docs/client"; - -declare global { - interface Window { - __nbApplyTheme?: () => void; - } -} - -function initThemeToggle(button: HTMLElement): () => void { - function handleClick() { - const isDark = document.documentElement.getAttribute("data-mode") === "dark"; - try { - localStorage.setItem("ui-mode", isDark ? "light" : "dark"); - } catch { - // Ignore storage errors (private mode / restricted contexts). - } - window.__nbApplyTheme?.(); - } - - window.__nbApplyTheme?.(); - button.addEventListener("click", handleClick); - return () => button.removeEventListener("click", handleClick); -} - -mount("[data-nb-theme-toggle]", initThemeToggle); diff --git a/docs/src/components/ui/toc/MobileTOC.astro b/docs/src/components/ui/toc/MobileTOC.astro deleted file mode 100644 index 9f464ee..0000000 --- a/docs/src/components/ui/toc/MobileTOC.astro +++ /dev/null @@ -1,60 +0,0 @@ ---- -/** - * MobileTOC — compact "jump to section" menu for narrow viewports. - * - * The desktop `TOC` rail only renders at `xl+` (right column). Below that - * there's no on-this-page nav, so this native `<select>` fills the gap: it - * sits under the page title, tracks the active heading via scroll-spy, and - * jumps to a section on change. - * - * A native `<select>` whose options are the page headings, indented by depth. - * The caret is an overlaid icon since native selects can't be styled, and the - * client mirrors the active heading back into the select value. - */ -import { Icon } from "astro-icon/components"; -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; -import type { TOCItem } from "@cloudflare/nimbus-docs/types"; - -interface Props extends HTMLAttributes<"nav"> { - headings: TOCItem[]; -} - -const { headings, class: className, ...attrs } = Astro.props; - -const hasHeadings = headings.length > 0; ---- - -{ - hasHeadings && ( - <nav - data-nb-mobile-toc - aria-label="On this page" - class={cn("relative", className)} - {...attrs} - > - <select - data-nb-mobile-toc-select - aria-label="Jump to section" - class="w-full appearance-none rounded-md border border-border bg-background py-2.5 pl-3 pr-9 text-sm font-medium text-foreground transition-colors hover:border-foreground/20 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50" - > - <option value="_top">Overview</option> - {headings.map((heading) => ( - <option value={heading.slug}> - {`${" ".repeat(Math.max(0, heading.depth - 2))}${heading.text}`} - </option> - ))} - </select> - <Icon - name="ph:caret-down" - aria-hidden="true" - class="pointer-events-none absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" - is:inline - /> - </nav> - ) -} - -<script> - import "./mobile-toc.client"; -</script> diff --git a/docs/src/components/ui/toc/TOC.astro b/docs/src/components/ui/toc/TOC.astro deleted file mode 100644 index 03a32a4..0000000 --- a/docs/src/components/ui/toc/TOC.astro +++ /dev/null @@ -1,95 +0,0 @@ ---- -/** - * TOC — on-this-page nav with scroll-spy. Static rail rendered inline - * (border-l + S-curve SVGs at indent changes); animated active indicator - * lives in toc.client.ts. - */ -import { cn } from "@/lib/cn"; -import type { HTMLAttributes } from "astro/types"; -import type { TOCItem } from "@cloudflare/nimbus-docs/types"; - -interface Props extends HTMLAttributes<"div"> { - headings: TOCItem[]; -} - -const { headings, class: className, ...attrs } = Astro.props; ---- - -{headings.length > 0 && ( - <div data-nb-toc class={cn("toc-container", className)} {...attrs}> - <h2 class="mb-2 text-sm font-semibold text-foreground">On this page</h2> - <nav aria-label="Table of contents" class="relative"> - <svg - data-nb-toc-rail - aria-hidden="true" - class="pointer-events-none absolute inset-0 h-full w-full overflow-visible" - fill="none" - > - <path - data-nb-toc-rail-active - class="stroke-primary opacity-0 transition-[stroke-dasharray,stroke-dashoffset,opacity] duration-300 ease-[cubic-bezier(0.32,0.72,0,1)] data-[ready=true]:opacity-100 data-[initial=true]:transition-opacity motion-reduce:transition-opacity" - stroke-width="2" - stroke-linecap="round" - /> - </svg> - - <ul class="flex list-none flex-col m-0 p-0"> - {headings.map((h, i) => { - const prevDepth = i > 0 ? headings[i - 1].depth : h.depth; - const nextDepth = i < headings.length - 1 ? headings[i + 1].depth : h.depth; - const indent = h.depth - 2; - const goingDeeper = h.depth > prevDepth; - const goingShallower = nextDepth < h.depth; - - return ( - <li> - {goingDeeper && ( - <svg - aria-hidden="true" - class="block h-2 text-border" - style={`margin-left: calc(${prevDepth - 2}rem - 0.0625rem); width: ${h.depth - prevDepth}rem;`} - viewBox="0 0 1 1" - preserveAspectRatio="none" - fill="none" - stroke="currentColor" - stroke-width="2" - overflow="visible" - > - <path d="M 0 0 C 0 0.5, 1 0.5, 1 1" vector-effect="non-scaling-stroke" /> - </svg> - )} - <a - href={`#${h.slug}`} - data-nb-toc-link - data-nb-slug={h.slug} - class="block border-l-2 border-border pl-5 py-1.5 text-[0.8125rem] leading-snug text-muted-foreground no-underline transition-colors duration-150 hover:border-foreground/20 hover:text-foreground aria-[current=true]:font-medium aria-[current=true]:text-foreground" - style={`margin-left: calc(${indent}rem - 0.125rem);`} - > - {h.text} - </a> - {goingShallower && ( - <svg - aria-hidden="true" - class="block h-2 text-border" - style={`margin-left: calc(${nextDepth - 2}rem - 0.0625rem); width: ${h.depth - nextDepth}rem;`} - viewBox="0 0 1 1" - preserveAspectRatio="none" - fill="none" - stroke="currentColor" - stroke-width="2" - overflow="visible" - > - <path d="M 1 0 C 1 0.5, 0 0.5, 0 1" vector-effect="non-scaling-stroke" /> - </svg> - )} - </li> - ); - })} - </ul> - </nav> - </div> -)} - -<script> - import "./toc.client"; -</script> diff --git a/docs/src/components/ui/toc/index.ts b/docs/src/components/ui/toc/index.ts deleted file mode 100644 index 7c9df3e..0000000 --- a/docs/src/components/ui/toc/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default as TOC } from "./TOC.astro"; -export { default as MobileTOC } from "./MobileTOC.astro"; diff --git a/docs/src/components/ui/toc/mobile-toc.client.ts b/docs/src/components/ui/toc/mobile-toc.client.ts deleted file mode 100644 index 4e6a845..0000000 --- a/docs/src/components/ui/toc/mobile-toc.client.ts +++ /dev/null @@ -1,136 +0,0 @@ -/** - * Mobile TOC — keeps the "jump to section" <select> in sync with the page. - * - * - select → page: on change, scroll to the chosen heading and suppress the - * observer briefly so the value doesn't flicker while the page scrolls to - * the target. - * - page → select: an IntersectionObserver mirrors the active heading back - * into the select value — the topmost heading inside the reading band, or - * the first/last heading clamped by scroll position when none intersect. - * - * Teardown via AbortController for view transitions; a persistent in-band set - * (like the desktop rail in `toc.client.ts`) so the active heading is stable - * when several fall inside the band at once; rect-based clamping so it doesn't - * rely on `offsetParent` layout. - */ - -import { mount } from "@cloudflare/nimbus-docs/client"; - -// Ignore the top 10% and bottom 70% of the viewport so the "active" heading is -// whatever sits near the top of the reading area. The reading band is [10%, -// 30%] of the viewport height; BAND_TOP is its upper edge, reused by the -// first/last clamp below. -const BAND_TOP = 0.1; -const ROOT_MARGIN = "-10% 0px -70% 0px"; -const SUPPRESS_MS = 1000; - -function prefersReducedMotion(): boolean { - return window.matchMedia("(prefers-reduced-motion: reduce)").matches; -} - -function initMobileToc(root: HTMLElement): () => void { - const select = root.querySelector<HTMLSelectElement>( - "[data-nb-mobile-toc-select]", - ); - if (!select) return () => {}; - - // Paired so slug/element indices stay aligned; `inBand` indexes into this. - type Heading = { slug: string; el: HTMLElement }; - const headings: Heading[] = Array.from(select.options) - .map((o) => o.value) - .filter((v) => v !== "_top") - .map((slug) => ({ slug, el: document.getElementById(slug) })) - .filter((h): h is Heading => h.el !== null); - - const controller = new AbortController(); - - // While true, observer callbacks are ignored so a click-driven scroll - // doesn't fight the value we just set. - let suppress = false; - let suppressTimer: ReturnType<typeof setTimeout> | undefined; - - function setActive(slug: string) { - if (select!.value !== slug) select!.value = slug; - } - - // select → page - select.addEventListener( - "change", - () => { - const slug = select.value; - suppress = true; - clearTimeout(suppressTimer); - suppressTimer = setTimeout(() => { - suppress = false; - }, SUPPRESS_MS); - - const behavior: ScrollBehavior = prefersReducedMotion() - ? "auto" - : "smooth"; - if (slug === "_top") { - window.scrollTo({ top: 0, behavior }); - return; - } - document.getElementById(slug)?.scrollIntoView({ behavior }); - }, - { signal: controller.signal }, - ); - - if (headings.length === 0) { - return () => { - controller.abort(); - clearTimeout(suppressTimer); - }; - } - - // page → select. Track every heading currently inside the band so the active - // one is stable when multiple short sections share it. - const inBand = new Set<number>(); - - function resolve() { - if (suppress) return; - - if (inBand.size > 0) { - // Topmost in-band heading (smallest document-order index). - setActive(headings[Math.min(...inBand)].slug); - return; - } - - // Nothing in the band — clamp to the first or last heading based on where - // the boundary headings sit relative to the band; otherwise keep the - // current value (we're mid-section between two headings). - const bandTop = window.innerHeight * BAND_TOP; - const firstTop = headings[0].el.getBoundingClientRect().top; - const lastTop = - headings[headings.length - 1].el.getBoundingClientRect().top; - if (firstTop > bandTop) { - setActive("_top"); - } else if (lastTop < bandTop) { - setActive(headings[headings.length - 1].slug); - } - } - - const observer = new IntersectionObserver( - (entries) => { - for (const entry of entries) { - const i = headings.findIndex((h) => h.el === entry.target); - if (i === -1) continue; - if (entry.isIntersecting) inBand.add(i); - else inBand.delete(i); - } - resolve(); - }, - { rootMargin: ROOT_MARGIN, threshold: 0 }, - ); - - for (const { el } of headings) observer.observe(el); - resolve(); // initial sync before the observer's first async callback - - return () => { - controller.abort(); - observer.disconnect(); - clearTimeout(suppressTimer); - }; -} - -mount("[data-nb-mobile-toc]", initMobileToc); diff --git a/docs/src/components/ui/toc/toc.client.ts b/docs/src/components/ui/toc/toc.client.ts deleted file mode 100644 index 14112f6..0000000 --- a/docs/src/components/ui/toc/toc.client.ts +++ /dev/null @@ -1,334 +0,0 @@ -/** - * Scroll-spy + animated rail indicator. Active heading tracked via a single - * IntersectionObserver; the dash slides by arc-length so it weaves through the - * rail's curves instead of cutting across. - */ - -import { mount } from "@cloudflare/nimbus-docs/client"; - -const READING_BAND = 0.25; -const BOTTOM_EPSILON = 2; -const REVEAL_PADDING = 12; - -function initToc(root: HTMLElement): () => void { - const nav = root.querySelector<HTMLElement>("nav"); - const activePath = root.querySelector<SVGPathElement>("[data-nb-toc-rail-active]"); - const links = root.querySelectorAll<HTMLElement>("[data-nb-toc-link]"); - if (!nav || !activePath || links.length === 0) return () => {}; - - const scrollHost = root.closest<HTMLElement>("[data-nb-toc-scroll-host]") ?? root; - const slugs = Array.from(links).map((l) => l.dataset.nbSlug!); - // Observe only resolvable headings, each carrying its original index, so - // scroll-spy stays aligned with the full-length links/segments even when a - // heading slugs to "" (e.g. emoji-only `## 🎉`) and has no DOM target. - const observed = slugs - .map((slug, index) => ({ el: document.getElementById(slug), index })) - .filter((o): o is { el: HTMLElement; index: number } => o.el !== null); - if (observed.length === 0) return () => {}; - const indexOfEl = new Map<HTMLElement, number>( - observed.map((o) => [o.el, o.index]), - ); - - let segments: { start: number; length: number }[] = []; - let totalLength = 0; - let currentIndex = -1; - let currentLink: HTMLElement | null = null; - let hasApplied = false; - - // Measure the rail from the DOM so the path stays pixel-perfect over the - // static gray rail, capturing each link's arc-length range as we go. - function buildRail() { - const navRect = nav!.getBoundingClientRect(); - - const m = Array.from(links).map((link) => { - const r = link.getBoundingClientRect(); - return { - x: r.left - navRect.left + 1, - yTop: r.top - navRect.top, - yBot: r.top - navRect.top + r.height, - }; - }); - - let d = ""; - const newSegments: { start: number; length: number }[] = []; - - // Measure each command in isolation (O(1)) and accumulate, rather than - // re-measuring the whole cumulatively-growing path with getTotalLength() - // on every iteration — the latter is O(n^2) and blocks the main thread on - // pages with hundreds of headings. Arc length is additive across - // contiguous commands, so summing isolated sub-paths matches the total. - // activePath doubles as the scratch measurer here; the full `d` is written - // back once at the end. - const measure = (subPath: string) => { - activePath!.setAttribute("d", subPath); - return activePath!.getTotalLength(); - }; - - let cumulative = 0; - let prevX = 0; - let prevYBot = 0; - - for (let i = 0; i < m.length; i++) { - const cur = m[i]; - - if (i === 0) { - d += `M ${cur.x} ${cur.yTop} `; - } else { - const prev = m[i - 1]; - let connector: string; - if (Math.abs(cur.x - prev.x) < 0.5) { - connector = `L ${cur.x} ${cur.yTop} `; - } else { - // Indent change → S-curve matching the static gap SVG. - const midY = (prev.yBot + cur.yTop) / 2; - connector = `C ${prev.x} ${midY}, ${cur.x} ${midY}, ${cur.x} ${cur.yTop} `; - } - d += connector; - cumulative += measure(`M ${prevX} ${prevYBot} ${connector}`); - } - - const start = cumulative; - - const seg = `L ${cur.x} ${cur.yBot} `; - d += seg; - cumulative += measure(`M ${cur.x} ${cur.yTop} ${seg}`); - - newSegments.push({ start, length: cumulative - start }); - - prevX = cur.x; - prevYBot = cur.yBot; - } - - activePath!.setAttribute("d", d); - segments = newSegments; - totalLength = cumulative; - } - - function applyActive(index: number, instant: boolean) { - const seg = segments[index]; - if (!seg) return; - - if (instant) { - activePath!.setAttribute("data-initial", "true"); - // Force recalc so only opacity transitions on first paint (no dash sweep). - void activePath!.getBoundingClientRect(); - } - - activePath!.style.strokeDasharray = `${seg.length} ${totalLength + 1}`; - activePath!.style.strokeDashoffset = `${-seg.start}`; - - if (instant) { - requestAnimationFrame(() => { - activePath!.setAttribute("data-ready", "true"); - requestAnimationFrame(() => { - activePath!.removeAttribute("data-initial"); - }); - }); - } - } - - function revealActiveLink(link: HTMLElement) { - const hostRect = scrollHost.getBoundingClientRect(); - const linkRect = link.getBoundingClientRect(); - - if (linkRect.top < hostRect.top + REVEAL_PADDING) { - scrollHost.scrollTop += linkRect.top - hostRect.top - REVEAL_PADDING; - return; - } - - if (linkRect.bottom > hostRect.bottom - REVEAL_PADDING) { - scrollHost.scrollTop += linkRect.bottom - hostRect.bottom + REVEAL_PADDING; - } - } - - function setActive(index: number) { - if (index === currentIndex) return; - currentIndex = index; - - currentLink?.removeAttribute("aria-current"); - const activeLink = links[index] ?? null; - activeLink?.setAttribute("aria-current", "true"); - currentLink = activeLink; - if (activeLink) revealActiveLink(activeLink); - - applyActive(index, !hasApplied); - hasApplied = true; - } - - const inBand = new Set<number>(); - let observedIndex = 0; - let atBottom = false; - let pinnedIndex: number | null = null; - let pinnedEnteredViewport = false; - - function resolve() { - if (pinnedIndex !== null) { - setActive(pinnedIndex); - return; - } - setActive(atBottom ? links.length - 1 : observedIndex); - } - - // rootMargin collapses the root to the top band; deepest in-band heading wins. - const spy = new IntersectionObserver( - (entries) => { - for (const entry of entries) { - const i = indexOfEl.get(entry.target as HTMLElement); - if (i === undefined) continue; - if (entry.isIntersecting) inBand.add(i); - else inBand.delete(i); - } - if (inBand.size > 0) observedIndex = Math.max(...inBand); - resolve(); - }, - { rootMargin: `0px 0px -${(1 - READING_BAND) * 100}% 0px`, threshold: 0 }, - ); - observed.forEach((o) => spy.observe(o.el)); - - function updateBottom() { - const scrollEl = document.scrollingElement ?? document.documentElement; - const maxScroll = scrollEl.scrollHeight - window.innerHeight; - const next = - maxScroll > BOTTOM_EPSILON && - scrollEl.scrollTop >= maxScroll - BOTTOM_EPSILON; - if (next !== atBottom) { - atBottom = next; - resolve(); - } - } - - function updateObservedIndex() { - const bandBottom = window.innerHeight * READING_BAND; - let nextIndex = 0; - for (const o of observed) { - if (o.el.getBoundingClientRect().top <= bandBottom) nextIndex = o.index; - else break; - } - observedIndex = nextIndex; - } - - function releaseStalePin() { - if (pinnedIndex === null) return; - const heading = document.getElementById(slugs[pinnedIndex]); - if (!heading) { - pinnedIndex = null; - pinnedEnteredViewport = false; - return; - } - - const rect = heading.getBoundingClientRect(); - const inViewport = rect.bottom >= 0 && rect.top <= window.innerHeight; - if (inViewport) { - pinnedEnteredViewport = true; - return; - } - - if (pinnedEnteredViewport) { - pinnedIndex = null; - pinnedEnteredViewport = false; - } - } - - let ticking = false; - function onScroll() { - if (ticking) return; - ticking = true; - requestAnimationFrame(() => { - updateObservedIndex(); - updateBottom(); - releaseStalePin(); - resolve(); - ticking = false; - }); - } - - function onLayoutChange() { - buildRail(); - updateObservedIndex(); - updateBottom(); - releaseStalePin(); - resolve(); - if (currentIndex >= 0) { - applyActive(currentIndex, true); - const activeLink = links[currentIndex]; - if (activeLink) revealActiveLink(activeLink); - } - } - - const controller = new AbortController(); - - nav.addEventListener( - "click", - (e) => { - if (e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return; - const link = (e.target as Element).closest<HTMLElement>("[data-nb-toc-link]"); - if (!link) return; - const i = slugs.indexOf(link.dataset.nbSlug!); - if (i === -1) return; - pinnedIndex = i; - const heading = document.getElementById(slugs[i]); - const rect = heading?.getBoundingClientRect(); - pinnedEnteredViewport = !!rect && rect.bottom >= 0 && rect.top <= window.innerHeight; - resolve(); - }, - { signal: controller.signal }, - ); - - // Hand-driven scrolling releases the pin and resumes auto-tracking. - function releasePin() { - if (pinnedIndex === null) return; - pinnedIndex = null; - pinnedEnteredViewport = false; - resolve(); - } - const NAV_KEYS = new Set([ - "ArrowUp", - "ArrowDown", - "PageUp", - "PageDown", - "Home", - "End", - " ", - "Spacebar", - ]); - window.addEventListener("wheel", releasePin, { - passive: true, - signal: controller.signal, - }); - window.addEventListener("touchmove", releasePin, { - passive: true, - signal: controller.signal, - }); - window.addEventListener( - "keydown", - (e) => { - if (NAV_KEYS.has(e.key)) releasePin(); - }, - { signal: controller.signal }, - ); - - window.addEventListener("scroll", onScroll, { - passive: true, - signal: controller.signal, - }); - window.addEventListener("resize", onLayoutChange, { - passive: true, - signal: controller.signal, - }); - - const ro = new ResizeObserver(onLayoutChange); - ro.observe(nav); - - buildRail(); - updateObservedIndex(); - updateBottom(); - resolve(); - - return () => { - controller.abort(); - ro.disconnect(); - spy.disconnect(); - }; -} - -mount("[data-nb-toc]", initToc); diff --git a/docs/src/content.config.ts b/docs/src/content.config.ts deleted file mode 100644 index 41a9c34..0000000 --- a/docs/src/content.config.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { defineCollection } from "astro:content"; -// `z` re-exported from `astro:content` is deprecated; import it from -// `astro/zod` (the pattern nimbus-docs' own schema helpers document). -import { z } from "astro/zod"; -import { docsCollection, partialsCollection } from "@cloudflare/nimbus-docs/content"; - -export const collections = { - docs: defineCollection( - docsCollection({ - schemaFields: { - // Nimbus docs are agent-friendly by default. Set `audience: human` - // to flag a page that's written primarily for human readers. - audience: z.literal("human").optional(), - }, - }), - ), - partials: defineCollection(partialsCollection()), -}; diff --git a/docs/src/content/docs/editor-stack.mdx b/docs/src/content/docs/editor-stack.mdx deleted file mode 100644 index 4a4b056..0000000 --- a/docs/src/content/docs/editor-stack.mdx +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: Editor Stack -description: LazyVim・lazygit・herdr を組み合わせたターミナル中心の編集環境。 -sidebar: - order: 4 ---- - -役割が重ならない 3 つを組み合わせている: - -| Tool | Role | Config | -| --- | --- | --- | -| [LazyVim](https://www.lazyvim.org/) | Neovim ディストリビューション(エディタ) | `home/.config/nvim` | -| [lazygit](https://github.com/jesseduffield/lazygit) | Git の TUI | `home/.config/lazygit/config.yml` | -| [herdr](https://herdr.dev/) | コーディングエージェント用のマルチプレクサ | `home/.config/herdr/config.toml` | -| [Crit](https://crit.md/) | AI エージェント向けのローカルレビューツール | なし(単一バイナリ) | - -herdr は tmux のエージェント版で、Claude Code や Codex を PTY セッションとして常駐させ、状態(作業中 / 待ち / 完了)を一覧しながら切り替える。サーバー側で生き続けるので、ターミナルを閉じても SSH で attach し直せる。 - -## Prerequisites - -`mise run install-apps`(macOS Brewfile)でインストールされる: - -- `neovim` -- `herdr` -- `lazygit` -- `ripgrep`、`fd`(LazyVim の grep / ファイル検索に必須) -- `tree-sitter-cli`(nvim-treesitter がパーサーをビルドするのに必要。brew の `tree-sitter` はライブラリのみで CLI は別 formula) -- `crit`(エージェントの変更をブラウザ UI で行コメントレビューする。`crit <file>` / `crit <url>` で起動) - -Crit を Claude Code から `/crit` スラッシュコマンドで使う場合は、プラグインを別途インストールする(プラグイン実体は `~/.claude/plugins` にランタイム管理されるため symlink 対象にはしない): - -```bash -claude plugin marketplace add tomasz-tomczyk/crit -claude plugin install crit@crit -``` - -## Setup - -```bash -mise run install-apps -mise run deploy -nvim --headless "+Lazy! sync" +qa # プラグインの初回インストール -``` - -`nvim` の初回起動でも同じ同期が走るので、headless での実行は省略してもよい。 - -## How it is linked - -`~/.config/nvim` は**ディレクトリごと**リンクしている。LazyVim が `lazy-lock.json` をリンク越しにリポジトリへ書き戻すため、プラグインのバージョンが git で追跡される。プラグイン本体は `~/.local/share/nvim`、セッション状態は `~/.local/state/nvim` に入るのでリポジトリは汚れない。 - -`~/.config/herdr` はログ・ソケット・`session.json` が同じディレクトリに書かれるので、`config.toml` だけを**ファイル単位**でリンクしている(`~/.config/lazygit` と同じ扱い)。 - -## herdr config - -設定なしでも動く。このリポジトリでは 3 点だけ変えている: - -- `theme.name = "terminal"` — Ghostty のテーマ(Birds Of Paradise)にそのまま追従させる -- `experimental.switch_ascii_input_source_in_prefix` — prefix(`ctrl+b`)を押している間だけ macOS の入力ソースを ASCII に切り替える。日本語入力中でも prefix コマンドが通る -- `experimental.reveal_hidden_cursor_for_cjk_ime` — Claude Code / Codex のように自前でカーソルを描く TUI で、IME の候補ウィンドウがカーソルを追従するようにする。`cjk_ime_agents` で対象を絞っているのは、全面適用すると Neovim のノーマルモードでカーソルが二重に見えるため - -コメント付きのデフォルト全文は `herdr --default-config`、設定の検証は `herdr config check`、起動中のサーバーへの反映は `herdr server reload-config`。 - -## Daily use - -```bash -herdr # セッションを起動 / attach(prefix は ctrl+b、ヘルプは prefix+?) -nvim # LazyVim(リーダーキーは space) -lazygit # Git TUI -``` - -LazyVim のプラグイン追加は `home/.config/nvim/lua/plugins/` に `.lua` を置くだけでよい(`example.lua` が雛形)。`lazy-lock.json` の差分はそのままコミットする。 diff --git a/docs/src/content/docs/mise-bootstrap.mdx b/docs/src/content/docs/mise-bootstrap.mdx deleted file mode 100644 index e01a04f..0000000 --- a/docs/src/content/docs/mise-bootstrap.mdx +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: mise bootstrap -description: macOS / Linux の新規マシンセットアップを mise bootstrap で収束させる仕組み。 -sidebar: - order: 3 ---- - -## Overview - -macOS / Linux の新規マシンセットアップは [`mise bootstrap`](https://mise.jdx.dev/bootstrap.html) が主役。 - -curl インストーラー(`install`)は、mise が存在する **前** に必要な鶏卵問題のステップだけを担当する: - -1. このリポジトリを `~/Codes/dotfiles` に clone(または pull) -2. macOS では Xcode Command Line Tools をインストール(`init/init-macos.sh`) -3. Homebrew をインストール(Brewfile / `install-apps` で引き続き使用) -4. mise 自体をインストール(`curl https://mise.run | sh`) -5. `mise trust` + `mise bootstrap --yes --update` を実行 - -以降、宣言的なマシン状態は以下に置く: - -- [`.miserc.toml`](https://github.com/umeruma/dotfiles/blob/main/.miserc.toml) — early-init(`auto_env = true` で OS 別設定を読み込む) -- [`mise.toml`](https://github.com/umeruma/dotfiles/blob/main/mise.toml) — 共通の bootstrap user/task と mise タスク -- [`mise.linux.toml`](https://github.com/umeruma/dotfiles/blob/main/mise.linux.toml) / [`mise.macos.toml`](https://github.com/umeruma/dotfiles/blob/main/mise.macos.toml) — OS パッケージ - -## What `mise bootstrap` does here - -| Phase | Config | This repo | -| --- | --- | --- | -| packages | `mise.linux.toml` の `[bootstrap.packages]` | Linux: `apt:build-essential`、`apt:zsh` | -| dotfiles | `mise.dotfiles.toml` / `mise.macos.toml` の `[dotfiles]` | `home/` の宣言的 symlink allowlist(実行時書き込みのある dir はファイル単位、静的な設定 dir はディレクトリごと) | -| macOS defaults | `mise.macos.toml` の `[bootstrap.macos.*]` / `[bootstrap.macos.defaults]` | Dock・Finder・キーボードなどスカラー値の設定(配列 / PlistBuddy は未移行) | -| user | `[bootstrap.user]` | `login_shell = "/bin/zsh"`(`install` 内の旧 `chsh` ブロックを置き換え) | -| task | `[tasks.bootstrap]` | `mise run deploy` を実行(Unix では `[dotfiles]`、Windows では PSDotFiles の冪等な再適用) | - -再実行しても安全: 宣言的なフェーズは収束するし、`bootstrap` タスクは冪等に保つ。 - -マシンを変更せずにプレビュー: - -``` -dot && mise bootstrap --dry-run --yes -``` - -不足しているものの確認: - -``` -dot && mise bootstrap status --missing -``` - -macOS defaults の差分(macOS のみ): - -``` -dot && mise bootstrap macos defaults status -dot && mise bootstrap macos defaults apply --dry-run --yes -``` - -## What stays outside bootstrap (for now) - -以下は意図的に bootstrap の外にある — Windows 専用、対話的、あるいは bootstrap の宣言的な仕組みより既存の方がリッチなもの: - -| Piece | Why | -| --- | --- | -| `install-win` + `win/*.winget` | Windows は winget / PSDotFiles を使う。mise bootstrap のパッケージ機構は winget をカバーしない | -| `macos/Brewfile` / `linux/Brewfile`(`mise run install-apps` 経由) | 意図的: `brew bundle add` / `brew bundle cleanup` の追加・追跡ワークフローが便利なため。bootstrap にはデプロイに必須のパッケージだけ残す | -| Xcode CLT | 対話的な `xcode-select --install` | - -## Gradual migration ideas - -experimental な bootstrap に慣れてきたら: - -1. **Shell activation** — `.zshrc` に書いている `eval "$(mise activate zsh)"` を mise 管理にしたければ、オプションの `[bootstrap.mise_shell_activate]` を使う - -(完了済み: macOS defaults → `[bootstrap.macos.defaults]`、stow → `[dotfiles]`。予定なし: Brewfile → `[bootstrap.packages]` — `brew bundle` ワークフローは欠点ではなく機能なので) - -`mise bootstrap` はまだ experimental 扱いのため、このリポジトリの `mise.toml` では `settings.experimental = true` を設定している。 - -## Related commands - -``` -mise run deploy # home/ を symlink(bootstrap タスクの実体でもある) -mise run install-apps # Brewfile / winget アプリ(opt-in) -mise run theme # Terminal.app テーマ -``` diff --git a/docs/src/content/docs/overview.mdx b/docs/src/content/docs/overview.mdx deleted file mode 100644 index 8fff7b4..0000000 --- a/docs/src/content/docs/overview.mdx +++ /dev/null @@ -1,115 +0,0 @@ ---- -title: dotfiles -description: umeruma の dotfiles を macOS / Linux / Windows にインストール・デプロイする。 -sidebar: - order: 1 ---- - -## install (macOS / Linux) -この dotfiles リポジトリは `~/Codes/dotfiles` に配置する前提で作られている。 - -実行前にスクリプトの中身を確認する: -[https://dot.umeru.ma/install](https://dot.umeru.ma/install) - -Terminal.app を開いて実行: - -``` -bash -c "$(curl -fsSL https://dot.umeru.ma/install)" -``` -リポジトリを `~/Codes/dotfiles` に clone して dotfiles をセットアップする。すでに存在する場合は最新を pull してから続行する。 - -clone 後、インストーラーは(必要なら)mise を入れて [`mise bootstrap`](https://mise.jdx.dev/bootstrap.html) を実行し、OS パッケージ・ログインシェル・`mise run deploy` を収束させる。詳細: [mise bootstrap](/mise-bootstrap) - -bash と curl のオプションのメモ: - -bash: -- `-c`: 渡した文字列を bash コマンドとして実行する(例: `bash -c "echo hello"` は `hello` を出力) - -curl: -- `-f` (`--fail`): サーバーエラー時に静かに失敗する(出力なし・非ゼロ終了) -- `-s` (`--silent`): サイレントモード。進捗やエラーメッセージを表示しない -- `-S` (`--show-error`): `-s` と併用時、失敗時のエラーメッセージだけは表示する -- `-L` (`--location`): HTTP リダイレクトを自動で追う - - -## install (Windows) - -PowerShell でのセットアップ(`install-win`、PSDotFiles、winget)は [Windows](/windows) を参照。 - -## jump to dotfiles - -ターミナルからは以下で dotfiles ディレクトリにすぐ移動できる: -``` -dot -``` - -.zshenv と .zshrc に以下がある: -``` -# on .zshenv -export DOTFILES="$HOME/Codes/dotfiles" - -# on .zshrc -alias dot='cd $DOTFILES' -``` - -## Deploy dotfiles - -dotfiles をホームディレクトリにデプロイするには: - -``` -dot && mise run deploy -``` - -### How it works - -symlink は mise の `[dotfiles]` セクションで宣言的に管理している。[`mise.dotfiles.toml`](https://github.com/umeruma/dotfiles/blob/main/mise.dotfiles.toml)(クロスプラットフォーム。`.miserc.toml` の `env = ["dotfiles"]` で読み込む)と [`mise.macos.toml`](https://github.com/umeruma/dotfiles/blob/main/mise.macos.toml)(macOS 専用)の 2 つで、各エントリは明示的な allowlist になっている: - -```toml -[dotfiles] -"~/.zshrc" = { source = "home/.zshrc", mode = "symlink" } -``` - -実行時に書き込みが発生するディレクトリ(ログや状態。例: `~/.config/karabiner`、`~/.config/micro`、`~/.config/lazygit`、`~/.config/herdr`)は**ファイル単位**でリンクし、アプリの状態がリポジトリに漏れないようにしている。純粋に静的な設定ディレクトリ(`~/.config/ghostty`、`~/.config/sheldon`)はディレクトリごとリンクする。 - -`~/.config/nvim` は例外で、書き込みが発生するがディレクトリごとリンクしている。LazyVim が `lazy-lock.json` をリンク越しにリポジトリへ書き戻し、プラグインのバージョンが git で追跡されるため。詳細: [Editor Stack](/editor-stack) - -よく使うコマンド: - -``` -mise dotfiles status # エントリごとに applied / differs / missing を表示 -mise run clean # home/ を指す symlink をすべて削除(dangling 含む) -dottrack <path> # 既存ファイルの追跡を開始(エントリ追加 + リンク) -``` - -Agent skills(`home/.agents/skills/`)は全エージェント共通の single source of truth: `~/.agents` はディレクトリごと 1 本のリンク(Cursor と GitHub Copilot は `~/.agents/skills/` を直接読む)で、Claude Code には `~/.claude/skills/` にスキル単位のリンクを張る。ディレクトリごとリンクするのは意図的で、`npx skills` でインストールしたスキルと `.skill-lock.json` がリンク越しにリポジトリ内へ入るため、インストールが git で追跡される。 - -## macOS defaults - -macOS の設定は `mise bootstrap` が [`mise.macos.toml`](https://github.com/umeruma/dotfiles/blob/main/mise.macos.toml)(`[bootstrap.macos.*]` と `[bootstrap.macos.defaults]`)から適用する。再収束させる、または差分を確認するには: - -``` -dot && mise bootstrap macos defaults status -``` - -詳細: [mise bootstrap](/mise-bootstrap) - -## macOS Terminal theme -macOS の Terminal にテーマを適用するには: -``` -dot && mise run theme -``` - -適用するとこうなる: - -<img alt="" src="https://i.gyazo.com/424031983a2fd63e67958a214050513e.png"/> - -## tech stack - -- [mise](https://mise.jdx.dev/) — タスクランナー兼マシンブートストラップ -- [sheldon](https://github.com/rossmacarthur/sheldon#readme) — zsh プラグインマネージャー -- [Homebrew](https://docs.brew.sh/Manpage) — パッケージマネージャー(Brewfile / `install-apps`) -- [mise `[dotfiles]`](https://mise.jdx.dev/bootstrap.html) — `home/` の宣言的 symlink デプロイ - -## website - -[dot.umeru.ma](https://dot.umeru.ma) diff --git a/docs/src/content/docs/setup-hard/ime-switching.md b/docs/src/content/docs/setup-hard/ime-switching.md deleted file mode 100644 index 55b6452..0000000 --- a/docs/src/content/docs/setup-hard/ime-switching.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: IME Switching -description: US 配列(HHKB)での日本語/英語 IME 切り替えを macOS は Karabiner、Windows は kanata で実現する設定。 -sidebar: - order: 1 ---- - -## 方針 - -キーボードは [HHKB の US(ANSI)配列](/setup-hard/) を使っているため、JIS 配列の「英数」「かな」キーが物理的に存在しない。そこで両 OS とも **修飾キーの単押し(tap)** に IME 切り替えを割り当てて、同じ操作感に揃えている: - -| 操作 | macOS | Windows | -| --- | --- | --- | -| **左 ⌘ / 左 Win 単押し** | 英数(英語入力) | English (US) IME に切り替え | -| **右 ⌘ / 右 Win 単押し** | かな(日本語入力) | 日本語 IME に切り替えてかな ON | -| 長押し・他キーと同時 | 通常の修飾キーとして動作 | 通常の Win キーとして動作 | - -トグル(`Win+Space` や `Alt+Shift` の循環切り替え)ではなく **常に特定の言語を直接選択** するので、今どちらの IME か気にせず決め打ちで押せる。 - -## macOS: Karabiner-Elements - -[Karabiner-Elements](https://karabiner-elements.pqrs.org/) の complex modification で ⌘ キーの単押しに `japanese_eisuu` / `japanese_kana` を割り当てている。設定は [`home/.config/karabiner/karabiner.json`](https://github.com/umeruma/dotfiles/blob/main/home/.config/karabiner/karabiner.json)。 - -自作ルールではなく、公式の [complex modifications ルール集](https://ke-complex-modifications.pqrs.org/#japanese)「For Japanese (日本語環境向けの設定)」からインポートしたテンプレート **「コマンドキーを単体で押したときに、英数・かなキーを送信する。(左コマンドキーは英数、右コマンドキーはかな) (rev 3)」** をそのまま使っている(インポート済みの定義は [`assets/complex_modifications/`](https://github.com/umeruma/dotfiles/blob/main/home/.config/karabiner/assets/complex_modifications/1731064377.json) にある)。挙動は: - -- 左 ⌘ 単押し → `japanese_eisuu`(英数) -- 右 ⌘ 単押し → `japanese_kana`(かな) -- 長押し判定は `to_if_held_down_threshold_milliseconds: 100`。`lazy: true` にしているので、他のキーと組み合わせたときは通常の ⌘ として即座に働く - -そのほかこのプロファイルでは: - -- `caps_lock` → `left_control` -- 特定のキーボード(デバイス ID 指定)で Command / Option の位置を入れ替え -- `virtual_hid_keyboard` は `ansi` を指定(US 配列として扱う) - -デプロイは mise の `[dotfiles]` で行うが、Karabiner は `~/.config/karabiner` に実行時の書き込みがあるため **ファイル単位** で symlink している([How it works](/overview#how-it-works) 参照)。Karabiner-Elements 本体は `mise run install-apps`(Brewfile)でインストール。 - -## Windows: kanata - -Windows には英数・かなキー相当の仕組みがないので、[kanata](https://github.com/jtroo/kanata)(`jtroo.kanata_gui`、winget でインストール)で Win キーの tap-hold を組んでいる。設定は [`home-win/Documents/kanata/kanata.kbd`](https://github.com/umeruma/dotfiles/blob/main/home-win/Documents/kanata/kanata.kbd)。 - -- **左 Win 単押し** → `Alt+Shift+2` を送信 → English (US) IME に切り替え -- **右 Win 単押し** → `Alt+Shift+1` を送信 → 日本語 IME に切り替え、50ms 待ってから かなキー(scan code 22)を送信して IME を ON -- `tap-hold-press` を使っているので、他のキーが押された瞬間に hold(通常の Win キー)へ確定する。`Win+S` などの組み合わせが誤って IME 切り替えにならず、Karabiner と同じ感覚で使える - -Windows 側は IME を直接選択する API がないため、**言語ごとの切り替えホットキー**(`Alt+Shift+1` / `Alt+Shift+2`)を OS 側で一度割り当てておく必要がある。この手順・自動起動(スタートアップ登録)・注意点は [Windows ページの Input language hot keys](/windows/#input-language-hot-keys-required) にまとめてある。 - -補足: 左 Win を「English (US) IME への切り替え」ではなく「日本語 IME のまま英数(直接入力)にする」動作にしたい場合は、`kanata.kbd` 内の `@lwin-jp` エイリアスに差し替える。 - -なお、Blender の Script Editor など一部のアプリでは kanata のマップが効かないことがある。 diff --git a/docs/src/content/docs/windows.mdx b/docs/src/content/docs/windows.mdx deleted file mode 100644 index c77bed8..0000000 --- a/docs/src/content/docs/windows.mdx +++ /dev/null @@ -1,171 +0,0 @@ ---- -title: Windows -description: install-win、PSDotFiles、winget、Kanata による PowerShell セットアップ。 -sidebar: - order: 2 ---- - -## Overview - -Windows のセットアップでは以下を使う: - -- **[PSDotFiles](https://github.com/ralish/PSDotFiles)** — [`home-win/`](https://github.com/umeruma/dotfiles/tree/main/home-win) を `$HOME` に symlink する -- **[WinGet Configuration](https://learn.microsoft.com/en-us/windows/package-manager/configuration/)** — [`win/`](https://github.com/umeruma/dotfiles/tree/main/win) 以下のファイルでパッケージをインストールする - -macOS / Linux では mise の宣言的な `[dotfiles]` allowlist と [`home/`](https://github.com/umeruma/dotfiles/tree/main/home) を使う。 - -## Prerequisites - -新規またはリセット直後の Windows では、まず Microsoft Store から **App Installer**(winget)を入れる。自分で用意する必要があるのは winget だけで、**Git**・**PowerShell 7**・**mise** はすべてスクリプトが winget 経由で自動インストールする。 - -install-win 実行時に winget がない場合、スクリプトが App Installer の Store ページを開いて案内を表示して停止する。App Installer を入れてからコマンドを再実行する。 - -## install-win - -このリポジトリは `~/Codes/dotfiles` に配置する。 - -実行前にスクリプトを確認する: -[https://dot.umeru.ma/install-win](https://dot.umeru.ma/install-win) - -install-win の前に **開発者モード** を有効にする(symlink 作成に必要)。 - -設定ページを直接開くには: - -```powershell -Start-Process "ms-settings:developers" -``` - -**PowerShell** で実行(ブートストラップは Windows PowerShell 5.1 でも OK。途中で PowerShell 7 で再起動する): - -```powershell -irm https://dot.umeru.ma/install-win | iex -``` - -やっていること: - -1. 必要なら PowerShell 7 をインストール -2. リポジトリを `~/Codes/dotfiles` に clone(既存なら最新を pull) -3. [`win/bootstrap.winget`](https://github.com/umeruma/dotfiles/blob/main/win/bootstrap.winget) で `winget configure` を実行(PowerShell 7、Git、mise) -4. PowerShell Gallery から **PSDotFiles** モジュールをインストール -5. `mise run deploy` で `home-win/` をリンク - -Windows PowerShell 5.1 から始めた場合、スクリプトは PowerShell 7 で自分自身を再起動して残りを実行する。完了後もターミナルは開いたままで、最後に GUI アプリ用の `mise run install-apps` を案内するバナーが表示される。 - -## Deploy dotfiles - -**PowerShell 7** でリポジトリのルートから: - -``` -cd $env:USERPROFILE\Codes\dotfiles -mise run deploy -``` - -これは [`script/deploy.ps1`](https://github.com/umeruma/dotfiles/blob/main/script/deploy.ps1) 経由で `Install-DotFiles home-win` を実行する。 - -symlink を削除するには: - -``` -mise run clean -``` - -## Install applications - -GUI などのアプリは [`win/apps.winget`](https://github.com/umeruma/dotfiles/blob/main/win/apps.winget) に列挙している: - -``` -mise run install-apps -``` - -パッケージの追加・削除はこのファイルを編集する。各エントリは `Microsoft.WinGet.DSC/WinGetPackage` に winget パッケージの `id` を指定する形式。 - -設定ファイルのプレビュー: - -``` -winget configure show -f win/apps.winget -``` - -`winget configure` には **WinGet v1.6.2631** 以降が必要。 - -## Kanata (keyboard remapper) - -macOS の Karabiner と揃えた IME 切り替えの全体像は [IME Switching](/setup-hard/ime-switching/) を参照。 - -[Kanata](https://github.com/jtroo/kanata) は [`win/apps.winget`](https://github.com/umeruma/dotfiles/blob/main/win/apps.winget)(`jtroo.kanata_gui`)でインストールする。ポータブル zip パッケージで、winget が GUI バイナリを `%LOCALAPPDATA%\Microsoft\WinGet\Links` 配下のコマンドエイリアス `kanata_windows_gui_winIOv2_x64` として登録するため、手動ダウンロードは不要。 - -設定は [`home-win/Documents/kanata/kanata.kbd`](https://github.com/umeruma/dotfiles/blob/main/home-win/Documents/kanata/kanata.kbd) にあり、PSDotFiles が `~\Documents\kanata\kanata.kbd` に symlink する。HHKB(US 配列)+ **2 つの入力方式**(English (US) IME + 日本語 Microsoft IME)を前提にしている: - -- **左 Win タップ** → English (US) IME に切り替え -- **右 Win タップ** → 日本語 IME に切り替えてかなを ON -- 長押しや他キーとの組み合わせ → Win キーは通常どおり動作 - -### Input language hot keys (required) - -Kanata は特定の IME を直接選択できない — Windows が公開しているのは循環切り替えのショートカット(`Win+Space` / `Alt+Shift`)だけ。そこで設定では言語ごとの切り替えホットキーを送信しているため、一度だけ割り当てが必要: - -```powershell -Start-Process "ms-settings:typing" -``` - -**キーボードの詳細設定 → 入力言語のホットキー**(クラシックな *テキスト サービスと入力言語 → キーの詳細設定* ダイアログが開く)で以下を設定する: - -| Action | Key sequence | -|---|---| -| **日本語 - Microsoft IME** へ切り替え | `左Alt+Shift+1` | -| **英語 (米国)** へ切り替え | `左Alt+Shift+2` | - -![言語ごとの切り替えホットキーを割り当てたキーの詳細設定ダイアログ](https://i.gyazo.com/bfcd161911640184eb11aaee778d8b52.png) - -これらは [`kanata.kbd`](https://github.com/umeruma/dotfiles/blob/main/home-win/Documents/kanata/kanata.kbd) の `A-S-1` / `A-S-2` と一致させる必要がある。アプリのショートカットと衝突する場合は、両方で別の数字(例: `Ctrl+Shift+1/2` → `C-S-1` / `C-S-2`)に変える。 - -Windows 11 24H2 では旧来の `rundll32 ... input.dll ... {HOTKEYS}` 呼び出しが効かないことが多いので、上記の `ms-settings:typing` 経由を使う。 - -### Autostart - -ログイン時に kanata を自動起動するには、(`install-apps` と `deploy` の後に)一度だけスタートアップのショートカットを作成する: - -``` -mise run setup-kanata -``` - -これはスタートアップフォルダに `Kanata.lnk` を作成し、winget でインストールした exe を `--cfg ~\Documents\kanata\kanata.kbd` 付きで指す(最小化してシステムトレイに常駐)。ログアウトせずすぐ起動するには: - -```powershell -Start-Process "$([Environment]::GetFolderPath('Startup'))\Kanata.lnk" -``` - -`winIOv2` バリアントは Windows の LLHOOK + SendInput を使うため、ドライバも管理者権限も不要。ただし管理者権限(UAC)で動くウィンドウには効かない。そこでもリマップしたい場合は、スタートアップショートカットの代わりにタスクスケジューラでログオン時に最上位特権で起動する。 - -## PowerShell profile and mise - -[`home-win/Documents/PowerShell/Microsoft.PowerShell_profile.ps1`](https://github.com/umeruma/dotfiles/blob/main/home-win/Documents/PowerShell/Microsoft.PowerShell_profile.ps1) で以下を設定している: - -- `$env:DOTFILES` -- `dot` でリポジトリに移動 -- シェル起動時に `mise activate pwsh` - -**PowerShell 7**(`pwsh`)を使うこと。Windows PowerShell 5.1 での mise activation はサポートされない。[mise PowerShell discussion](https://github.com/jdx/mise/discussions/6733) を参照。 - -## Developer Mode (symlinks) - -PSDotFiles はシンボリックリンクを作成する。**開発者モード** を有効にする: - -**設定 → システム → 開発者向け → 開発者モード** - -またはデプロイ用シェルを管理者として実行する。 - -`$PROFILE` がすでに存在する場合は、最初のデプロイ前にバックアップする。競合時は PSDotFiles がエラーを報告するので、手動で解決するか、先に PSDotFiles の `-WhatIf` で確認する: - -```powershell -$DotFilesPath = "$HOME\Codes\dotfiles" -Import-Module PSDotFiles -Install-DotFiles home-win -WhatIf -``` - -## `home/` vs `home-win/` - -| Directory | Used on | Tool | -|------------|----------------|-------------| -| `home/` | macOS, Linux | mise `[dotfiles]` | -| `home-win/`| Windows | PSDotFiles | - -Windows 専用のファイルは `home-win/` に置き、mac 専用ツール(Karabiner、Ghostty など)が Windows にデプロイされないようにする。 diff --git a/docs/src/layouts/BaseLayout.astro b/docs/src/layouts/BaseLayout.astro deleted file mode 100644 index 7fe399c..0000000 --- a/docs/src/layouts/BaseLayout.astro +++ /dev/null @@ -1,118 +0,0 @@ ---- -import "@fontsource-variable/inter"; -import "@fontsource-variable/jetbrains-mono"; -import "../styles/globals.css"; -import "../styles/prose.css"; -import { config } from "virtual:nimbus/config"; -import { getCollectionLlmsUrl, getVersionStatus } from "@cloudflare/nimbus-docs"; -import AgentDirective from "@/components/AgentDirective.astro"; -import { SearchDialog } from "@/components/ui/search"; -import NimbusHead from "@cloudflare/nimbus-docs/components/NimbusHead.astro"; -import type { BasePageProps } from "@cloudflare/nimbus-docs/types"; - -type Props = BasePageProps; - -const { - title, - description, - noindex, - markdownUrl, - socialImage, - lastUpdated, - head: pageHead = [], - collection, - entryId, -} = Astro.props; - -const lang = config.locale ?? "en"; -// Per-page agent-index pointer. For pages in non-primary or version -// collections, this resolves to `/<prefix>/llms.txt` (e.g. `/v0/llms.txt` -// for a v0 docs page, `/blog/llms.txt` for a blog post). Falls back to -// the root `/llms.txt` when no collection is provided. -// Hidden-version pages don't advertise an agent index (the per-version -// llms.txt isn't emitted for them); suppress the AgentDirective entirely. -const versionStatus = collection ? await getVersionStatus(collection) : null; -const isHiddenVersion = versionStatus?.isHidden === true; -const llmsIndexPath = collection - ? await getCollectionLlmsUrl(collection) - : "/llms.txt"; -const llmsUrl = Astro.site - ? new URL(llmsIndexPath, Astro.site).href - : llmsIndexPath; ---- - -<!doctype html> -<html lang={lang}> - <head> - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1" /> - - <script is:inline> - (() => { - const KEY = "ui-mode"; - const media = window.matchMedia("(prefers-color-scheme: dark)"); - - const readPref = () => { - try { - const v = localStorage.getItem(KEY); - return v === "dark" || v === "light" ? v : null; - } catch { - return null; - } - }; - - const resolveMode = () => readPref() ?? (media.matches ? "dark" : "light"); - - const applyTheme = () => { - const root = document.documentElement; - const mode = resolveMode(); - if (mode === "dark") root.setAttribute("data-mode", "dark"); - else root.removeAttribute("data-mode"); - root.style.colorScheme = mode; - document.querySelectorAll("[data-nb-theme-toggle]").forEach((b) => { - b.setAttribute("data-nb-state", mode); - }); - }; - - applyTheme(); - media.addEventListener("change", () => { - if (!readPref()) applyTheme(); - }); - window.addEventListener("storage", (e) => { - if (e.key === KEY) applyTheme(); - }); - - window.__nbApplyTheme = applyTheme; - })(); - </script> - - <NimbusHead - title={title} - description={description} - noindex={noindex} - markdownUrl={markdownUrl} - socialImage={socialImage} - lastUpdated={lastUpdated} - head={pageHead} - collection={collection} - entryId={entryId} - /> - </head> - <body class="min-h-screen bg-background text-foreground antialiased"> - <a - href="#main-content" - class="sr-only focus:not-sr-only focus:absolute focus:left-2 focus:top-2 focus:z-100 focus:rounded-md focus:bg-primary focus:px-4 focus:py-2 focus:text-sm focus:font-medium focus:text-primary-foreground focus:no-underline focus-visible:outline-2 focus-visible:outline-ring focus-visible:outline-offset-2" - > - Skip to content - </a> - {markdownUrl && !isHiddenVersion && <AgentDirective markdownUrl={markdownUrl} llmsUrl={llmsUrl} />} - <slot /> - {config.search !== false && <SearchDialog />} - - <script> - import { codeCopy, headingAnchors } from "@cloudflare/nimbus-docs/client"; - codeCopy(); - headingAnchors(); - </script> - </body> -</html> diff --git a/docs/src/layouts/DocsLayout.astro b/docs/src/layouts/DocsLayout.astro deleted file mode 100644 index 77b6473..0000000 --- a/docs/src/layouts/DocsLayout.astro +++ /dev/null @@ -1,350 +0,0 @@ ---- -/** - * DocsLayout — three-column docs layout. - * - * Named slots for overrides (all optional, defaults render otherwise): - * header, sidebar, toc, page-title, content-footer, pagination - */ -import { Icon } from "astro-icon/components"; -import BaseLayout from "./BaseLayout.astro"; -import Header from "@/components/Header.astro"; -import { Banner } from "@/components/ui/banner"; -import { Sidebar, SidebarFilter } from "@/components/ui/sidebar"; -import { TOC, MobileTOC } from "@/components/ui/toc"; -import { Breadcrumbs } from "@/components/ui/breadcrumbs"; -import { Pagination } from "@/components/ui/pagination"; -import { PageActions } from "@/components/ui/page-actions"; -import { Badge } from "@/components/ui/badge"; -import type { DocsPageProps } from "@cloudflare/nimbus-docs/types"; -import { getVersionStatus, getVersionAlternates } from "@cloudflare/nimbus-docs"; - -type Props = DocsPageProps & { audience?: "human" }; - -const { title, description, sidebar, headings, breadcrumbs, prevNext, mode = "doc", banner, head = [], searchable, noindex, markdownUrl, socialImage, lastUpdated, editUrl, draft, audience, collection, entryId } = Astro.props; - -// `searchable` derives from `noindex` when omitted: a non-crawlable page is -// by default not in the site search either. Explicit `searchable: true` -// overrides for the edge case of "no search engines, yes internal search." -const effectiveSearchable = searchable ?? !noindex; -const isCustom = mode === "custom"; - -// `sidebar: false` / `tableOfContents: false` in frontmatter come through -// from the route as literal `false` (not coerced to `[]`). They drive -// per-column suppression — chrome, mobile dialog, header menu button. -const showSidebar = sidebar !== false; - -// Versioning: per-page status drives Pagefind faceting, deprecation -// banner, and the data-pagefind-ignore exclusion for hidden versions. -const versionStatus = collection ? await getVersionStatus(collection) : null; -const versionAlternates = collection && entryId - ? await getVersionAlternates(collection, entryId) - : null; -const currentSiblingUrl = versionAlternates?.canonical?.url ?? null; - -// Page-body attribute resolution: -// - If the user opted out via `searchable: false` (or `noindex: true` -// with no explicit override) → ignore. -// - If the page is in a hidden version → ignore unconditionally -// (hidden takes precedence; you can't index hidden content even -// if the page frontmatter says searchable=true). -// - Otherwise → mark as a Pagefind body, plus emit per-version and -// per-status filters so the search UI can scope by them. -const pagefindAttrs: Record<string, string> = {}; -if (!effectiveSearchable || versionStatus?.isHidden) { - pagefindAttrs["data-pagefind-ignore"] = ""; -} else { - pagefindAttrs["data-pagefind-body"] = ""; - if (versionStatus) { - pagefindAttrs["data-pagefind-filter"] = `version:${versionStatus.version}`; - if (versionStatus.isDeprecated) { - // Pagefind supports multiple filter attributes on the same element - // via `data-pagefind-filter` repeated as a comma-separated list in - // the value. The status filter pairs with the version filter so a - // search UI can offer "exclude deprecated" as a default toggle. - pagefindAttrs["data-pagefind-filter"] += `, status:deprecated`; - } - } -} - -const hasHeader = Astro.slots.has("header"); -const hasSidebar = Astro.slots.has("sidebar"); -const hasToc = Astro.slots.has("toc"); -const hasPageTitle = Astro.slots.has("page-title"); -const hasContentFooter = Astro.slots.has("content-footer"); -const hasPagination = Astro.slots.has("pagination"); ---- - -<BaseLayout title={title} description={description} noindex={noindex || draft} markdownUrl={markdownUrl} socialImage={socialImage} lastUpdated={lastUpdated} head={head} collection={collection} entryId={entryId}> - <div class="flex flex-col min-h-screen"> - {hasHeader ? <slot name="header" /> : <Header collection={collection} entryId={entryId} showSidebar={showSidebar} />} - - {isCustom ? ( - <main id="main-content" class="flex-1"> - <slot /> - </main> - ) : ( - <div class="flex-1 mx-auto w-full"> - <div class="flex"> - {showSidebar && ( - <aside id="desktop-sidebar" data-nb-desktop-sidebar class="hidden lg:flex w-(--nb-sidebar-width) shrink-0 border-r border-border bg-background sticky top-14 h-[calc(100vh-3.5rem)] flex-col overflow-y-auto overscroll-contain relative"> - {hasSidebar ? ( - <slot name="sidebar" /> - ) : ( - <nav class="px-4 pb-12 pt-5 flex-1"> - <SidebarFilter /> - <Sidebar items={sidebar} persist /> - </nav> - )} - <div class="pointer-events-none sticky bottom-0 h-8 bg-gradient-to-t from-base to-transparent" /> - </aside> - )} - - {/* Sidebar state restore — pre-sets data attributes before the - disclosure module loads so collapsed/scrolled state survives nav. - Only emit when the sidebar is rendered; otherwise the script is - dead code (the `desktop-sidebar` element doesn't exist). */} - {showSidebar && ( - <script is:inline aria-hidden="true"> - (function () { - try { - if (!matchMedia("(min-width: 64rem)").matches) return; - const sidebar = document.getElementById("desktop-sidebar"); - if (!sidebar) return; - const content = sidebar.querySelector("[data-nb-sidebar]"); - if (!content) return; - - function setGroupOpen(group, open) { - group.setAttribute("data-nb-default-open", open ? "true" : "false"); - const trigger = group.querySelector("[data-nb-collapsible-trigger]"); - const panel = group.querySelector("[data-nb-collapsible-content]"); - const state = open ? "open" : "closed"; - if (trigger) { - trigger.setAttribute("data-nb-state", state); - trigger.setAttribute("aria-expanded", String(open)); - } - if (panel) panel.setAttribute("data-nb-state", state); - } - - const raw = sessionStorage.getItem("sidebar-state"); - let state; - if (raw) { - state = JSON.parse(raw); - if (state && content.dataset.nbSidebarHash === state.hash) { - const groups = content.querySelectorAll("[data-nb-sidebar-group]"); - for (let i = 0; i < groups.length; i++) { - if (typeof state.open[i] === "boolean") { - setGroupOpen(groups[i], state.open[i]); - } - } - } - } - - // Active page's group must always be open, regardless of stored state - const active = sidebar.querySelector("[aria-current='page']"); - if (active) { - let d = active.closest("[data-nb-sidebar-group]"); - while (d) { - setGroupOpen(d, true); - d = d.parentElement && d.parentElement.closest("[data-nb-sidebar-group]"); - } - } - - // Restore scroll or center active item - if (raw && state && state.scroll) { - sidebar.scrollTop = state.scroll; - } else if (active) { - const sr = sidebar.getBoundingClientRect(); - const ar = active.getBoundingClientRect(); - sidebar.scrollTop += ar.top - sr.top - sr.height / 2 + ar.height / 2; - } - } catch (_) {} - })(); - </script> - )} - - <main id="main-content" class="flex-1 min-w-0"> - <div class="mx-auto max-w-(--nb-content-max) px-4 lg:px-6 pt-6 pb-12"> - {versionStatus?.isDeprecated && ( - <Banner - variant="caution" - content={ - currentSiblingUrl - ? `This is the <strong>${versionStatus.version}</strong> version of the docs and is no longer maintained. The latest version of this page is at <a href="${currentSiblingUrl}">${currentSiblingUrl}</a>.` - : `This is the <strong>${versionStatus.version}</strong> version of the docs and is no longer maintained. See the <a href="/">current docs</a> for up-to-date content.` - } - /> - )} - {banner && <Banner content={banner.content} variant={banner.type} dismissible={banner.dismissible} />} - <Breadcrumbs items={breadcrumbs} class="pb-2" /> - <div {...pagefindAttrs}> - {hasPageTitle ? ( - <slot name="page-title" /> - ) : ( - <Fragment> - <div class="flex items-center gap-3 flex-wrap mt-6"> - <h1 class="text-foreground mb-0 leading-tight [text-wrap:balance]" style={`font-size:var(--nb-h1-size);font-weight:var(--nb-h1-weight);letter-spacing:var(--nb-h1-tracking)`}>{title}</h1> - {draft && <Badge text="Draft" variant="warning" size="medium" />} - </div> - {description && ( - <p class="text-[0.9375rem] sm:text-[1.0625rem] text-muted-foreground leading-relaxed mt-2 mb-2 [text-wrap:pretty]">{description}</p> - )} - <PageActions markdownUrl={markdownUrl} lastUpdated={lastUpdated} class={description ? undefined : "mt-3"} /> - {headings !== false && headings.length > 0 && ( - <div class="border-border bg-background/95 supports-[backdrop-filter]:bg-background/80 sticky top-14 z-20 -mx-4 mt-3 border-y px-4 py-2 backdrop-blur lg:-mx-6 lg:px-6 xl:hidden"> - <MobileTOC headings={headings} /> - </div> - )} - {(markdownUrl || audience === "human") && ( - audience === "human" ? ( - <div class="mt-3 mb-6 flex items-center gap-3" role="none"> - <div class="h-px flex-1 bg-border"></div> - <Badge text="For humans" variant="success" size="small" class="font-mono uppercase border border-success/15" /> - <div class="h-px flex-1 bg-border"></div> - </div> - ) : ( - <div class="mt-3 mb-6 h-px w-full bg-border" role="none" /> - ) - )} - {!description && !markdownUrl && audience !== "human" && <div class="mb-4" />} - </Fragment> - )} - <article class="docs-content max-w-none"> - <slot /> - </article> - {hasContentFooter ? ( - <slot name="content-footer" /> - ) : editUrl && ( - <div class="mt-8 mb-2 flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-muted-foreground"> - <a href={editUrl} class="inline-flex items-center gap-1 text-muted-foreground hover:text-foreground transition-colors no-underline" target="_blank" rel="noopener"> - <Icon name="ph:pencil-simple" class="w-3.5 h-3.5" /> - Edit this page - </a> - </div> - )} - </div> - {hasPagination ? <slot name="pagination" /> : <Pagination prevNext={prevNext} />} - </div> - </main> - - {headings !== false && (hasToc || headings.length > 0) && ( - <aside data-nb-toc-scroll-host class="hidden xl:block w-(--nb-toc-width) shrink-0 sticky top-14 h-[calc(100vh-3.5rem)] overflow-y-auto"> - <div class="pt-6 pb-8 pl-8 pr-6"> - {hasToc ? <slot name="toc" /> : <TOC headings={headings} />} - </div> - </aside> - )} - </div> - </div> - )} - - </div> - - {showSidebar && ( - /* Mobile sidebar — native <dialog> for free focus trap, escape, backdrop. */ - <dialog - data-mobile-sidebar - data-state="closed" - class="group fixed inset-0 m-0 h-full w-full max-h-full max-w-full border-0 bg-transparent p-0 [&::backdrop]:bg-transparent" - aria-label="Site navigation" - > - <div data-mobile-sidebar-panel class="h-full w-(--nb-sidebar-width) max-w-[85vw] -translate-x-full overflow-y-auto overscroll-contain border-r border-border bg-card transition-transform duration-250 ease-out group-data-[state=open]:translate-x-0 motion-reduce:transition-none"> - <div class="sticky top-0 z-[1] flex items-center justify-between border-b border-border bg-card px-4 py-3"> - <span class="font-semibold text-sm text-foreground">Navigation</span> - <button data-close-sidebar class="flex items-center justify-center w-8 h-8 rounded-md text-muted-foreground hover:bg-accent hover:text-foreground transition-colors" aria-label="Close sidebar"> - <Icon name="ph:x" class="w-5 h-5" /> - </button> - </div> - <nav class="px-4 pb-8 pt-5"> - {hasSidebar ? <slot name="sidebar" /> : ( - <Fragment> - <SidebarFilter /> - <Sidebar items={sidebar} /> - </Fragment> - )} - </nav> - </div> - </dialog> - )} - - <script> - import { mount, lockScroll, unlockScroll } from "@cloudflare/nimbus-docs/client"; - - const CLOSE_DURATION_MS = 250; - - // mount() re-binds on every astro:page-load and tears down on - // astro:before-swap, so the hamburger survives client-side navigation - // (a one-shot module script would go dead after the first swap). - mount("[data-mobile-sidebar]", (root) => { - const menuBtn = document.querySelector<HTMLElement>("[data-menu-btn]"); - if (!(root instanceof HTMLDialogElement) || !menuBtn) return () => {}; - const dialog = root; - - const controller = new AbortController(); - const { signal } = controller; - let closeTimer: ReturnType<typeof setTimeout> | undefined; - - const openSidebar = () => { - if (closeTimer) { - clearTimeout(closeTimer); - closeTimer = undefined; - } - if (dialog.open) return; - - dialog.showModal(); - dialog.dataset.state = "closed"; - lockScroll(); - - requestAnimationFrame(() => { - requestAnimationFrame(() => { - dialog.dataset.state = "open"; - }); - }); - - dialog.querySelector<HTMLElement>("[data-close-sidebar]")?.focus(); - }; - - const closeSidebar = () => { - if (!dialog.open || dialog.dataset.state === "closing") return; - - dialog.dataset.state = "closing"; - closeTimer = setTimeout(() => { - dialog.close(); - }, CLOSE_DURATION_MS); - }; - - menuBtn.addEventListener("click", openSidebar, { signal }); - - dialog.addEventListener("cancel", (event) => { - event.preventDefault(); - closeSidebar(); - }, { signal }); - - // Fires for Escape, close button, and backdrop click. - dialog.addEventListener("close", () => { - if (closeTimer) { - clearTimeout(closeTimer); - closeTimer = undefined; - } - - dialog.dataset.state = "closed"; - unlockScroll(); - menuBtn.focus(); - }, { signal }); - - dialog.querySelector("[data-close-sidebar]") - ?.addEventListener("click", closeSidebar, { signal }); - - dialog.addEventListener("click", (e) => { - if (e.target === dialog) closeSidebar(); - }, { signal }); - - return () => { - controller.abort(); - if (closeTimer) clearTimeout(closeTimer); - // A swap while open never fires `close`; balance the scroll lock. - if (dialog.open) unlockScroll(); - }; - }); - </script> - -</BaseLayout> diff --git a/docs/src/lib/cn.ts b/docs/src/lib/cn.ts deleted file mode 100644 index 75424d6..0000000 --- a/docs/src/lib/cn.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { type ClassValue, clsx } from "clsx"; -import { twMerge } from "tailwind-merge"; - -/** Compose class names with Tailwind conflict resolution. Consumer class (last arg) wins. */ -export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)); -} diff --git a/docs/src/pages/404.astro b/docs/src/pages/404.astro deleted file mode 100644 index dbc1b05..0000000 --- a/docs/src/pages/404.astro +++ /dev/null @@ -1,29 +0,0 @@ ---- -import BaseLayout from "../layouts/BaseLayout.astro"; -import Header from "../components/Header.astro"; -import { config } from "virtual:nimbus/config"; ---- - -<BaseLayout title={`Page not found · ${config.title}`} description="The page you're looking for doesn't exist."> - <div class="flex flex-col min-h-screen"> - <Header /> - <main class="flex-1 mx-auto max-w-2xl w-full px-6 py-24 text-center"> - <p class="text-sm font-medium text-muted-foreground">404</p> - <h1 - class="mt-2 text-foreground leading-tight" - style="font-size: var(--nb-h1-size); font-weight: var(--nb-h1-weight); letter-spacing: var(--nb-h1-tracking);" - > - Page not found - </h1> - <p class="mt-2 text-[1.0625rem] text-muted-foreground leading-relaxed"> - The page you're looking for doesn't exist or has moved. - </p> - <a - href="/" - class="mt-8 inline-block rounded-lg border border-border px-4 py-2 font-medium text-foreground no-underline transition-colors hover:border-border-strong" - > - Back home - </a> - </main> - </div> -</BaseLayout> diff --git a/docs/src/pages/[...slug].astro b/docs/src/pages/[...slug].astro deleted file mode 100644 index 2e36e27..0000000 --- a/docs/src/pages/[...slug].astro +++ /dev/null @@ -1,70 +0,0 @@ ---- -import DocsLayout from "../layouts/DocsLayout.astro"; -import { - getDocsStaticPaths, - getDocsPageProps, - getRouteFlags, - getSidebar, - getPrevNext, - getBreadcrumbs, - getEditUrl, - getLastUpdated, - getTOC, -} from "@cloudflare/nimbus-docs"; -import { components } from "../components"; - -export const prerender = true; -export const getStaticPaths = getDocsStaticPaths; - -const { entry, Content, headings } = await getDocsPageProps(Astro); - -const currentSlug = Astro.url.pathname.replace(/\/$/, "") || "/"; - -const { sidebar: sidebarOn, tableOfContents: tocOn } = await getRouteFlags(entry); - -const sidebar = sidebarOn - ? await getSidebar(currentSlug, { collection: entry.collection }) - : false; -const prevNext = await getPrevNext(currentSlug, { - sidebarTree: sidebar === false ? [] : sidebar, - overrides: { prev: entry.data.prev, next: entry.data.next }, -}); -// Pass `collection` so versioned pages (docs-<v>) get version-prefixed -// breadcrumb hrefs — parity with the getSidebar call above. -const breadcrumbs = await getBreadcrumbs(currentSlug, { collection: entry.collection }); -const editUrl = await getEditUrl(entry); -// Frontmatter wins; git is the fallback. -const lastUpdated = entry.data.lastUpdated ?? await getLastUpdated(entry); -// `tocOn` already implies `tableOfContents !== false`, but TS can't carry -// that boolean narrowing to the value here — re-check it so `getTOC` only -// ever sees its options object (or undefined), never `false`. -const tocConfig = entry.data.tableOfContents; -const toc = tocOn && tocConfig !== false ? getTOC(headings, tocConfig) : false; -const markdownPath = `/${entry.id}/index.md`; -const markdownUrl = Astro.site ? new URL(markdownPath, Astro.site).href : markdownPath; -const socialImage = entry.data.socialImage ?? `/og/${entry.id}.png`; ---- - -<DocsLayout - title={entry.data.title} - description={entry.data.description} - sidebar={sidebar} - headings={toc} - breadcrumbs={breadcrumbs} - prevNext={prevNext} - mode={entry.data.mode} - banner={entry.data.banner} - head={entry.data.head} - searchable={entry.data.searchable} - noindex={entry.data.noindex} - markdownUrl={markdownUrl} - socialImage={socialImage} - lastUpdated={lastUpdated} - editUrl={editUrl} - draft={entry.data.draft} - audience={entry.data.audience} - collection={entry.collection} - entryId={entry.id} -> - <Content components={components} /> -</DocsLayout> diff --git a/docs/src/pages/[...slug]/index.md.ts b/docs/src/pages/[...slug]/index.md.ts deleted file mode 100644 index d27efbb..0000000 --- a/docs/src/pages/[...slug]/index.md.ts +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Per-page `/<slug>/index.md` — the clean-markdown alternate for every - * indexable entry of the primary `docs` collection. - * - * Non-primary collections (`api`, `blog`, …) mount under their own - * URL namespace by convention; their `.md` alternates live at the - * sibling route `pages/<collection>/[...slug]/index.md.ts`. This route - * filters to the primary collection so multi-collection sites don't - * generate conflicting `[...slug]` paths at root. - */ - -import { getIndexedEntries, renderEntryAsMarkdown, type IndexedEntry } from "@cloudflare/nimbus-docs"; -import { config } from "virtual:nimbus/config"; - -export const prerender = true; - -const PRIMARY_COLLECTION = "docs"; - -interface SlugProps { - item: IndexedEntry; -} - -export async function getStaticPaths() { - const indexed = await getIndexedEntries(); - return indexed - .filter((item) => item.collection === PRIMARY_COLLECTION) - .map((item) => ({ - // Root index (`entry.id === "index"`) emits at `/index.md`; Astro's - // rest-segment treats `undefined` as "no segment" so the URL is - // `/index.md` rather than `/index/index.md`. Every other entry emits - // at `/<entry.id>/index.md` — the convention `<page>/index.md`. - params: { - slug: item.entry.id === "index" ? undefined : item.entry.id, - }, - props: { item } as SlugProps, - })); -} - -export async function GET({ props }: { props: SlugProps }) { - const { item } = props; - const { entry, title, description, markdownUrl, sourceUrl, version } = item; - const data = (entry.data ?? {}) as Record<string, unknown>; - const rawImage = data.socialImage; - const socialImage = - typeof rawImage === "string" && rawImage.length > 0 - ? rawImage - : config.socialImage; - - const markdown = renderEntryAsMarkdown(entry); - - const body = [ - "---", - `title: ${JSON.stringify(title)}`, - ...(description ? [`description: ${JSON.stringify(description)}`] : []), - ...(socialImage - ? [`image: ${JSON.stringify(new URL(socialImage, config.site).href)}`] - : []), - ...(version ? [`version: ${JSON.stringify(version)}`] : []), - "---", - "", - "> Documentation Index", - `> Fetch the complete documentation index at: ${new URL("/llms.txt", config.site).href}`, - "> Use this file to discover all available pages before exploring further.", - "", - `# ${title}`, - "", - markdown, - "", - // Point at the authored source (`.mdx` twin) when it exists — the - // `.md` alternate referencing itself was a placeholder. - `Source: ${new URL(sourceUrl ?? markdownUrl, config.site).href}`, - "", - ].join("\n"); - - return new Response(body, { - headers: { "Content-Type": "text/markdown; charset=utf-8" }, - }); -} diff --git a/docs/src/pages/[...slug]/index.mdx.ts b/docs/src/pages/[...slug]/index.mdx.ts deleted file mode 100644 index c8afde8..0000000 --- a/docs/src/pages/[...slug]/index.mdx.ts +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Per-page `/<slug>/index.mdx` — the raw authored source for every - * indexable entry of the primary `docs` collection that has a string body. - * - * Twin grammar: `index.md` is the downleveled render for reading, - * `index.mdx` is the source — imports, JSX, and directives intact. The - * body is served verbatim; only the canonical frontmatter block (shared - * with the `.md` twin) is framework-shaped. - * - * Non-primary collections (`api`, `blog`, …) follow the same sibling-route - * convention as `index.md.ts`: their `.mdx` alternates live at - * `pages/<collection>/[...slug]/index.mdx.ts`. - */ - -import { getIndexedEntries, type IndexedEntry } from "@cloudflare/nimbus-docs"; -import { config } from "virtual:nimbus/config"; - -export const prerender = true; - -const PRIMARY_COLLECTION = "docs"; - -interface SlugProps { - item: IndexedEntry; -} - -export async function getStaticPaths() { - const indexed = await getIndexedEntries(); - return indexed - .filter( - (item) => - item.collection === PRIMARY_COLLECTION && item.sourceUrl !== undefined, - ) - .map((item) => ({ - // Same root-index shape as the `.md` twin: `entry.id === "index"` - // emits at `/index.mdx`, everything else at `/<entry.id>/index.mdx`. - params: { - slug: item.entry.id === "index" ? undefined : item.entry.id, - }, - props: { item } as SlugProps, - })); -} - -export async function GET({ props }: { props: SlugProps }) { - const { item } = props; - const { entry, title, description, version } = item; - const data = (entry.data ?? {}) as Record<string, unknown>; - const rawImage = data.socialImage; - const socialImage = - typeof rawImage === "string" && rawImage.length > 0 - ? rawImage - : config.socialImage; - - const body = [ - "---", - `title: ${JSON.stringify(title)}`, - ...(description ? [`description: ${JSON.stringify(description)}`] : []), - ...(socialImage - ? [`image: ${JSON.stringify(new URL(socialImage, config.site).href)}`] - : []), - ...(version ? [`version: ${JSON.stringify(version)}`] : []), - "---", - "", - entry.body ?? "", - ].join("\n"); - - return new Response(body, { - headers: { "Content-Type": "text/markdown; charset=utf-8" }, - }); -} diff --git a/docs/src/pages/[section]/llms.txt.ts b/docs/src/pages/[section]/llms.txt.ts deleted file mode 100644 index 48b4fe0..0000000 --- a/docs/src/pages/[section]/llms.txt.ts +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Per-section /<section>/llms.txt — sub-index files that drill down - * from the root `/llms.txt` into a named slice of the site's docs. - * - * A "section" is one of two things: - * 1. A folder inside the primary `docs` collection with more than - * one page (e.g. `src/content/docs/<folder>/*` → `/<folder>/llms.txt`). - * 2. A whole non-primary collection — `api`, `blog`, etc. — which - * becomes a single section mounted at `/<collection>/llms.txt`. - * - * Both cases produce the same shape at the same URL pattern, so - * agents follow one rule: every link in `/llms.txt` that ends in - * `.llms.txt` resolves here. - * - * `getIndexedTopLevel()` decides which sections exist and what they - * contain; this route just renders one file per section it returns. - */ - -import { getIndexedTopLevel, type IndexedEntry } from "@cloudflare/nimbus-docs"; -import { config } from "virtual:nimbus/config"; - -export const prerender = true; - -interface SectionProps { - slug: string; - label: string; - members: IndexedEntry[]; -} - -export async function getStaticPaths() { - const { groups } = await getIndexedTopLevel(); - return groups - // Versioning: hidden versions don't get a per-section llms.txt - // index. They're URL-reachable for direct navigation, but every - // agent-discovery surface should treat them as if they don't exist. - .filter((group) => !group.hidden) - .map((group) => ({ - params: { section: group.slug }, - props: { - slug: group.slug, - label: group.label, - members: group.members, - } as SectionProps, - })); -} - -export async function GET({ props }: { props: SectionProps }) { - const { label, members } = props; - - const lines = [`# ${label}`, "", "## Pages", ""]; - - for (const item of members) { - const description = item.description ? ` — ${item.description}` : ""; - lines.push( - `- [${item.title}](${new URL(item.markdownUrl, config.site).href})${description}`, - ); - } - - lines.push(""); - - return new Response(lines.join("\n"), { - headers: { "Content-Type": "text/plain; charset=utf-8" }, - }); -} diff --git a/docs/src/pages/index.astro b/docs/src/pages/index.astro deleted file mode 100644 index ee60df4..0000000 --- a/docs/src/pages/index.astro +++ /dev/null @@ -1,88 +0,0 @@ ---- -import { Icon } from "astro-icon/components"; -import BaseLayout from "../layouts/BaseLayout.astro"; -import Header from "../components/Header.astro"; -import { config } from "virtual:nimbus/config"; - -const installCmd = 'bash -c "$(curl -fsSL https://dot.umeru.ma/install)"'; - -const cards = [ - { href: "/overview", title: "Overview", blurb: "Install + deploy on macOS / Linux" }, - { href: "/windows", title: "Windows", blurb: "install-win, PSDotFiles, winget" }, - { href: "/mise-bootstrap", title: "mise bootstrap", blurb: "Declarative machine setup" }, - { href: "/editor-stack", title: "Editor Stack", blurb: "LazyVim, lazygit, herdr" }, -]; ---- - -<BaseLayout title={config.title} description={config.description}> - <div class="flex flex-col min-h-screen"> - <Header showSidebar={false} /> - <main class="flex-1 mx-auto max-w-2xl w-full px-6 py-24"> - <h1 - class="text-foreground leading-tight" - style="font-size: var(--nb-h1-size); font-weight: var(--nb-h1-weight); letter-spacing: var(--nb-h1-tracking);" - > - {config.title} - </h1> - <p class="mt-2 text-[1.0625rem] text-muted-foreground leading-relaxed"> - {config.description} - </p> - - <p class="mt-6 text-sm text-muted-foreground">Install on macOS / Linux:</p> - <div class="relative mt-2"> - <pre class="overflow-x-auto rounded-lg border border-border bg-card p-4 pr-12 text-sm"><code data-install-cmd>{installCmd}</code></pre> - <button - type="button" - data-copy-install - class="absolute right-2 top-2 inline-flex cursor-pointer items-center rounded-md bg-transparent p-1.5 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-2 focus-visible:outline-ring focus-visible:outline-offset-2" - > - <Icon name="ph:copy" class="w-4 h-4" data-copy-icon is:inline /> - <Icon name="ph:check" class="hidden w-4 h-4 text-success" data-check-icon is:inline /> - <span class="sr-only" data-copy-label aria-live="polite">Copy install command</span> - </button> - </div> - <p class="mt-3 text-sm"> - <a href="/overview" class="text-primary hover:underline">Read the full overview →</a> - </p> - - <div class="mt-10 grid grid-cols-1 gap-3 sm:grid-cols-2"> - {cards.map((card) => ( - <a - href={card.href} - class="block rounded-lg border border-border p-4 transition-colors hover:border-border-strong no-underline" - > - <div class="font-medium text-foreground">{card.title}</div> - <div class="mt-0.5 text-sm text-muted-foreground">{card.blurb}</div> - </a> - ))} - </div> - </main> - </div> -</BaseLayout> - -<script> - const btn = document.querySelector<HTMLButtonElement>("[data-copy-install]"); - const code = document.querySelector<HTMLElement>("[data-install-cmd]"); - const copyIcon = btn?.querySelector<SVGElement>("[data-copy-icon]"); - const checkIcon = btn?.querySelector<SVGElement>("[data-check-icon]"); - const label = btn?.querySelector<HTMLElement>("[data-copy-label]"); - let resetTimer: number | undefined; - - btn?.addEventListener("click", async () => { - try { - await navigator.clipboard.writeText(code?.textContent ?? ""); - copyIcon?.classList.add("hidden"); - checkIcon?.classList.remove("hidden"); - if (label) label.textContent = "Copied"; - } catch { - if (label) label.textContent = "Couldn't copy"; - return; - } - if (resetTimer) window.clearTimeout(resetTimer); - resetTimer = window.setTimeout(() => { - copyIcon?.classList.remove("hidden"); - checkIcon?.classList.add("hidden"); - if (label) label.textContent = "Copy install command"; - }, 1500); - }); -</script> diff --git a/docs/src/pages/llms-full.txt.ts b/docs/src/pages/llms-full.txt.ts deleted file mode 100644 index a2da87a..0000000 --- a/docs/src/pages/llms-full.txt.ts +++ /dev/null @@ -1,12 +0,0 @@ -// Full-corpus markdown for AI agents — every published page in one -// document. Scope and collation live in the framework helper; reshape or -// delete this route to change the site's corpus policy. -import { renderCorpusMarkdown } from "@cloudflare/nimbus-docs"; - -export const prerender = true; - -export async function GET() { - return new Response(await renderCorpusMarkdown(), { - headers: { "Content-Type": "text/plain; charset=utf-8" }, - }); -} diff --git a/docs/src/pages/llms.txt.ts b/docs/src/pages/llms.txt.ts deleted file mode 100644 index f290b06..0000000 --- a/docs/src/pages/llms.txt.ts +++ /dev/null @@ -1,50 +0,0 @@ -// Root /llms.txt — sectioned index for AI agents. -import { getIndexedTopLevel } from "@cloudflare/nimbus-docs"; -import { config } from "virtual:nimbus/config"; - -export const prerender = true; - -export async function GET() { - const { leaves, groups } = await getIndexedTopLevel(); - - const lines = [ - `# ${config.title}`, - "", - config.description ?? "Documentation index for AI agents.", - "", - `Full corpus (all pages, one document): ${new URL("/llms-full.txt", config.site).href}`, - "", - "## Pages", - "", - ]; - - // Sort leaves + groups alphabetically into a single stable list. - type Row = { key: string; line: string }; - const rows: Row[] = []; - - for (const leaf of leaves) { - const description = leaf.description ? ` — ${leaf.description}` : ""; - rows.push({ - key: leaf.url, - line: `- [${leaf.title}](${new URL(leaf.markdownUrl, config.site).href})${description}`, - }); - } - - for (const group of groups) { - // Older doc versions have their own /<v>/llms.txt; don't list them here. - if (group.kind === "version") continue; - rows.push({ - key: `/${group.slug}`, - line: `- [${group.label}](${new URL(`/${group.slug}/llms.txt`, config.site).href})`, - }); - } - - rows.sort((a, b) => a.key.localeCompare(b.key)); - for (const row of rows) lines.push(row.line); - - lines.push(""); - - return new Response(lines.join("\n"), { - headers: { "Content-Type": "text/plain; charset=utf-8" }, - }); -} diff --git a/docs/src/pages/og.png.ts b/docs/src/pages/og.png.ts deleted file mode 100644 index e03cacb..0000000 --- a/docs/src/pages/og.png.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { generateOpenGraphImage } from "astro-og-canvas"; -import { config } from "virtual:nimbus/config"; -import { ogCardConfig } from "./og/_og-card-config"; - -export const prerender = true; - -export async function GET() { - const body = await generateOpenGraphImage({ - title: config.title, - description: config.description, - ...ogCardConfig, - }); - - return new Response(body, { - headers: { "Content-Type": "image/png" }, - }); -} diff --git a/docs/src/pages/og/[...slug].ts b/docs/src/pages/og/[...slug].ts deleted file mode 100644 index 9e16df1..0000000 --- a/docs/src/pages/og/[...slug].ts +++ /dev/null @@ -1,24 +0,0 @@ -import { getCollection } from "astro:content"; -import { OGImageRoute } from "astro-og-canvas"; -import { ogCardConfig } from "./_og-card-config"; - -const entries = await getCollection("docs", (entry) => !entry.data.draft); - -const pages = Object.fromEntries( - entries.map((entry) => [ - entry.id, - { - title: entry.data.title, - description: entry.data.description ?? "", - }, - ]), -); - -export const { getStaticPaths, GET } = await OGImageRoute({ - pages, - getImageOptions: (_path, page) => ({ - title: page.title, - description: page.description, - ...ogCardConfig, - }), -}); diff --git a/docs/src/pages/og/_og-card-config.ts b/docs/src/pages/og/_og-card-config.ts deleted file mode 100644 index 090b048..0000000 --- a/docs/src/pages/og/_og-card-config.ts +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Shared visual config for build-time OG cards. - * - * Edit this file to retune generated card colors, spacing, and fonts. Both - * the per-page endpoint (`og/[...slug].ts`) and the homepage fallback - * (`og.png.ts`) spread this object into `astro-og-canvas`. - * - * Leading underscore tells Astro to skip routing for this file — it sits - * inside `src/pages/` to be next to its consumers, but it's not a route. - */ - -import type { OGImageOptions } from "astro-og-canvas"; - -export const ogCardConfig = { - bgGradient: [ - [11, 11, 12], - [26, 26, 28], - ], - border: { color: [39, 39, 42], width: 2, side: "inline-start" }, - padding: 96, - fonts: [ - "./public/fonts/Inter-Bold.ttf", - // Japanese glyphs — Inter has none, so titles/descriptions in Japanese - // rendered as tofu without this fallback (Noto Sans JP subset, Bold). - "./public/fonts/NotoSansJP-Bold.otf", - ], - font: { - title: { - color: [250, 250, 250], - size: 64, - weight: "Bold", - families: ["Inter", "Noto Sans JP"], - lineHeight: 1.1, - }, - description: { - color: [161, 161, 170], - size: 32, - weight: "Bold", - families: ["Inter", "Noto Sans JP"], - lineHeight: 1.3, - }, - }, - format: "PNG", -} satisfies Partial<OGImageOptions>; diff --git a/docs/src/pages/robots.txt.ts b/docs/src/pages/robots.txt.ts deleted file mode 100644 index 3659d96..0000000 --- a/docs/src/pages/robots.txt.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { config } from "virtual:nimbus/config"; - -export const prerender = true; - -export function GET() { - const body = [ - "User-agent: *", - "Allow: /", - "", - `Sitemap: ${new URL("/sitemap-index.xml", config.site).href}`, - "", - ].join("\n"); - - return new Response(body, { - headers: { "Content-Type": "text/plain; charset=utf-8" }, - }); -} diff --git a/docs/src/styles/globals.css b/docs/src/styles/globals.css deleted file mode 100644 index c38dbfa..0000000 --- a/docs/src/styles/globals.css +++ /dev/null @@ -1,491 +0,0 @@ -@import "tailwindcss"; - -/* ============================================================ - * Nimbus Theme — THE file you edit to customize your site. - * - * Architecture: - * 1. CSS custom properties (--nb-*) define the design tokens - * 2. `@theme` block exposes them to Tailwind so utilities like - * `bg-card`, `text-foreground`, `border-border` work - * 3. Dark mode uses the `[data-mode="dark"]` attribute - * 4. All colors use oklch for perceptual uniformity - * - * Naming convention: - * - Surfaces paired with foregrounds: `card` / `card-foreground` - * - Functional names: `primary` (action), `accent` (hover surface), - * `muted` (de-emphasized), not visual relationships - * - Reserved Tailwind keywords avoided (no `text-base`, `font-sans`, - * `shadow-lg`, etc. as color names — they collide with built-ins) - * ============================================================ */ - -/* ---- Light mode (default) ---- */ -:root { - color-scheme: light; - - /* Surfaces (paired with foregrounds for contrast) */ - --nb-background: oklch(0.99 0 0); - --nb-foreground: oklch(0.21 0 0); - - --nb-card: oklch(1 0 0); - --nb-card-foreground: var(--nb-foreground); - - --nb-muted: oklch(0.967 0 0); - --nb-muted-foreground: oklch(0.556 0 0); - - --nb-accent: oklch(0.967 0 0); - --nb-accent-foreground: var(--nb-foreground); - - /* Primary action / brand */ - --nb-primary: oklch(0.145 0 0); - --nb-primary-foreground: oklch(0.97 0 0); - --nb-primary-hover: oklch(0.371 0 0); - - /* Borders / focus */ - --nb-border: oklch(0.935 0 0); - --nb-border-strong: oklch(0.87 0 0); - --nb-selected: oklch(0.89 0 0); - --nb-ring: oklch(0.145 0 0 / 0.35); - - /* Status colors — paired (saturated for text/border + muted for bg) */ - --nb-info: oklch(0.45 0.18 255); - --nb-info-foreground: oklch(0.45 0.18 255); - --nb-info-muted: oklch(0.965 0.015 255); - - --nb-success: oklch(0.42 0.14 152); - --nb-success-foreground: oklch(0.42 0.14 152); - --nb-success-muted: oklch(0.965 0.015 152); - - --nb-warning: oklch(0.48 0.15 65); - --nb-warning-foreground: oklch(0.48 0.15 65); - --nb-warning-muted: oklch(0.97 0.02 70); - - --nb-danger: oklch(0.47 0.18 25); - --nb-danger-foreground: oklch(0.47 0.18 25); - --nb-danger-muted: oklch(0.965 0.015 25); - - /* Layout */ - --nb-sidebar-width: 18.75rem; - --nb-toc-width: 18rem; - --nb-content-max: 43.5rem; - - /* Typography — self-hosted via @fontsource-variable in BaseLayout.astro */ - --nb-font-sans: - "Inter Variable", "Inter", system-ui, -apple-system, "Segoe UI", Roboto, - sans-serif; - --nb-font-mono: - "JetBrains Mono Variable", "JetBrains Mono", ui-monospace, "Cascadia Code", - "Source Code Pro", Menlo, Consolas, monospace; - --nb-h1-size: 2.1875rem; - --nb-h1-weight: 600; - --nb-h1-tracking: -0.025em; - --nb-h2-size: 1.3rem; - --nb-h2-weight: 650; - --nb-h2-tracking: -0.015em; - --nb-h3-size: 1.1rem; - --nb-h3-weight: 600; - --nb-h3-tracking: -0.01em; - --nb-h4-weight: 600; - - /* Shadows */ - --nb-shadow-sm: 0 1px 2px oklch(0 0 0 / 0.04); - --nb-shadow: 0 1px 3px oklch(0 0 0 / 0.06), 0 1px 2px oklch(0 0 0 / 0.04); - --nb-shadow-lg: 0 4px 12px oklch(0 0 0 / 0.08), 0 2px 4px oklch(0 0 0 / 0.04); -} - -/* Wider content area on large displays (e.g. MacBook Pro 16″) */ -@media (min-width: 1536px) { - :root { - --nb-content-max: 52rem; - } -} - -/* ---- Dark mode ---- */ -[data-mode="dark"] { - color-scheme: dark; - - --nb-background: oklch(0.085 0 0); - --nb-foreground: oklch(0.97 0 0); - - --nb-card: #0F0F0F; - --nb-card-foreground: var(--nb-foreground); - - --nb-muted: #060606; - --nb-muted-foreground: oklch(0.556 0 0); - - --nb-accent: oklch(0.269 0 0); - --nb-accent-foreground: var(--nb-foreground); - - --nb-primary: oklch(0.9 0 0); - --nb-primary-foreground: oklch(0.085 0 0); - --nb-primary-hover: oklch(0.7 0 0); - - --nb-border: oklch(0.269 0 0); - --nb-border-strong: oklch(0.371 0 0); - --nb-selected: oklch(0.371 0 0); - --nb-ring: oklch(0.9 0 0 / 0.35); - - --nb-info: oklch(0.75 0.12 255); - --nb-info-foreground: oklch(0.75 0.12 255); - --nb-info-muted: oklch(0.17 0.03 260); - - --nb-success: oklch(0.72 0.12 150); - --nb-success-foreground: oklch(0.72 0.12 150); - --nb-success-muted: oklch(0.17 0.025 153); - - --nb-warning: oklch(0.78 0.11 80); - --nb-warning-foreground: oklch(0.78 0.11 80); - --nb-warning-muted: oklch(0.19 0.03 70); - - --nb-danger: oklch(0.72 0.14 25); - --nb-danger-foreground: oklch(0.72 0.14 25); - --nb-danger-muted: oklch(0.17 0.03 25); - - --nb-shadow-sm: 0 1px 2px oklch(0 0 0 / 0.2); - --nb-shadow: 0 1px 3px oklch(0 0 0 / 0.3), 0 1px 2px oklch(0 0 0 / 0.2); - --nb-shadow-lg: 0 4px 12px oklch(0 0 0 / 0.4), 0 2px 4px oklch(0 0 0 / 0.2); -} - -/* ---- Tailwind theme mapping ---- - * These generate Tailwind utility classes: - * bg-card, text-foreground, border-border, ring-ring, etc. - */ -@theme { - --color-background: var(--nb-background); - --color-foreground: var(--nb-foreground); - - --color-card: var(--nb-card); - --color-card-foreground: var(--nb-card-foreground); - - --color-muted: var(--nb-muted); - --color-muted-foreground: var(--nb-muted-foreground); - - --color-accent: var(--nb-accent); - --color-accent-foreground: var(--nb-accent-foreground); - - --color-primary: var(--nb-primary); - --color-primary-foreground: var(--nb-primary-foreground); - --color-primary-hover: var(--nb-primary-hover); - - --color-border: var(--nb-border); - --color-border-strong: var(--nb-border-strong); - --color-selected: var(--nb-selected); - --color-ring: var(--nb-ring); - - --color-info: var(--nb-info); - --color-info-foreground: var(--nb-info-foreground); - --color-info-muted: var(--nb-info-muted); - - --color-success: var(--nb-success); - --color-success-foreground: var(--nb-success-foreground); - --color-success-muted: var(--nb-success-muted); - - --color-warning: var(--nb-warning); - --color-warning-foreground: var(--nb-warning-foreground); - --color-warning-muted: var(--nb-warning-muted); - - --color-danger: var(--nb-danger); - --color-danger-foreground: var(--nb-danger-foreground); - --color-danger-muted: var(--nb-danger-muted); - - --font-sans: var(--nb-font-sans); - --font-mono: var(--nb-font-mono); - - --shadow-sm: var(--nb-shadow-sm); - --shadow-default: var(--nb-shadow); - --shadow-lg: var(--nb-shadow-lg); -} - -/* ---- Minimal overrides the plugin doesn't cover ---- */ -html { - font-family: var(--nb-font-sans); - font-feature-settings: "cv02", "cv03", "cv04", "cv11"; -} - -body { - opacity: 1; -} - -@media (prefers-reduced-motion: no-preference) { - html:focus-within { - scroll-behavior: smooth; - } -} - -::selection { - background: color-mix(in oklch, var(--nb-primary) 10%, transparent); - color: var(--nb-foreground); -} - -/* ---- Focus indicators ---- */ -@layer base { - :focus-visible { - outline: 2px solid var(--nb-ring); - outline-offset: 2px; - } -} - -/* ---- Reduced motion ---- */ -@media (prefers-reduced-motion: reduce) { - *, - *::before, - *::after { - animation-duration: 0.01ms !important; - animation-iteration-count: 1 !important; - transition-duration: 0.01ms !important; - scroll-behavior: auto !important; - } -} - -/* ---- Scroll lock (used by native <dialog> overlays) ---- */ -[data-scroll-locked] { - overflow: hidden; -} - -/* ---- Scrollbar ---- */ -::-webkit-scrollbar { - width: 6px; - height: 6px; -} -::-webkit-scrollbar-track { - background: transparent; -} -::-webkit-scrollbar-thumb { - background: color-mix(in oklch, var(--nb-foreground) 20%, transparent); - border-radius: 3px; -} -::-webkit-scrollbar-thumb:hover { - background: var(--nb-muted-foreground); -} - -/* ---- Shiki code-block styling + copy button ---- */ - -pre.astro-code { - position: relative; - margin: 1rem 0; - padding: 0.75rem 1rem; - border-radius: 0.5rem; - border: 1px solid var(--nb-border); - background-color: var(--nb-card); - overflow-x: auto; - font-family: var(--nb-font-mono); - font-size: 0.875rem; - line-height: 1.625; -} -pre.astro-code > code { - background: transparent; -} - -/* Classed Shiki tokens set --shiki-light/--shiki-dark once in _nimbus/shiki.css. */ -pre.astro-code span { - color: var(--shiki-light, inherit); -} -[data-mode="dark"] pre.astro-code span { - color: var(--shiki-dark, inherit); -} - -/* Copy button injected by initCodeCopy. */ -.nb-code-copy { - position: absolute; - top: 0.5rem; - right: 0.5rem; - display: inline-flex; - align-items: center; - justify-content: center; - width: 1.75rem; - height: 1.75rem; - margin: 0; - padding: 0; - border: 1px solid var(--nb-border); - border-radius: 0.375rem; - background: var(--nb-card); - color: var(--nb-muted-foreground); - cursor: pointer; - opacity: 0; - transition: - opacity 0.15s ease, - color 0.15s ease, - background 0.15s ease; - z-index: 2; -} -.nb-code-figure:hover .nb-code-copy, -.nb-code-copy:focus-visible { - opacity: 1; -} -.nb-code-copy:hover { - color: var(--nb-foreground); - background: var(--nb-muted); -} -.nb-code-copy svg { - width: 0.875rem; - height: 0.875rem; -} -.nb-code-copy[data-state="copied"] { - color: var(--nb-success); -} - -/* ---- Premium code chrome ---- */ - -/* Every Shiki block is wrapped in a .nb-code-figure (titled or not). - Chrome lives on the figure so the language badge + copy button can sit - on a non-scrolling ancestor — iOS Safari slides absolutely-positioned - children of overflow:auto containers. */ -.nb-code-figure { - position: relative; - margin: 1rem 0; - border: 1px solid var(--nb-border); - border-radius: 0.5rem; - background-color: var(--nb-card); - overflow: hidden; -} -.nb-code-figure > pre.astro-code { - margin: 0; - border: 0; - border-radius: 0; - background-color: transparent; -} -.nb-code-title { - display: flex; - align-items: center; - justify-content: space-between; - gap: 0.75rem; - padding: 0.5rem 0.875rem; - border-bottom: 1px solid var(--nb-border); - background: color-mix(in oklch, var(--nb-muted) 50%, transparent); - font-family: var(--nb-font-mono); - font-size: 0.75rem; - line-height: 1.4; -} -.nb-code-title-name { - color: var(--nb-foreground); - font-weight: 500; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -.nb-code-title-lang { - flex-shrink: 0; - padding: 0.0625rem 0.375rem; - border-radius: 0.25rem; - background: var(--nb-muted); - color: var(--nb-muted-foreground); - font-size: 0.6875rem; - letter-spacing: 0.02em; - text-transform: uppercase; -} - -/* Language badge — pinned to the figure (which doesn't scroll), so it - stays at top-right even when the pre overflows horizontally. Hidden - when a figcaption is already showing the language (titled blocks). */ -.nb-code-figure[data-nb-lang]:not(.nb-code-figure-titled)::before { - content: attr(data-nb-lang); - position: absolute; - top: 0.5rem; - right: 0.625rem; - padding: 0.0625rem 0.375rem; - border-radius: 0.25rem; - background: var(--nb-muted); - color: var(--nb-muted-foreground); - font-family: var(--nb-font-mono); - font-size: 0.6875rem; - letter-spacing: 0.02em; - text-transform: uppercase; - pointer-events: none; - opacity: 0.75; - transition: opacity 0.15s ease; - z-index: 1; -} -.nb-code-figure:hover::before { - opacity: 0; -} -/* Hide plaintext/text "language" — it's noise. */ -.nb-code-figure[data-nb-lang="text"]::before, -.nb-code-figure[data-nb-lang="plaintext"]::before, -.nb-code-figure[data-nb-lang="plain"]::before, -.nb-code-figure[data-nb-lang="txt"]::before { - display: none; -} - -/* Block-level lines so tints + gutters paint across the full row. */ -pre.astro-code code { - display: block; - width: max-content; - min-width: 100%; -} -pre.astro-code .line { - display: inline-block; - width: 100%; - padding-inline: 1rem; - margin-inline: -1rem; - box-sizing: content-box; -} - -/* Highlighted lines (`{1,3-5}` meta or `// [!code highlight]`). */ -pre.astro-code .line.highlighted { - background: color-mix(in oklch, var(--nb-info) 12%, transparent); - box-shadow: inset 2px 0 0 var(--nb-info); -} - -/* Diff lines (`// [!code ++]` / `// [!code --]`). */ -pre.astro-code .line.diff { - position: relative; -} -pre.astro-code .line.diff.add { - background: color-mix(in oklch, var(--nb-success) 10%, transparent); - box-shadow: inset 2px 0 0 var(--nb-success); -} -pre.astro-code .line.diff.remove { - background: color-mix(in oklch, var(--nb-danger) 10%, transparent); - box-shadow: inset 2px 0 0 var(--nb-danger); -} -pre.astro-code .line.diff.add::before, -pre.astro-code .line.diff.remove::before { - position: absolute; - left: 0.25rem; - color: var(--nb-muted-foreground); - font-weight: 600; -} -pre.astro-code .line.diff.add::before { - content: "+"; - color: var(--nb-success); -} -pre.astro-code .line.diff.remove::before { - content: "−"; - color: var(--nb-danger); -} - -/* Focus mode — dim non-focused lines; clears on hover. */ -pre.astro-code.has-focused .line:not(.focused) { - opacity: 0.45; - filter: blur(0.25px); - transition: opacity 0.2s ease, filter 0.2s ease; -} -pre.astro-code.has-focused:hover .line:not(.focused) { - opacity: 1; - filter: none; -} - -/* Error / warning lines — use muted tokens for theme-tuned tints. */ -pre.astro-code .line.highlighted.error { - background: var(--nb-danger-muted); - box-shadow: inset 2px 0 0 var(--nb-danger); -} -pre.astro-code .line.highlighted.warning { - background: var(--nb-warning-muted); - box-shadow: inset 2px 0 0 var(--nb-warning); -} - -/* Word highlight (`// [!code word:foo]` and meta `/foo/`). */ -pre.astro-code .highlighted-word { - padding: 0.0625rem 0.25rem; - margin: -0.0625rem -0.125rem; - border-radius: 0.25rem; - background: color-mix(in oklch, var(--nb-info) 18%, transparent); - box-shadow: 0 0 0 1px color-mix(in oklch, var(--nb-info) 30%, transparent); -} - -/* ---- Mobile sidebar toggle ---- */ - -/* Hide hamburger on pages without a sidebar dialog. */ -body:not(:has([data-mobile-sidebar])) [data-menu-btn] { - display: none; -} diff --git a/docs/src/styles/prose.css b/docs/src/styles/prose.css deleted file mode 100644 index 5b4427b..0000000 --- a/docs/src/styles/prose.css +++ /dev/null @@ -1,331 +0,0 @@ -/* Docs markdown styling scoped to docs content containers only. */ - -.docs-content { - font-size: 0.9375rem; - line-height: 1.75; - color: var(--nb-foreground); - /* Break a long unbroken token (URL, hash, no-space string) so it wraps within - the content column instead of leaking past the page width. Inherited, so it - covers headings, paragraphs, list items, and inline code; `pre` code blocks - are unaffected (their `white-space: pre` doesn't wrap — they scroll instead, - via `pre.astro-code { overflow-x: auto }`), and wide tables keep their own - `.nb-table-scroll` handling. */ - overflow-wrap: break-word; -} - -/* Vertical rhythm — every direct child gets spacing by default. - Components can override with their own margin utilities (my-4, mt-6, etc.) - because :where() keeps specificity at (0,1,0) and utilities come later. */ -.docs-content > :where(:not(:first-child)) { - margin-top: 1.25rem; -} - -.docs-content :where(ul:not([class])) { - padding-left: 1.25rem; - list-style-type: disc; -} - -.docs-content :where(ol:not([class])) { - padding-left: 1.25rem; - list-style-type: decimal; -} - -.docs-content :where(ul:not([class]) ul:not([class])) { - list-style-type: circle; -} - -.docs-content :where(ul:not([class]) ul:not([class]) ul:not([class])) { - list-style-type: square; -} - -.docs-content :where(li:not([class])) { - margin: 0.25rem 0; -} - -.docs-content :where(blockquote:not([class])) { - margin: 1.25rem 0; - padding-left: 1rem; - border-left: 2px solid var(--nb-border); - color: var(--nb-muted-foreground); -} - -.docs-content :where(hr:not([class])) { - border: 0; - border-top: 1px solid var(--nb-border); - margin: 1.5rem 0; -} - -/* Component boundary — elements with a class attribute are component-owned. - Markdown never adds classes to h1–h6 or p; components always do. */ -.docs-content :where(h1, h2, h3, h4, h5, h6, p):where([class]) { - margin: 0; - font-size: inherit; -} - -/* Markdown heading typography is token-driven from globals.css. */ -.docs-content :where(h1:not([class])) { - font-size: var(--nb-h1-size); - font-weight: var(--nb-h1-weight); - letter-spacing: var(--nb-h1-tracking); - margin-top: 0; -} - -.docs-content :where(h2:not([class])) { - font-size: var(--nb-h2-size); - font-weight: var(--nb-h2-weight); - letter-spacing: var(--nb-h2-tracking); - margin-top: 2.5rem; -} - -.docs-content :where(h3:not([class])) { - font-size: var(--nb-h3-size); - font-weight: var(--nb-h3-weight); - letter-spacing: var(--nb-h3-tracking); - margin-top: 2rem; -} - -.docs-content :where(h4:not([class]), h5:not([class]), h6:not([class])) { - font-weight: var(--nb-h4-weight); -} - -.docs-content :where(h1:not([class]), h2:not([class]), h3:not([class]), h4:not([class])) { - scroll-margin-top: 5rem; -} - -/* Typographic wrapping — balance multi-line headings (no orphan words), - pretty-wrap body copy (no single-word last lines). Progressive - enhancement; unsupported browsers ignore both. */ -.docs-content :where(h1:not([class]), h2:not([class]), h3:not([class]), h4:not([class])) { - text-wrap: balance; -} - -.docs-content :where(p:not([class]), li:not([class]), blockquote:not([class])) { - text-wrap: pretty; -} - -.docs-content :where(h2[id], h3[id], h4[id]) { - position: relative; -} - -.docs-content .heading-anchor { - margin-left: 0.5rem; - color: var(--nb-muted-foreground); - text-decoration: none; - opacity: 0; - transition: opacity 0.15s, color 0.15s; -} - -.docs-content :where(h2[id], h3[id], h4[id]):hover .heading-anchor, -.docs-content .heading-anchor:focus-visible { - opacity: 1; -} - -.docs-content .heading-anchor:hover { - color: var(--nb-foreground); -} - -.docs-content :where(code:not([class])):not(:where(pre *)) { - font-family: var(--nb-font-mono); - direction: ltr; - unicode-bidi: isolate; - background: var(--nb-muted); - border: 1px solid var(--nb-border); - border-radius: 0.375rem; - padding: 0.125rem 0.375rem; - font-size: 0.8125em; - font-weight: 450; -} - -.docs-content :where(code:not([class])):not(:where(pre *))::before, -.docs-content :where(code:not([class])):not(:where(pre *))::after { - content: none; -} - -.docs-content :where(pre:not([class])) { - font-family: var(--nb-font-mono); -} - -/* Shiki-rendered code blocks — wider vertical margin than base rhythm - (1.25rem) because code blocks are visually dense. Inline code-token - styling (background, border, padding) is reset because Shiki spans - already carry their own colors via inline styles. */ -.docs-content .nb-code-figure { - margin: 1.5rem 0; -} - -.docs-content pre.astro-code code { - direction: ltr; - unicode-bidi: isolate; - background: none; - border: none; - padding: 0; - font-size: inherit; - font-weight: inherit; - border-radius: 0; -} - -/* Fills its column; scroll is owned by the `.nb-table-scroll` wrapper (injected - by the tableScroll() hast plugin), since `overflow` is ignored on a table. */ -.docs-content :where(table:not([class])) { - display: table; - width: 100%; - max-width: 100%; - text-align: left; - border-collapse: separate; - border-spacing: 0; - border-radius: 0.75rem; - border: 1px solid var(--nb-border); - table-layout: auto; -} - -/* Wide tables scroll within this box at all widths instead of overflowing the - page; short tables still fill it via the inner `width: 100%`. */ -.docs-content :where(.nb-table-scroll) { - max-width: 100%; - overflow-x: auto; - overflow-y: hidden; - overscroll-behavior-x: contain; - -webkit-overflow-scrolling: touch; -} - -.docs-content :where(th:not([class])), -.docs-content :where(td:not([class])) { - padding: 0.625rem 0.75rem; - text-align: left; - vertical-align: top; - border-bottom: 1px solid var(--nb-border); -} - -.docs-content :where(th:not([class])) { - background: var(--nb-muted); - font-weight: 600; - font-size: 0.8125rem; - white-space: nowrap; -} - -.docs-content :where(tbody:not([class]) tr:not([class]):last-child td:not([class])) { - border-bottom: none; -} - -/* Round the outer corner cells to match the table's border-radius — - `border-collapse: separate` leaves square cell backgrounds (the muted - thead fill in particular) that would otherwise poke past the rounded - table border. */ -.docs-content :where(thead:not([class]) tr:not([class]):first-child th:not([class]):first-child) { - border-top-left-radius: 0.75rem; -} -.docs-content :where(thead:not([class]) tr:not([class]):first-child th:not([class]):last-child) { - border-top-right-radius: 0.75rem; -} -.docs-content :where(tbody:not([class]) tr:not([class]):last-child td:not([class]):first-child) { - border-bottom-left-radius: 0.75rem; -} -.docs-content :where(tbody:not([class]) tr:not([class]):last-child td:not([class]):last-child) { - border-bottom-right-radius: 0.75rem; -} - -.docs-content :where(a:not([class])) { - color: var(--nb-foreground); - text-decoration-line: underline; - text-decoration-color: var(--nb-border-strong); - text-underline-offset: 3px; - text-decoration-thickness: 1px; - font-weight: 500; - transition: text-decoration-color 0.15s; -} - -.docs-content :where(a:not([class]):hover) { - text-decoration-color: var(--nb-foreground); -} - -/* ---- Long-tail prose vocabulary ---- - Elements markdown/MDX authors can reach for that would otherwise - render with raw browser defaults. Same component boundary as the rest - of the file: `:not([class])` leaves component-owned markup alone. */ - -/* Keycaps. The thicker bottom border stands in for a pressed edge — - border darkening, not a drop shadow. */ -.docs-content :where(kbd:not([class])) { - display: inline-block; - font-family: var(--nb-font-mono); - font-size: 0.75em; - font-weight: 500; - line-height: 1; - color: var(--nb-foreground); - background: var(--nb-muted); - border: 1px solid var(--nb-border); - border-bottom-width: 2px; - border-radius: 0.375rem; - padding: 0.1875rem 0.375rem; - vertical-align: 0.0625rem; -} - -/* Inline highlight — harmonized with ::selection instead of the - browser's fluorescent yellow. `box-decoration-break` keeps the tint - coherent when the highlight wraps across lines. */ -.docs-content :where(mark:not([class])) { - background: color-mix(in oklch, var(--nb-primary) 12%, transparent); - color: var(--nb-foreground); - border-radius: 0.25rem; - padding: 0.0625rem 0.25rem; - -webkit-box-decoration-break: clone; - box-decoration-break: clone; -} - -/* Native disclosure. Scope guard: FileTree builds classless <details> - internally (`.file-tree :global(details)`), so exclude its subtree — - without this the rows below would grow double carets and borders. */ -.docs-content :where(details:not([class]):not(.file-tree *)) { - border: 1px solid var(--nb-border); - border-radius: 0.5rem; - padding: 0.625rem 0.875rem; -} - -.docs-content :where(details:not([class]):not(.file-tree *) > summary) { - display: flex; - align-items: center; - justify-content: space-between; - gap: 0.625rem; - cursor: pointer; - font-weight: 500; - list-style: none; - user-select: none; -} - -.docs-content :where(details:not([class]):not(.file-tree *) > summary)::-webkit-details-marker { - display: none; -} - -/* Trailing chevron — label left, indicator right, matching Collapsible. */ -.docs-content :where(details:not([class]):not(.file-tree *) > summary)::after { - content: ""; - flex-shrink: 0; - width: 0.4375em; - height: 0.4375em; - border-right: 1.5px solid var(--nb-muted-foreground); - border-bottom: 1.5px solid var(--nb-muted-foreground); - transform: rotate(-45deg); - transition: transform 0.2s cubic-bezier(0.32, 0.72, 0, 1); -} - -.docs-content :where(details[open]:not([class]):not(.file-tree *) > summary)::after { - transform: rotate(45deg) translateY(-0.125em); -} - -.docs-content :where(details[open]:not([class]):not(.file-tree *) > summary) { - margin-bottom: 0.5rem; -} - -/* Definition lists — term/description pairs. */ -.docs-content :where(dt:not([class])) { - font-weight: 600; -} - -.docs-content :where(dt:not([class]):not(:first-child)) { - margin-top: 0.75rem; -} - -.docs-content :where(dd:not([class])) { - margin-left: 1rem; - color: var(--nb-muted-foreground); -} diff --git a/docs/tsconfig.json b/docs/tsconfig.json index cea96c7..705f372 100644 --- a/docs/tsconfig.json +++ b/docs/tsconfig.json @@ -1,11 +1,46 @@ { - "extends": "astro/tsconfigs/strict", "compilerOptions": { "baseUrl": ".", + "target": "ESNext", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "react-jsx", + "incremental": true, "paths": { - "@/*": ["src/*"] - } + "fumadocs-mdx:collections/*": [ + ".source/*" + ], + "@/*": [ + "./*" + ] + }, + "plugins": [ + { + "name": "next" + } + ] }, - "include": [".astro/types.d.ts", "**/*"], - "exclude": ["dist"] + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + ".next/dev/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] } diff --git a/docs/vercel.json b/docs/vercel.json new file mode 100644 index 0000000..cee2a91 --- /dev/null +++ b/docs/vercel.json @@ -0,0 +1,11 @@ +{ + "headers": [ + { + "source": "/install", + "headers": [ + { "key": "Content-Type", "value": "text/plain; charset=utf-8" }, + { "key": "Cache-Control", "value": "public, max-age=0, must-revalidate" } + ] + } + ] +} \ No newline at end of file diff --git a/docs/wrangler.jsonc b/docs/wrangler.jsonc deleted file mode 100644 index 44351cd..0000000 --- a/docs/wrangler.jsonc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "$schema": "node_modules/wrangler/config-schema.json", - "name": "dotfiles", - "compatibility_date": "2026-07-25", - "assets": { - "directory": "./dist", - "not_found_handling": "404-page" - } -} diff --git a/home-win/Documents/PowerShell/Microsoft.PowerShell_profile.ps1 b/home-win/Documents/PowerShell/Microsoft.PowerShell_profile.ps1 deleted file mode 100644 index f6f83f4..0000000 --- a/home-win/Documents/PowerShell/Microsoft.PowerShell_profile.ps1 +++ /dev/null @@ -1,23 +0,0 @@ -$env:DOTFILES = "$HOME\Codes\dotfiles" -$DotFilesPath = $env:DOTFILES - -function dot { - Set-Location $env:DOTFILES -} - -$miseCommand = Get-Command mise -ErrorAction SilentlyContinue -if (-not $miseCommand) { - $wingetMiseBin = Get-ChildItem -Path "$HOME\AppData\Local\Microsoft\WinGet\Packages" -Directory -Filter "jdx.mise*" -ErrorAction SilentlyContinue | - Sort-Object LastWriteTime -Descending | - Select-Object -First 1 | - ForEach-Object { Join-Path $_.FullName "mise\bin" } - - if ($wingetMiseBin -and (Test-Path (Join-Path $wingetMiseBin "mise.exe"))) { - $env:Path = "$wingetMiseBin;$env:Path" - $miseCommand = Get-Command mise -ErrorAction SilentlyContinue - } -} - -if ($miseCommand) { - (& mise activate pwsh) | Out-String | Invoke-Expression -} diff --git a/home-win/Documents/kanata/kanata.kbd b/home-win/Documents/kanata/kanata.kbd deleted file mode 100644 index 1a87f85..0000000 --- a/home-win/Documents/kanata/kanata.kbd +++ /dev/null @@ -1,42 +0,0 @@ -;; Kanata config - HHKB HYBRID Type-S (US layout) -;; Two input methods installed: English (US) IME + Japanese Microsoft IME. -;; Left Win tap -> switch to English (US) IME -;; Right Win tap -> switch to Japanese IME, then Kana (IME on) -;; Held / combined with other keys -> behaves as the original Win key. -;; -;; Requires Windows "input language hot keys" (Start-Process "ms-settings:typing" -;; -> Advanced keyboard settings -> Input language hot keys): -;; To Japanese - Microsoft IME = Left Alt+Shift+1 -;; To English (United States) = Left Alt+Shift+2 -;; These directly SELECT a language (not the toggle), so switching is deterministic. -;; -;; Reference: https://blog.naa0yama.com/p/01w11-uhbda8wz/ - -(defcfg - process-unmapped-keys yes - log-layer-changes no -) - -(defsrc - lmet rmet -) - -(defalias - ;; 0x1A = 26 (Eisu/英数), 0x16 = 22 (Kana/かな) - ;; 50 = 50ms delay so the IME has switched before the code is sent. - ;; tap-hold-press: the moment another key is pressed, resolve to the hold - ;; action (lmet/rmet) immediately. This makes Win+S / Win+Space feel as snappy - ;; as Karabiner. Plain tap-hold only decides on timeout/release, so fast - ;; Win-combos were being mis-fired as taps (language switch). - lwin (tap-hold-press 200 200 (macro A-S-2) lmet) - rwin (tap-hold-press 200 200 (macro A-S-1 50 (arbitrary-code 22)) rmet) - - ;; Alternative for Left Win: stay in Japanese IME and send Eisu (英数 direct - ;; input) instead of switching to the English (US) IME. Swap the @lwin line - ;; in the layer to @lwin-jp if you prefer this. - lwin-jp (tap-hold-press 200 200 (macro A-S-1 50 (arbitrary-code 26)) lmet) -) - -(deflayer default - @lwin @rwin -) diff --git a/home/.agents/.skill-lock.json b/home/.agents/.skill-lock.json deleted file mode 100644 index c522e79..0000000 --- a/home/.agents/.skill-lock.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "version": 3, - "skills": { - "find-skills": { - "source": "vercel-labs/skills", - "sourceType": "github", - "sourceUrl": "https://github.com/vercel-labs/skills.git", - "skillPath": "skills/find-skills/SKILL.md", - "skillFolderHash": "eb6a23305aea6e340d14b9de3766e721f9f4861b", - "installedAt": "2026-06-27T14:47:14.761Z", - "updatedAt": "2026-06-27T14:47:14.761Z" - } - }, - "dismissed": { - "findSkillsPrompt": true - }, - "lastSelectedAgents": [ - "amp", - "antigravity", - "antigravity-cli", - "cline", - "codex", - "cursor", - "deepagents", - "gemini-cli", - "github-copilot", - "kimi-code-cli", - "opencode", - "warp", - "zed" - ] -} \ No newline at end of file diff --git a/home/.agents/instructions/global.instructions.md b/home/.agents/instructions/global.instructions.md deleted file mode 100644 index 94061d1..0000000 --- a/home/.agents/instructions/global.instructions.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -description: "Global personal preferences for all projects" -applyTo: "**" ---- - -- 返答は常に日本語で行う -- 不明瞭な指示は質問して明確にする - -## 作業 - -- Webプロジェクトの実行/ビルドは `mise run ...` を正として扱う -- git worktree の指定がない限り、基本は現在の作業ツリーで進める -- 現在の作業ツリーが main なら、その main 上で作業を続行する -- 別 worktree が必要なケースだけ、必要性を確認または提案する - -## コード設計 - -- 関心の分離を保つ -- 状態とロジックを分離する -- 可読性と保守性を重視する -- コントラクト層(API/型)を厳密に定義し、実装層は再生成可能に保つ diff --git a/home/.agents/skills/commit/SKILL.md b/home/.agents/skills/commit/SKILL.md deleted file mode 100644 index 239ee9e..0000000 --- a/home/.agents/skills/commit/SKILL.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -name: commit -description: "Use when the user runs /commit or asks to create a git commit automatically from current changes following this repository conventions." ---- - -# /commit - -このスキルは、現在の変更からコミット規則に沿ったコミットを自動で作成する。 - -## コミット規則 - -1. 英語で書く -2. Conventional Commits の形式に従う: `<type>(<scope>): <description>` - -### タイプ一覧 - -| タイプ | 使うタイミング | -| :----------- | :--------------------------------------------------- | -| `feat` | 新機能の追加 | -| `fix` | バグ修正 | -| `docs` | ドキュメントのみの変更 | -| `style` | フォーマット修正など(ロジック変更なし) | -| `refactor` | バグ修正でも機能追加でもないコード変更 | -| `perf` | パフォーマンス改善 | -| `test` | テストの追加・更新 | -| `chore` | ビルド、依存関係更新、ツール設定変更 | -| `ci` | CI/CD 設定の変更 | - -### ルール - -- description は命令形で書く("add"、"added" や "adds" は使わない)。 -- description は 72 文字以内に収める。 -- 関連する Issue がある場合はフッターに記載する: `Fixes #123` - -### 例 - -``` -feat(layout): add responsive header component -fix(store): resolve hydration mismatch in AppStore -docs: add PostCSS usage guide to README -chore(deps): update astro to v6.1.0 -refactor(animations): extract easing constants to separate file -``` - -## Workflow - -1. `git status --short` で変更を確認。 -2. `git diff --staged` と `git diff` を見て要約を作る。 -3. 上記コミット規則に沿うコミットタイトルを1つ決める。 -4. ステージされていない変更があれば `git add -A`。 -5. `git commit -m "<title>"` を実行。 -6. 実行結果(コミットハッシュとタイトル)を返す。 - -## Fallback - -- 変更がない場合はコミットしないで「No changes to commit」を返す。 -- 規則に適合しない場合は、修正した候補タイトルを提示してから実行する。 diff --git a/home/.agents/skills/dev-server/SKILL.md b/home/.agents/skills/dev-server/SKILL.md deleted file mode 100644 index 9a5404f..0000000 --- a/home/.agents/skills/dev-server/SKILL.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -name: dev-server -description: "Use when starting the dev server with mise run dev in the current git worktree. Prefer inferring the target path from the active file or recent worktree context so the user does not need to remember the worktree path every time. Use for: devサーバー起動, worktreeでdev, person-newでdev, feature branchでdev確認, 現在のworktreeでdev, mise run dev in worktree." -argument-hint: "[optional: branch name or worktree name]" ---- - -# Dev Server in Worktree - -worktree 環境で `mise run dev` を正しく起動するワークフロー。 - -## 目的 - -毎回 worktree のパスを手で指定しなくてよいようにする。 -また、同じ worktree ですでに VS Code terminal 上の dev server が起動しているなら、 -新しい terminal を増やさず **既存 terminal を再利用する**。 -基本方針は以下。 - -1. まず **現在編集中のファイルのパス** から worktree を推定する -2. 同じ worktree の dev server が既存 terminal で動いていないか確認する -3. それで決まらない場合だけ **直近の作業コンテキスト** や引数の branch 名を使う -4. 最後に `git wt --json` で対応する path を確認する - -つまり、ユーザーが `/dev-server person-new` と言わなくても、 -「今 `/.git/wt/person-new/` 配下のファイルを触っている」ならその worktree を使う。 - -## 注意事項 - -`run_in_terminal` の `isBackground=true` はツールが `cd` を省略し、常にワークスペースルートから起動する。そのため **worktree での起動には必ず `isBackground=false` を使う**。 - -ただし、**同じ worktree の既存 terminal で `mise run dev` がすでに起動中なら、新しい terminal を作らない**。 -見えている terminal だけでなく、直近にエージェントが起動した hidden terminal も再利用候補とする。 - -サーバーが起動するとエージェントはブロックされるが、ユーザーが確認後に Ctrl+C で停止すれば自動的に再開するため問題ない。 - -また、wt コマンドで node_modulesはコピーされないため、worktree での起動前にルートで一度 `bun install` を実行しておく必要がある。 - -## Procedure - -### 1. 作業中の worktree パスを特定する - -優先順位は次のとおり。 - -1. **アクティブファイルの絶対パス** - - 例: `/repo/.git/wt/person-new/src/...` なら worktree は `/repo/.git/wt/person-new` -2. **直近の作業コンテキスト** - - 直前にその worktree で build / dev / edit をしていれば、その path を使う -3. **スキル引数** - - branch 名や worktree 名が渡されている場合はそれを使う -4. **`git wt --json`** - - 上記で曖昧なら一覧から path を特定する - -```sh -git wt --json -``` - -現在編集中のファイルパスか、直近の作業コンテキストから対象の worktree ディレクトリを特定する。 -例: `/path/to/repo/.git/wt/<branch-name>/` - -アクティブファイルが worktree 配下にあるなら、**原則としてその path をそのまま使う**。 - -### 2. 既存 terminal の再利用を優先する - -対象 worktree path が決まったら、**新しく起動する前に** VS Code 上の既存 terminal を確認する。 - -優先順位は次のとおり。 - -1. **同じ worktree path で起動済みの persistent terminal** - - 直前に `cd <same-worktree> && mise run dev` を実行している terminal があればそれを使う - - その terminal の出力を確認し、サーバーが待受中なら **新規起動しない** -2. **VS Code 上で見えている terminal の作業ディレクトリ / 最終コマンド** - - cwd が同じ worktree、かつ `mise run dev` や `astro dev` が動いていれば再利用する -3. **上記に一致しない場合のみ、新規 terminal で起動する** - -判定ルール: - -- `cwd == <worktree-path>` または `cd <worktree-path> && mise run dev` の履歴がある -- 出力に `astro ... ready` や `watching for file changes` がある -- その場合は「既存サーバーを利用中」とみなし、新しい terminal を増やさない - -### 3. 必要な場合だけ `isBackground=false` でサーバーを起動する - -```sh -cd <worktree-path> && mise run dev -``` - -ユーザーが確認を終えて Ctrl+C でサーバーを停止すると、エージェントは次のステップへ進む。 - -## 実行テンプレート - -最終的にやることはこれだけ。 - -```sh -cd <active-or-resolved-worktree-path> && mise run dev -``` - -ただし、同じ worktree の既存 terminal がすでに生きているなら、 -**起動ではなく既存 terminal の参照を優先する**。 diff --git a/home/.agents/skills/find-skills/SKILL.md b/home/.agents/skills/find-skills/SKILL.md deleted file mode 100644 index 7369d66..0000000 --- a/home/.agents/skills/find-skills/SKILL.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -name: find-skills -description: Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill. ---- - -# Find Skills - -This skill helps you discover and install skills from the open agent skills ecosystem. - -## When to Use This Skill - -Use this skill when the user: - -- Asks "how do I do X" where X might be a common task with an existing skill -- Says "find a skill for X" or "is there a skill for X" -- Asks "can you do X" where X is a specialized capability -- Expresses interest in extending agent capabilities -- Wants to search for tools, templates, or workflows -- Mentions they wish they had help with a specific domain (design, testing, deployment, etc.) - -## What is the Skills CLI? - -The Skills CLI (`npx skills`) is the package manager for the open agent skills ecosystem. Skills are modular packages that extend agent capabilities with specialized knowledge, workflows, and tools. - -**Key commands:** - -- `npx skills find [query] [--owner <owner>]` - Search for skills interactively or by keyword, optionally scoped to a GitHub owner -- `npx skills add <package>` - Install a skill from GitHub or other sources -- `npx skills check` - Check for skill updates -- `npx skills update` - Update all installed skills - -**Browse skills at:** https://skills.sh/ - -## How to Help Users Find Skills - -### Step 1: Understand What They Need - -When a user asks for help with something, identify: - -1. The domain (e.g., React, testing, design, deployment) -2. The specific task (e.g., writing tests, creating animations, reviewing PRs) -3. Whether this is a common enough task that a skill likely exists - -### Step 2: Check the Leaderboard First - -Before running a CLI search, check the [skills.sh leaderboard](https://skills.sh/) to see if a well-known skill already exists for the domain. The leaderboard ranks skills by total installs, surfacing the most popular and battle-tested options. - -For example, top skills for web development include: -- `vercel-labs/agent-skills` — React, Next.js, web design (100K+ installs each) -- `anthropics/skills` — Frontend design, document processing (100K+ installs) - -### Step 3: Search for Skills - -If the leaderboard doesn't cover the user's need, run the find command: - -```bash -npx skills find [query] [--owner <owner>] -``` - -For example: - -- User asks "how do I make my React app faster?" → `npx skills find react performance` -- User asks "can you help me with PR reviews?" → `npx skills find pr review` -- User asks "I need to create a changelog" → `npx skills find changelog` - -### Step 4: Verify Quality Before Recommending - -**Do not recommend a skill based solely on search results.** Always verify: - -1. **Install count** — Prefer skills with 1K+ installs. Be cautious with anything under 100. -2. **Source reputation** — Official sources (`vercel-labs`, `anthropics`, `microsoft`) are more trustworthy than unknown authors. -3. **GitHub stars** — Check the source repository. A skill from a repo with <100 stars should be treated with skepticism. - -### Step 5: Present Options to the User - -When you find relevant skills, present them to the user with: - -1. The skill name and what it does -2. The install count and source -3. The install command they can run -4. A link to learn more at skills.sh - -Example response: - -``` -I found a skill that might help! The "react-best-practices" skill provides -React and Next.js performance optimization guidelines from Vercel Engineering. -(185K installs) - -To install it: -npx skills add vercel-labs/agent-skills@react-best-practices - -Learn more: https://skills.sh/vercel-labs/agent-skills/react-best-practices -``` - -### Step 6: Offer to Install - -If the user wants to proceed, you can install the skill for them: - -```bash -npx skills add <owner/repo@skill> -g -y -``` - -The `-g` flag installs globally (user-level) and `-y` skips confirmation prompts. - -## Common Skill Categories - -When searching, consider these common categories: - -| Category | Example Queries | -| --------------- | ---------------------------------------- | -| Web Development | react, nextjs, typescript, css, tailwind | -| Testing | testing, jest, playwright, e2e | -| DevOps | deploy, docker, kubernetes, ci-cd | -| Documentation | docs, readme, changelog, api-docs | -| Code Quality | review, lint, refactor, best-practices | -| Design | ui, ux, design-system, accessibility | -| Productivity | workflow, automation, git | - -## Tips for Effective Searches - -1. **Use specific keywords**: "react testing" is better than just "testing" -2. **Try alternative terms**: If "deploy" doesn't work, try "deployment" or "ci-cd" -3. **Check popular sources**: Many skills come from `vercel-labs/agent-skills` or `ComposioHQ/awesome-claude-skills` - -## When No Skills Are Found - -If no relevant skills exist: - -1. Acknowledge that no existing skill was found -2. Offer to help with the task directly using your general capabilities -3. Suggest the user could create their own skill with `npx skills init` - -Example: - -``` -I searched for skills related to "xyz" but didn't find any matches. -I can still help you with this task directly! Would you like me to proceed? - -If this is something you do often, you could create your own skill: -npx skills init my-xyz-skill -``` diff --git a/home/.agents/skills/git-wt/SKILL.md b/home/.agents/skills/git-wt/SKILL.md deleted file mode 100644 index aa5ad8d..0000000 --- a/home/.agents/skills/git-wt/SKILL.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -name: wt -description: "git wt(k1LoW/git-wt)を使ってgit worktreeを作成・切り替え・削除するワークフロー。Use when: worktreeで並行作業する, ブランチを切り替える, feature branch per task, worktree管理, 並列タスク実行, git worktree list/add/remove。エージェントが複数ブランチを横断して自律的にタスクを実行する場合にも使用する。" -argument-hint: "<branch|worktree|path> | list | delete" ---- - -# git-wt ワークフロー - -`git wt`([k1LoW/git-wt](https://github.com/k1LoW/git-wt))は `git worktree` をシンプルに扱うための Git サブコマンド。 - -## When to Use - -- 「ブランチ X で実装して」と依頼されたとき -- 複数ブランチ・タスクを 並行して 進めるとき -- 現在の作業を捨てずに別ブランチを覗きたいとき -- worktree の一覧確認・クリーンアップをするとき - -## 既定動作 - -- ユーザーが branch / worktree / path を明示していない場合は、worktree を切るかどうかを先に確認しない -- 未指定時の基本動作は、現在の作業ツリーでそのまま進めることとする -- 現在の作業ツリーが `main` なら、その `main` 上で作業を続行する前提で扱う -- 別 worktree を提案するのは、並行作業、別ブランチ指定、作業分離の必要性が明確な場合だけに限る - ---- - -## コマンドリファレンス - -```sh -# 一覧表示 -git wt # 全 worktree を表示 -git wt --json # JSON 形式で表示 - -# 切り替え / 作成(ブランチ・worktree がなければ自動作成) -git wt <branch> # ブランチ名で切り替え -git wt <worktree-folder-name> # .git/wt/ 内のフォルダ名で切り替え -git wt <path> # 絶対 / 相対パスで切り替え - -# 削除(safe: デフォルトブランチは保護される) -git wt -d <branch|path> # worktree + ブランチを削除 -git wt -D <branch|path> # 強制削除 -``` - -## 即実行ルール - -- 対象が明示されていない限り、「worktree を切るか」を確認する質問は挟まず、現在の作業ツリーを既定として扱う -- ユーザーが `/wt <branch|worktree|path>` のように対象を明示したら、一覧確認や存在確認を先に挟まず `git wt <target>` を最優先で実行する -- `git wt <target>` は既存 worktree への切り替えと、未作成時の新規作成を兼ねる前提で扱う -- 一覧確認のための `git wt` は、対象が曖昧なとき、削除候補を見たいとき、または `git wt <target>` が失敗したときだけ行う -- エージェントは「まず一覧を見る」より「まず切り替えを試す」を基本動作にする - ---- - -## エージェント向けワークフロー - -機能ブランチに閉じたタスクを実行するときの推奨手順: - -1. 切り替え / 作成 — 対象が明示されているなら、まず `git wt <branch>` で対象ブランチへ移動(なければ自動作成) -2. 現在地確認 — 必要な場合にだけ `git wt` で worktree 一覧を確認 -3. 作業 — コード変更・テスト・コミットをその worktree で実施 -4. 別タスクへ — `git wt <other-branch>` で別 worktree へ切り替え(現在の変更は保持) -5. 完了後クリーンアップ — マージ済みなら `git wt -d <branch>` で削除 - -> ポイント: `git wt` は worktree 間の `cd` を自動で行う(Shell Integration が必要。後述)。 -> エージェントが `run_in_terminal` でコマンドを実行する場合は、パスを明示的に変更するか `--nocd` でパスを取得してから `cd` すること。 -- worktree を閉じる前に、対象ブランチは non-fast-forward merge で取り込むことを推奨(`git merge --no-ff <branch>`) - ---- - -## 推奨設定 - -### zsh Shell Integration セットアップ - -`~/.zshrc` に追加することで、`git wt <branch>` が worktree へ自動 `cd` できるようになる。 - -```sh -eval "$(git wt --init zsh)" -``` - -> `--nocd` を付けると `cd` なし・補完のみになる: -> `eval "$(git wt --init zsh --nocd)"` - -### 新規 worktree 作成時に依存をインストール(hook 例) - -```sh -# Node.js プロジェクト -git config --add wt.hook "bun install" - -# Go プロジェクト -git config --add wt.hook "go mod download" -``` - -### .gitignore ファイルを新 worktree にコピー - -```sh -git config wt.copyignored true # .env など全て -# または特定ファイルのみ -git config --add wt.copy ".env" -git config --add wt.copy ".vscode/" -``` - ---- - -## レシピ - -### fzf でインタラクティブ選択(zsh/bash) - -```sh -cd $(git wt | fzf --header-lines=1 | awk '{if ($1 == "*") print $2; else print $1}') -``` - -### tmux: 新 worktree を新ウィンドウで開く - -```sh -git config wt.nocd create -git config --add wt.hook 'tmux neww -c "$PWD" -n "$(basename -s .git `git remote get-url origin`):$(git branch --show-current)"' -``` - -### 削除前にリモートブランチも消す - -```sh -git config --add wt.deletehook "git push origin --delete $(git branch --show-current)" -``` diff --git a/home/.claude/CLAUDE.md b/home/.claude/CLAUDE.md deleted file mode 100644 index b3eb959..0000000 --- a/home/.claude/CLAUDE.md +++ /dev/null @@ -1,6 +0,0 @@ -# Global memory (Claude Code) - -Copilot/Cursor と共通の指示を単一ソースとして読み込む。 -編集は `home/.agents/instructions/global.instructions.md` 側で行う。 - -@~/.copilot/instructions/global.instructions.md diff --git a/home/.config/herdr/config.toml b/home/.config/herdr/config.toml deleted file mode 100644 index bb8b591..0000000 --- a/home/.config/herdr/config.toml +++ /dev/null @@ -1,25 +0,0 @@ -onboarding = false -# herdr — agent multiplexer (https://herdr.dev) -# Print the full commented defaults with `herdr --default-config`. -# Apply edits to a running server with `herdr server reload-config`. -# Only this file is symlinked: herdr writes logs, sockets and session.json -# into the same directory, so ~/.config/herdr itself stays local. - -[theme] -# Follow the host terminal palette (Ghostty: Birds Of Paradise) instead of -# a bundled scheme, so herdr matches whatever the terminal is themed with. -name = "terminal" - -[experimental] -# Prefix mode expects ASCII keys. Switch the macOS input source while it is -# active so ctrl+b chords still register with a Japanese IME turned on. -switch_ascii_input_source_in_prefix = true - -# Agent TUIs paint their own cursor, which leaves the IME candidate window -# stranded. Reveal the real cursor for those panes only — applying it -# everywhere would draw a second cursor in vim normal mode. -reveal_hidden_cursor_for_cjk_ime = true -cjk_ime_agents = ["claude", "codex"] - -[ui] -agent_panel_sort = "spaces" diff --git a/home/.config/karabiner/karabiner.json b/home/.config/karabiner/karabiner.json index 1701ead..1491835 100644 --- a/home/.config/karabiner/karabiner.json +++ b/home/.config/karabiner/karabiner.json @@ -50,31 +50,23 @@ "vendor_id": 6127 }, "simple_modifications": [ - { - "from": { "key_code": "left_command" }, - "to": [{ "key_code": "left_option" }] - }, { "from": { "key_code": "left_option" }, "to": [{ "key_code": "left_command" }] }, { - "from": { "key_code": "print_screen" }, - "to": [{ "key_code": "right_option" }] + "from": { "key_code": "left_command" }, + "to": [{ "key_code": "left_option" }] }, { "from": { "key_code": "right_option" }, "to": [{ "key_code": "right_command" }] + }, + { + "from": { "key_code": "print_screen" }, + "to": [{ "key_code": "right_option" }] } ] - }, - { - "identifiers": { - "is_keyboard": true, - "product_id": 256, - "vendor_id": 2131 - }, - "treat_as_built_in_keyboard": true } ], "name": "Default profile", diff --git a/home/.config/nvim/.gitignore b/home/.config/nvim/.gitignore deleted file mode 100644 index cc5457a..0000000 --- a/home/.config/nvim/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -tt.* -.tests -doc/tags -debug -.repro -foo.* -*.log -data diff --git a/home/.config/nvim/.neoconf.json b/home/.config/nvim/.neoconf.json deleted file mode 100644 index 7c48087..0000000 --- a/home/.config/nvim/.neoconf.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "neodev": { - "library": { - "enabled": true, - "plugins": true - } - }, - "neoconf": { - "plugins": { - "lua_ls": { - "enabled": true - } - } - } -} diff --git a/home/.config/nvim/LICENSE b/home/.config/nvim/LICENSE deleted file mode 100644 index 261eeb9..0000000 --- a/home/.config/nvim/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/home/.config/nvim/init.lua b/home/.config/nvim/init.lua deleted file mode 100644 index 2514f9e..0000000 --- a/home/.config/nvim/init.lua +++ /dev/null @@ -1,2 +0,0 @@ --- bootstrap lazy.nvim, LazyVim and your plugins -require("config.lazy") diff --git a/home/.config/nvim/lazy-lock.json b/home/.config/nvim/lazy-lock.json deleted file mode 100644 index 8a1b602..0000000 --- a/home/.config/nvim/lazy-lock.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "LazyVim": { "branch": "main", "commit": "c10948c50b18fae7f256433afdef09e432410480" }, - "SchemaStore.nvim": { "branch": "main", "commit": "19e40cef03a380bfb578793a08222826118664dd" }, - "blink.cmp": { "branch": "main", "commit": "78336bc89ee5365633bcf754d93df01678b5c08f" }, - "bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" }, - "catppuccin": { "branch": "main", "commit": "79e2049a0fdf7ec840f8463fe1d962c94493196b" }, - "conform.nvim": { "branch": "master", "commit": "619363c30309d29ffa631e67c8183f2a72caa373" }, - "flash.nvim": { "branch": "main", "commit": "b6346946d10d07998efee029fb0f7a593806d0cd" }, - "friendly-snippets": { "branch": "main", "commit": "6cd7280adead7f586db6fccbd15d2cac7e2188b9" }, - "gitsigns.nvim": { "branch": "main", "commit": "31d6fb2d618bca1482b9f274751ead5f03461408" }, - "grug-far.nvim": { "branch": "main", "commit": "0f6a5d0d7a70659b11bbcd6b3673ee0fe61b6024" }, - "lazy.nvim": { "branch": "main", "commit": "85c7ff3711b730b4030d03144f6db6375044ae82" }, - "lazydev.nvim": { "branch": "main", "commit": "ff2cbcba459b637ec3fd165a2be59b7bbaeedf0d" }, - "lualine.nvim": { "branch": "master", "commit": "221ce6b2d999187044529f49da6554a92f740a96" }, - "markdown-preview.nvim": { "branch": "master", "commit": "a923f5fc5ba36a3b17e289dc35dc17f66d0548ee" }, - "mason-lspconfig.nvim": { "branch": "main", "commit": "7adc933dabcc7c86ae6b07aff7ee68eac398491f" }, - "mason.nvim": { "branch": "main", "commit": "2a6940af80375532e5e9e7c1f2fc6319a1b7a69d" }, - "mini.ai": { "branch": "main", "commit": "25248c6aa002391936a6200f12d1466015987133" }, - "mini.icons": { "branch": "main", "commit": "98faae31e9be1cc054ae63485e58ceb185efcad0" }, - "mini.pairs": { "branch": "main", "commit": "b1c5a726921b7a8c9321e9a7a208aa0571de5810" }, - "noice.nvim": { "branch": "main", "commit": "7bfd942445fb63089b59f97ca487d605e715f155" }, - "nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" }, - "nvim-lint": { "branch": "master", "commit": "a219b2c9e5b4765e5c845aba119dad55806fcaf1" }, - "nvim-lspconfig": { "branch": "master", "commit": "7ab79bb1b57160a537f427ac8a6026102f12b701" }, - "nvim-treesitter": { "branch": "main", "commit": "61df84986b4b4ec469ee745a182e433d49f8c27e" }, - "nvim-treesitter-textobjects": { "branch": "main", "commit": "898ee307df58f854d11cd7edd06472574d48014e" }, - "nvim-ts-autotag": { "branch": "main", "commit": "88c1453db4ba7dd24131086fe51fdf74e587d275" }, - "persistence.nvim": { "branch": "main", "commit": "b20b2a7887bd39c1a356980b45e03250f3dce49c" }, - "plenary.nvim": { "branch": "master", "commit": "74b06c6c75e4eeb3108ec01852001636d85a932b" }, - "render-markdown.nvim": { "branch": "main", "commit": "f422cb5c6855f150e2ddcfaf44e7157b98b34f6a" }, - "snacks.nvim": { "branch": "main", "commit": "882c996cf28183f4d63640de0b4c02ec886d01f2" }, - "todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" }, - "tokyonight.nvim": { "branch": "main", "commit": "cdc07ac78467a233fd62c493de29a17e0cf2b2b6" }, - "trouble.nvim": { "branch": "main", "commit": "bd67efe408d4816e25e8491cc5ad4088e708a69a" }, - "ts-comments.nvim": { "branch": "main", "commit": "a59d6092213447450191122c9346f309161504cb" }, - "which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" } -} diff --git a/home/.config/nvim/lazyvim.json b/home/.config/nvim/lazyvim.json deleted file mode 100644 index c30dae6..0000000 --- a/home/.config/nvim/lazyvim.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extras": [ - "lazyvim.plugins.extras.lang.json", - "lazyvim.plugins.extras.lang.markdown", - "lazyvim.plugins.extras.lang.toml" - ], - "install_version": 8, - "news": { - "NEWS.md": "11866" - }, - "version": 8 -} \ No newline at end of file diff --git a/home/.config/nvim/lua/config/autocmds.lua b/home/.config/nvim/lua/config/autocmds.lua deleted file mode 100644 index 4221e75..0000000 --- a/home/.config/nvim/lua/config/autocmds.lua +++ /dev/null @@ -1,8 +0,0 @@ --- Autocmds are automatically loaded on the VeryLazy event --- Default autocmds that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/autocmds.lua --- --- Add any additional autocmds here --- with `vim.api.nvim_create_autocmd` --- --- Or remove existing autocmds by their group name (which is prefixed with `lazyvim_` for the defaults) --- e.g. vim.api.nvim_del_augroup_by_name("lazyvim_wrap_spell") diff --git a/home/.config/nvim/lua/config/keymaps.lua b/home/.config/nvim/lua/config/keymaps.lua deleted file mode 100644 index 2c134f7..0000000 --- a/home/.config/nvim/lua/config/keymaps.lua +++ /dev/null @@ -1,3 +0,0 @@ --- Keymaps are automatically loaded on the VeryLazy event --- Default keymaps that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/keymaps.lua --- Add any additional keymaps here diff --git a/home/.config/nvim/lua/config/lazy.lua b/home/.config/nvim/lua/config/lazy.lua deleted file mode 100644 index d73bfa1..0000000 --- a/home/.config/nvim/lua/config/lazy.lua +++ /dev/null @@ -1,53 +0,0 @@ -local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" -if not (vim.uv or vim.loop).fs_stat(lazypath) then - local lazyrepo = "https://github.com/folke/lazy.nvim.git" - local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath }) - if vim.v.shell_error ~= 0 then - vim.api.nvim_echo({ - { "Failed to clone lazy.nvim:\n", "ErrorMsg" }, - { out, "WarningMsg" }, - { "\nPress any key to exit..." }, - }, true, {}) - vim.fn.getchar() - os.exit(1) - end -end -vim.opt.rtp:prepend(lazypath) - -require("lazy").setup({ - spec = { - -- add LazyVim and import its plugins - { "LazyVim/LazyVim", import = "lazyvim.plugins" }, - -- import/override with your plugins - { import = "plugins" }, - }, - defaults = { - -- By default, only LazyVim plugins will be lazy-loaded. Your custom plugins will load during startup. - -- If you know what you're doing, you can set this to `true` to have all your custom plugins lazy-loaded by default. - lazy = false, - -- It's recommended to leave version=false for now, since a lot the plugin that support versioning, - -- have outdated releases, which may break your Neovim install. - version = false, -- always use the latest git commit - -- version = "*", -- try installing the latest stable version for plugins that support semver - }, - install = { colorscheme = { "tokyonight", "habamax" } }, - checker = { - enabled = true, -- check for plugin updates periodically - notify = false, -- notify on update - }, -- automatically check for plugin updates - performance = { - rtp = { - -- disable some rtp plugins - disabled_plugins = { - "gzip", - -- "matchit", - -- "matchparen", - -- "netrwPlugin", - "tarPlugin", - "tohtml", - "tutor", - "zipPlugin", - }, - }, - }, -}) diff --git a/home/.config/nvim/lua/config/options.lua b/home/.config/nvim/lua/config/options.lua deleted file mode 100644 index 3ea1454..0000000 --- a/home/.config/nvim/lua/config/options.lua +++ /dev/null @@ -1,3 +0,0 @@ --- Options are automatically loaded before lazy.nvim startup --- Default options that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/options.lua --- Add any additional options here diff --git a/home/.config/nvim/lua/plugins/example.lua b/home/.config/nvim/lua/plugins/example.lua deleted file mode 100644 index 17f53d6..0000000 --- a/home/.config/nvim/lua/plugins/example.lua +++ /dev/null @@ -1,197 +0,0 @@ --- since this is just an example spec, don't actually load anything here and return an empty spec --- stylua: ignore -if true then return {} end - --- every spec file under the "plugins" directory will be loaded automatically by lazy.nvim --- --- In your plugin files, you can: --- * add extra plugins --- * disable/enabled LazyVim plugins --- * override the configuration of LazyVim plugins -return { - -- add gruvbox - { "ellisonleao/gruvbox.nvim" }, - - -- Configure LazyVim to load gruvbox - { - "LazyVim/LazyVim", - opts = { - colorscheme = "gruvbox", - }, - }, - - -- change trouble config - { - "folke/trouble.nvim", - -- opts will be merged with the parent spec - opts = { use_diagnostic_signs = true }, - }, - - -- disable trouble - { "folke/trouble.nvim", enabled = false }, - - -- override nvim-cmp and add cmp-emoji - { - "hrsh7th/nvim-cmp", - dependencies = { "hrsh7th/cmp-emoji" }, - ---@param opts cmp.ConfigSchema - opts = function(_, opts) - table.insert(opts.sources, { name = "emoji" }) - end, - }, - - -- change some telescope options and a keymap to browse plugin files - { - "nvim-telescope/telescope.nvim", - keys = { - -- add a keymap to browse plugin files - -- stylua: ignore - { - "<leader>fp", - function() require("telescope.builtin").find_files({ cwd = require("lazy.core.config").options.root }) end, - desc = "Find Plugin File", - }, - }, - -- change some options - opts = { - defaults = { - layout_strategy = "horizontal", - layout_config = { prompt_position = "top" }, - sorting_strategy = "ascending", - winblend = 0, - }, - }, - }, - - -- add pyright to lspconfig - { - "neovim/nvim-lspconfig", - ---@class PluginLspOpts - opts = { - ---@type lspconfig.options - servers = { - -- pyright will be automatically installed with mason and loaded with lspconfig - pyright = {}, - }, - }, - }, - - -- add tsserver and setup with typescript.nvim instead of lspconfig - { - "neovim/nvim-lspconfig", - dependencies = { - "jose-elias-alvarez/typescript.nvim", - init = function() - require("lazyvim.util").lsp.on_attach(function(_, buffer) - -- stylua: ignore - vim.keymap.set( "n", "<leader>co", "TypescriptOrganizeImports", { buffer = buffer, desc = "Organize Imports" }) - vim.keymap.set("n", "<leader>cR", "TypescriptRenameFile", { desc = "Rename File", buffer = buffer }) - end) - end, - }, - ---@class PluginLspOpts - opts = { - ---@type lspconfig.options - servers = { - -- tsserver will be automatically installed with mason and loaded with lspconfig - tsserver = {}, - }, - -- you can do any additional lsp server setup here - -- return true if you don't want this server to be setup with lspconfig - ---@type table<string, fun(server:string, opts:_.lspconfig.options):boolean?> - setup = { - -- example to setup with typescript.nvim - tsserver = function(_, opts) - require("typescript").setup({ server = opts }) - return true - end, - -- Specify * to use this function as a fallback for any server - -- ["*"] = function(server, opts) end, - }, - }, - }, - - -- for typescript, LazyVim also includes extra specs to properly setup lspconfig, - -- treesitter, mason and typescript.nvim. So instead of the above, you can use: - { import = "lazyvim.plugins.extras.lang.typescript" }, - - -- add more treesitter parsers - { - "nvim-treesitter/nvim-treesitter", - opts = { - ensure_installed = { - "bash", - "html", - "javascript", - "json", - "lua", - "markdown", - "markdown_inline", - "python", - "query", - "regex", - "tsx", - "typescript", - "vim", - "yaml", - }, - }, - }, - - -- since `vim.tbl_deep_extend`, can only merge tables and not lists, the code above - -- would overwrite `ensure_installed` with the new value. - -- If you'd rather extend the default config, use the code below instead: - { - "nvim-treesitter/nvim-treesitter", - opts = function(_, opts) - -- add tsx and treesitter - vim.list_extend(opts.ensure_installed, { - "tsx", - "typescript", - }) - end, - }, - - -- the opts function can also be used to change the default opts: - { - "nvim-lualine/lualine.nvim", - event = "VeryLazy", - opts = function(_, opts) - table.insert(opts.sections.lualine_x, { - function() - return "😄" - end, - }) - end, - }, - - -- or you can return new options to override all the defaults - { - "nvim-lualine/lualine.nvim", - event = "VeryLazy", - opts = function() - return { - --[[add your custom lualine config here]] - } - end, - }, - - -- use mini.starter instead of alpha - { import = "lazyvim.plugins.extras.ui.mini-starter" }, - - -- add jsonls and schemastore packages, and setup treesitter for json, json5 and jsonc - { import = "lazyvim.plugins.extras.lang.json" }, - - -- add any tools you want to have installed below - { - "williamboman/mason.nvim", - opts = { - ensure_installed = { - "stylua", - "shellcheck", - "shfmt", - "flake8", - }, - }, - }, -} diff --git a/home/.config/nvim/stylua.toml b/home/.config/nvim/stylua.toml deleted file mode 100644 index 5d6c50d..0000000 --- a/home/.config/nvim/stylua.toml +++ /dev/null @@ -1,3 +0,0 @@ -indent_type = "Spaces" -indent_width = 2 -column_width = 120 \ No newline at end of file diff --git a/home/.config/sheldon/plugins.toml b/home/.config/sheldon/plugins.toml index 2db730e..fdbaabd 100644 --- a/home/.config/sheldon/plugins.toml +++ b/home/.config/sheldon/plugins.toml @@ -12,9 +12,6 @@ shell = "zsh" -[templates] -defer = "{{ hooks?.pre | nl }}{% for file in files %}zsh-defer source \"{{ file }}\"\n{% endfor %}{{ hooks?.post | nl }}" - [plugins] # [plugins.zsh-autosuggestions] @@ -27,6 +24,9 @@ github = "zdharma/fast-syntax-highlighting" [plugins.zsh-defer] github = "romkatv/zsh-defer" +[templates] +defer = "{{ hooks?.pre | nl }}{% for file in files %}zsh-defer source \"{{ file }}\"\n{% endfor %}{{ hooks?.post | nl }}" + # https://github.com/supercrabtree/k [plugins.k] github = "supercrabtree/k" @@ -38,11 +38,9 @@ github = "sindresorhus/pure" use = ["async.zsh", "pure.zsh"] # https://github.com/b4b4r07/enhancd -# Interactive shells only (see is_agent_shell in ~/.zshenv). [plugins.enhancd] github = "b4b4r07/enhancd" use = ["init.sh"] -profiles = ["interactive"] # https://github.com/zsh-users/zsh-syntax-highlighting [plugins.zsh-syntax-highlighting] diff --git a/home/.gitconfig b/home/.gitconfig index da5e39a..1193faf 100644 --- a/home/.gitconfig +++ b/home/.gitconfig @@ -1,60 +1,35 @@ [core] - excludesfile = ~/.gitignore - symlinks = true - editor = open -W -a 'Visual Studio Code' + excludesfile = ~/.gitignore + symlinks = true [init] - defaultBranch = main + defaultBranch = main [user] - name = Takumi Saito - email = dev@umeru.ma + name = Takumi Saito + email = dev@umeru.ma [filter "lfs"] - clean = git-lfs clean -- %f - smudge = git-lfs smudge -- %f - process = git-lfs filter-process - required = true + clean = git-lfs clean -- %f + smudge = git-lfs smudge -- %f + process = git-lfs filter-process + required = true [http] - version = HTTP/1.1 + version = HTTP/1.1 [difftool] - prompt = false + prompt = false [mergetool] - prompt = false + prompt = false [includeIf "gitdir:~/Codes/"] - path = ~/Codes/.gitconfig + path = ~/Codes/.gitconfig [includeIf "gitdir:~/Codes_DL/"] - path = ~/Codes_DL/.gitconfig + path = ~/Codes_DL/.gitconfig [pull] - rebase = false - + rebase = false [credential] - helper = osxkeychain + helper = osxkeychain # Git Worktree Manager Settings # https://github.com/k1LoW/git-wt?tab=readme-ov-file#configuration [wt] - basedir = .git/wt - copyuntracked = true - copyignored = false - copymodified = true - -[alias] -# # 過去1年間で最も変更されたファイルトップ20(高チャーン=潜在的リスク) -# stats-hotfiles = !git log --format=format: --name-only --since='1 year ago' | sort | uniq -c | sort -nr | head -20 - -# # コミット数でランク付けした貢献者(バスファクター分析) -# stats-contributors = !git shortlog -sn --no-merges - -# # 直近6ヶ月のアクティブな貢献者 -# stats-contributors-recent = !git shortlog -sn --no-merges --since='6 months ago' - -# # バグ修正コミットに最も頻繁に現れるファイルトップ20 -# stats-bugs = !git log -i --grep='fix' --grep='bug' --grep='broken' --name-only --format='' | sort | uniq -c | sort -nr | head -20 - -# # 月ごとにグループ化したコミット活動(プロジェクト速度) -# stats-activity = !git log --format='%ad' --date=format:'%Y-%m' | sort | uniq -c - -# # 過去1年間のリバート、ホットフィックス、緊急パッチ -# stats-hotfixes = !git log --graph --decorate --date=short --pretty=format:"%C(blue)%h%Creset %C(dim white)%ad%Creset %s %C(green)%an%Creset %C(cyan)%d%Creset" --since='1 year ago' --grep='revert' --grep='hotfix' --grep='emergency' --grep='rollback' -i - -# # 全てのコードベース診断を一度に実行 -# stats-all = !sh -c 'echo "=== Hotspot Files ===" && git stats-hotfiles && echo "" && echo "=== All Contributors ===" && git stats-contributors && echo "" && echo "=== Bug-related Files ===" && git stats-bugs && echo "" && echo "=== Commit Activity ===" && git stats-activity && echo "" && echo "=== Hotfixes and Reverts ===" && git stats-hotfixes' - + basedir = .worktrees + copyuntracked = true + copyignored = true + copymodified = true diff --git a/home/.hammerspoon/hide_menubar_for_meeting.lua b/home/.hammerspoon/hide_menubar_for_meeting.lua deleted file mode 100644 index 6ee6241..0000000 --- a/home/.hammerspoon/hide_menubar_for_meeting.lua +++ /dev/null @@ -1,31 +0,0 @@ -local M = {} - --- DeskPad 起動中はメニューバーを隠す(会議・画面共有向け) -local triggerAppBundleID = "com.stengo.DeskPad" - -local function setMenuBarAutohide(state) - hs.osascript.applescript(string.format([[ - tell application "System Events" to tell dock preferences - set autohide menu bar to %s - end tell - ]], tostring(state))) -end - -function M.init() - local watcher = hs.application.watcher.new(function(name, event, app) - if app:bundleID() == triggerAppBundleID then - if event == hs.application.watcher.launched then - setMenuBarAutohide(true) - elseif event == hs.application.watcher.terminated then - setMenuBarAutohide(false) - end - end - end) - watcher:start() - - if hs.application.get(triggerAppBundleID) then - setMenuBarAutohide(true) - end -end - -return M diff --git a/home/.hammerspoon/init.lua b/home/.hammerspoon/init.lua deleted file mode 100644 index e4e605b..0000000 --- a/home/.hammerspoon/init.lua +++ /dev/null @@ -1 +0,0 @@ -require("hide_menubar_for_meeting").init() diff --git a/home/.stow-local-ignore b/home/.stow-local-ignore new file mode 100644 index 0000000..a8babb9 --- /dev/null +++ b/home/.stow-local-ignore @@ -0,0 +1 @@ +^\.DS_Store$ diff --git a/home/.zprofile b/home/.zprofile index 1decedf..d7ccce0 100644 --- a/home/.zprofile +++ b/home/.zprofile @@ -15,7 +15,7 @@ typeset -U path # DOTFILES bin if [[ -d "$DOTFILES/bin" ]]; then - path=("$DOTFILES/bin" $path) + path=("$DOTFILES/bin" $path) fi # Add local bin @@ -23,25 +23,25 @@ path=("$HOME/.local/bin" $path) # Homebrew: put binaries on PATH and export common envs if [[ -d "/opt/homebrew" ]]; then - eval "$(/opt/homebrew/bin/brew shellenv)" - - # Add Homebrew completions to fpath (if needed) - # path=("/opt/homebrew/bin" "/opt/homebrew/sbin" $path) - # if command -v brew >/dev/null 2>&1; then - # fpath=($(brew --prefix)/share/zsh/site-functions $fpath) - # fi - - # Bundle file - export HOMEBREW_BUNDLE_FILE="$DOTFILES/macos/Brewfile" - - # Avoid installing certain formulae via Homebrew - # Link: https://docs.brew.sh/Manpage#:~:text=fishcompletion%2C%20zshcompletion%2C%20stageonly.-,HOMEBREW_FORBIDDEN_FORMULAE,-A%20space-separated%20list - export HOMEBREW_FORBIDDEN_FORMULAE="python python3 pip npm pnpm yarn claude" + eval "$(/opt/homebrew/bin/brew shellenv)" + + # Add Homebrew completions to fpath (if needed) + # path=("/opt/homebrew/bin" "/opt/homebrew/sbin" $path) + # if command -v brew >/dev/null 2>&1; then + # fpath=($(brew --prefix)/share/zsh/site-functions $fpath) + # fi + + # Bundle file + export HOMEBREW_BUNDLE_FILE="$DOTFILES/macos/Brewfile" + + # Avoid installing certain formulae via Homebrew + # Link: https://docs.brew.sh/Manpage#:~:text=fishcompletion%2C%20zshcompletion%2C%20stageonly.-,HOMEBREW_FORBIDDEN_FORMULAE,-A%20space-separated%20list + export HOMEBREW_FORBIDDEN_FORMULAE="node python python3 pip npm pnpm yarn claude" fi # Rustup in Homebrew prefix (if present) if [[ -d "/opt/homebrew/opt/rustup/bin" ]]; then - path=("/opt/homebrew/opt/rustup/bin" $path) + path=("/opt/homebrew/opt/rustup/bin" $path) fi # ------------------------- @@ -50,7 +50,7 @@ fi # pkgx interactive initialization (if installed) # if command -v pkgx >/dev/null 2>&1; then -# eval "$(pkgx --quiet dev --shellcode)" +# eval "$(pkgx --quiet dev --shellcode)" # fi # fpath=($HOME/.homesick/repos/homeshick/completions $fpath) diff --git a/home/.zshenv b/home/.zshenv index 8124526..865390f 100644 --- a/home/.zshenv +++ b/home/.zshenv @@ -15,13 +15,3 @@ export READNULLCMD="less" export DOTFILES="$HOME/Codes/dotfiles" export DOTFILES_HOME="$HOME/Codes/dotfiles/home" - -# AI agent subprocesses (Cursor, Claude Code, Codex, …) -# Used by .zshrc to skip interactive-only sheldon plugins (enhancd). -is_agent_shell() { - [[ -n "${CURSOR_AGENT:-}" ]] && return 0 - [[ -n "${CLAUDE_CODE_CHILD_SESSION:-}" ]] && return 0 - [[ "${AGENT:-}" == codex ]] && return 0 - [[ -n "${CODEX_CI:-}" ]] && return 0 - return 1 -} diff --git a/home/.zshrc b/home/.zshrc index 55f5baa..8a5d7d3 100644 --- a/home/.zshrc +++ b/home/.zshrc @@ -71,13 +71,8 @@ export ENHANCD_FILTER="fzy --prompt '❯ '" export ENHANCD_DOT_SHOW_FULLPATH=1 # sheldon (plugin manager) -# enhancd is profile-gated (interactive only); skip it in AI agent shells. +# Ensure SHELDON is installed; this eval is interactive-only if command -v sheldon >/dev/null 2>&1; then - if is_agent_shell; then - unset SHELDON_PROFILE - else - export SHELDON_PROFILE=interactive - fi eval "$(sheldon source)" fi @@ -98,34 +93,13 @@ wt() { git wt "$(printf '%s\n' "$line" | awk '{print $(NF-1)}')" } -wr() { - # git-wt で管理されているディレクトリを fzy で選択して削除 - local line - line="$(git wt | tail -n +2 | fzy)" || return - [[ -n "$line" ]] || return - local dir="$(printf '%s\n' "$line" | awk '{print $(NF-1)}')" - git wt -d "$dir" -} - # lazygit (git UI) export XDG_CONFIG_HOME="$HOME/.config" -alias lg="lazygit" - -# Cursor IDE (Editor Window; skip Agents/Glass on launch) -# Note: `cu` is taken by /usr/bin/cu (serial dial-up), so use `cur` instead. -alias cursor='cursor --classic' -alias cs='cursor --classic' # ------------------------- # Aliases & small functions # ------------------------- - -# github cli aliases -# https://cli.github.com/manual/gh_repo_gitignore_view -gi() { gh repo gitignore "$@"; } - -# https://cli.github.com/manual/gh_repo_license_view -gli() { gh repo license "$@"; } +gi() { curl -L -s "https://www.gitignore.io/api/$@" ;} alias ls="ls -G" alias ll="ls -lG" @@ -148,6 +122,7 @@ dottrack() { fi local target="$HOME/$1" + local dest="$DOTFILES_HOME/home/$1" # ホームディレクトリに存在するか確認 if [[ ! -e "$target" ]]; then @@ -155,11 +130,14 @@ dottrack() { return 1 fi - # [dotfiles] にエントリ追加 + 実体を home/ へコピー - mise -C "$DOTFILES_HOME" dotfiles add --path "$DOTFILES_HOME/mise.dotfiles.toml" --yes --source "home/$1" "$target" + # 親ディレクトリを作成 + mkdir -p "$(dirname "$dest")" + + # ファイル/ディレクトリを移動 + mv "$target" "$dest" - # 元ファイルを symlink に置換(内容同一なので --force 不要) - mise -C "$DOTFILES_HOME" dotfiles apply --yes + # stow でシンボリックリンクを作成 + stow -d "$DOTFILES_HOME" -t "$HOME" home - echo "✓ Tracked: $1 (entry added to mise.toml [dotfiles])" + echo "✓ Tracked: $1" } diff --git a/init/init-linux.sh b/init/init-linux.sh new file mode 100644 index 0000000..16cff5b --- /dev/null +++ b/init/init-linux.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +sudo apt-get update + +if ! type make >/dev/null 2>&1; then + sudo apt-get install build-essential +fi +if ! type zsh >/dev/null 2>&1; then + sudo apt-get install zsh +fi \ No newline at end of file diff --git a/install b/install index 56445ab..1b2d39e 100644 --- a/install +++ b/install @@ -13,38 +13,17 @@ is_exist() { type "$1" > /dev/null 2>&1 } -ensure_mise_on_path() { - # mise.run installs to ~/.local/bin by default - if [ -d "${HOME}/.local/bin" ]; then - export PATH="${HOME}/.local/bin:${PATH}" - fi - # Homebrew mise (if present) - if [ -x /opt/homebrew/bin/mise ]; then - export PATH="/opt/homebrew/bin:${PATH}" - elif [ -x /usr/local/bin/mise ]; then - export PATH="/usr/local/bin:${PATH}" - fi -} - install() { # Create ~/Codes directory if it doesn't exist mkdir -p "${HOME}/Codes" - # Clone the dotfiles repo if it doesn't exist; otherwise pull latest + # Clone the dotfiles repo if it doesn't exist if [ -d "${DOT_DIRECTORY}" ]; then echo "DOTFILES have already been installed at ${DOT_DIRECTORY}" - if is_exist "git"; then - echo "Pulling latest changes..." - cd "${DOT_DIRECTORY}" - git pull origin main - else - echo "git required" - exit 1 - fi else if is_exist "git"; then echo "Cloning dotfiles to ${DOT_DIRECTORY}..." - git clone --filter=blob:none --depth 1 "${REMOTE_URL}" "${DOT_DIRECTORY}" + git clone --filter=blob:none --depth 1 --recurse-submodules --shallow-submodules "${REMOTE_URL}" "${DOT_DIRECTORY}" else echo "git required" exit 1 @@ -56,14 +35,33 @@ install() { echo "" cd "${DOT_DIRECTORY}" + + if [ "$uname_s" = "Linux" ]; then + bash ./init/init-linux.sh + fi - # macOS: Command Line Tools (interactive; not covered by mise bootstrap) if [ "$uname_s" = "Darwin" ]; then bash ./init/init-macos.sh fi - # Homebrew is still used by `mise run install-apps` (Brewfile) and shellenv in .zprofile. - # CLI/GUI packages can gradually move to [bootstrap.packages] (brew: / brew-cask: / mas:). + # Check if just is installed; if not, download and install to ./bin/just + echo "" + if is_exist ./bin/just; then + echo "just is installed" + ./bin/just --version || { echo "just command not working"; exit 1; } + else + # create ./bin + mkdir -p ./bin + + # download and extract just to ./bin/just + curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to ./bin + + # just should now be executable + ./bin/just --version || { echo "just install failed"; exit 1; } + echo "just install succeeded" + fi + + # Check if Homebrew is installed; if not, install it echo "" if type brew >/dev/null 2>&1; then echo "brew is installed"; @@ -77,30 +75,27 @@ install() { # Check if mise is installed; if not, install it echo "" - ensure_mise_on_path if type mise >/dev/null 2>&1; then - echo "mise is installed ($(mise --version))"; + echo "mise is installed"; else echo "Installing mise..." curl -sL https://mise.run | sh - ensure_mise_on_path fi - if ! type mise >/dev/null 2>&1; then - echo "error: mise not found on PATH after install" - echo "hint: add ~/.local/bin to PATH and re-run" - exit 1 - fi + # Run just deploy to create symlinks and install packages + ./bin/just deploy - # Trust this repo's mise.toml, then converge packages / login shell / deploy. - # See https://mise.jdx.dev/bootstrap.html + # Change default shell to /bin/zsh if not already echo "" - echo "Running mise bootstrap..." - mise trust --yes - mise bootstrap --yes --update + if [ "$SHELL" = "/bin/zsh" ]; then + echo "Using /bin/zsh" + else + echo "Change default shell to /bin/zsh" + chsh -s /bin/zsh + fi echo "" - echo "If you want to install apps, run: mise run install-apps" + echo "If you want to install apps, run: just install-apps" } install diff --git a/install-win b/install-win deleted file mode 100644 index fa55541..0000000 --- a/install-win +++ /dev/null @@ -1,261 +0,0 @@ -#Requires -Version 5.1 -<# -.SYNOPSIS - Bootstrap dotfiles on Windows (PowerShell 7, mise, PSDotFiles, home-win deploy). - -.DESCRIPTION - Clone to ~/Codes/dotfiles, apply win/bootstrap.winget, install PSDotFiles, - then run mise run deploy. Install GUI apps separately with: mise run install-apps - - Review this script before running: - irm https://dot.umeru.ma/install-win | iex -#> -$ErrorActionPreference = 'Stop' - -$DotDirectory = Join-Path $HOME 'Codes/dotfiles' -$RemoteUrl = 'https://github.com/umeruma/dotfiles.git' -$script:Relaunched = $false - -function Test-CommandExists { - param([string]$Name) - return $null -ne (Get-Command $Name -ErrorAction SilentlyContinue) -} - -function Assert-WingetAvailable { - if (Test-CommandExists winget) { - return - } - - Write-Host '' - Write-Host 'winget (App Installer) was not found.' -ForegroundColor Yellow - Write-Host 'winget is the prerequisite for this setup: Git, PowerShell 7 and mise' -ForegroundColor Yellow - Write-Host 'are installed automatically through winget once it is available.' -ForegroundColor Yellow - Write-Host '' - Write-Host 'Install "App Installer" from the Microsoft Store, then re-run this script.' - Write-Host 'Opening the Microsoft Store page...' - - try { - Start-Process 'ms-windows-store://pdp/?ProductId=9NBLGGH4NNS1' | Out-Null - } catch { - Write-Host 'Could not open the Store automatically. Search for "App Installer" in the Microsoft Store.' - } - - throw 'winget is required. Install App Installer from the Microsoft Store, then re-run: irm https://dot.umeru.ma/install-win | iex' -} - -function Resolve-PwshPath { - $command = Get-Command pwsh -ErrorAction SilentlyContinue | Select-Object -First 1 - if ($command) { - return $command.Source - } - - $programFilesRoot = if ($env:ProgramW6432) { $env:ProgramW6432 } else { $env:ProgramFiles } - $fallbackPath = Join-Path $programFilesRoot 'PowerShell\7\pwsh.exe' - if (Test-Path $fallbackPath) { - return $fallbackPath - } - - return $null -} - -function Invoke-ScriptInPwsh { - param([Parameter(Mandatory)][string]$PwshPath) - - $escapedDotDirectory = $DotDirectory.Replace("'", "''") - $escapedRemoteUrl = $RemoteUrl.Replace("'", "''") - $scriptText = @( - '$ErrorActionPreference = ''Stop''' - ('$DotDirectory = ''' + $escapedDotDirectory + '''') - ('$RemoteUrl = ''' + $escapedRemoteUrl + '''') - '$script:Relaunched = $false' - "function Test-CommandExists {`n$(${function:Test-CommandExists}.ToString())`n}" - "function Assert-WingetAvailable {`n$(${function:Assert-WingetAvailable}.ToString())`n}" - "function Resolve-PwshPath {`n$(${function:Resolve-PwshPath}.ToString())`n}" - "function Invoke-ScriptInPwsh {`n$(${function:Invoke-ScriptInPwsh}.ToString())`n}" - "function Ensure-PowerShell7 {`n$(${function:Ensure-PowerShell7}.ToString())`n}" - "function Ensure-Repository {`n$(${function:Ensure-Repository}.ToString())`n}" - "function Invoke-BootstrapWinget {`n$(${function:Invoke-BootstrapWinget}.ToString())`n}" - "function Ensure-PSDotFiles {`n$(${function:Ensure-PSDotFiles}.ToString())`n}" - "function Write-DeveloperModeWarningIfNeeded {`n$(${function:Write-DeveloperModeWarningIfNeeded}.ToString())`n}" - "function Invoke-Deploy {`n$(${function:Invoke-Deploy}.ToString())`n}" - "function Invoke-Main {`n$(${function:Invoke-Main}.ToString())`n}" - 'Invoke-Main' - ) -join "`n`n" - - $encoded = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($scriptText)) - & $PwshPath -NoProfile -EncodedCommand $encoded - if ($LASTEXITCODE -ne 0) { - throw "dotfiles bootstrap (PowerShell 7) failed with exit code $LASTEXITCODE" - } -} - -function Ensure-PowerShell7 { - if ($PSVersionTable.PSVersion.Major -ge 7) { - return - } - - $pwshPath = Resolve-PwshPath - if (-not $pwshPath) { - if (-not (Test-CommandExists winget)) { - throw 'PowerShell 7 is required. Install winget and Microsoft.PowerShell, then re-run this script.' - } - - Write-Host 'Installing PowerShell 7...' - & winget install --id Microsoft.PowerShell --exact --accept-package-agreements --accept-source-agreements --disable-interactivity - if ($LASTEXITCODE -ne 0) { - throw "winget install Microsoft.PowerShell failed (exit $LASTEXITCODE)" - } - - $pwshPath = Resolve-PwshPath - } - - if (-not $pwshPath) { - throw 'PowerShell 7 was installed but pwsh was not found on PATH or in the default install location.' - } - - Write-Host 'Re-launching with pwsh...' - Invoke-ScriptInPwsh -PwshPath $pwshPath - $script:Relaunched = $true -} - -function Ensure-Repository { - $parent = Split-Path -Parent $DotDirectory - if (-not (Test-Path $parent)) { - New-Item -ItemType Directory -Force -Path $parent | Out-Null - } - - if (Test-Path $DotDirectory) { - Write-Host "DOTFILES already installed at $DotDirectory" - if (-not (Test-CommandExists git)) { - throw 'git is required to update dotfiles' - } - Set-Location $DotDirectory - Write-Host 'Pulling latest changes...' - & git pull origin main - if ($LASTEXITCODE -ne 0) { - throw 'git pull failed' - } - return - } - - if (-not (Test-CommandExists git)) { - if (Test-CommandExists winget) { - Write-Host 'Installing Git for Windows...' - & winget install --id Git.Git --exact --accept-package-agreements --accept-source-agreements --disable-interactivity - if ($LASTEXITCODE -ne 0) { - throw "winget install Git.Git failed (exit $LASTEXITCODE)" - } - $env:Path = [System.Environment]::GetEnvironmentVariable('Path', 'Machine') + ';' + [System.Environment]::GetEnvironmentVariable('Path', 'User') - } else { - throw 'git is required to clone dotfiles' - } - } - - Write-Host "Cloning dotfiles to $DotDirectory..." - & git clone --filter=blob:none --depth 1 $RemoteUrl $DotDirectory - if ($LASTEXITCODE -ne 0) { - throw 'git clone failed' - } -} - -function Invoke-BootstrapWinget { - param([string]$RepoRoot) - - $config = Join-Path $RepoRoot 'win/bootstrap.winget' - if (-not (Test-Path $config)) { - throw "Bootstrap configuration not found: $config" - } - - if (-not (Test-CommandExists winget)) { - throw 'winget is required. Install App Installer from the Microsoft Store.' - } - - Write-Host "Applying bootstrap packages ($config)..." - & winget configure -f $config --accept-configuration-agreements --disable-interactivity - if ($LASTEXITCODE -ne 0) { - throw "winget configure failed (exit $LASTEXITCODE)" - } - - $machinePath = [System.Environment]::GetEnvironmentVariable('Path', 'Machine') - $userPath = [System.Environment]::GetEnvironmentVariable('Path', 'User') - $env:Path = "$machinePath;$userPath" -} - -function Ensure-PSDotFiles { - if (Get-Module -ListAvailable -Name PSDotFiles) { - Write-Host 'PSDotFiles is installed' - return - } - - Write-Host 'Installing PSDotFiles from PowerShell Gallery...' - Set-PSRepository -Name PSGallery -InstallationPolicy Trusted -ErrorAction SilentlyContinue - Install-Module -Name PSDotFiles -Scope CurrentUser -Force -AllowClobber -} - -function Write-DeveloperModeWarningIfNeeded { - try { - $key = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock' -Name 'AllowDevelopmentWithoutDevLicense' -ErrorAction Stop - if ($key.AllowDevelopmentWithoutDevLicense -eq 1) { - return - } - } catch { - # ignore - } - - Write-Warning @" -Developer Mode may not be enabled. Enable it for symlink creation: - Settings -> System -> For developers -> Developer Mode -"@ -} - -function Invoke-Deploy { - param([string]$RepoRoot) - - Set-Location $RepoRoot - $env:DOTFILES = $RepoRoot - - if (-not (Test-CommandExists mise)) { - throw 'mise not found on PATH after bootstrap. Open a new terminal or log out/in, then run: mise run deploy' - } - - Write-Host 'Running mise run deploy...' - & mise run deploy - if ($LASTEXITCODE -ne 0) { - throw "mise run deploy failed (exit $LASTEXITCODE)" - } -} - -function Invoke-Main { - Assert-WingetAvailable - Ensure-PowerShell7 - if ($script:Relaunched) { - return - } - - Write-Host '' - Write-Host 'Start to setup DOTFILES (Windows)' - Write-Host '' - - Ensure-Repository - Set-Location $DotDirectory - - Invoke-BootstrapWinget -RepoRoot $DotDirectory - Ensure-PSDotFiles - Write-DeveloperModeWarningIfNeeded - Invoke-Deploy -RepoRoot $DotDirectory - - Write-Host '' - Write-Host '============================================================' -ForegroundColor Green - Write-Host ' DOTFILES setup complete!' -ForegroundColor Green - Write-Host '============================================================' -ForegroundColor Green - Write-Host '' - Write-Host ' NEXT STEP - install your GUI apps:' -ForegroundColor Cyan - Write-Host '' - Write-Host ' cd $env:DOTFILES; mise run install-apps' -ForegroundColor White - Write-Host '' - Write-Host ' (Open a new PowerShell 7 window and run "mise doctor" to verify.)' - Write-Host '============================================================' -ForegroundColor Green - Write-Host '' -} - -Invoke-Main diff --git a/justfile b/justfile new file mode 100644 index 0000000..f075e1c --- /dev/null +++ b/justfile @@ -0,0 +1,95 @@ +# dotfiles justfile +# Expected installation path: ~/Codes/dotfiles + +# Variables +dotpath := justfile_directory() +uname_s := `uname -s` +expected_path := env_var("HOME") + "/Codes/dotfiles" + +# Default recipe +[private] +default: help + +# Self-documented help +help: + @just --list --unsorted + +# Fetch changes for this repo +update: + git pull origin main + git submodule init + git submodule update + git submodule foreach git pull origin main + +# Verify installation path +# check-path: +# @echo "Current path: {{dotpath}}" +# @echo "Expected path: {{expected_path}}" +# #!/usr/bin/env bash +# if [ "{{dotpath}}" != "{{expected_path}}" ]; then \ +# echo "⚠️ Warning: Not running from expected path"; \ +# echo " Current: {{dotpath}}"; \ +# echo " Expected: {{expected_path}}"; \ +# echo " Consider moving this repository to ~/Codes/dotfiles"; \ +# else \ +# echo "✅ Running from correct path"; \ +# fi + +# Show dot files to deploy in this repo +list: + @find home -name ".*" -not -name ".DS_Store" -type f | sort + +# Remove the dot files which deployed +clean: + @echo 'Clean dot files in your home directory...' + stow -D -v -d {{dotpath}} -t ~ home + +# Ensure subdirectories exist before deploying (reads from .deploy_subdir) +[private] +prepare-subdirs: + #!/usr/bin/env bash + set -euo pipefail + echo '==> Ensure required subdirectories exist (from .deploy_subdir)' + if [[ -f .deploy_subdir ]]; then + while IFS= read -r path; do + # Skip blank lines and comments (leading/trailing whitespace allowed) + [[ "$path" =~ ^[[:space:]]*$ ]] && continue + [[ "$path" =~ ^[[:space:]]*# ]] && continue + # Trim leading/trailing whitespace + path="${path#"${path%%[![:space:]]*}"}" + path="${path%"${path##*[![:space:]]}"}" + mkdir -p "$HOME/$path" + echo " mkdir -p $HOME/$path" + done < .deploy_subdir + else + echo ' (skip) .deploy_subdir not found' + fi + +# Create symlink to home directory +deploy: clean prepare-subdirs + @echo '==> Start to deploy dotfiles to home directory.' + stow -v -d {{dotpath}} -t ~ home + +# Install apps +install-apps: + #!/usr/bin/env bash + if [ "{{uname_s}}" = "Linux" ]; then \ + brew bundle --file=./linux/Brewfile; \ + sudo apt-get install hugo; \ + elif [ "{{uname_s}}" = "Darwin" ]; then \ + brew bundle --file=./macos/Brewfile; \ + fi + +# Update macOS's defaults setting +defaults: + #!/usr/bin/env bash + if [ "{{uname_s}}" = "Darwin" ]; then \ + bash ./macos/defaults.sh; \ + fi + +# Install Terminal theme +theme: + #!/usr/bin/env bash + if [ "{{uname_s}}" = "Darwin" ]; then \ + open ./macos/BirdsOfParadise.terminal; \ + fi diff --git a/macos/Brewfile b/macos/Brewfile index 86aafab..ad2baf3 100644 --- a/macos/Brewfile +++ b/macos/Brewfile @@ -1,13 +1,4 @@ # brew "eza" - -# Editor / agent stack — see docs/editor-stack -brew "neovim" # LazyVim (config in home/.config/nvim) -brew "herdr" # agent multiplexer (https://herdr.dev) -brew "ripgrep" # required (LazyVim grep, project search) -brew "fd" # required (LazyVim file picker) -brew "tree-sitter-cli" # required (nvim-treesitter parser builds) - -brew "crit" # inline code review for AI agent workflows (https://crit.md) brew "diffr" brew "ffmpeg" brew "fzy" @@ -16,6 +7,7 @@ brew "gifsicle" brew "git" brew "git-lfs" brew "git-sizer" +brew "handbrake" brew "imagemagick" brew "jq" brew "k1LoW/tap/git-wt" @@ -23,55 +15,46 @@ brew "lazygit" brew "lftp" brew "mas" brew "micro" -brew "mole" # CLI companion to mole-app (mo clean, mo purge, …) brew "mkcert" brew "rust" brew "sheldon" brew "shellcheck" +brew "stow" brew "websocat" brew "pkgx" -brew "rclone" cask "1password" cask "1password-cli" cask "alt-tab" -# Menu bar icon organiser -cask "bartender" cask "cleanmymac" -cask "claude" -cask "claude-code" cask "clop" -cask "cursor" -cask "cursor-cli" cask "deskpad" cask "discord" cask "figma" cask "ghostty" cask "gyazo" -cask "hammerspoon" -cask "handbrake-app" cask "karabiner-elements" cask "loopback" -# Native Mac app — cleanup, app management, disk analysis (https://mole.fit) -cask "mole-app" -# Free and open-source RSS reader -cask "netnewswire" cask "ngrok" cask "notion" +cask "orbstack" cask "raycast" +cask "soundsource" cask "transmit" cask "visual-studio-code" cask "elgato-wave-link" -# Assign keys, and then decorate and label them cask "elgato-stream-deck" cask "xcodes-app" mas "Apple Configurator", id: 1037126344 mas "CotEditor", id: 1024640650 mas "Craft", id: 1487937127 mas "Day One", id: 1055511498 +mas "Developer", id: 640199958 mas "Dropover", id: 1355679052 +mas "Hidden Bar", id: 1452453066 mas "iPreview", id: 1519213509 mas "Keka", id: 470158793 mas "MeetingBar", id: 1532419400 mas "OpenIn", id: 1643649331 +mas "Reeder", id: 1529448980 mas "Slack", id: 803453959 mas "WorldWideWeb", id: 1621370168 diff --git a/macos/defaults.sh b/macos/defaults.sh new file mode 100644 index 0000000..5a3e101 --- /dev/null +++ b/macos/defaults.sh @@ -0,0 +1,215 @@ +#!/bin/bash +# update defaults for macos 11.1 + +# thanks https://wilsonmar.github.io/dotfiles/ + +echo "Start update defaults setting..." + +# Close any open System Preferences panes, to prevent them from overriding +# settings we’re about to change +osascript -e 'tell application "System Preferences" to quit' + +# Ask for the administrator password upfront +sudo -v + +# Keep-alive: update existing `sudo` time stamp until `defaults.sh` has finished +while true; do sudo -n true; sleep 60; kill -0 "$$" || exit; done 2>/dev/null & + +######################################## +# SECTION: General # +######################################## + +# Set accent color to Green +defaults write -g AppleAccentColor -int 3 +defaults write -g AppleHighlightColor -string "0.752941 0.964706 0.678431 Green" + +# Set sidebar icon size to Large +defaults write -g NSTableViewDefaultSizeMode -int 3 + +# Desable tinting +defaults write -g AppleReduceDesktopTinting -int 1 + +# Always show scrollbars +defaults write -g AppleShowScrollBars -string "WhenScrolling" + +######################################## +# SECTION: Docs & Menu Bar # +######################################## + +defaults write com.apple.dock autohide -bool true +defaults write com.apple.dock autohide-delay -float 0 +defaults write com.apple.dock autohide-time-modifier -float 0 +defaults write com.apple.dock tilesize -float 75 +defaults write com.apple.dock show-recents -bool false + +# Remove all show-in-dock apps +defaults write com.apple.dock persistent-apps -array +# Remove all show-in-dock folders +defaults write com.apple.dock persistent-others -array + +# Add default apps & folders +# see https://stackoverflow.com/a/59637792 +__dock_app() { + printf '%s%s%s%s%s' \ + '<dict><key>tile-data</key><dict><key>file-data</key><dict>' \ + '<key>_CFURLString</key><string>' \ + "$1" \ + '</string><key>_CFURLStringType</key><integer>0</integer>' \ + '</dict></dict></dict>' +} +defaults write com.apple.dock \ + persistent-apps -array "$(__dock_app /System/Applications/System\ Preferences.app)" \ + "$(__dock_app /System/Applications/Launchpad.app)" \ + "$(__dock_app /System/Applications/Mission\ Control.app)" + +__dock_other() { + printf '%s%s%s%s%s%s' \ + '<dict><key>tile-data</key><dict><key>showas</key><integer>1</integer>' \ + '<key>arrangement</key><integer>2</integer><key>displayas</key><integer>1</integer>' \ + '<key>file-data</key><dict><key>_CFURLString</key><string>' \ + "$1" \ + '</string><key>_CFURLStringType</key><integer>0</integer>' \ + '</dict></dict><key>tile-type</key><string>directory-tile</string></dict>' +} +defaults write com.apple.dock \ + persistent-others -array "$(__dock_other ~/Desktop/)" \ + "$(__dock_other ~/Downloads/)" + +killall Dock + +######################################## +# SECTION: Mission Control # +######################################## + +# Don’t automatically rearrange Spaces based on most recent use +defaults write com.apple.dock mru-spaces -bool false + +######################################## +# SECTION: Spotlight # +######################################## + +# No changes now + +######################################## +# SECTION: Languages & Reagion # +######################################## + +defaults write -g AppleLanguages -array "en-JP" "ja-JP" +defaults write -g AppleLocale -string "en_JP" +defaults write -g AppleMeasurementUnits -string "Centimeters" +defaults write -g AppleMetricUnits -bool true +defaults write -g AppleTemperatureUnit -string "Celsius" + +# Set First day of week to Monday +defaults write -g AppleFirstWeekday -dict gregorian 2 +# Set Time fromat to 24-Hour Time +defaults write -g AppleICUForce24HourTime -bool true + +killall SystemUIServer + +######################################## +# SECTION: Software Update # +######################################## + +# Disable auto system update +defaults write com.apple.SoftwareUpdate AutomaticallyInstallMacOSUpdates -bool false +defaults write com.apple.SoftwareUpdate AutomaticCheckEnabled -bool false +defaults write com.apple.SoftwareUpdate AutomaticDownload -bool false +defaults write com.apple.SoftwareUpdate CriticalUpdateInstall -bool false +defaults write com.apple.SoftwareUpdate ConfigDataInstall -bool false + +# Desable app store auto update +defaults write com.apple.commerce AutoUpdate -bool false + +######################################## +# SECTION: Sound # +######################################## + +defaults write com.apple.systemuiserver "NSStatusItem Visible Siri" -bool false +defaults write com.apple.systemuiserver "NSStatusItem Visible com.apple.menuextra.volume" -bool true +defaults write -g com.apple.sound.beep.flash -int 0 +defaults write -g com.apple.sound.beep.sound -string "/System/Library/Sounds/Bottle.aiff" + +######################################## +# SECTION: Kyeboad # +######################################## + +defaults write -g InitialKeyRepeat -int 15 +defaults write -g KeyRepeat -int 2 + +# Disable Shortcuts > +# Spotlight > Show Spotlight search +defaults write com.apple.symbolichotkeys AppleSymbolicHotKeys -dict-add 64 "<dict><key>enabled</key><false/></dict>" +# Screenshots > Copy picture of screen to clipboard +defaults write com.apple.symbolichotkeys AppleSymbolicHotKeys -dict-add 29 "<dict><key>enabled</key><false/></dict>" +# Screenshots > Copy picture of selected area to clipboard +defaults write com.apple.symbolichotkeys AppleSymbolicHotKeys -dict-add 31 "<dict><key>enabled</key><false/></dict>" + +######################################## +# SECTION: Trackpad # +######################################## + +defaults write -g com.apple.trackpad.forceClick -bool false +defaults write -g com.apple.trackpad.scaling -float 2 + +######################################## +# SECTION: Mouse # +######################################## + +defaults write -g com.apple.mouse.doubleClickThreshold -float 0.5 +defaults write -g com.apple.mouse.scaling -float 3 + +######################################## +# SECTION: Finder # +######################################## + +# Enable spring-loading and set delay +defaults write -g com.apple.springing.enabled -bool true +defaults write -g com.apple.springing.delay -float 0.1 + +defaults write -g AppleShowAllExtensions -bool true + +# Use list view in all Finder windows by default +# Four-letter codes for the other view modes: `icnv`, `clmv`, `Flwv` +defaults write com.apple.finder FXPreferredViewStyle -string "Nlsv" + +defaults write com.apple.finder ShowStatusBar -bool true +defaults write com.apple.finder ShowPathbar -bool true + +defaults write com.apple.finder NewWindowTarget -string "PfHm" +defaults write com.apple.finder NewWindowTargetPath -string "file://${HOME}/" + +# At Desktop +# Show item info near icons on the desktop and in other icon views +/usr/libexec/PlistBuddy -c "Set :DesktopViewSettings:IconViewSettings:showItemInfo true" ~/Library/Preferences/com.apple.finder.plist +# Show item info to the right of the icons on the desktop +/usr/libexec/PlistBuddy -c "Set DesktopViewSettings:IconViewSettings:labelOnBottom false" ~/Library/Preferences/com.apple.finder.plist +# Increase grid spacing for icons on the desktop and in other icon views +/usr/libexec/PlistBuddy -c "Set :DesktopViewSettings:IconViewSettings:gridSpacing 100" ~/Library/Preferences/com.apple.finder.plist +# Increase the size of icons on the desktop and in other icon views +/usr/libexec/PlistBuddy -c "Set :DesktopViewSettings:IconViewSettings:iconSize 40" ~/Library/Preferences/com.apple.finder.plist + +/usr/libexec/PlistBuddy -c "Set :DesktopViewSettings:IconViewSettings:textSize 12" ~/Library/Preferences/com.apple.finder.plist + +/usr/libexec/PlistBuddy -c "Set :DesktopViewSettings:IconViewSettings:arrangeBy name" ~/Library/Preferences/com.apple.finder.plist + +# Expand save panel by default +defaults write -g NSNavPanelExpandedStateForSaveMode -bool true + +# Expand print panel by default +defaults write -g PMPrintingExpandedStateForPrint -bool true + +# Expand the following File Info panes: +# “General”, “Open with”, and “Sharing & Permissions” +defaults write com.apple.finder FXInfoPanesExpanded -dict \ + General -bool true \ + OpenWith -bool true \ + Privileges -bool true + +# If you want to change default finder window size, +# click close button with holding command key after resize window. +# https://apple.stackexchange.com/a/192959 + +killall Finder + +echo "Done. Note that some of these changes require a logout/restart to take effect." diff --git a/metadata/home-win.xml b/metadata/home-win.xml deleted file mode 100644 index e004c22..0000000 --- a/metadata/home-win.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Component xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Metadata.xsd"> - <FriendlyName>Windows home dotfiles</FriendlyName> - <Detection> - <Method>Static</Method> - <Availability>AlwaysInstall</Availability> - </Detection> -</Component> diff --git a/mise.dotfiles.toml b/mise.dotfiles.toml deleted file mode 100644 index 6fa4889..0000000 --- a/mise.dotfiles.toml +++ /dev/null @@ -1,36 +0,0 @@ -# Cross-platform [dotfiles] allowlist, loaded via `env = ["dotfiles"]` -# in .miserc.toml (merged with mise.toml). macOS-only entries live in -# mise.macos.toml. Applied by `mise dotfiles apply` / `mise bootstrap`. -# Dirs that receive runtime writes (logs, state) get per-file entries -# so app state stays out of the repo. - -[dotfiles] -# shell / git -"~/.zshenv" = { source = "home/.zshenv", mode = "symlink" } -"~/.zprofile" = { source = "home/.zprofile", mode = "symlink" } -"~/.zshrc" = { source = "home/.zshrc", mode = "symlink" } -"~/.gitconfig" = { source = "home/.gitconfig", mode = "symlink" } -# static config dirs (whole-dir links; new repo files show up automatically) -"~/.config/ghostty" = { source = "home/.config/ghostty", mode = "symlink" } -"~/.config/sheldon" = { source = "home/.config/sheldon", mode = "symlink" } -# ~/.config/nvim is linked whole-dir on purpose: LazyVim writes lazy-lock.json -# back through the link into the repo, so plugin versions stay tracked by git. -# Plugin payloads live in ~/.local/share/nvim, session state in ~/.local/state/nvim. -"~/.config/nvim" = { source = "home/.config/nvim", mode = "symlink" } -# runtime-write dirs: per-file links only -"~/.config/herdr/config.toml" = { source = "home/.config/herdr/config.toml", mode = "symlink" } -"~/.config/lazygit/config.yml" = { source = "home/.config/lazygit/config.yml", mode = "symlink" } -"~/.config/micro/bindings.json" = { source = "home/.config/micro/bindings.json", mode = "symlink" } -"~/.config/micro/plug/editorconfig" = { source = "home/.config/micro/plug/editorconfig", mode = "symlink" } -# AI agents — single source of truth: home/.agents. -# ~/.agents is linked whole-dir on purpose: Cursor and Copilot read -# ~/.agents/skills natively, and skill installers (npx skills) write -# installed skills + .skill-lock.json through the link into the repo, -# so installs are tracked by git. Claude Code only reads -# ~/.claude/skills, so repo-authored skills get per-skill entries there. -"~/.agents" = { source = "home/.agents", mode = "symlink" } -"~/.claude/CLAUDE.md" = { source = "home/.claude/CLAUDE.md", mode = "symlink" } -"~/.copilot/instructions/global.instructions.md" = { source = "home/.agents/instructions/global.instructions.md", mode = "symlink" } -"~/.claude/skills/commit" = { source = "home/.agents/skills/commit", mode = "symlink" } -"~/.claude/skills/dev-server" = { source = "home/.agents/skills/dev-server", mode = "symlink" } -"~/.claude/skills/git-wt" = { source = "home/.agents/skills/git-wt", mode = "symlink" } diff --git a/mise.linux.toml b/mise.linux.toml deleted file mode 100644 index 9817388..0000000 --- a/mise.linux.toml +++ /dev/null @@ -1,6 +0,0 @@ -# Loaded on Linux only (merged with mise.toml). -# Replaces init/init-linux.sh. - -[bootstrap.packages] -"apt:build-essential" = "latest" -"apt:zsh" = "latest" diff --git a/mise.macos.toml b/mise.macos.toml deleted file mode 100644 index 0506c59..0000000 --- a/mise.macos.toml +++ /dev/null @@ -1,75 +0,0 @@ -# Loaded on macOS only (merged with mise.toml). - -[bootstrap.macos.dock] -autohide = true -tilesize = 75 -show_recents = false -mru_spaces = false - -[bootstrap.macos.finder] -show_pathbar = true -show_status_bar = true -preferred_view_style = "list" - -[bootstrap.macos.keyboard] -key_repeat = 2 -initial_key_repeat = 15 - -[bootstrap.macos.defaults."com.apple.dock"] -"autohide-delay" = 0 -"autohide-time-modifier" = 0 - -[bootstrap.macos.defaults."NSGlobalDomain"] -AppleAccentColor = 3 -AppleHighlightColor = "0.752941 0.964706 0.678431 Green" -NSTableViewDefaultSizeMode = 3 -AppleReduceDesktopTinting = 1 -AppleShowScrollBars = "WhenScrolling" -AppleLocale = "en_JP" -AppleMeasurementUnits = "Centimeters" -AppleMetricUnits = true -AppleTemperatureUnit = "Celsius" -AppleICUForce24HourTime = true -"com.apple.springing.enabled" = true -"com.apple.springing.delay" = 0.1 -AppleShowAllExtensions = true -NSNavPanelExpandedStateForSaveMode = true -PMPrintingExpandedStateForPrint = true -"com.apple.trackpad.forceClick" = false -"com.apple.trackpad.scaling" = 2.0 -"com.apple.mouse.doubleClickThreshold" = 0.5 -"com.apple.mouse.scaling" = 3.0 -"com.apple.sound.beep.flash" = 0 -"com.apple.sound.beep.sound" = "/System/Library/Sounds/Bottle.aiff" - -[bootstrap.macos.defaults."com.apple.SoftwareUpdate"] -AutomaticallyInstallMacOSUpdates = false -AutomaticCheckEnabled = false -AutomaticDownload = false -CriticalUpdateInstall = false -ConfigDataInstall = false - -[bootstrap.macos.defaults."com.apple.commerce"] -AutoUpdate = false - -[bootstrap.macos.defaults."com.apple.systemuiserver"] -"NSStatusItem Visible Siri" = false -"NSStatusItem Visible com.apple.menuextra.volume" = true - -[bootstrap.macos.defaults."com.apple.finder"] -NewWindowTarget = "PfHm" - -# macOS-only dotfiles. Hammerspoon is per-file so runtime Spoons/ stays -# local; karabiner.json is per-file so automatic_backups/ stays local. -[dotfiles] -"~/.hammerspoon/init.lua" = { source = "home/.hammerspoon/init.lua", mode = "symlink" } -"~/.hammerspoon/hide_menubar_for_meeting.lua" = { source = "home/.hammerspoon/hide_menubar_for_meeting.lua", mode = "symlink" } -"~/.config/karabiner/karabiner.json" = { source = "home/.config/karabiner/karabiner.json", mode = "symlink" } -"~/.config/karabiner/assets/complex_modifications" = { source = "home/.config/karabiner/assets/complex_modifications", mode = "symlink" } - -[bootstrap.hooks.post-defaults] -run = [ - "killall Dock 2>/dev/null || true", - "killall Finder 2>/dev/null || true", - "killall SystemUIServer 2>/dev/null || true", -] diff --git a/mise.toml b/mise.toml deleted file mode 100644 index 9805f32..0000000 --- a/mise.toml +++ /dev/null @@ -1,64 +0,0 @@ -[settings] -# Required for `mise bootstrap` (packages, login shell, etc.) -experimental = true - -[bootstrap.user] -login_shell = "/bin/zsh" - -# Runs at the end of `mise bootstrap` (after packages / user / tools). -# On Unix `mise bootstrap` also applies [dotfiles] natively at step 3; -# running deploy again here is idempotent and keeps Windows covered. -[tasks.bootstrap] -description = "Deploy dotfiles ([dotfiles] on Unix, PSDotFiles on Windows)" -run = "mise run deploy" -run_windows = "mise run deploy" - -[tasks.help] -description = "List available tasks" -run = "zsh script/help.zsh" -run_windows = "pwsh -NoProfile -Command \"Write-Host 'Task help is not supported on Windows.'; exit 1\"" - -[tasks.update] -description = "Fetch latest changes" -run = "zsh script/update.zsh" -run_windows = "pwsh -NoProfile -Command \"Write-Host 'Task update is not supported on Windows.'; exit 1\"" - -[tasks.list] -description = "Show dotfiles to deploy" -run = "mise dotfiles status" -run_windows = "pwsh -NoProfile -Command \"Write-Host 'Task list is not supported on Windows.'; exit 1\"" - -[tasks.clean] -description = "Remove deployed symlinks from $HOME" -run = "zsh script/clean.zsh" -run_windows = "pwsh -NoProfile -File script/clean-windows.ps1" - -[tasks.prepare-subdirs] -description = "Ensure required subdirectories exist (Windows, from .deploy_subdir-windows)" -hide = true -run = "true" -run_windows = "pwsh -NoProfile -File script/prepare-subdirs-windows.ps1" - -# `clean` runs first so entries removed from [dotfiles] don't leave -# stale links behind; apply then relinks everything in the allowlist. -[tasks.deploy] -description = "Deploy dotfiles to $HOME (mise [dotfiles] on Unix, PSDotFiles on Windows)" -depends = ["clean", "prepare-subdirs"] -run = "mise dotfiles apply -y" -run_windows = "pwsh -NoProfile -File script/deploy.ps1" - -[tasks.install-apps] -description = "Install apps (Brewfile on Unix, win/apps.winget on Windows)" -run = "zsh script/install-apps.zsh" -run_windows = "pwsh -NoProfile -File script/install-apps.ps1" - -[tasks.setup-kanata] -description = "Create kanata autostart shortcut (Windows)" -run = "echo 'Task setup-kanata is only supported on Windows.'; exit 1" -run_windows = "pwsh -NoProfile -File script/setup-kanata.ps1" - -[tasks.theme] -description = "Install Terminal theme (macOS)" -run = "zsh script/theme.zsh" -run_windows = "pwsh -NoProfile -Command \"Write-Host 'Task theme is not supported on Windows.'; exit 1\"" - diff --git a/script/_lib.ps1 b/script/_lib.ps1 deleted file mode 100644 index 092b415..0000000 --- a/script/_lib.ps1 +++ /dev/null @@ -1,81 +0,0 @@ -# Shared helpers for Windows dotfiles scripts. - -function Get-RepoRoot { - $root = Resolve-Path (Join-Path $PSScriptRoot '..') - return $root.Path -} - -function Test-CommandAvailable { - param([Parameter(Mandatory)][string]$Name) - return $null -ne (Get-Command $Name -ErrorAction SilentlyContinue) -} - -function Assert-CommandAvailable { - param([Parameter(Mandatory)][string]$Name) - if (-not (Test-CommandAvailable $Name)) { - throw "Required command not found: $Name" - } -} - -function Test-DeveloperModeEnabled { - try { - $key = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock' -Name 'AllowDevelopmentWithoutDevLicense' -ErrorAction Stop - return $key.AllowDevelopmentWithoutDevLicense -eq 1 - } catch { - return $false - } -} - -function Write-DeveloperModeWarning { - if (Test-DeveloperModeEnabled) { - return - } - Write-Warning @" -Developer Mode does not appear to be enabled. PSDotFiles needs permission to create symbolic links. -Enable: Settings -> System -> For developers -> Developer Mode -Or run this shell as Administrator. -"@ -} - -function Invoke-WingetConfigure { - param( - [Parameter(Mandatory)][string]$ConfigPath - ) - - Assert-CommandAvailable winget - - $args = @( - 'configure', - '-f', $ConfigPath, - '--accept-configuration-agreements', - '--disable-interactivity' - ) - - & winget @args - if ($LASTEXITCODE -ne 0) { - throw "winget configure failed (exit $LASTEXITCODE): $ConfigPath" - } -} - -function Install-DeploySubdirsWindows { - param( - [Parameter(Mandatory)][string]$RepoRoot - ) - - $listPath = Join-Path $RepoRoot '.deploy_subdir-windows' - if (-not (Test-Path $listPath)) { - Write-Host '(skip) .deploy_subdir-windows not found' - return - } - - Write-Host '==> Ensure required subdirectories exist (from .deploy_subdir-windows)' - Get-Content $listPath | ForEach-Object { - $line = $_.Trim() - if ([string]::IsNullOrWhiteSpace($line) -or $line.StartsWith('#')) { - return - } - $target = Join-Path $HOME $line - New-Item -ItemType Directory -Force -Path $target | Out-Null - Write-Host " mkdir -p $target" - } -} diff --git a/script/_lib.zsh b/script/_lib.zsh deleted file mode 100644 index 9c0cd8d..0000000 --- a/script/_lib.zsh +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env zsh - -emulate -L zsh -set -eu -set -o pipefail - -# Absolute path to this file's directory (stable even when sourced). -DOTFILES_SCRIPT_DIR=${${(%):-%x}:A:h} - -# Returns repository root (dotfiles root). -repo_root() { - local root - root=${DOTFILES_SCRIPT_DIR:h} - print -r -- "$root" -} - -require_cmd() { - local cmd=${1:?command required} - if ! command -v "$cmd" >/dev/null 2>&1; then - print -u2 -r -- "error: required command not found: $cmd" - return 127 - fi -} diff --git a/script/clean-windows.ps1 b/script/clean-windows.ps1 deleted file mode 100644 index 1cf85f9..0000000 --- a/script/clean-windows.ps1 +++ /dev/null @@ -1,27 +0,0 @@ -#Requires -Version 5.1 -$ErrorActionPreference = 'Stop' - -. "$PSScriptRoot/_lib.ps1" - -$repo = Get-RepoRoot -Set-Location $repo - -if (-not (Get-Module -ListAvailable -Name PSDotFiles)) { - throw 'PSDotFiles module is not installed. Run: Install-Module -Name PSDotFiles -Scope CurrentUser' -} - -Import-Module PSDotFiles - -$Global:DotFilesPath = $repo -Write-Host '==> Remove home-win/ symlinks from home directory.' - -try { - $component = Get-DotFiles -Path $repo -Autodetect -ErrorAction SilentlyContinue | Where-Object Name -eq 'home-win' - if (-not $component) { - throw 'PSDotFiles component not found: home-win' - } - - $component | Remove-DotFiles -Verbose -ErrorAction Stop -} catch { - Write-Host " (skip) $($_.Exception.Message)" -} diff --git a/script/clean.zsh b/script/clean.zsh deleted file mode 100644 index e2b0960..0000000 --- a/script/clean.zsh +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env zsh - -emulate -L zsh -set -eu -set -o pipefail - -source "${0:A:h}/_lib.zsh" - -local root -root=$(repo_root) - -# Remove every symlink under the scan roots whose target points into the -# repo's home/ tree — including dangling links. Real files and dirs -# (app runtime state) are never touched. - -print -r -- "Removing symlinks pointing into $root/home ..." - -local -a scan_roots=( - "$HOME/.zshenv" "$HOME/.zprofile" "$HOME/.zshrc" "$HOME/.gitconfig" - "$HOME/.hammerspoon" "$HOME/.config" - "$HOME/.claude" "$HOME/.cursor" "$HOME/.copilot" "$HOME/.agents" -) - -local removed=0 -local p link target -for p in "${scan_roots[@]}"; do - [[ -e $p || -L $p ]] || continue - while IFS= read -r link; do - target=$(readlink "$link") - [[ $target = /* ]] || target="${link:h}/$target" - target=${target:a} - if [[ $target == "$root/home" || $target == "$root/home/"* ]]; then - print -r -- "unlink: $link -> $target" - rm "$link" - removed=$(( removed + 1 )) - fi - done < <(find "$p" -maxdepth 6 -type l 2>/dev/null) -done - -# Prune dirs the sweep may have emptied (deepest first) so that -# whole-dir [dotfiles] entries can be applied in their place. -local -a prune_dirs=( - "$HOME/.config/ghostty/shaders" - "$HOME/.config/ghostty" - "$HOME/.config/nvim" - "$HOME/.config/sheldon" - "$HOME/.config/micro/plug/editorconfig/help" - "$HOME/.config/micro/plug/editorconfig" - "$HOME/.config/karabiner/assets/complex_modifications" - "$HOME/.claude/skills/commit" - "$HOME/.claude/skills/dev-server" - "$HOME/.claude/skills/git-wt" - "$HOME/.cursor/skills/commit" - "$HOME/.cursor/skills/dev-server" - "$HOME/.cursor/skills/git-wt" - "$HOME/.copilot/skills/commit" - "$HOME/.copilot/skills/dev-server" - "$HOME/.copilot/skills/git-wt" - "$HOME/.agents/skills/commit" - "$HOME/.agents/skills/dev-server" - "$HOME/.agents/skills/git-wt" - "$HOME/.agents/skills" - "$HOME/.agents/instructions" - "$HOME/.agents" -) - -local d -for d in "${prune_dirs[@]}"; do - if [[ -d $d && ! -L $d ]] && rmdir "$d" 2>/dev/null; then - print -r -- "rmdir: $d" - fi -done - -print -r -- "Done ($removed symlink(s) removed)." diff --git a/script/deploy.ps1 b/script/deploy.ps1 deleted file mode 100644 index 8146e90..0000000 --- a/script/deploy.ps1 +++ /dev/null @@ -1,25 +0,0 @@ -#Requires -Version 5.1 -$ErrorActionPreference = 'Stop' - -. "$PSScriptRoot/_lib.ps1" - -$repo = Get-RepoRoot -Set-Location $repo - -Write-DeveloperModeWarning -Install-DeploySubdirsWindows -RepoRoot $repo - -if (-not (Get-Module -ListAvailable -Name PSDotFiles)) { - throw 'PSDotFiles module is not installed. Run: Install-Module -Name PSDotFiles -Scope CurrentUser' -} - -Import-Module PSDotFiles - -$Global:DotFilesPath = $repo -Write-Host '==> Deploy home-win/ to home directory via PSDotFiles.' -$component = Get-DotFiles -Path $repo -Autodetect -ErrorAction SilentlyContinue | Where-Object Name -eq 'home-win' -if (-not $component) { - throw 'PSDotFiles component not found: home-win' -} - -$component | Install-DotFiles -Verbose -ErrorAction Stop diff --git a/script/help.zsh b/script/help.zsh deleted file mode 100644 index f2d8fb3..0000000 --- a/script/help.zsh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env zsh - -emulate -L zsh -set -eu -set -o pipefail - -# Lists available mise tasks. -if command -v mise >/dev/null 2>&1; then - mise tasks -else - print -u2 -r -- "error: mise is not installed" - print -u2 -r -- "hint: https://mise.jdx.dev/" - exit 127 -fi diff --git a/script/install-apps.ps1 b/script/install-apps.ps1 deleted file mode 100644 index 0ce255b..0000000 --- a/script/install-apps.ps1 +++ /dev/null @@ -1,14 +0,0 @@ -#Requires -Version 5.1 -$ErrorActionPreference = 'Stop' - -. "$PSScriptRoot/_lib.ps1" - -$repo = Get-RepoRoot -$config = Join-Path $repo 'win/apps.winget' - -if (-not (Test-Path $config)) { - throw "WinGet configuration not found: $config" -} - -Write-Host "==> Install apps via winget configure ($config)" -Invoke-WingetConfigure -ConfigPath $config diff --git a/script/install-apps.zsh b/script/install-apps.zsh deleted file mode 100644 index 649c8f0..0000000 --- a/script/install-apps.zsh +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env zsh - -emulate -L zsh -set -eu -set -o pipefail - -source "${0:A:h}/_lib.zsh" - -local root uname_s -root=$(repo_root) -cd "$root" - -uname_s=$(uname -s) - -if [[ "$uname_s" == "Linux" ]]; then - require_cmd brew - brew bundle --file=./linux/Brewfile - - if command -v apt-get >/dev/null 2>&1; then - sudo apt-get install hugo - else - print -u2 -r -- "warn: apt-get not found; skipping 'sudo apt-get install hugo'" - fi -elif [[ "$uname_s" == "Darwin" ]]; then - require_cmd brew - brew bundle --file=./macos/Brewfile -else - print -u2 -r -- "error: unsupported OS: $uname_s" - exit 1 -fi diff --git a/script/prepare-subdirs-windows.ps1 b/script/prepare-subdirs-windows.ps1 deleted file mode 100644 index c71ccd9..0000000 --- a/script/prepare-subdirs-windows.ps1 +++ /dev/null @@ -1,7 +0,0 @@ -#Requires -Version 5.1 -$ErrorActionPreference = 'Stop' - -. "$PSScriptRoot/_lib.ps1" - -$repo = Get-RepoRoot -Install-DeploySubdirsWindows -RepoRoot $repo diff --git a/script/setup-kanata.ps1 b/script/setup-kanata.ps1 deleted file mode 100644 index acc2b7d..0000000 --- a/script/setup-kanata.ps1 +++ /dev/null @@ -1,44 +0,0 @@ -#Requires -Version 5.1 -# Create (or refresh) a Startup shortcut so kanata launches on login. -# Prerequisites: -# - kanata installed: mise run install-apps (jtroo.kanata_gui) -# - config deployed: mise run deploy (home-win/Documents/kanata/kanata.kbd) -$ErrorActionPreference = 'Stop' - -. "$PSScriptRoot/_lib.ps1" - -# winget installs the portable zip and registers this exe as a command alias -# (a symlink under WinGet\Links), which stays stable across version upgrades. -$exeName = 'kanata_windows_gui_winIOv2_x64.exe' -$exePath = Join-Path $env:LOCALAPPDATA "Microsoft\WinGet\Links\$exeName" - -if (-not (Test-Path $exePath)) { - throw @" -kanata was not found at: - $exePath -Install it first: mise run install-apps (or: winget install jtroo.kanata_gui) -"@ -} - -$cfg = Join-Path $HOME 'Documents\kanata\kanata.kbd' -if (-not (Test-Path $cfg)) { - throw "kanata config not found: $cfg (run: mise run deploy)" -} - -$startup = [Environment]::GetFolderPath('Startup') -$shortcutPath = Join-Path $startup 'Kanata.lnk' - -$wsh = New-Object -ComObject WScript.Shell -$shortcut = $wsh.CreateShortcut($shortcutPath) -$shortcut.TargetPath = $exePath -$shortcut.Arguments = "--cfg `"$cfg`"" -$shortcut.WorkingDirectory = Split-Path $cfg -$shortcut.WindowStyle = 7 # minimized (GUI variant lives in the system tray) -$shortcut.Description = 'Kanata keyboard remapper' -$shortcut.Save() - -Write-Host "==> Created startup shortcut: $shortcutPath" -Write-Host " Target: $exePath --cfg $cfg" -Write-Host '' -Write-Host 'Start it now without logging out:' -Write-Host " Start-Process '$shortcutPath'" diff --git a/script/theme.zsh b/script/theme.zsh deleted file mode 100644 index 3a5ddbe..0000000 --- a/script/theme.zsh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env zsh - -emulate -L zsh -set -eu -set -o pipefail - -source "${0:A:h}/_lib.zsh" - -local root uname_s -root=$(repo_root) -cd "$root" - -uname_s=$(uname -s) - -if [[ "$uname_s" == "Darwin" ]]; then - open ./macos/BirdsOfParadise.terminal -else - print -r -- "(skip) theme: not macOS" -fi diff --git a/script/update.zsh b/script/update.zsh deleted file mode 100644 index ad976bf..0000000 --- a/script/update.zsh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env zsh - -emulate -L zsh -set -eu -set -o pipefail - -source "${0:A:h}/_lib.zsh" - -local root -root=$(repo_root) -cd "$root" - -require_cmd git - -git pull origin main diff --git a/win/apps.winget b/win/apps.winget deleted file mode 100644 index e4346de..0000000 --- a/win/apps.winget +++ /dev/null @@ -1,109 +0,0 @@ -# yaml-language-server: $schema=https://aka.ms/configuration-dsc-schema/0.2 - -properties: - configurationVersion: 0.2.0 - resources: - - resource: Microsoft.WinGet.DSC/WinGetPackage - directives: - description: Visual Studio Code - settings: - id: Microsoft.VisualStudioCode - source: winget - - - resource: Microsoft.WinGet.DSC/WinGetPackage - directives: - description: Cursor - settings: - id: Anysphere.Cursor - source: winget - - - resource: Microsoft.WinGet.DSC/WinGetPackage - directives: - description: Claude - settings: - id: Anthropic.Claude - source: winget - - - resource: Microsoft.WinGet.DSC/WinGetPackage - directives: - description: Claude Code - settings: - id: Anthropic.ClaudeCode - source: winget - - - resource: Microsoft.WinGet.DSC/WinGetPackage - directives: - description: Slack - settings: - id: SlackTechnologies.Slack - source: winget - - - resource: Microsoft.WinGet.DSC/WinGetPackage - directives: - description: Unity Hub - settings: - id: Unity.UnityHub - source: winget - - - resource: Microsoft.WinGet.DSC/WinGetPackage - directives: - description: Zen Browser - settings: - id: Zen-Team.Zen-Browser - source: winget - - - resource: Microsoft.WinGet.DSC/WinGetPackage - directives: - description: Gyazo - settings: - id: Nota.Gyazo - source: winget - - - resource: Microsoft.WinGet.DSC/WinGetPackage - directives: - description: 1Password - settings: - id: AgileBits.1Password - source: winget - - - resource: Microsoft.WinGet.DSC/WinGetPackage - directives: - description: Kanata (keyboard remapper) - settings: - id: jtroo.kanata_gui - source: winget - - - resource: Microsoft.WinGet.DSC/WinGetPackage - directives: - description: Raycast - settings: - id: 9PFXXSHC64H3 - source: msstore - - - resource: Microsoft.WinGet.DSC/WinGetPackage - directives: - description: Notion - settings: - id: Notion.Notion - source: winget - - - resource: Microsoft.WinGet.DSC/WinGetPackage - directives: - description: Notion Calendar - settings: - id: Notion.NotionCalendar - source: winget - - - resource: Microsoft.WinGet.DSC/WinGetPackage - directives: - description: Figma - settings: - id: Figma.Figma - source: winget - - - resource: Microsoft.WinGet.DSC/WinGetPackage - directives: - description: Elgato Wave Link - settings: - id: Elgato.WaveLink - source: winget diff --git a/win/bootstrap.winget b/win/bootstrap.winget deleted file mode 100644 index 7cb287e..0000000 --- a/win/bootstrap.winget +++ /dev/null @@ -1,25 +0,0 @@ -# yaml-language-server: $schema=https://aka.ms/configuration-dsc-schema/0.2 - -properties: - configurationVersion: 0.2.0 - resources: - - resource: Microsoft.WinGet.DSC/WinGetPackage - directives: - description: PowerShell 7 - settings: - id: Microsoft.PowerShell - source: winget - - - resource: Microsoft.WinGet.DSC/WinGetPackage - directives: - description: Git for Windows - settings: - id: Git.Git - source: winget - - - resource: Microsoft.WinGet.DSC/WinGetPackage - directives: - description: mise - settings: - id: jdx.mise - source: winget