diff --git a/AGENTS.md b/AGENTS.md index 6f6e68f3..968c9f02 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -59,18 +59,19 @@ The project uses **pnpm 11** (pinned via `packageManager` in `package.json`) and ```bash git clone https://github.com/techmc-wiki/gtmc.git cd gtmc -pnpm install # also runs scripts/postinstall.mjs (see below) +pnpm install # also runs scripts/postinstall.ts (see below) cp .env.example .env # fill in GitHub OAuth, DATABASE_URL, etc. pnpm dev # http://localhost:3000 ``` -`pnpm install` triggers `scripts/postinstall.mjs`, which: +`pnpm install` triggers `scripts/postinstall.ts`, which: 1. Adds `.gitconfig` to the local Git config include path. -2. Initializes the `articles/` submodule if it is missing or empty (otherwise leaves the existing checkout alone). -3. Runs `prisma generate` (with a placeholder `DATABASE_URL` if none is set, to allow client codegen offline). -4. Runs `tsx scripts/generate-article-manifest.ts` to seed `data/manifest.json`. -5. Runs `playwright install chromium` for the PDF generator and any browser tests. +2. Initializes the `articles/` and `glossary/` submodules at their pinned commits if needed. +3. Generates the glossary manifest. +4. Runs `prisma generate` (with a placeholder `DATABASE_URL` if none is set, to allow client codegen offline), unless heavy postinstall steps are explicitly skipped. +5. Runs `tsx scripts/generate-article-manifest.ts` and `tsx scripts/generate-author-profiles.ts`. +6. Runs `playwright install chromium` for the PDF generator and any browser tests. ### Environment variables @@ -101,6 +102,7 @@ pnpm style:fix # prettier --write pnpm build:content # Generate content artifacts (manifest, glossary, articles, PDF) pnpm build:next # Next.js production build pnpm build # Both phases: content generation then Next build +pnpm prepare:articles # Prepare articles submodule for build (pinned by default) pnpm analyze # ANALYZE=true pnpm build (bundle analyzer) pnpm lighthouse # Run Lighthouse CI locally (requires running server) ``` @@ -118,12 +120,21 @@ Key things to know: pnpm articles:status # Show submodule status pnpm articles:init # Reinitialize at the pinned commit pnpm articles:update # Pull the latest articles commit +pnpm prepare:articles # Prepare articles for a build using GTMC_ARTICLES_SOURCE pnpm generate:manifest # Rebuild data/manifest.json pnpm generate:content # Re-render rendered article content pnpm articles:pdf # Re-render the offline PDF (public/gtmc.pdf) ``` -Vercel checkouts use whatever commit is pinned by this repo; to ship updated article content, commit the new submodule pointer here. **Do not mix submodule pointer updates into feature/fix commits** (see `CONTRIBUTING.md`). +Article build source is controlled by `GTMC_ARTICLES_SOURCE`: + +- unset or blank: leave the current `articles/` checkout untouched; no `git submodule` command runs. +- `pinned`: run `git submodule update --init --recursive articles` to check out the commit pinned by this repo. +- `latest`: run `git submodule update --init --recursive --remote articles` before the content build, advancing to the branch configured in `.gitmodules` (currently `main`). + +Vercel runs `pnpm build:vercel`, which sets `GTMC_ARTICLES_SOURCE=latest` before calling `pnpm prepare:articles`, so deployments consume the newest configured article branch. For reproducible local or CI builds, set `GTMC_ARTICLES_SOURCE=pinned`; leaving it unset preserves the checkout already prepared by `pnpm install`. + +For reproducible releases, update and commit the submodule pointer here with `pnpm articles:update`. **Do not mix submodule pointer updates into feature/fix commits** (see `CONTRIBUTING.md`). ### Glossary submodule @@ -197,7 +208,7 @@ Notes: - `pnpm build` is **non-trivial** — phase 1 regenerates all content artifacts before phase 2 invokes `next build`. Allow time and disk space accordingly. - `next.config.ts` configures `outputFileTracingIncludes` / `Excludes` so search and litematica endpoints get the right files but article binaries are not pulled into every lambda. Keep these patterns in sync if you add similar routes. (Future: glossary manifests may need similar treatment if served from dedicated API routes.) -- Vercel uses `vercel.json` to install Chromium system libraries on Amazon Linux before `pnpm install`, then runs `pnpm build` exactly as above. +- Vercel uses `vercel.json` to install Chromium system libraries on Amazon Linux before `pnpm install`, then runs `pnpm build:vercel`. That script installs Playwright Chromium, prepares the articles submodule according to `GTMC_ARTICLES_SOURCE`, deploys Prisma migrations, and runs the two-phase `pnpm build`. - CI workflows (`.github/workflows/`): - `build.yml` — runs on every push and PR; installs deps with `--frozen-lockfile`, generates the Prisma client with a placeholder `DATABASE_URL`, then runs `pnpm typecheck` and `pnpm build`. - `style_and_lint.yml` — runs on pushes to `main`; runs `pnpm lint:check` and `pnpm style:check`. diff --git a/app/[locale]/(private)/draft/[id]/page.tsx b/app/[locale]/(private)/draft/[id]/page.tsx index 696e41bc..4921af34 100644 --- a/app/[locale]/(private)/draft/[id]/page.tsx +++ b/app/[locale]/(private)/draft/[id]/page.tsx @@ -8,7 +8,6 @@ import { decodeStoredDraftFiles } from "@/lib/drafts/files" import { notFound, redirect } from "next/navigation" import { readFile } from "fs/promises" import path from "path" -import { ARTICLES_PATH } from "@/lib/articles/fs" function buildDraftEditorData( draft: { @@ -126,33 +125,14 @@ export default async function EditDraftPage({ } async function loadContributingGuides() { - const guideTargets = [ - { - id: "web", - title: "GTMC Web", - filePath: path.join(process.cwd(), "CONTRIBUTING.md"), - }, - { - id: "articles", - title: "Articles", - filePath: path.join(ARTICLES_PATH, "CONTRIBUTING.md"), - }, - ] - - const guides = await Promise.all( - guideTargets.map(async (guide) => { - try { - const content = await readFile(guide.filePath, "utf8") - return { - id: guide.id, - title: guide.title, - content, - } - } catch { - return null - } - }) - ) + const guides = await Promise.all([ + readFile(path.join(process.cwd(), "CONTRIBUTING.md"), "utf8") + .then((content) => ({ id: "web", title: "GTMC Web", content })) + .catch(() => null), + readFile(path.join(process.cwd(), "articles", "CONTRIBUTING.md"), "utf8") + .then((content) => ({ id: "articles", title: "Articles", content })) + .catch(() => null), + ]) return guides.filter( ( diff --git a/app/[locale]/_homepage/continue-reading.tsx b/app/[locale]/_homepage/continue-reading.tsx index e88d398a..b4974bf8 100644 --- a/app/[locale]/_homepage/continue-reading.tsx +++ b/app/[locale]/_homepage/continue-reading.tsx @@ -11,9 +11,11 @@ import { export function ContinueReading() { const t = useTranslations("Homepage") - const [bookmark] = React.useState(() => - typeof window === "undefined" ? null : readBookmark() - ) + const [bookmark, setBookmark] = React.useState(null) + + React.useEffect(() => { + setBookmark(readBookmark()) + }, []) const pct = bookmark ? Math.round(bookmark.progress * 100) : 0 const progressStyle = React.useMemo( diff --git a/app/[locale]/_homepage/hero-card.tsx b/app/[locale]/_homepage/hero-card.tsx index b4a08349..68c319f5 100644 --- a/app/[locale]/_homepage/hero-card.tsx +++ b/app/[locale]/_homepage/hero-card.tsx @@ -79,7 +79,7 @@ export function HeroCard({
- {t("heroDescription")} + {t("heroTagline")} diff --git a/app/[locale]/pdf/layout.tsx b/app/[locale]/pdf/layout.tsx index 988b19fa..53075fb3 100644 --- a/app/[locale]/pdf/layout.tsx +++ b/app/[locale]/pdf/layout.tsx @@ -1,43 +1,10 @@ import * as React from "react" -import { getTranslations } from "next-intl/server" -import { DesktopNav } from "@/components/layout/desktop-nav" -import { MobileNav } from "@/components/layout/mobile-nav" -import { LanguageSwitcher } from "@/components/layout/language-switcher" -import { ThemeToggle } from "@/components/layout/theme-toggle" -import { SiteShell } from "@/components/layout/site-shell" -import { Logo } from "@/components/ui/logo" - -function buildNavLinks(t: Awaited>>) { - return [ - { href: "/articles", label: t("articles") }, - { href: "/pdf", label: "PDF" }, - ] -} +import { MainSiteShell } from "@/components/layout/main-site-shell" export default async function PdfLayout({ children, }: { children: React.ReactNode }) { - const t = await getTranslations("Nav") - const navLinks = buildNavLinks(t) - - return ( - - - - - } - rightSlot={ - <> - - - - - }> - {children} - - ) + return {children} } diff --git a/app/api/litematica-assets/[...path]/route.ts b/app/api/litematica-assets/[...path]/route.ts index bc88d3e4..752f0a9a 100644 --- a/app/api/litematica-assets/[...path]/route.ts +++ b/app/api/litematica-assets/[...path]/route.ts @@ -3,7 +3,7 @@ import fs from "fs" import path from "path" const BASE_MINECRAFT_DIR = path.join( - /* turbopackIgnore: true */ process.cwd(), + process.cwd(), "litematica-renderer", "assets", "minecraft" @@ -22,12 +22,12 @@ function getCachedFilePath(targetName: string) { return cached } -function setCachedFilePath(targetName: string, fullPath: string) { +function setCachedFilePath(targetName: string, relativePath: string) { if (fileCache.has(targetName)) { fileCache.delete(targetName) } - fileCache.set(targetName, fullPath) + fileCache.set(targetName, relativePath) if (fileCache.size > FILE_CACHE_LIMIT) { const oldestKey = fileCache.keys().next().value @@ -52,6 +52,16 @@ export async function GET( const assetPath = pathArray.join("/") const fileName = pathArray[pathArray.length - 1] + const normalizedAssetPath = path.normalize(assetPath).replaceAll("\\", "/") + if ( + normalizedAssetPath === ".." || + normalizedAssetPath.startsWith("../") || + normalizedAssetPath.split("/").includes("..") || + path.isAbsolute(normalizedAssetPath) + ) { + return new NextResponse("Forbidden", { status: 403 }) + } + // 递归查找文件函数 const findFile = async ( dir: string, @@ -69,46 +79,56 @@ export async function GET( const found = await findFile(fullPath, targetName) if (found) return found } else if (entry.name === targetName) { - setCachedFilePath(targetName, fullPath) - return fullPath + const relativePath = path.relative(BASE_MINECRAFT_DIR, fullPath) + setCachedFilePath(targetName, relativePath) + return relativePath } } /* oxlint-enable eslint/no-await-in-loop */ return null } - let localTarget: string | null = null + let relativeTarget: string | null = null // 允许直接以 models/block/xxx.json 或者 textures/block/xxx.png 访问 - const explicitTarget = path.join(BASE_MINECRAFT_DIR, assetPath) + const explicitTarget = path.join(BASE_MINECRAFT_DIR, normalizedAssetPath) if (fs.existsSync(explicitTarget)) { - localTarget = explicitTarget + relativeTarget = normalizedAssetPath } else { // 后备:旧逻辑直接查找 block/xxx 目录 - const directTarget = path.join(BASE_TEXTURES_DIR, "block", assetPath) + const directTarget = path.join( + BASE_TEXTURES_DIR, + "block", + normalizedAssetPath + ) if (fs.existsSync(directTarget)) { - localTarget = directTarget + relativeTarget = path.join("textures", "block", normalizedAssetPath) } else { // 否则我们在整个 textures 目录中进行全局搜索 - localTarget = await findFile(BASE_TEXTURES_DIR, fileName) + relativeTarget = await findFile(BASE_TEXTURES_DIR, fileName) } } - if (!localTarget) { + if (!relativeTarget) { return new NextResponse("Asset Not Found", { status: 404 }) } - // 安全检查:防止路径穿越攻击 - if (!localTarget.startsWith(BASE_MINECRAFT_DIR)) { + if ( + path.isAbsolute(relativeTarget) || + relativeTarget === ".." || + relativeTarget.startsWith(".." + path.sep) + ) { return new NextResponse("Forbidden", { status: 403 }) } try { - const fileBuffer = await fs.promises.readFile(localTarget) + const fileBuffer = await fs.promises.readFile( + path.join(BASE_MINECRAFT_DIR, relativeTarget) + ) let contentType = "image/png" - if (localTarget.endsWith(".json")) contentType = "application/json" - if (localTarget.endsWith(".mcmeta")) contentType = "application/json" + if (relativeTarget.endsWith(".json")) contentType = "application/json" + if (relativeTarget.endsWith(".mcmeta")) contentType = "application/json" return new NextResponse(new Uint8Array(fileBuffer), { headers: { diff --git a/app/opengraph-image.tsx b/app/opengraph-image.tsx index 4f4fee8d..7e339319 100644 --- a/app/opengraph-image.tsx +++ b/app/opengraph-image.tsx @@ -8,7 +8,6 @@ if ( process.env.VERCEL = "0" } -export const runtime = "edge" export const alt = "Graduate Texts in Minecraft" export const size = { width: 1200, height: 630 } export const contentType = "image/png" diff --git a/app/sitemap.ts b/app/sitemap.ts index 540c4778..326fd5e3 100644 --- a/app/sitemap.ts +++ b/app/sitemap.ts @@ -1,4 +1,5 @@ import type { MetadataRoute } from "next" +import { cacheLife } from "next/cache" import { listAllIssues } from "@/lib/github" import { getSiteUrl } from "@/lib/site-url" @@ -12,8 +13,6 @@ import { } from "@/lib/articles/manifest" import { loadGlossaryManifest } from "@/lib/glossary/manifest" -export const revalidate = 3600 - const STATIC_LAST_MODIFIED = new Date("2024-12-08T10:28:55.000Z") function localizedAlternates(base: string, path: string) { @@ -46,6 +45,9 @@ function flattenTree( } export default async function sitemap(): Promise { + "use cache" + cacheLife("hours") + const BASE = getSiteUrl() const staticUrls: MetadataRoute.Sitemap = [ diff --git a/articles b/articles index 35d479a9..cd165d4a 160000 --- a/articles +++ b/articles @@ -1 +1 @@ -Subproject commit 35d479a951b2862fcc5d2b01301b27e7a96e3c29 +Subproject commit cd165d4ac949c8b2a29245bf9a60d496f3a912a8 diff --git a/lib/articles/frontmatter-parser.ts b/lib/articles/frontmatter-parser.ts index db68dd48..89686d33 100644 --- a/lib/articles/frontmatter-parser.ts +++ b/lib/articles/frontmatter-parser.ts @@ -1,12 +1,8 @@ import matter from "gray-matter" -// ─── New API ──────────────────────────────────────────────────────────────── - export interface SourceFrontMatter { slug: string title: string - "chapter-title"?: string - "intro-title"?: string description?: string index: number "is-advanced"?: boolean @@ -17,70 +13,101 @@ export interface TranslationFrontMatter { translates: string "translated-from-revision": string title?: string - "chapter-title"?: string - "intro-title"?: string description?: string banner?: { src: string; alt?: string } } -interface ParseSourceFrontMatterOptions { - allowTitlelessFolder?: boolean +export interface SourceReadmeFrontMatter { + slug: string + "chapter-title": string + "intro-title"?: string + index: number +} + +export interface TranslationReadmeFrontMatter { + translates: string + "translated-from-revision": string + "chapter-title": string + "intro-title"?: string } -// ─── Allowed / legacy key sets ───────────────────────────────────────────── +type BannerFrontMatter = { src: string; alt?: string } const SOURCE_ALLOWED_KEYS = new Set([ "slug", "title", - "chapter-title", - "intro-title", "description", "index", "is-advanced", "banner", - "author", ]) const TRANSLATION_ALLOWED_KEYS = new Set([ + "slug", + "index", + "is-advanced", "translates", "translated-from-revision", "title", - "chapter-title", - "intro-title", "description", "banner", ]) -const LEGACY_KEYS = new Set([ - "title-en", - "chapter-title-en", - "intro-title-en", - "date", - "lastmod", - "co-authors", +const SOURCE_README_ALLOWED_KEYS = new Set([ + "slug", + "chapter-title", + "intro-title", + "index", ]) -// ─── Helpers ──────────────────────────────────────────────────────────────── +const TRANSLATION_README_ALLOWED_KEYS = new Set([ + "slug", + "index", + "translates", + "translated-from-revision", + "chapter-title", + "intro-title", +]) -function checkLegacyKeys(data: Record): void { - for (const key of Object.keys(data)) { - if (LEGACY_KEYS.has(key)) { - throw new Error(`legacy key '${key}' not allowed`) - } - } -} +// ─── Helpers ──────────────────────────────────────────────────────────────── function checkAdditionalProperties( data: Record, allowedKeys: Set ): void { for (const key of Object.keys(data)) { - if (!allowedKeys.has(key) && !LEGACY_KEYS.has(key)) { + if (!allowedKeys.has(key)) { throw new Error(`unknown key '${key}' not allowed`) } } } +function parseRequiredString( + data: Record, + key: string +): string { + const value = data[key] + if (typeof value !== "string") { + throw new Error(`missing required key '${key}'`) + } + return value +} + +function parseRequiredNonEmptyString( + data: Record, + key: string +): string { + const value = parseRequiredString(data, key) + if (value === "") { + throw new Error(`missing required key '${key}'`) + } + return value +} + +function parseOptionalString(value: unknown): string | undefined { + return typeof value === "string" ? value : undefined +} + function parseIndex(value: unknown): number { if (typeof value === "number" && Number.isInteger(value)) { return value @@ -96,7 +123,7 @@ function parseIndex(value: unknown): number { function parseBanner( value: unknown -): { src: string; alt?: string } | undefined { +): BannerFrontMatter | undefined { if (typeof value !== "object" || value === null) return undefined const obj = value as Record if (typeof obj.src !== "string") return undefined @@ -108,36 +135,19 @@ function parseBanner( // ─── Parsers ──────────────────────────────────────────────────────────────── -export function parseSourceFrontMatter( - content: string, - options: ParseSourceFrontMatterOptions = {} -): SourceFrontMatter { +function parseFrontMatterData(content: string): Record { const { data } = matter(content) - const raw = data as Record + return data as Record +} - checkLegacyKeys(raw) +export function parseSourceFrontMatter(content: string): SourceFrontMatter { + const raw = parseFrontMatterData(content) checkAdditionalProperties(raw, SOURCE_ALLOWED_KEYS) - if (typeof raw.slug !== "string" || raw.slug === "") { - throw new Error("missing required key 'slug'") - } - const title = typeof raw.title === "string" ? raw.title : "" - - if (!options.allowTitlelessFolder && title === "") { - throw new Error("missing required key 'title'") - } - return { - slug: raw.slug, - title, - "chapter-title": - typeof raw["chapter-title"] === "string" - ? raw["chapter-title"] - : undefined, - "intro-title": - typeof raw["intro-title"] === "string" ? raw["intro-title"] : undefined, - description: - typeof raw.description === "string" ? raw.description : undefined, + slug: parseRequiredNonEmptyString(raw, "slug"), + title: parseRequiredNonEmptyString(raw, "title"), + description: parseOptionalString(raw.description), index: parseIndex(raw.index), "is-advanced": raw["is-advanced"] === true ? true : undefined, banner: parseBanner(raw.banner), @@ -147,34 +157,48 @@ export function parseSourceFrontMatter( export function parseTranslationFrontMatter( content: string ): TranslationFrontMatter { - const { data } = matter(content) - const raw = data as Record - - checkLegacyKeys(raw) + const raw = parseFrontMatterData(content) checkAdditionalProperties(raw, TRANSLATION_ALLOWED_KEYS) - if (typeof raw.translates !== "string" || raw.translates === "") { - throw new Error("missing required key 'translates'") + return { + translates: parseRequiredNonEmptyString(raw, "translates"), + "translated-from-revision": parseRequiredNonEmptyString( + raw, + "translated-from-revision" + ), + title: parseOptionalString(raw.title), + description: parseOptionalString(raw.description), + banner: parseBanner(raw.banner), } - if ( - typeof raw["translated-from-revision"] !== "string" || - raw["translated-from-revision"] === "" - ) { - throw new Error("missing required key 'translated-from-revision'") +} + +export function parseSourceReadmeFrontMatter( + content: string +): SourceReadmeFrontMatter { + const raw = parseFrontMatterData(content) + checkAdditionalProperties(raw, SOURCE_README_ALLOWED_KEYS) + + return { + slug: parseRequiredString(raw, "slug"), + "chapter-title": parseRequiredNonEmptyString(raw, "chapter-title"), + "intro-title": parseOptionalString(raw["intro-title"]), + index: parseIndex(raw.index), } +} + +export function parseTranslationReadmeFrontMatter( + content: string +): TranslationReadmeFrontMatter { + const raw = parseFrontMatterData(content) + checkAdditionalProperties(raw, TRANSLATION_README_ALLOWED_KEYS) return { - translates: raw.translates, - "translated-from-revision": raw["translated-from-revision"], - title: typeof raw.title === "string" ? raw.title : undefined, - "chapter-title": - typeof raw["chapter-title"] === "string" - ? raw["chapter-title"] - : undefined, - "intro-title": - typeof raw["intro-title"] === "string" ? raw["intro-title"] : undefined, - description: - typeof raw.description === "string" ? raw.description : undefined, - banner: parseBanner(raw.banner), + translates: parseRequiredNonEmptyString(raw, "translates"), + "translated-from-revision": parseRequiredNonEmptyString( + raw, + "translated-from-revision" + ), + "chapter-title": parseRequiredNonEmptyString(raw, "chapter-title"), + "intro-title": parseOptionalString(raw["intro-title"]), } } diff --git a/messages/en.json b/messages/en.json index b8ad6693..b582b7b3 100644 --- a/messages/en.json +++ b/messages/en.json @@ -347,7 +347,7 @@ "sectionDownload": "DOWNLOAD", "sectionRead": "READ", "sectionSource": "SOURCE", - "tagline": "A community-authored treatise on Technical Minecraft." + "tagline": "Knowledge exists. Structure matters." }, "forbidden": { "description": "Your operator level is insufficient for this operation. Request elevated permissions and try again.", @@ -443,6 +443,7 @@ "glossaryCardDesc": "The index of terms — technical Minecraft vocabulary in 12 languages.", "glossaryCardTitle": "Glossary", "heroDescription": "The community-driven online textbook of Minecraft redstone and game mechanics. Tutorials, explanations, and code analysis for conquering academic problems in a world of blocks.", + "heroTagline": "Knowledge exists. Structure matters.", "initializing": "INITIALIZING...", "loggedInAs": "LOGGED IN AS {username}", "loginGithub": "LOGIN", diff --git a/messages/zh.json b/messages/zh.json index 546b2060..841d6a2b 100644 --- a/messages/zh.json +++ b/messages/zh.json @@ -347,7 +347,7 @@ "sectionDownload": "下载", "sectionRead": "阅读", "sectionSource": "源码", - "tagline": "一部由社区共同撰写的技术 Minecraft 论著。" + "tagline": "知识从未缺失,缺失的是连接。" }, "forbidden": { "description": "您的操作等级不足以执行此操作,请申请更高权限后重试。", @@ -443,6 +443,7 @@ "glossaryCardDesc": "全书索引——以 12 种语言收录的技术性 Minecraft 词汇。", "glossaryCardTitle": "术语表", "heroDescription": "社区驱动的 Minecraft 红石和技术在线教科书。提供入门教程、机制阐述和源码阅读,助你在方块世界中攻克学术难题。", + "heroTagline": "知识从未缺失,缺失的是连接。", "initializing": "初始化中...", "loggedInAs": "登录为 {username}", "loginGithub": "登录", diff --git a/next.config.ts b/next.config.ts index 8c500472..0a1eb61f 100644 --- a/next.config.ts +++ b/next.config.ts @@ -31,6 +31,7 @@ const nextConfig: NextConfig = { "papaparse", ], experimental: { + useTypeScriptCli: true, optimizePackageImports: [ "motion/react", "@codemirror/state", diff --git a/package.json b/package.json index 71c5fee8..d9405511 100644 --- a/package.json +++ b/package.json @@ -4,40 +4,40 @@ "private": true, "scripts": { "analyze": "next experimental-analyze", - "build:content": "tsx scripts/generate-article-manifest.ts && tsx scripts/generate-author-profiles.ts && tsx scripts/generate-glossary-manifest.ts && tsx scripts/generate-article-content.ts && tsx scripts/generate-pdf.ts --locale all", + "articles:init": "git submodule update --init --recursive", + "articles:pdf": "node --run build:pdf", + "articles:status": "git submodule status articles", + "articles:update": "git submodule update --remote articles", + "build:content": "node --run generate:manifest && node --run generate:author-profiles && node --run generate:glossary-manifest && node --run generate:content && node --run build:pdf", "build:next": "next build", "build:pdf": "tsx scripts/generate-pdf.ts --locale all", - "build:vercel": "playwright install chromium && node --run db:migrate:deploy && node --run build", + "build:vercel": "GTMC_ARTICLES_SOURCE=latest playwright install chromium && node --run prepare:articles && node --run db:migrate:deploy && node --run build", "build": "if [ \"$GTMC_SKIP_CONTENT_BUILD\" != 'true' ]; then pnpm build:content; fi && pnpm build:next", + "check": "node --run typecheck && node --run lint:check && node --run style:check", "db:migrate:deploy": "prisma migrate deploy", - "generate:content": "tsx scripts/generate-article-content.ts", - "generate:manifest": "tsx scripts/generate-article-manifest.ts", - "generate:author-profiles": "tsx scripts/generate-author-profiles.ts", + "dev": "next dev", + "fmt:check": "oxfmt --check", + "fmt:fix": "oxfmt", + "fmt": "node --run fmt:check", "generate:aliases": "tsx scripts/generate-author-aliases.ts", + "generate:author-profiles": "tsx scripts/generate-author-profiles.ts", + "generate:content": "tsx scripts/generate-article-content.ts", "generate:glossary-manifest": "tsx scripts/generate-glossary-manifest.ts", - "articles:generate-content": "tsx scripts/generate-article-content.ts", - "articles:generate-manifest": "tsx scripts/generate-article-manifest.ts", - "articles:init": "git submodule update --init --recursive", - "articles:pdf": "npx tsx scripts/generate-pdf.ts --locale all", - "articles:status": "git submodule status articles", - "articles:update": "git submodule update --remote articles", + "generate:manifest": "tsx scripts/generate-article-manifest.ts", "glossary:init": "git submodule update --init --recursive", "glossary:status": "git submodule status glossary", "glossary:update": "git submodule update --remote glossary", - "dev": "next dev", "lighthouse": "lhci autorun", "lint:check": "oxlint .", "lint:fix": "oxlint . --fix", "lint": "node --run lint:check", + "postinstall": "tsx scripts/postinstall.ts", + "prepare:articles": "tsx scripts/prepare-articles-for-build.ts", + "prepare": "husky", "style:check": "node --run fmt:check", "style:fix": "node --run fmt:fix", "style": "node --run style:check", - "postinstall": "node scripts/postinstall.mjs", - "fmt:check": "oxfmt --check", - "fmt:fix": "oxfmt", - "fmt": "node --run fmt:check", - "typecheck": "tsc --noEmit", - "prepare": "husky" + "typecheck": "tsc --noEmit" }, "dependencies": { "@auth/prisma-adapter": "^2.11.2", @@ -70,9 +70,9 @@ "mime-types": "^3.0.2", "minisearch": "^7.2.0", "motion": "^12.42.2", - "next": "16.2.10", + "next": "16.3.0-preview.5", "next-auth": "5.0.0-beta.31", - "next-intl": "^4.13.1", + "next-intl": "^4.13.2", "node-diff3": "^3.2.1", "pangu": "^7.2.1", "papaparse": "^5.5.4", @@ -111,7 +111,6 @@ "@types/papaparse": "^5.5.2", "@types/react": "^19.2.17", "@types/three": "^0.185.0", - "ajv": "^8.20.0", "gitnexus": "^1.6.9", "husky": "^9.1.7", "lint-staged": "^17.0.8", @@ -124,7 +123,7 @@ "tailwindcss": "^4.3.2", "tailwindcss-animate": "^1.0.7", "tsx": "^4.23.0", - "typescript": "^6.0.3", + "typescript": "^7.0.2", "vitest": "^4.1.10" }, "resolutions": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 79d1c612..efa4ae44 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,7 +10,7 @@ importers: dependencies: '@auth/prisma-adapter': specifier: ^2.11.2 - version: 2.11.2(@prisma/client@7.8.0(prisma@7.8.0(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3))(typescript@6.0.3)) + version: 2.11.2(@prisma/client@7.8.0(prisma@7.8.0(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@7.0.2))(typescript@7.0.2)) '@codemirror/autocomplete': specifier: ^6.20.3 version: 6.20.3 @@ -34,10 +34,10 @@ importers: version: 7.8.0 '@prisma/client': specifier: 7.8.0 - version: 7.8.0(prisma@7.8.0(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3))(typescript@6.0.3) + version: 7.8.0(prisma@7.8.0(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@7.0.2))(typescript@7.0.2) '@supabase/supabase-js': specifier: ^2.110.0 - version: 2.110.0 + version: 2.110.2 '@tanstack/react-virtual': specifier: ^3.14.5 version: 3.14.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) @@ -46,16 +46,16 @@ importers: version: 4.0.9 '@uiw/react-codemirror': specifier: ^4.25.9 - version: 4.25.10(@babel/runtime@7.29.7)(@codemirror/autocomplete@6.20.3)(@codemirror/language@6.12.3)(@codemirror/lint@6.9.7)(@codemirror/search@6.7.0)(@codemirror/state@6.6.0)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.43.6)(codemirror@6.0.2)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + version: 4.25.11(@babel/runtime@7.29.7)(@codemirror/autocomplete@6.20.3)(@codemirror/language@6.12.4)(@codemirror/lint@6.9.7)(@codemirror/search@6.7.1)(@codemirror/state@6.7.1)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.43.6)(codemirror@6.0.2)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@vercel/analytics': specifier: ^2.0.1 - version: 2.0.1(next@16.2.10(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7) + version: 2.0.1(next@16.3.0-preview.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7) '@vercel/blob': specifier: ^2.5.0 - version: 2.5.0 + version: 2.6.1 '@vercel/speed-insights': specifier: ^2.0.0 - version: 2.0.0(next@16.2.10(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7) + version: 2.0.0(next@16.3.0-preview.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7) browser-image-compression: specifier: ^2.0.2 version: 2.0.2 @@ -99,14 +99,14 @@ importers: specifier: ^12.42.2 version: 12.42.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) next: - specifier: 16.2.10 - version: 16.2.10(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + specifier: 16.3.0-preview.5 + version: 16.3.0-preview.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) next-auth: specifier: 5.0.0-beta.31 - version: 5.0.0-beta.31(next@16.2.10(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7) + version: 5.0.0-beta.31(next@16.3.0-preview.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7) next-intl: - specifier: ^4.13.1 - version: 4.13.1(next@16.2.10(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + specifier: ^4.13.2 + version: 4.13.2(@swc/helpers@0.5.23)(next@16.3.0-preview.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7)(typescript@7.0.2) node-diff3: specifier: ^3.2.1 version: 3.2.1 @@ -118,7 +118,7 @@ importers: version: 5.5.4 prisma: specifier: 7.8.0 - version: 7.8.0(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3) + version: 7.8.0(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@7.0.2) prismarine-nbt: specifier: ^2.8.0 version: 2.8.0 @@ -160,7 +160,7 @@ importers: version: 9.0.0 schematic-renderer: specifier: ^1.6.1 - version: 1.6.1(vite@8.0.16(@types/node@26.1.0)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0)) + version: 1.6.1(@swc/helpers@0.5.23)(vite@8.1.4(@types/node@26.1.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0)) shiki: specifier: ^4.3.1 version: 4.3.1 @@ -197,7 +197,7 @@ importers: version: 4.3.2 '@types/hast': specifier: ^3.0.4 - version: 3.0.4 + version: 3.0.5 '@types/mdast': specifier: ^4.0.4 version: 4.0.4 @@ -206,7 +206,7 @@ importers: version: 3.0.1 '@types/node': specifier: ^26.1.0 - version: 26.1.0 + version: 26.1.1 '@types/papaparse': specifier: ^5.5.2 version: 5.5.2 @@ -215,10 +215,7 @@ importers: version: 19.2.17 '@types/three': specifier: ^0.185.0 - version: 0.185.0 - ajv: - specifier: ^8.20.0 - version: 8.20.0 + version: 0.185.1 gitnexus: specifier: ^1.6.9 version: 1.6.9(graphology-types@0.24.8)(zod@4.4.3) @@ -233,7 +230,7 @@ importers: version: 0.57.0 oxlint: specifier: ^1.72.0 - version: 1.72.0 + version: 1.73.0 pdf-lib: specifier: ^1.17.1 version: 1.17.1 @@ -256,11 +253,11 @@ importers: specifier: ^4.23.0 version: 4.23.0 typescript: - specifier: ^6.0.3 - version: 6.0.3 + specifier: ^7.0.2 + version: 7.0.2 vitest: specifier: ^4.1.10 - version: 4.1.10(@types/node@26.1.0)(vite@8.0.16(@types/node@26.1.0)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0)) + version: 4.1.10(@types/node@26.1.1)(vite@8.1.4(@types/node@26.1.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0)) packages: @@ -294,9 +291,6 @@ packages: '@codemirror/autocomplete@6.20.3': resolution: {integrity: sha512-tlosUqb+3BbxCxZdu4tKeRghPFC+QM7q4X5YhKV2eCmPG+1r2F3f4AaSz5sCrFqUtX4Jh20VFTKecl16MgiV9g==} - '@codemirror/commands@6.10.3': - resolution: {integrity: sha512-JFRiqhKu+bvSkDLI+rUhJwSxQxYb759W5GBezE8Uc8mHLqC9aV/9aTC7yJSqCtB3F00pylrLCwnyS91Ap5ej4Q==} - '@codemirror/commands@6.10.4': resolution: {integrity: sha512-Ryk9y9T0FFVF0cUGhAknveAyUOl/A1qReTFi+qPKtOh2Z9F4AUBz3XOrYD4ZEgZirdugVzHvd/2/Wcwy5OliTg==} @@ -366,8 +360,8 @@ packages: '@codemirror/language-data@6.5.2': resolution: {integrity: sha512-CPkWBKrNS8stYbEU5kwBwTf3JB1kghlbh4FSAwzGW2TEscdeHHH4FGysREW86Mqnj3Qn09s0/6Ea/TutmoTobg==} - '@codemirror/language@6.12.3': - resolution: {integrity: sha512-QwCZW6Tt1siP37Jet9Tb02Zs81TQt6qQrZR2H+eGMcFsL1zMrk2/b9CLC7/9ieP1fjIUMgviLWMmgiHoJrj+ZA==} + '@codemirror/language@6.12.4': + resolution: {integrity: sha512-1q4PaT+o6PbgpkJt4Q8Fv5XJxTy4FUZ4MWETtyiDw3J0Pyr9E2vqcKL+k9wcvjNTIsauxvE7OfmWj3FRPHQ76A==} '@codemirror/legacy-modes@6.5.3': resolution: {integrity: sha512-xCsmIzH78MyWkib9jlPaaun57XNkfbMIhagfaZVd0iLTqlpw3jXaIcbZm72MTmmn64eTZpBVNjbyYh+QXnxRsg==} @@ -378,14 +372,8 @@ packages: '@codemirror/merge@6.12.2': resolution: {integrity: sha512-V8JvyAPjHbPupqP7BeMcsdsYCbyPij74jxIbaIJDORI+VZzW44zFmon8bF+oxGWvOKhcRmkiUMXd8MxHr3YA2w==} - '@codemirror/search@6.7.0': - resolution: {integrity: sha512-ZvGm99wc/s2cITtMT15LFdn8aH/aS+V+DqyGq/N5ZlV5vWtH+nILvC2nw0zX7ByNoHHDZ2IxxdW38O0tc5nVHg==} - - '@codemirror/state@6.6.0': - resolution: {integrity: sha512-4nbvra5R5EtiCzr9BTHiTLc+MLXK2QGiAVYMyi8PkQd3SR+6ixar/Q/01Fa21TBIDOZXgeWV4WppsQolSreAPQ==} - - '@codemirror/state@6.7.0': - resolution: {integrity: sha512-Zbl9NyscLMZkfXPQnNAIIAFftidrA1UbcJEIMp24C0Bukc2I5T8wJS0wsXYsnDOqCFJUeJ1BITGNs5CqPDSmSg==} + '@codemirror/search@6.7.1': + resolution: {integrity: sha512-uMe5UO6PamJtSHrXhhHOzSX3ReWtiJrva6GnPMwSOrZtiExb5X5eExhr2OUZQVvdxPsKpY3Ro2mFbQadpPWmHA==} '@codemirror/state@6.7.1': resolution: {integrity: sha512-9QzNDgE4EYDnAHfrTlR2lwiPciiOymLtwKK+8yHQzCc7GXhAP9xdEbEJFy2IWB1j9UGUl9BsgMmTo/ImA02T7A==} @@ -393,9 +381,6 @@ packages: '@codemirror/theme-one-dark@6.1.3': resolution: {integrity: sha512-NzBdIvEJmx6fjeremiGp3t/okrLPYT0d9orIc7AFun8oZcRk58aejkqhv6spnz4MLAevrKNPMQYXEWMg4s+sKA==} - '@codemirror/view@6.43.5': - resolution: {integrity: sha512-7uT/vUgH6dfXWn3WqOe23KneILMvGy5wQjNMEcRXLKzziJ9NOktpW6tGoyQpwVkBgE5Gj6hKkCcsddbnkaWrOQ==} - '@codemirror/view@6.43.6': resolution: {integrity: sha512-EVunGSYN1wz1p75WY1s3Xg7t3i8Yol0kGZGizNdX9BUFgMFILYVe8/u6EVpo7Ff5PwbZuILb4QAq7IZoKzIEQA==} @@ -420,17 +405,17 @@ packages: '@electric-sql/pglite@0.4.1': resolution: {integrity: sha512-mZ9NzzUSYPOCnxHH1oAHPRzoMFJHY472raDKwXl/+6oPbpdJ7g8LsCN4FSaIIfkiCKHhb3iF/Zqo3NYxaIhU7Q==} - '@emnapi/core@1.10.0': - resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} - - '@emnapi/runtime@1.10.0': - resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + '@emnapi/core@1.11.1': + resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==} '@emnapi/runtime@1.11.1': resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} - '@emnapi/wasi-threads@1.2.1': - resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + '@emnapi/runtime@1.11.2': + resolution: {integrity: sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==} + + '@emnapi/wasi-threads@1.2.2': + resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} '@esbuild/aix-ppc64@0.28.1': resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} @@ -606,26 +591,26 @@ packages: '@formatjs/fast-memoize@2.2.7': resolution: {integrity: sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ==} - '@formatjs/fast-memoize@3.1.6': - resolution: {integrity: sha512-H5aexk1Le7T9TPmscacZ+1pR6CTa2n1wq+HDVGXhH8TzUlQQpeXzZs91dRtmFHrbeNbjPFPfQujUqm7MHgVoXQ==} + '@formatjs/fast-memoize@3.1.7': + resolution: {integrity: sha512-zXfhLpvA6T7+efdt9JLbBwZ00tT7NsBMDVnDu8rpHeNNv8KfRZAMo2gkG0k9lK/Nzc//3kJ9pImsfuJxk3KhUA==} '@formatjs/icu-messageformat-parser@2.11.4': resolution: {integrity: sha512-7kR78cRrPNB4fjGFZg3Rmj5aah8rQj9KPzuLsmcSn4ipLXQvC04keycTI1F7kJYDwIXtT2+7IDEto842CfZBtw==} - '@formatjs/icu-messageformat-parser@3.5.12': - resolution: {integrity: sha512-YyzzxVgYJ8DELmmkhn0Yr0rUj0dTJFf9Jp628K3S0ysInBWxLVDOS8i3RP91cCp4DMK4WYb4cVMhWA9i4knSJg==} + '@formatjs/icu-messageformat-parser@3.5.14': + resolution: {integrity: sha512-jDvgtoLqe3U6yzoBlToMTkWBe38qSi7LN7kFlnXzd5ig8nn+4tSlED0xtEtdYakZVZGJJY2rW1D5xS3BFZh6kA==} '@formatjs/icu-skeleton-parser@1.8.16': resolution: {integrity: sha512-H13E9Xl+PxBd8D5/6TVUluSpxGNvFSlN/b3coUp0e0JpuWXXnQDiavIpY3NnvSp4xhEMoXyyBvVfdFX8jglOHQ==} - '@formatjs/icu-skeleton-parser@2.1.10': - resolution: {integrity: sha512-XuSva+8ZGawk8VnD5VD6UeH8KarQ/Z022zgjHDoHmlNiAewstXuuzXc0Hk5pGFSdG+nNw5bfJKXqj1ZXHn9yUA==} + '@formatjs/icu-skeleton-parser@2.1.11': + resolution: {integrity: sha512-j8cUmOJzVgkHuS0QiQ6ga76UIoLOFSAMWhs7aZJztH3aAdCOAE6vpC8KVvFB4cU10ON0y2/5oOVmPJ43s2lTwA==} '@formatjs/intl-localematcher@0.6.2': resolution: {integrity: sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA==} - '@formatjs/intl-localematcher@0.8.10': - resolution: {integrity: sha512-P/IC3qws3jH+1fEs+o0RIFgXKRaQlFehjS5W0FPAqdo6hgzawLl+eD0q0JjheQ3XtoOe5n8WSYfX06KQZI/QJA==} + '@formatjs/intl-localematcher@0.8.12': + resolution: {integrity: sha512-5H3r5ZJ2jZqHEv9K343lvHmeMDKMxssawAVD2H4J9xtu0ZXb6MlNxwLqdwBxJSHFU0C24KSZnffgmAi+59mK4A==} '@hono/node-server@1.19.11': resolution: {integrity: sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==} @@ -633,6 +618,12 @@ packages: peerDependencies: hono: ^4 + '@hono/node-server@1.19.14': + resolution: {integrity: sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==} + engines: {node: '>=18.14.1'} + peerDependencies: + hono: ^4 + '@huggingface/jinja@0.5.9': resolution: {integrity: sha512-uWTG+l3VJRsl7EXxYizuL3P+cCPoc3cRqbWWRcQN0FhejRfbdq0RNhCmbY/YDtnTcz9icdLYuLDjsnz4d8JMuw==} engines: {node: '>=18'} @@ -853,8 +844,8 @@ packages: '@lezer/cpp@1.1.6': resolution: {integrity: sha512-vh9gWWJOXFVY8HBHK3Twzq8MgwG2iN4GSyzBP9sCGTe37P15x2R14VaBQk0VA0ezTRN1KHYBBsHhvpGZ2Xy/pA==} - '@lezer/css@1.3.3': - resolution: {integrity: sha512-RzBo8r+/6QJeow7aPHIpGVIH59xTcJXp399820gZoMo9noQDRVpJLheIBUicYwKcsbOYoBRoLZlf2720dG/4Tg==} + '@lezer/css@1.3.4': + resolution: {integrity: sha512-N+tn9tej2hPvyKgHEApMOQfHczDJCwxrRFS3SPn9QjYN+uwHvEDnCgKRrb3mxDYxRS8sKMM8fhC3+lc04Abz5Q==} '@lezer/go@1.0.1': resolution: {integrity: sha512-xToRsYxwsgJNHTgNdStpcvmbVuKxTapV0dM0wey1geMMRc9aggoVyKgzYp41D2/vVOx+Ii4hmE206kvxIXBVXQ==} @@ -877,8 +868,8 @@ packages: '@lezer/lr@1.4.10': resolution: {integrity: sha512-rnCpTIBafOx4mRp43xOxDJbFipJm/c0cia/V5TiGlhmMa+wsSdoGmUN3w5Bqrks/09Q/D4tNAmWaT8p6NRi77A==} - '@lezer/markdown@1.6.4': - resolution: {integrity: sha512-N0SxazMj4k65DBfaf1azqtMZd6u7MqluP84/NZnB/io8Td9aleFmAhz9hcbvSfsxT5tdYlJ5qgv5aMJGY4zEtA==} + '@lezer/markdown@1.7.1': + resolution: {integrity: sha512-MEBZeFSBxgteUjEC3Wxg2Dwld5/JxRKG267L3bMFdibm8KjqSdiJYBeFw1Nt1CM8+zKMpSIEHblY8FD9z38sJQ==} '@lezer/php@1.0.5': resolution: {integrity: sha512-W7asp9DhM6q0W6DYNwIkLSKOvxlXRrif+UXBMxzsJUuqmhE7oVU+gS3THO4S/Puh7Xzgm858UNaFi6dxTP8dJA==} @@ -927,57 +918,57 @@ packages: '@next/bundle-analyzer@16.2.10': resolution: {integrity: sha512-KcepWhb3IVniZgm00GSSCQDEUQqZXuXtuXRh8J6e3Un342TcQ77iK4DedeEkct+fcx7yFEDL2J6z4Jeho5JDAw==} - '@next/env@16.2.10': - resolution: {integrity: sha512-zLPxg9M0MEHmygpj5OuxjQ+vHMiy/K7cSp74G8ecYolmgUWw0RwN02tF56npup/+qaI8JB97hQgS/r2Hb6QwVA==} + '@next/env@16.3.0-preview.5': + resolution: {integrity: sha512-XqdVR0utAWMsVc1OIyO48D32vrdmC4/uAgI3Ds088YlOO4vfGKXXVyvkGFkOZkOK0xg7bNYNfJAarX4A0tYqGg==} - '@next/swc-darwin-arm64@16.2.10': - resolution: {integrity: sha512-v9IdJCa0H0mbo+8z5zwUpOk1Vj7RjkcI5uNYf5Ws1y6szf/p3Mzl9hLaST8SCt6L9h8NGnruZcd2+o0NTNwDhA==} + '@next/swc-darwin-arm64@16.3.0-preview.5': + resolution: {integrity: sha512-PPWAJGoIkzVpz5hOD9V/qGNdkBuWj3QXhjQU8BQ1FXlMy6xsy4+aD/3UoasKy/HYInW4h1LqdQtDhiQkLYrrMA==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@16.2.10': - resolution: {integrity: sha512-17IS0jJRViROGmA9uGdNR8VPJpfbnaVG7E9qhso5jDLkmyd0lSDORWxbcKINzcFqzZqGwGtMSnrFRxBpuUYjLQ==} + '@next/swc-darwin-x64@16.3.0-preview.5': + resolution: {integrity: sha512-UPN/RS1H+kr9fgJrbFoH7bs1b9q2/G5cFe+uUf0nP4Hlgfl8NzfTBHEJKTfLAGqi1Qemwuyd29pvRy2vwEjL5g==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-linux-arm64-gnu@16.2.10': - resolution: {integrity: sha512-GRQRsRtuciNJvB54AvvuQTiq0oZtFwa1owQqtZD8wwnGpM2L39MV22kpI72YSXLKIyY40LC66EiLFv4PiicXxg==} + '@next/swc-linux-arm64-gnu@16.3.0-preview.5': + resolution: {integrity: sha512-kh+bKgk9ZIlmxMkEPnQZXtKc7/AyUyIS9jXgbKt4hWyxXEEZVDmXhiU2bh1zZpthMr/l09wz9z6CvfXtCWUJBA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] libc: [glibc] - '@next/swc-linux-arm64-musl@16.2.10': - resolution: {integrity: sha512-zkN9MQYS7UQBro+FnISUq1itaQjXI9xqISzuQ+2bc921NcJ1x4yPCqrn77tVN6/dOOXaaWVX3k6/bR07pPwK+A==} + '@next/swc-linux-arm64-musl@16.3.0-preview.5': + resolution: {integrity: sha512-m09/acXFGhlp+U6m7Wn0AqsmLqars3qI9eBXDpPJm4h/XVS9HPHNzWGy2BI7F1iLoFX59Uy0tcau9ey7JVud3w==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] libc: [musl] - '@next/swc-linux-x64-gnu@16.2.10': - resolution: {integrity: sha512-iCVJnwvrPYECvA6WM/7+oo+OiTvedIKLxtCLAZP4xZR3nXa1zmzZyLPbYCmWvpd4CvMYF1EMTafd0ii3DygLvA==} + '@next/swc-linux-x64-gnu@16.3.0-preview.5': + resolution: {integrity: sha512-/EBiqRjLZJWJo6Keq9upJfhrP+tNpePy1beBfOL+tUn68inwNiJEjx+0Lgve99Zur8kSk9TgSmDmwgQxX4iM+g==} engines: {node: '>= 10'} cpu: [x64] os: [linux] libc: [glibc] - '@next/swc-linux-x64-musl@16.2.10': - resolution: {integrity: sha512-ov2g4H0dHY9bPoOU83m91hWT7Iq5qy13bUnyyshLU3HGR1Ownn0X9QpmDPc5iIUaahTp7f7LeGAhV4DSFtackw==} + '@next/swc-linux-x64-musl@16.3.0-preview.5': + resolution: {integrity: sha512-lUCiPFoecSGkM8aeY6UAgQDiJjR3DhPsI036mznlHFg89ZLoeRdo521N4nmk6EpbPpNzRujgiboBkbuyexDgCg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] libc: [musl] - '@next/swc-win32-arm64-msvc@16.2.10': - resolution: {integrity: sha512-DwAnhLX76HQiFFQNgWlcK+JzlnD1rZ+UK/WY0ZMI/deXpvgnesjNYrqcfo1JzBuz4Kf7o3brIBL0glI1junatA==} + '@next/swc-win32-arm64-msvc@16.3.0-preview.5': + resolution: {integrity: sha512-Nr4e3dRB86gElIgysL/L7dr9tuRLIq3looK8hLxnYDLUvLza2Tu/7Ik/X6DSRGejIrbZsYjnH3S4xYeAAf7Prw==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-x64-msvc@16.2.10': - resolution: {integrity: sha512-0JXq3b85Jk9Jg4ntLUbXSPvoDw3gpZou7twuKdoFG2jOw635v7+IiXfTaa0TxVMyx78pUjnrVYwLgjKfX4e6/A==} + '@next/swc-win32-x64-msvc@16.3.0-preview.5': + resolution: {integrity: sha512-Svg+VCRUbyNsBuh96hN+1ael8dNXqVQVZqOe9tqFlF4mUzIk5CQFcn5VsZPrz8GNP9HCxJfrfy3PM0cXoSXliw==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -1023,8 +1014,8 @@ packages: resolution: {integrity: sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==} engines: {node: '>= 20'} - '@octokit/request@10.0.10': - resolution: {integrity: sha512-KxNC2pTqqhszMNrf12ZRd4PonRgyJdsM4F/jySiddQK+DsRcfBtUvqn8t7UsyZhnRJHvX46OohDt5N3VqIWC2w==} + '@octokit/request@10.0.11': + resolution: {integrity: sha512-+s7HUxjfFqOMS9VlIwDffq0MikjSAK0gSpG73W+meAvVAvX4MBrHYTK5Bj3Uot55qFT4gzUtfzE4mGWY4Br8/Q==} engines: {node: '>= 20'} '@octokit/rest@22.0.1': @@ -1034,8 +1025,8 @@ packages: '@octokit/types@16.0.0': resolution: {integrity: sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==} - '@oxc-project/types@0.133.0': - resolution: {integrity: sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==} + '@oxc-project/types@0.139.0': + resolution: {integrity: sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==} '@oxfmt/binding-android-arm-eabi@0.57.0': resolution: {integrity: sha512-qVBsEO+KugOsCmUHcO8iqNnqc65p7PCKpCs8M66mPZ+Ri+CWbcpoQOEJBg2OTu03+0qu++NK1jj6IzvQVs0Sig==} @@ -1159,124 +1150,124 @@ packages: cpu: [x64] os: [win32] - '@oxlint/binding-android-arm-eabi@1.72.0': - resolution: {integrity: sha512-zhCmvn+1Mj3UchAc/90i99S0t7jJUsHmFVSPg4UWrjO8b8eaSGwscgO6QAUtvHBstkjQwBttQNswEnAF1mIQdA==} + '@oxlint/binding-android-arm-eabi@1.73.0': + resolution: {integrity: sha512-HZQRN/UMBu+Ut+/9MiAChkbP4qZqrNOWBcNI45vOT40GVhbGR0JgHB87L48D4iAqFQIdVmeQYtV9RF89AjTKkg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxlint/binding-android-arm64@1.72.0': - resolution: {integrity: sha512-mtH+aY/ozv1eZoCUC2owjFAtyNBKHpJHygKeEu9zXXnQGW1Q2/qOpvx+I+Lf23+TvTz66F4iiXUbl2cGvoLPCQ==} + '@oxlint/binding-android-arm64@1.73.0': + resolution: {integrity: sha512-Gp+KJRylv2aW7thRpG5p1KTxZq4ZJFbWowrKzufNq9d3ssl3r3JviYV45/+p+7CN1Nv0zDd1e8Ex0b/HUDq4TQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxlint/binding-darwin-arm64@1.72.0': - resolution: {integrity: sha512-EvnajNPDtfknB3ZieeOOyDTwJn9QXDiwfnF4ZDQqART6RG6hjY4WigQcZdGoK2dkB3e1vrmEzN9aYbQCUkh/gQ==} + '@oxlint/binding-darwin-arm64@1.73.0': + resolution: {integrity: sha512-3de96NdtXhxERMjIz7wsp2HYMY6pMQycGxFWac2mFecAx6VeARF/IqFb1QIaqiCRIdfzBwzTed+pCTCoiS+CYA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxlint/binding-darwin-x64@1.72.0': - resolution: {integrity: sha512-ZkCdEa/G80A7vEHfeCDz/+L3m33DE73v32mDKhgOIgz8Uwf0DFcK7+uu6qC+7LEhmz5fpOe1osWKyjSNMydFIQ==} + '@oxlint/binding-darwin-x64@1.73.0': + resolution: {integrity: sha512-5zx/uPW32TiaOeVY1dQ/H5iOf0K1HOdFKOJhLqGl4o63+i1fpzoqqu/mKtd7OFgFjNCdhlyTGgjVkQTZm1ELcg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxlint/binding-freebsd-x64@1.72.0': - resolution: {integrity: sha512-NroXv2vh+sxVY1uya/rM5pjhx1hm8BzlYpx9q67QP0Xhw5MH2bf5GJylpvLEC+781p1Xli/317EoV9AlGwViag==} + '@oxlint/binding-freebsd-x64@1.73.0': + resolution: {integrity: sha512-qNe4gKHaGnLuZJ8toUg90JAa0S2vTVvDw+0bRi3q1avXZXDT4u5mMeECf3nD4HYrbdn1O7dXqWut4onY/yx/Xg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxlint/binding-linux-arm-gnueabihf@1.72.0': - resolution: {integrity: sha512-0NDywYgfj279Ou/BcQuCYSj7NJwBfmWn5qc5uGO/Ny7fUWmXyIpvawqX/8acQlWG6IXelJsJhj+JAy6sjsKj0A==} + '@oxlint/binding-linux-arm-gnueabihf@1.73.0': + resolution: {integrity: sha512-cCehYh5hTbfShm/fxTD6wwrGUWIpvX+N5OxmAMhFhDeTGXvw+BeNj889tpxsFQ9ZLatQ6wImuY8tsKLZ+FMz7w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxlint/binding-linux-arm-musleabihf@1.72.0': - resolution: {integrity: sha512-4vpXB06h65Ezsy4hRyrGjGrfa1SkVPii09yaajiYhmVpgsFiLD+KNxIx/BNAY+XiO+i1yqp9HHdwqM8VTqa5XQ==} + '@oxlint/binding-linux-arm-musleabihf@1.73.0': + resolution: {integrity: sha512-d5j5GDU/2dMgjVhw7TQT9ITrsIr1Y02KEXKyVGIXUkD+KiaxE9TP65FS2ZdgTBemQvoRL+gSBdbrIm3cQIeacg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxlint/binding-linux-arm64-gnu@1.72.0': - resolution: {integrity: sha512-immaN4g2ZGFiOkKrvRX9LvzZdd2GkQM5wR+UyzYyUuyhUTXGQ4HKUJH18xp4G8OfhCVaVAJfKZxwE1r8+4hhaQ==} + '@oxlint/binding-linux-arm64-gnu@1.73.0': + resolution: {integrity: sha512-Eyf1SrP3+yR1DI3OJgOY2Pvrr9dWP9TK37xPaDYycwTtlGlI45erJAVIfH5/m/xosDt6BupJYEFi47bvbTuuyw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-arm64-musl@1.72.0': - resolution: {integrity: sha512-JGHS9Mnr7iWyyLDxgCv1MhzVpAckgptg00F2gnxt/GD7lQ2SW1BRcxHqhSTaSdDpjWRrBkBxMMh4+Hn3aVtExg==} + '@oxlint/binding-linux-arm64-musl@1.73.0': + resolution: {integrity: sha512-IlT/OJApEDKaMmCooHuncgJZbbCe7T5QIWmTZBEtYscWvzPQuuEinVcid6kwQRVQOUdb7PUCz4jQHnaYXdfJXw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@oxlint/binding-linux-ppc64-gnu@1.72.0': - resolution: {integrity: sha512-AOYgBZqxNshrg83P9v0RYv+m8s10Cqkj4/PxXFDhcS3k7FqsIG5+CxErshZCIN7G8iy4Y+VGfAsuEdar8AcbBg==} + '@oxlint/binding-linux-ppc64-gnu@1.73.0': + resolution: {integrity: sha512-L+JYcb/vdg5fmcH08V6o0YYLU28cTH1SPNulwJdvK9NK49aXSkYy6oNpKBmddArVOXYqNepriDGiZ04G54kh1Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-riscv64-gnu@1.72.0': - resolution: {integrity: sha512-QMybPS5ij3/vrKG67mqzHwW++91sYxK/PPUVi6SBtNCEzW4niS52fVBdXbQ6nou0wWbUPEpx8Sl/ZjtgE3clXA==} + '@oxlint/binding-linux-riscv64-gnu@1.73.0': + resolution: {integrity: sha512-Qtk0g3bKV6OwWjIm7R8kQN1uOZRKQt/MODK2a8QfkwhTpXBD53ozx5XLVWLGDQAVyp2otLW4D2wB98XfAfMPGA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-riscv64-musl@1.72.0': - resolution: {integrity: sha512-gOc3W7JV0PXRpIL7stUlLe3Wa9Gp0Kdlup87IT3gHDvPKck2xNgMIl/Gs2lldYY2lyXZDC4rWi3hmoLUobkgbQ==} + '@oxlint/binding-linux-riscv64-musl@1.73.0': + resolution: {integrity: sha512-wX0NQKZVxltkAOVmzFcpOaMpdaUvsq1Eqpx9tkAfl71UdkTlSo1R4AdAnGccR1Fm2+TzFgZ22CyyGuZ41RDr/A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [musl] - '@oxlint/binding-linux-s390x-gnu@1.72.0': - resolution: {integrity: sha512-rpGxph+FjjHcYI5q6uxB3Az+tnfmEnDbSA8+PK9ZE/VzyUAkvBOMeuY7ZQMhu5mpZH7YQDsTdW6Cx4kV/msc6w==} + '@oxlint/binding-linux-s390x-gnu@1.73.0': + resolution: {integrity: sha512-vPe7UGBMWyiLTtnqS4xxgMQFSFGmtQwhwCxuiw6lXygaO6bVt0D8dFVg8Xv05eaiN3ybC0HXXHUAohFMFvqoCQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@oxlint/binding-linux-x64-gnu@1.72.0': - resolution: {integrity: sha512-WND+uhf/Ko13SLqQMWQUgsZuLvYYEvL0ZKgg0tgGYfLqxG7l8Ju123fHDMJyYSDl5E3bUbpFUuii/OvMreFQzw==} + '@oxlint/binding-linux-x64-gnu@1.73.0': + resolution: {integrity: sha512-2CwIWr9cemFC/CbRBWZvuk5mffz6ObmfFkfcC/9rTQ7f+icNhYr2kOjf9Rt8lLvugvkdGDOmkoVoFFHh6ClCTw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-x64-musl@1.72.0': - resolution: {integrity: sha512-SrpbrUL70nG9vh6zP4/oKHWgLuHquwsr7MW9XOn0olBVgh10Uqr8qscKhQoBGEn6olK/IUpn5GSKcdQ5AjUhGA==} + '@oxlint/binding-linux-x64-musl@1.73.0': + resolution: {integrity: sha512-nDadfJgg7NBBxG0N560wOe7LLX5QiYp6qBaI7viuk5EUORFBktU/NfV0MbTqU3gTqQDCh4VyxKdo5VADxk9w8Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@oxlint/binding-openharmony-arm64@1.72.0': - resolution: {integrity: sha512-qkrsEn6NmgFKr7U/QnezQMb+q/vzAy0Dd9Y95gQGQTyjzDLN+HRZMuM5u70iyH4nBLCfKBzhjMsYCehKay2jyg==} + '@oxlint/binding-openharmony-arm64@1.73.0': + resolution: {integrity: sha512-wGjJC+NLH9xP+IKGn9RDW94ojJR/wPbg5WCnQjj/oReaOtCQthr8ws1zICe77JFmo4ouUdeTHHZL/ESGiF6Pmw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxlint/binding-win32-arm64-msvc@1.72.0': - resolution: {integrity: sha512-LWR6ZlFZph+KPjXv8opgZsXRDCdrdQe8VL8Cg9zxCoBS73h6znzZpydVgmdnwj8mB9AuSM5jxEgDJDpQkjboeg==} + '@oxlint/binding-win32-arm64-msvc@1.73.0': + resolution: {integrity: sha512-I7X47GPGljw225YUQ5SbC/rb1Kkdrd0yQf0x+hYxeKS6DpfjMbo9ccQPQ6LNY6BoJQ1sHhgDUGuMn5Vg5gHT6w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxlint/binding-win32-ia32-msvc@1.72.0': - resolution: {integrity: sha512-yt6HEh7IsHvtjRWtmeZRX134eaXKHq5Gnqlf1xBJdJl1JtdoRUEJw3nAxpZoUDS860cX/foKbztO441anVBtVQ==} + '@oxlint/binding-win32-ia32-msvc@1.73.0': + resolution: {integrity: sha512-5lWj+3h+74Fm1jYOO9qkJA4xkAlZA099DkXppuXsk7UpnpZLttsefrZU469vChGaG6hcSqrkKXQOvMTZtbjeNg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxlint/binding-win32-x64-msvc@1.72.0': - resolution: {integrity: sha512-b2eKFD2hX7tIwmo/cyH6TDq8vzWRZ2qNHrzoGntUTmq0h3zQh/uX3eTSHCwI8OB/ADQfJCRelLItK8BsxuucDA==} + '@oxlint/binding-win32-x64-msvc@1.73.0': + resolution: {integrity: sha512-WaNRvh4f6zY9CvUQk2YoA1O90ieWrIklI84+HXFr9Isjz9CSESrdqo/RtIYt4Dll/cAchqGDMehfaZd0vqEFZw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -1556,97 +1547,97 @@ packages: '@types/react': optional: true - '@rolldown/binding-android-arm64@1.0.3': - resolution: {integrity: sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==} + '@rolldown/binding-android-arm64@1.1.5': + resolution: {integrity: sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.3': - resolution: {integrity: sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==} + '@rolldown/binding-darwin-arm64@1.1.5': + resolution: {integrity: sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.3': - resolution: {integrity: sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==} + '@rolldown/binding-darwin-x64@1.1.5': + resolution: {integrity: sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.3': - resolution: {integrity: sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==} + '@rolldown/binding-freebsd-x64@1.1.5': + resolution: {integrity: sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.3': - resolution: {integrity: sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==} + '@rolldown/binding-linux-arm-gnueabihf@1.1.5': + resolution: {integrity: sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.3': - resolution: {integrity: sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==} + '@rolldown/binding-linux-arm64-gnu@1.1.5': + resolution: {integrity: sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.0.3': - resolution: {integrity: sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==} + '@rolldown/binding-linux-arm64-musl@1.1.5': + resolution: {integrity: sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.0.3': - resolution: {integrity: sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==} + '@rolldown/binding-linux-ppc64-gnu@1.1.5': + resolution: {integrity: sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.0.3': - resolution: {integrity: sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==} + '@rolldown/binding-linux-s390x-gnu@1.1.5': + resolution: {integrity: sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.0.3': - resolution: {integrity: sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==} + '@rolldown/binding-linux-x64-gnu@1.1.5': + resolution: {integrity: sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.0.3': - resolution: {integrity: sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==} + '@rolldown/binding-linux-x64-musl@1.1.5': + resolution: {integrity: sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.0.3': - resolution: {integrity: sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==} + '@rolldown/binding-openharmony-arm64@1.1.5': + resolution: {integrity: sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.3': - resolution: {integrity: sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==} + '@rolldown/binding-wasm32-wasi@1.1.5': + resolution: {integrity: sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.3': - resolution: {integrity: sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==} + '@rolldown/binding-win32-arm64-msvc@1.1.5': + resolution: {integrity: sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.3': - resolution: {integrity: sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==} + '@rolldown/binding-win32-x64-msvc@1.1.5': + resolution: {integrity: sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -1727,31 +1718,31 @@ packages: '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - '@supabase/auth-js@2.110.0': - resolution: {integrity: sha512-Mi288WCTp6wxMFCOu/UgzgHEXODjdl2uVTLqK11eanzGZaldU3RyP8Am+ZbNuVzFP+5+iOvppxzv7N5Ym84xTg==} + '@supabase/auth-js@2.110.2': + resolution: {integrity: sha512-Qj7a6EDP+AMMQFWqGv+qFa8r6re//dk+qQI5bA0KK+PZmnI3JPu97TDeNt6SMiQ2FkklP79hP2yDFYSnA989OA==} engines: {node: '>=22.0.0'} - '@supabase/functions-js@2.110.0': - resolution: {integrity: sha512-Fde5wlY8ZZy+9yqrWlQHo8MacSyUBArBEtN2boB4thJQigPnQD/cc61qZN0n3I1L0gwhWtHYwIMnOBKxSvF6Hw==} + '@supabase/functions-js@2.110.2': + resolution: {integrity: sha512-ZjjqrXpxM9/rE+eAtZxiK45EWy9EBoJQ322Q5Y75LccYQNh212neHTgXP/o4MIzmH0LNXT8UzvTZtQOfOzyoeQ==} engines: {node: '>=22.0.0'} '@supabase/phoenix@0.4.4': resolution: {integrity: sha512-Gt0pqoXuIqX/8dvG0OKp/wMCobXNH3klNbUPBNyOfN0YA1IswrM3HyWFMOPk1Jy+BRaIyDPcFx4jLBwHNmlyfQ==} - '@supabase/postgrest-js@2.110.0': - resolution: {integrity: sha512-ZbC1QZL3jcvBUfVKjJbgRM27G4Mg3Zzqdm44m5pJafe1e52Cli793EOnwQucomBAGEUDd03Nzaf7XV3ji/XexQ==} + '@supabase/postgrest-js@2.110.2': + resolution: {integrity: sha512-++LBmcIMwCtgO4tISQUmo9+2xkRwHQqS8ZKMCnhXLe9P8k8YQRXuMoh/RiSzQSoev8gqet0W7yOboW0cUxnt0Q==} engines: {node: '>=22.0.0'} - '@supabase/realtime-js@2.110.0': - resolution: {integrity: sha512-Wn2AWpneZuDFTkp/65tqctvoh+3JvyTjMam8sTMqVWy5BgkU8zAvFwilPYPPPhkINeKF8NAJKP7FclJ2iGCUMw==} + '@supabase/realtime-js@2.110.2': + resolution: {integrity: sha512-z3jTOTPgyn6E3r6dVOOQ10He4yAMB2czjFw7xVdX3s16MHElna5rY1gVaePs0NIo6xvtMYbtmOXlFaFt/ePLpg==} engines: {node: '>=22.0.0'} - '@supabase/storage-js@2.110.0': - resolution: {integrity: sha512-71+gU3HrhiylAhftY6FmO5PPdcsScnVcS766CVD+vTYK9qTDLbrx8FhgBYbqGm3iV/wkTfzrNJfjGsMeFRkJRQ==} + '@supabase/storage-js@2.110.2': + resolution: {integrity: sha512-EhsRSwSnmQefKJsAxoRUZ0hvHr92ECM8DDGAKR5z0HdoJx4heI60PjHUTruVNZxKX6XeobLGDyLud020Bw1iwg==} engines: {node: '>=22.0.0'} - '@supabase/supabase-js@2.110.0': - resolution: {integrity: sha512-8yI84VJiEVW4zxZpLUmxXmjzQ7O2St9X/ymzlBETDHTURPWG3LmvbSiibq+7dqAJmyoUfxZnSfXeM4HCM8s4XQ==} + '@supabase/supabase-js@2.110.2': + resolution: {integrity: sha512-r9q9w4ZQ6mOjh36aqUNFSisBF611vzpO8JphBESr2Q1SWvmGFQeI7Jq7Y+PaNMZ6Zszz+S2yTlJStCpnaMSnQg==} engines: {node: '>=22.0.0'} '@swc/core-darwin-arm64@1.15.43': @@ -1847,11 +1838,14 @@ packages: '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + '@swc/helpers@0.5.23': + resolution: {integrity: sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==} + '@swc/types@0.1.27': resolution: {integrity: sha512-K6h3iUlqeM946U4sXFYeahefR1YBbXJvko+hv8WS8/0BNJ4OHiHRywMnQUJCqkR7Y9+hqQ1TvEpiKqUhz7NEFg==} - '@swc/wasm@1.15.41': - resolution: {integrity: sha512-wFocmIRY5pSvqxzvJbsKiHyP6oNrSPqBbicF1TV3n0E1ZekSQm/hG9cbRYwxd2pVGL4Nmg8JNpIeLSwRS97Gdg==} + '@swc/wasm@1.15.43': + resolution: {integrity: sha512-jYqeckrzZGAU+9OSfmL15MWfhkKWRCC8QMssL/MZu/MaIP76mU3VHjzqxlwKIz9DOSR/9jCqi1+QlWE0ILNehA==} '@tailwindcss/node@4.3.2': resolution: {integrity: sha512-yWP/sqEcBLaD8JuA6zNwxoYKr75qxTioYwlRwekj5Jr/I5GXnoJfjetH/psLUIv74cYTH2lBUEzBkinthoYcBg==} @@ -1984,8 +1978,8 @@ packages: '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} - '@types/hast@3.0.4': - resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + '@types/hast@3.0.5': + resolution: {integrity: sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==} '@types/js-yaml@4.0.9': resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} @@ -2002,11 +1996,11 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/node@24.13.2': - resolution: {integrity: sha512-fRa09kZTgu8o71KFcDjUFuc7F+dEbZYZmkI0mg5YBTRs0yMKjYHsq/c0urDKeDb+D5qVgXOdFcuu+DZPKOITwA==} + '@types/node@24.13.3': + resolution: {integrity: sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==} - '@types/node@26.1.0': - resolution: {integrity: sha512-O0A1G3xPGy4w7AgQdAQYUlQ+BKk2Oovw8eRpofyp5KdBZULnbe+WqaOVNrm705SHphCiG4XHsACrSmPu1f+Kgw==} + '@types/node@26.1.1': + resolution: {integrity: sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==} '@types/papaparse@5.5.2': resolution: {integrity: sha512-gFnFp/JMzLHCwRf7tQHrNnfhN4eYBVYYI897CGX4MY1tzY9l2aLkVyx2IlKZ/SAqDbB3I1AOZW5gTMGGsqWliA==} @@ -2020,8 +2014,8 @@ packages: '@types/stats.js@0.17.4': resolution: {integrity: sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==} - '@types/three@0.185.0': - resolution: {integrity: sha512-O2Uy8Cj4Nonr8dWUUbifMdPe8B0Mq7EdOHb89S4+kjUw/KhbjTZrUuYlrQ1bpUKG+EP9QJnN7qNxbHGlGoLHMA==} + '@types/three@0.185.1': + resolution: {integrity: sha512-db1xTb+EgYF2didW+eudSvVPtn75zo+fGsY8ShQrJY/B5ZBmC2Fiaykv3aImHAlCNEGuMPkPGXBJGLwzu5mC7A==} '@types/ungap__structured-clone@1.2.0': resolution: {integrity: sha512-ZoaihZNLeZSxESbk9PUAPZOlSpcKx81I1+4emtULDVmBLkYutTcMlCj2K9VNlf9EWODxdO6gkAqEaLorXwZQVA==} @@ -2038,8 +2032,128 @@ packages: '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - '@uiw/codemirror-extensions-basic-setup@4.25.10': - resolution: {integrity: sha512-P3vytLlpE62KYSWrMUnwDCv2lvaQDuDZzyj03mHntuHo5bSl34fRZpjTY3kQTPGuXHxkGSYpoPFFj+hMTqaaMQ==} + '@typescript/typescript-aix-ppc64@7.0.2': + resolution: {integrity: sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [aix] + + '@typescript/typescript-darwin-arm64@7.0.2': + resolution: {integrity: sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [darwin] + + '@typescript/typescript-darwin-x64@7.0.2': + resolution: {integrity: sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [darwin] + + '@typescript/typescript-freebsd-arm64@7.0.2': + resolution: {integrity: sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [freebsd] + + '@typescript/typescript-freebsd-x64@7.0.2': + resolution: {integrity: sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [freebsd] + + '@typescript/typescript-linux-arm64@7.0.2': + resolution: {integrity: sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [linux] + + '@typescript/typescript-linux-arm@7.0.2': + resolution: {integrity: sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==} + engines: {node: '>=16.20.0'} + cpu: [arm] + os: [linux] + + '@typescript/typescript-linux-loong64@7.0.2': + resolution: {integrity: sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==} + engines: {node: '>=16.20.0'} + cpu: [loong64] + os: [linux] + + '@typescript/typescript-linux-mips64el@7.0.2': + resolution: {integrity: sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==} + engines: {node: '>=16.20.0'} + cpu: [mips64el] + os: [linux] + + '@typescript/typescript-linux-ppc64@7.0.2': + resolution: {integrity: sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [linux] + + '@typescript/typescript-linux-riscv64@7.0.2': + resolution: {integrity: sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==} + engines: {node: '>=16.20.0'} + cpu: [riscv64] + os: [linux] + + '@typescript/typescript-linux-s390x@7.0.2': + resolution: {integrity: sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==} + engines: {node: '>=16.20.0'} + cpu: [s390x] + os: [linux] + + '@typescript/typescript-linux-x64@7.0.2': + resolution: {integrity: sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [linux] + + '@typescript/typescript-netbsd-arm64@7.0.2': + resolution: {integrity: sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [netbsd] + + '@typescript/typescript-netbsd-x64@7.0.2': + resolution: {integrity: sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [netbsd] + + '@typescript/typescript-openbsd-arm64@7.0.2': + resolution: {integrity: sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [openbsd] + + '@typescript/typescript-openbsd-x64@7.0.2': + resolution: {integrity: sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [openbsd] + + '@typescript/typescript-sunos-x64@7.0.2': + resolution: {integrity: sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [sunos] + + '@typescript/typescript-win32-arm64@7.0.2': + resolution: {integrity: sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [win32] + + '@typescript/typescript-win32-x64@7.0.2': + resolution: {integrity: sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [win32] + + '@uiw/codemirror-extensions-basic-setup@4.25.11': + resolution: {integrity: sha512-otyFa+n9IOYtEjaKOxPedHkj15fTPUF21wdR9pv0GpZPfuGl27cvmcv6+tognbRu9VvEcsHKE+ESoszeo3KfTw==} peerDependencies: '@codemirror/autocomplete': '>=6.0.0' '@codemirror/commands': '>=6.0.0' @@ -2049,8 +2163,8 @@ packages: '@codemirror/state': '>=6.0.0' '@codemirror/view': '>=6.0.0' - '@uiw/react-codemirror@4.25.10': - resolution: {integrity: sha512-DzgSMwM5qzB7v1FIb4gEeriYt67iiay756/HIOM9mAbeOVK0MO7rqefHf0O5c0269pJKMW7AH9FjclExD23V9w==} + '@uiw/react-codemirror@4.25.11': + resolution: {integrity: sha512-DYVFAKLX+F/4JS9N/7xexh+TICrlncwkX9HKKInrP1bwO0tSfc3k0GB6oawTYhelVKh20cX3TuRx+NJSkVXuMw==} peerDependencies: '@babel/runtime': '>=7.11.0' '@codemirror/state': '>=6.0.0' @@ -2060,8 +2174,8 @@ packages: react: '>=17.0.0' react-dom: '>=17.0.0' - '@ungap/structured-clone@1.3.1': - resolution: {integrity: sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==} + '@ungap/structured-clone@1.3.2': + resolution: {integrity: sha512-5jsZFwgR5rTdKwidH9Qmat75RKwqfpKlWWB1frDkljN127mwqBu8K0PYo7/hFpF03IEJpfVPpCQDY/eDx3iHvA==} '@vercel/analytics@2.0.1': resolution: {integrity: sha512-MTQG6V9qQrt1tsDeF+2Uoo5aPjqbVPys1xvnIftXSJYG2SrwXRHnqEvVoYID7BTruDz4lCd2Z7rM1BdkUehk2g==} @@ -2092,8 +2206,8 @@ packages: vue-router: optional: true - '@vercel/blob@2.5.0': - resolution: {integrity: sha512-ke6WnMMYlUu9nBFmyjwEkC2o03Ku2X7QIeJ3KtlOJzblS/8Xau209zt0ic76rd7IvV5nrKCH/BzP4MkFmoSLuw==} + '@vercel/blob@2.6.1': + resolution: {integrity: sha512-KTJytw85j1XQBxjN5d6UXI7fIWNQe1jotn4nWN+0hePqLs+Qi1B3jHdQcSKFGF0m2rsy9uhPT6GOXMtHe3qNzg==} engines: {node: '>=20.0.0'} '@vercel/cli-config@0.2.0': @@ -2103,8 +2217,8 @@ packages: resolution: {integrity: sha512-kQF8LGie/Hbdq9/psJxLE7owRTcqMQMhgybU04gCeR7cbQAr5t8OrjefDNColJv1QSSucFt4pLwRiARVmlOnug==} engines: {node: '>= 18'} - '@vercel/oidc@3.7.1': - resolution: {integrity: sha512-RrSsVWbq3KLK5lJobyTPp3tSthNfUp+zWkXno5Wkko0oEW05rA4ngOrnVypP4+L8/Av89uPo2rWFmzL8iwnsmA==} + '@vercel/oidc@3.8.0': + resolution: {integrity: sha512-r00laGW6Pv778RoR6M2NxX91ycSj+PBwVo+fOb9Bif+F0IyUKt25zrvBzfEzQpeAzbqOgPZyQibEWDdDFApd+A==} engines: {node: '>= 20'} '@vercel/speed-insights@2.0.0': @@ -2285,8 +2399,8 @@ packages: resolution: {integrity: sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==} engines: {node: '>= 6.0.0'} - axe-core@4.12.0: - resolution: {integrity: sha512-FTavr/7Ba0IptwGOPxnQvdyW2tAsdLBMTBXz7rKH6xJ2skpyxpBxyHkDdBs4lf69yRqYpkqCdfhnwS8YULGOmg==} + axe-core@4.12.1: + resolution: {integrity: sha512-s7iGf5GaVMxEG0ENN9x+xTr7GFZCb1ZP/1uATUpCEK2X78nDB3RwbtFCo9pGAf9ru+VwoQ464DkaLEeRM08wJA==} engines: {node: '>=4'} b4a@1.8.1: @@ -2315,8 +2429,8 @@ packages: bare-abort-controller: optional: true - bare-fs@4.7.2: - resolution: {integrity: sha512-aTvMFUWkBmjzKtEQMDGGDNF8bkfpD5N1b/FCwt7A3wrU4t1o/e/85Wzkluh6JlODCjqVESYCkQCdTXqZ9G7VFg==} + bare-fs@4.7.4: + resolution: {integrity: sha512-y1kC+ffIx/tPLdTE693uNjHfzTfr+ravR5tvWlMXe25nELbkqV400S71qHDwbkAQ1FVEZobB1NFRzFbCCcyBCQ==} engines: {bare: '>=1.16.0'} peerDependencies: bare-buffer: '*' @@ -2324,15 +2438,11 @@ packages: bare-buffer: optional: true - bare-os@3.9.1: - resolution: {integrity: sha512-6M5XjcnsygQNPMCMPXSK379xrJFiZ/AEMNBmFEmQW8d/789VQATvriyi5r0HYTL9TkQ26rn3kgdTG3aisbrXkQ==} - engines: {bare: '>=1.14.0'} + bare-path@3.1.1: + resolution: {integrity: sha512-JprUlveX3QjApC1cTpsUOiscADftCGVWkzitbHsRqv84hzYwYHw2mbluddsq5TvI8mH/8Ov1f4BiMAdcB0oYnQ==} - bare-path@3.0.1: - resolution: {integrity: sha512-ghj2DSK/2e99a1anTVPCV4m4YIYtrbXhfM7V3D7XZLOTsybnYyaJloymGqssQc8l/or0UoDyRtNQkmkEF/ysgQ==} - - bare-stream@2.13.1: - resolution: {integrity: sha512-Vp0cnjYyrEC4whYTymQ+YZi6pBpfiICZO3cfRG8sy67ZNWe951urv1x4eW1BKNngw3U+3fPYb5JQvHbCtxH7Ow==} + bare-stream@2.13.3: + resolution: {integrity: sha512-Kc+brLqvEqGkjyfiwJmImAOqLZL7OsoLKuavx+hJjgVV3nLTOjloJyPMFxjUPerGGHrNH0fLU06jjykMLWrERQ==} peerDependencies: bare-abort-controller: '*' bare-buffer: '*' @@ -2351,8 +2461,8 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.10.40: - resolution: {integrity: sha512-BSSLZ9/Cjjv7Gtj5B68ZzXcXUg8iOf3fme+FCuh8rC/Go+Kmh8cox7M3A8dolou16s64QjLPOSdngh7GxXvkSw==} + baseline-browser-mapping@2.10.42: + resolution: {integrity: sha512-c/jurFrDLyui7o1J86yLkRu4LMsTYcBohveus7/I2Hzdn9KIP2bdJPTue/lR1KH46enoPbD77GKeSYNdyPoD3Q==} engines: {node: '>=6.0.0'} hasBin: true @@ -2370,8 +2480,8 @@ packages: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} - body-parser@1.20.5: - resolution: {integrity: sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA==} + body-parser@1.20.6: + resolution: {integrity: sha512-p5tAzS57i5MV9fZFDj9LeIiTZEufbSe2eDozP+ElheSUq1m74CRq1jI4mYNDdVs9vQztXFLuk/Gd6BWTdwRJ5g==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} body-parser@2.3.0: @@ -2382,8 +2492,8 @@ packages: resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - brace-expansion@1.1.15: - resolution: {integrity: sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==} + brace-expansion@1.1.16: + resolution: {integrity: sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==} brace-expansion@5.0.7: resolution: {integrity: sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==} @@ -2430,8 +2540,8 @@ packages: resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} engines: {node: '>=6'} - caniuse-lite@1.0.30001800: - resolution: {integrity: sha512-MMHtuAz9Ys840zAY5F4k6fV5GaivZ9sPk+nz0mY+GYVzRBnYkN0mpqkSR92oWRQ19yQWo4HvBV/FnC16AJX8MA==} + caniuse-lite@1.0.30001803: + resolution: {integrity: sha512-g/uHREV2ZpK9qMalCsWaxmA6ol+DX8GYhuf3T40RKoP+oL7vhRJh8LNt73PCjpnR6l14FzfPrB5Yux4PKm2meg==} ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -2954,8 +3064,8 @@ packages: resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} engines: {node: '>= 18'} - exsolve@1.0.8: - resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} + exsolve@1.1.0: + resolution: {integrity: sha512-D+42+T12DdIlJM3uepa55qGiL3sYdLBOxIl2ifQCzCHz4c7eiolaHsi3BIqEr7JxBzxv2pYZQX9kw16ziMcEmw==} extend-shallow@2.0.1: resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} @@ -2977,8 +3087,8 @@ packages: resolution: {integrity: sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==} engines: {node: '>=8.0.0'} - fast-copy@4.0.3: - resolution: {integrity: sha512-58apWr0GUiDFM8+3afrO6eYwJBn9ZAhDOzG3L+/9llab/haCARS2UIfffmOurYLwbgDRs8n0rfr6qAAPEAuAQw==} + fast-copy@4.0.4: + resolution: {integrity: sha512-eVAiWVNPSEGIzDl5yPuLrx8fNMogScXvD9xp1Kzd41FjRIz2I3sSIcxsFeM5EzFfHAfobdvs8ZySffUopljvIA==} fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -2992,8 +3102,8 @@ packages: fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - fast-uri@3.1.2: - resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==} + fast-uri@3.1.3: + resolution: {integrity: sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==} fd-slicer@1.1.0: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} @@ -3081,8 +3191,8 @@ packages: resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} engines: {node: '>= 0.8'} - fs-extra@11.3.5: - resolution: {integrity: sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg==} + fs-extra@11.3.6: + resolution: {integrity: sha512-w8ZNZr2mKIc7qeNaQ9AVPT1+iFaI+Avd4xudVOvdDJ8VytREi1Ft5Ih7hd9jjehod8vAM5GMsfQ/TpPf4EyoEA==} engines: {node: '>=14.14'} fs.realpath@1.0.0: @@ -3138,8 +3248,8 @@ packages: gif.js.optimized@1.0.1: resolution: {integrity: sha512-IS0F42Xken6lp/iR4irgG4r52tvxRkEKsXGZmlUHUOb00SWNMezJOJwkVaJk2MLW53rqzMbPnnBtEhs9hcMJ9w==} - giget@3.2.0: - resolution: {integrity: sha512-GvHTWcykIR/fP8cj8dMpuMMkvaeJfPvYnhq0oW+chSeIr+ldX21ifU2Ms6KBoyKZQZmVaUAAhQ2EZ68KJF8a7A==} + giget@3.3.0: + resolution: {integrity: sha512-gzi2D96p+AMfDcmJHGDj3KJ9NRiwvlFAU5yfa3ROwWZmFUjX4P43x3BcyRaOMMLto1vUo7C+86+MFhYTl6Ryiw==} hasBin: true github-slugger@2.0.0: @@ -3288,8 +3398,8 @@ packages: help-me@5.0.0: resolution: {integrity: sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==} - hono@4.12.25: - resolution: {integrity: sha512-2NFaIyNVgJmBs/ecmtGzlmluTFs5cHEWGTdu0t1HBwYzoGXOL5nUQBRMXsXWla5i4KkG//QMzVP88m1+I3fdAQ==} + hono@4.12.28: + resolution: {integrity: sha512-YwUvVpSF7m1yOblFPrU3Hbo8XhPheBoiyfGuII6z19LnOr6JpDnyyp7LFNrfV56wS8tpvtBFGRISHN02pDdLOA==} engines: {node: '>=16.9.0'} html-escaper@2.0.2: @@ -3344,12 +3454,12 @@ packages: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} - iconv-lite@0.7.2: - resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + iconv-lite@0.7.3: + resolution: {integrity: sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==} engines: {node: '>=0.10.0'} - icu-minify@4.13.1: - resolution: {integrity: sha512-nFYW2im0WJ3RUVZwabd71J8QTZRtkK1xxZBY7klg7a6KS/os17LZSj9q1VhbRSnk3S8Mv2I7F1izr/aEJ6cUsw==} + icu-minify@4.13.2: + resolution: {integrity: sha512-XhYQTEnBXBCyF6ERiwItFweoOXDUciujaGjIWCA7RhOCEPDfhVSTtuwfRq6HdVk7tKnYJh+yaurP96zGnaKsPg==} ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -3388,8 +3498,8 @@ packages: intl-messageformat@10.7.18: resolution: {integrity: sha512-m3Ofv/X/tV8Y3tHXLohcuVuhWKo7BBq62cqY15etqmLxg2DZ34AGGgQDeR+SCta2+zICb1NX83af0GJmbQ1++g==} - intl-messageformat@11.2.9: - resolution: {integrity: sha512-cGzymZerpDhVXRKjKLgXKda9gI29TU2o88L7gwNMHp3WZVxA/0c5tX52udXbW9JklDApolvMXZG6Dhhdz5eirA==} + intl-messageformat@11.2.11: + resolution: {integrity: sha512-aDG5bvFRbQvRoT2Bh9FV6yV8t7o0MjEGknZ6pnin5Wt52PJwaBOHDfvz+oPEe78Pl3InQYKugBgCdXijLj6viQ==} ip-address@10.2.0: resolution: {integrity: sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==} @@ -3711,8 +3821,8 @@ packages: lookup-closest-locale@6.2.0: resolution: {integrity: sha512-/c2kL+Vnp1jnV6K6RpDTHK3dgg0Tu2VVp+elEiJpjfS1UyY7AjOYHohRug6wT0OpoX2qFgNORndE9RqesfVxWQ==} - lru-cache@11.5.1: - resolution: {integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==} + lru-cache@11.5.2: + resolution: {integrity: sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==} engines: {node: 20 || >=22} lru-cache@7.18.3: @@ -4021,8 +4131,8 @@ packages: resolution: {integrity: sha512-FBrGau0IXmuqg4haEZRBfHNWB5mUARw6hNwPDXXGg0XzVJ50mr/9hb267lvpVMnhZ1FON3qNd4Xfcez1rbFwSg==} engines: {node: '>= 8.0'} - n8ao@1.10.2: - resolution: {integrity: sha512-gh4i0xFP8DiRaNoX75kPiG3kGl7PmX9SW/OIn3Sv/YZmHrA8faLdSU1MM6M4gKtfKpxDnZagodu8FKob5URCVw==} + n8ao@1.10.3: + resolution: {integrity: sha512-JFRk4WgUAUWO2KdJTqmBT02dP9kG7rE2oQbBy64E9+YwQ3d96KB9QBanqNy/NnYUfUTYU6Z/5OS5t/yLey7+6Q==} peerDependencies: postprocessing: '>=6.30.0' three: '>=0.137' @@ -4068,11 +4178,11 @@ packages: nodemailer: optional: true - next-intl-swc-plugin-extractor@4.13.1: - resolution: {integrity: sha512-RhlH2DR1ViEXzcX7G3tDXAvzNrBL2Ph54Hq/q/9oP9eXQV/okh3UQpA/lx2k9U5Ck83CZOSgH0eFTNi5U+zyXw==} + next-intl-swc-plugin-extractor@4.13.2: + resolution: {integrity: sha512-O30N/Y4ifzRe5Sz80jD1Qkg4VY6Zfef4SbHNNE166QkHswBf3/Kygpdd1X52sUUwTCk6uvdisO8ybfAN/VYJHQ==} - next-intl@4.13.1: - resolution: {integrity: sha512-aS8KTA+nNhSNJJBlIhxgvU135WzoObwzFwav4wTDti/Gmhxqe0fs/Q343igo8Z7HGqPB/xgmoagwySZAlHmIfA==} + next-intl@4.13.2: + resolution: {integrity: sha512-iCYycEP7/PE+1ue4MWBuz1qns6ESA+SGzuXxNMNN1qiYUh2fLhJPiZvHW1zZC7zMTn44aJUglOVZxUb1+hUz6g==} peerDependencies: next: ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0 @@ -4081,8 +4191,8 @@ packages: typescript: optional: true - next@16.2.10: - resolution: {integrity: sha512-2som5AVXb3kE6Yjine3/mNbBayYF58eguBWIVVUdr1y/L426xyVEgYxgBG+1QC34P2x5E+tcDup6XkuOAX3dCA==} + next@16.3.0-preview.5: + resolution: {integrity: sha512-I5rVC4VcvAL1FPr6AY5WEQUSe6o1Bt0Oa/qH5hfPhci4FRMCPeAQ95tgxFOgJDk2wME1K009k0bjS17nQ0Bq1w==} engines: {node: '>=20.9.0'} hasBin: true peerDependencies: @@ -4140,8 +4250,8 @@ packages: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} - nucleation@0.2.13: - resolution: {integrity: sha512-udIxzSczAuJgyDQ8Rl1BoBjJox98lU/GQjoY/qBmhDRRnrCXsTf+l93D6vlOxMci/kgmmMMFvkJyIwqjXWU/+A==} + nucleation@0.2.17: + resolution: {integrity: sha512-JOgXHrxsX+KSFo2OzvskJCam7jcKQgBoSUC5eUvaYiRcfqBPQ6W76QUNWcZCcoFu/K9pX9Ma5aKpL/ELQHPD1w==} oauth4webapi@3.8.6: resolution: {integrity: sha512-iwemM91xz8nryHti2yTmg5fhyEMVOkOXwHNqbvcATjyajb5oQxCQzrNOA6uElRHuMhQQTKUyFKV9y/CNyg25BQ==} @@ -4254,12 +4364,12 @@ packages: vite-plus: optional: true - oxlint@1.72.0: - resolution: {integrity: sha512-1rhdZIP/EvoI91ABIwNU5Q8+bWf8mjrS5UzIOZld4d4bXxJvtlUhlQvaoTogIGin/qdErMOrwaIJvCSIAKTLhA==} + oxlint@1.73.0: + resolution: {integrity: sha512-u91G9TJzU6yqKWNZUYprQB07W7YvntZXaRxQ6CkoytepYhLWUXWsr1M8zUJ34VatNPuUAr3Z8GH+O2A331CluQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: - oxlint-tsgolint: '>=0.22.1' + oxlint-tsgolint: '>=0.24.0' vite-plus: '*' peerDependenciesMeta: oxlint-tsgolint: @@ -4290,8 +4400,8 @@ packages: pako@1.0.11: resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} - pako@2.1.0: - resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} + pako@2.2.0: + resolution: {integrity: sha512-zJq6RP/5q+TO2OpFV3FHzlPnFjmkb7Nc99a5SNjJE+uu/PkpChs+NIZSSzbBoD+6kjiISXjfYdwj1ZRQ81dz/w==} pandemonium@2.4.1: resolution: {integrity: sha512-wRqjisUyiUfXowgm7MFH2rwJzKIr20rca5FsHXCMNm1W5YPP1hCtrZfgmQ62kP7OZ7Xt+cR858aB28lu5NX55g==} @@ -4354,8 +4464,8 @@ packages: pg-cloudflare@1.4.0: resolution: {integrity: sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==} - pg-connection-string@2.13.0: - resolution: {integrity: sha512-EMnU9E2fSULdsbErBbMaXJvFeD9B4+nPcM3f+4lsiCR0BHLPrLVjv3DbyM2hgQQviKJaTWIRRTjKjWlHg3p2ig==} + pg-connection-string@2.14.0: + resolution: {integrity: sha512-XwWDGcLRGCXAR8F/AM5bG7Q+A3Wm2s6QeEjlOKZLlH3UYcguiqCWKyWXVag5TLTIjR7oOJUY8kcADaZgWPyLeg==} pg-int8@1.0.1: resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} @@ -4366,15 +4476,15 @@ packages: peerDependencies: pg: '>=8.0' - pg-protocol@1.14.0: - resolution: {integrity: sha512-n5taZ1kO3s9ngDTVxsEznOqCyToTgz0FLuPq0B33COy5pPpuWJpY3/2oRBVETuOgzdqRXfWpM9HIhp2LBBT1BA==} + pg-protocol@1.15.0: + resolution: {integrity: sha512-cq9sECI5s0+uPUXjbz8ioyPJni6RzsRib0US67i5IoTZKw8fNeYlVE7u8F4dG7vEJJtc5wdD1K189lCCUwqWTQ==} pg-types@2.2.0: resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} engines: {node: '>=4'} - pg@8.21.0: - resolution: {integrity: sha512-AUP1EYJuHraQGsVoCQVIcM7TEJVGtDzxWtGFZd8rds9d+CCXlU5Js1rYgfLNvxy9iJrpHjGrRjoi/3BT9fRyiA==} + pg@8.22.0: + resolution: {integrity: sha512-8wih1vVIBMxoUM2oB4soJsD9tDnDpLv4OXBJ+EJzFsvycD+lfyIreC2gGHq78f8jbLLt+bvlPTFdFZfJkOuzAA==} engines: {node: '>= 16.0.0'} peerDependencies: pg-native: '>=3.0.1' @@ -4392,10 +4502,6 @@ packages: resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} engines: {node: '>=8.6'} - picomatch@4.0.4: - resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} - engines: {node: '>=12'} - picomatch@4.0.5: resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} engines: {node: '>=12'} @@ -4437,8 +4543,8 @@ packages: po-parser@2.1.1: resolution: {integrity: sha512-ECF4zHLbUItpUgE3OTtLKlPjeBN+fKEczj2zYjDfCGOzicNs0GK3Vg2IoAYwx7LH/XYw43fZQP6xnZ4TkNxSLQ==} - postcss@8.4.31: - resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + postcss@8.5.10: + resolution: {integrity: sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==} engines: {node: ^10 || ^12 || >=14} postcss@8.5.16: @@ -4469,10 +4575,10 @@ packages: resolution: {integrity: sha512-Jtc2612XINuBjIl/QTWsV5UvE8UHuNblcO3vVADSrKsrc6RqGX6lOW1cEo3CM2v0XG4Nat8nI+YM7/f26VxXLw==} engines: {node: '>=12'} - postprocessing@6.39.1: - resolution: {integrity: sha512-R2dG2zy+BAx3USl5EHw+PvnrlbT5PKnZVp3se0HCR0pWH8WQdh742yNG4YWOsq6c0bFpffk0Gd2RqPeoP/wKng==} + postprocessing@6.39.2: + resolution: {integrity: sha512-AxPY+xFyVOsz+8bbHSyQBoOK4AUqSQspTXXIsNcKhmGJRm/afHRAwZ8bKC02AeSPII0PW6lbCN84SgAoWFsKKA==} peerDependencies: - three: '>= 0.168.0 < 0.185.0' + three: '>= 0.168.0 < 0.186.0' preact-render-to-string@6.5.11: resolution: {integrity: sha512-ubnauqoGczeGISiOh6RjX0/cdaF8v/oDXIjO85XALCQjwQP+SB4RDXXtvZ6yTYSjG+PC1QRP2AhPgCEsM2EvUw==} @@ -4558,8 +4664,8 @@ packages: pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} - qs@6.15.2: - resolution: {integrity: sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==} + qs@6.15.3: + resolution: {integrity: sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==} engines: {node: '>=0.6'} querystring@0.2.0: @@ -4574,6 +4680,10 @@ packages: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} + range-parser@1.3.0: + resolution: {integrity: sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==} + engines: {node: '>= 0.6'} + raw-body@2.5.3: resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} engines: {node: '>= 0.8'} @@ -4725,8 +4835,8 @@ packages: resolution: {integrity: sha512-s+pyvQeIKIZ0dx5iJiQk1tPLJAWln39+MI5jtM8wnyws+G5azk+dMnMX0qfbqNetKKNgcWWOdi0sfm+FbQbgdQ==} engines: {node: '>=10.0.0'} - rolldown@1.0.3: - resolution: {integrity: sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==} + rolldown@1.1.5: + resolution: {integrity: sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -4835,8 +4945,8 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - shell-quote@1.8.4: - resolution: {integrity: sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ==} + shell-quote@1.9.0: + resolution: {integrity: sha512-Iov+JwFv/2HcTpcwNMKd8+IWNb8tboQJNQTkAY/LLVK7gGH9jy+LGkVqPxfekHl+yMmiqXszdGWXgkfml7hjqA==} engines: {node: '>= 0.4'} shiki@4.3.1: @@ -4944,15 +5054,15 @@ packages: std-env@3.10.0: resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} - std-env@4.1.0: - resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==} + std-env@4.2.0: + resolution: {integrity: sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==} streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} - streamx@2.27.0: - resolution: {integrity: sha512-WZ189TKnHoAokYHvwzaAQMpd55cgUmFIcJFzBSgGcb886jau5DL+XdDhTWV4ps3FLvk+OORp0dLRTPsLZ21CSA==} + streamx@2.28.0: + resolution: {integrity: sha512-1Yowhzjf0ivGMrTIkY9hav5TxobO9qIVqUE41fiCGMGgc3CLlf4MY+9AHmZqBWgDTue0fY9zWjYFVyf6Diuobw==} string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} @@ -4970,8 +5080,8 @@ packages: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} - string-width@8.2.1: - resolution: {integrity: sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==} + string-width@8.2.2: + resolution: {integrity: sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==} engines: {node: '>=20'} string_decoder@1.1.1: @@ -5071,8 +5181,8 @@ packages: resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} engines: {node: '>=6'} - tar-fs@3.1.2: - resolution: {integrity: sha512-QGxxTxxyleAdyM3kpFs14ymbYmNFrfY+pHj7Z8FgtbZ7w2//VAgLMac7sT6nRpIHjppXO2AwwEOg0bPFVRcmXw==} + tar-fs@3.1.3: + resolution: {integrity: sha512-/hU4AXnIdZu+Gvl1pk0oI5f5HxWsCJRtY2aFaJdk9VvyL48DWU6iU5WAIPG+wIi1YvWA6eTJvIviP/tMAZZNwQ==} tar-stream@3.2.0: resolution: {integrity: sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==} @@ -5290,9 +5400,9 @@ packages: typedarray-to-buffer@3.1.5: resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} - typescript@6.0.3: - resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} - engines: {node: '>=14.17'} + typescript@7.0.2: + resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==} + engines: {node: '>=16.20.0'} hasBin: true typical@7.3.0: @@ -5361,8 +5471,8 @@ packages: url@0.10.3: resolution: {integrity: sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==} - use-intl@4.13.1: - resolution: {integrity: sha512-UU5C3zAC7yVg3m7rq5C8VF5J5jhAfvS19Wi9bPNCB9xB7jQYBsUcrqfdxs4Mxl9XR3x6BDB5K++iAw7/rcm3gg==} + use-intl@4.13.2: + resolution: {integrity: sha512-p6/gCromeBoec+wEuOIkPaytH77RBjW94KWv8MRsNrbI4UOx8QgwNhgl9lbPOKM/b0dpanLhCYztLEH5yQUjtg==} peerDependencies: react: ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0 @@ -5421,13 +5531,13 @@ packages: peerDependencies: vite: ^2 || ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - vite@8.0.16: - resolution: {integrity: sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==} + vite@8.1.4: + resolution: {integrity: sha512-bTT9PsdWO+MQMNG9ZXIP/qM9wGh37DFxTV/sPq9cFpHr3w4jkgef032PkAL9jAqhk3Nz8NQw3O8n6/xFkqO4QQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.1.18 + '@vitejs/devtools': ^0.3.0 esbuild: ^0.27.0 || ^0.28.0 jiti: '>=1.21.0' less: ^4.0.0 @@ -5646,8 +5756,8 @@ packages: resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} engines: {node: '>=8'} - yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + yargs@17.7.3: + resolution: {integrity: sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==} engines: {node: '>=12'} yauzl@2.10.0: @@ -5685,10 +5795,10 @@ snapshots: preact: 10.24.3 preact-render-to-string: 6.5.11(preact@10.24.3) - '@auth/prisma-adapter@2.11.2(@prisma/client@7.8.0(prisma@7.8.0(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3))(typescript@6.0.3))': + '@auth/prisma-adapter@2.11.2(@prisma/client@7.8.0(prisma@7.8.0(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@7.0.2))(typescript@7.0.2))': dependencies: '@auth/core': 0.41.2 - '@prisma/client': 7.8.0(prisma@7.8.0(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3))(typescript@6.0.3) + '@prisma/client': 7.8.0(prisma@7.8.0(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@7.0.2))(typescript@7.0.2) transitivePeerDependencies: - '@simplewebauthn/browser' - '@simplewebauthn/server' @@ -5698,21 +5808,14 @@ snapshots: '@codemirror/autocomplete@6.20.3': dependencies: - '@codemirror/language': 6.12.3 - '@codemirror/state': 6.6.0 - '@codemirror/view': 6.43.5 - '@lezer/common': 1.5.2 - - '@codemirror/commands@6.10.3': - dependencies: - '@codemirror/language': 6.12.3 - '@codemirror/state': 6.7.0 - '@codemirror/view': 6.43.5 + '@codemirror/language': 6.12.4 + '@codemirror/state': 6.7.1 + '@codemirror/view': 6.43.6 '@lezer/common': 1.5.2 '@codemirror/commands@6.10.4': dependencies: - '@codemirror/language': 6.12.3 + '@codemirror/language': 6.12.4 '@codemirror/state': 6.7.1 '@codemirror/view': 6.43.6 '@lezer/common': 1.5.2 @@ -5721,29 +5824,29 @@ snapshots: dependencies: '@codemirror/lang-html': 6.4.11 '@codemirror/lang-javascript': 6.2.5 - '@codemirror/language': 6.12.3 + '@codemirror/language': 6.12.4 '@lezer/common': 1.5.2 '@lezer/highlight': 1.2.3 '@lezer/lr': 1.4.10 '@codemirror/lang-cpp@6.0.3': dependencies: - '@codemirror/language': 6.12.3 + '@codemirror/language': 6.12.4 '@lezer/cpp': 1.1.6 '@codemirror/lang-css@6.3.1': dependencies: '@codemirror/autocomplete': 6.20.3 - '@codemirror/language': 6.12.3 - '@codemirror/state': 6.7.0 + '@codemirror/language': 6.12.4 + '@codemirror/state': 6.7.1 '@lezer/common': 1.5.2 - '@lezer/css': 1.3.3 + '@lezer/css': 1.3.4 '@codemirror/lang-go@6.0.1': dependencies: '@codemirror/autocomplete': 6.20.3 - '@codemirror/language': 6.12.3 - '@codemirror/state': 6.7.0 + '@codemirror/language': 6.12.4 + '@codemirror/state': 6.7.1 '@lezer/common': 1.5.2 '@lezer/go': 1.0.1 @@ -5752,25 +5855,25 @@ snapshots: '@codemirror/autocomplete': 6.20.3 '@codemirror/lang-css': 6.3.1 '@codemirror/lang-javascript': 6.2.5 - '@codemirror/language': 6.12.3 - '@codemirror/state': 6.7.0 - '@codemirror/view': 6.43.5 + '@codemirror/language': 6.12.4 + '@codemirror/state': 6.7.1 + '@codemirror/view': 6.43.6 '@lezer/common': 1.5.2 - '@lezer/css': 1.3.3 + '@lezer/css': 1.3.4 '@lezer/html': 1.3.13 '@codemirror/lang-java@6.0.2': dependencies: - '@codemirror/language': 6.12.3 + '@codemirror/language': 6.12.4 '@lezer/java': 1.1.3 '@codemirror/lang-javascript@6.2.5': dependencies: '@codemirror/autocomplete': 6.20.3 - '@codemirror/language': 6.12.3 + '@codemirror/language': 6.12.4 '@codemirror/lint': 6.9.7 - '@codemirror/state': 6.7.0 - '@codemirror/view': 6.43.5 + '@codemirror/state': 6.7.1 + '@codemirror/view': 6.43.6 '@lezer/common': 1.5.2 '@lezer/javascript': 1.5.4 @@ -5778,22 +5881,22 @@ snapshots: dependencies: '@codemirror/autocomplete': 6.20.3 '@codemirror/lang-html': 6.4.11 - '@codemirror/language': 6.12.3 - '@codemirror/state': 6.7.0 - '@codemirror/view': 6.43.5 + '@codemirror/language': 6.12.4 + '@codemirror/state': 6.7.1 + '@codemirror/view': 6.43.6 '@lezer/common': 1.5.2 '@lezer/highlight': 1.2.3 '@lezer/lr': 1.4.10 '@codemirror/lang-json@6.0.2': dependencies: - '@codemirror/language': 6.12.3 + '@codemirror/language': 6.12.4 '@lezer/json': 1.0.3 '@codemirror/lang-less@6.0.2': dependencies: '@codemirror/lang-css': 6.3.1 - '@codemirror/language': 6.12.3 + '@codemirror/language': 6.12.4 '@lezer/common': 1.5.2 '@lezer/highlight': 1.2.3 '@lezer/lr': 1.4.10 @@ -5802,9 +5905,9 @@ snapshots: dependencies: '@codemirror/autocomplete': 6.20.3 '@codemirror/lang-html': 6.4.11 - '@codemirror/language': 6.12.3 - '@codemirror/state': 6.7.0 - '@codemirror/view': 6.43.5 + '@codemirror/language': 6.12.4 + '@codemirror/state': 6.7.1 + '@codemirror/view': 6.43.6 '@lezer/common': 1.5.2 '@lezer/highlight': 1.2.3 '@lezer/lr': 1.4.10 @@ -5813,46 +5916,46 @@ snapshots: dependencies: '@codemirror/autocomplete': 6.20.3 '@codemirror/lang-html': 6.4.11 - '@codemirror/language': 6.12.3 - '@codemirror/state': 6.6.0 - '@codemirror/view': 6.43.5 + '@codemirror/language': 6.12.4 + '@codemirror/state': 6.7.1 + '@codemirror/view': 6.43.6 '@lezer/common': 1.5.2 - '@lezer/markdown': 1.6.4 + '@lezer/markdown': 1.7.1 '@codemirror/lang-php@6.0.2': dependencies: '@codemirror/lang-html': 6.4.11 - '@codemirror/language': 6.12.3 - '@codemirror/state': 6.7.0 + '@codemirror/language': 6.12.4 + '@codemirror/state': 6.7.1 '@lezer/common': 1.5.2 '@lezer/php': 1.0.5 '@codemirror/lang-python@6.2.1': dependencies: '@codemirror/autocomplete': 6.20.3 - '@codemirror/language': 6.12.3 - '@codemirror/state': 6.7.0 + '@codemirror/language': 6.12.4 + '@codemirror/state': 6.7.1 '@lezer/common': 1.5.2 '@lezer/python': 1.1.19 '@codemirror/lang-rust@6.0.2': dependencies: - '@codemirror/language': 6.12.3 + '@codemirror/language': 6.12.4 '@lezer/rust': 1.0.2 '@codemirror/lang-sass@6.0.2': dependencies: '@codemirror/lang-css': 6.3.1 - '@codemirror/language': 6.12.3 - '@codemirror/state': 6.7.0 + '@codemirror/language': 6.12.4 + '@codemirror/state': 6.7.1 '@lezer/common': 1.5.2 '@lezer/sass': 1.1.0 '@codemirror/lang-sql@6.10.0': dependencies: '@codemirror/autocomplete': 6.20.3 - '@codemirror/language': 6.12.3 - '@codemirror/state': 6.7.0 + '@codemirror/language': 6.12.4 + '@codemirror/state': 6.7.1 '@lezer/common': 1.5.2 '@lezer/highlight': 1.2.3 '@lezer/lr': 1.4.10 @@ -5861,14 +5964,14 @@ snapshots: dependencies: '@codemirror/lang-html': 6.4.11 '@codemirror/lang-javascript': 6.2.5 - '@codemirror/language': 6.12.3 + '@codemirror/language': 6.12.4 '@lezer/common': 1.5.2 '@lezer/highlight': 1.2.3 '@lezer/lr': 1.4.10 '@codemirror/lang-wast@6.0.2': dependencies: - '@codemirror/language': 6.12.3 + '@codemirror/language': 6.12.4 '@lezer/common': 1.5.2 '@lezer/highlight': 1.2.3 '@lezer/lr': 1.4.10 @@ -5876,17 +5979,17 @@ snapshots: '@codemirror/lang-xml@6.1.0': dependencies: '@codemirror/autocomplete': 6.20.3 - '@codemirror/language': 6.12.3 - '@codemirror/state': 6.7.0 - '@codemirror/view': 6.43.5 + '@codemirror/language': 6.12.4 + '@codemirror/state': 6.7.1 + '@codemirror/view': 6.43.6 '@lezer/common': 1.5.2 '@lezer/xml': 1.0.6 '@codemirror/lang-yaml@6.1.3': dependencies: '@codemirror/autocomplete': 6.20.3 - '@codemirror/language': 6.12.3 - '@codemirror/state': 6.7.0 + '@codemirror/language': 6.12.4 + '@codemirror/state': 6.7.1 '@lezer/common': 1.5.2 '@lezer/highlight': 1.2.3 '@lezer/lr': 1.4.10 @@ -5915,10 +6018,10 @@ snapshots: '@codemirror/lang-wast': 6.0.2 '@codemirror/lang-xml': 6.1.0 '@codemirror/lang-yaml': 6.1.3 - '@codemirror/language': 6.12.3 + '@codemirror/language': 6.12.4 '@codemirror/legacy-modes': 6.5.3 - '@codemirror/language@6.12.3': + '@codemirror/language@6.12.4': dependencies: '@codemirror/state': 6.7.1 '@codemirror/view': 6.43.6 @@ -5929,7 +6032,7 @@ snapshots: '@codemirror/legacy-modes@6.5.3': dependencies: - '@codemirror/language': 6.12.3 + '@codemirror/language': 6.12.4 '@codemirror/lint@6.9.7': dependencies: @@ -5939,44 +6042,29 @@ snapshots: '@codemirror/merge@6.12.2': dependencies: - '@codemirror/language': 6.12.3 - '@codemirror/state': 6.6.0 - '@codemirror/view': 6.43.5 + '@codemirror/language': 6.12.4 + '@codemirror/state': 6.7.1 + '@codemirror/view': 6.43.6 '@lezer/highlight': 1.2.3 style-mod: 4.1.3 - '@codemirror/search@6.7.0': + '@codemirror/search@6.7.1': dependencies: '@codemirror/state': 6.7.1 '@codemirror/view': 6.43.6 crelt: 1.0.7 - '@codemirror/state@6.6.0': - dependencies: - '@marijn/find-cluster-break': 1.0.3 - - '@codemirror/state@6.7.0': - dependencies: - '@marijn/find-cluster-break': 1.0.3 - '@codemirror/state@6.7.1': dependencies: '@marijn/find-cluster-break': 1.0.3 '@codemirror/theme-one-dark@6.1.3': dependencies: - '@codemirror/language': 6.12.3 + '@codemirror/language': 6.12.4 '@codemirror/state': 6.7.1 '@codemirror/view': 6.43.6 '@lezer/highlight': 1.2.3 - '@codemirror/view@6.43.5': - dependencies: - '@codemirror/state': 6.7.0 - crelt: 1.0.7 - style-mod: 4.1.3 - w3c-keyname: 2.2.8 - '@codemirror/view@6.43.6': dependencies: '@codemirror/state': 6.7.1 @@ -5998,23 +6086,23 @@ snapshots: '@electric-sql/pglite@0.4.1': {} - '@emnapi/core@1.10.0': + '@emnapi/core@1.11.1': dependencies: - '@emnapi/wasi-threads': 1.2.1 + '@emnapi/wasi-threads': 1.2.2 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.10.0': + '@emnapi/runtime@1.11.1': dependencies: tslib: 2.8.1 optional: true - '@emnapi/runtime@1.11.1': + '@emnapi/runtime@1.11.2': dependencies: tslib: 2.8.1 optional: true - '@emnapi/wasi-threads@1.2.1': + '@emnapi/wasi-threads@1.2.2': dependencies: tslib: 2.8.1 optional: true @@ -6116,7 +6204,7 @@ snapshots: dependencies: tslib: 2.8.1 - '@formatjs/fast-memoize@3.1.6': {} + '@formatjs/fast-memoize@3.1.7': {} '@formatjs/icu-messageformat-parser@2.11.4': dependencies: @@ -6124,28 +6212,32 @@ snapshots: '@formatjs/icu-skeleton-parser': 1.8.16 tslib: 2.8.1 - '@formatjs/icu-messageformat-parser@3.5.12': + '@formatjs/icu-messageformat-parser@3.5.14': dependencies: - '@formatjs/icu-skeleton-parser': 2.1.10 + '@formatjs/icu-skeleton-parser': 2.1.11 '@formatjs/icu-skeleton-parser@1.8.16': dependencies: '@formatjs/ecma402-abstract': 2.3.6 tslib: 2.8.1 - '@formatjs/icu-skeleton-parser@2.1.10': {} + '@formatjs/icu-skeleton-parser@2.1.11': {} '@formatjs/intl-localematcher@0.6.2': dependencies: tslib: 2.8.1 - '@formatjs/intl-localematcher@0.8.10': + '@formatjs/intl-localematcher@0.8.12': dependencies: - '@formatjs/fast-memoize': 3.1.6 + '@formatjs/fast-memoize': 3.1.7 - '@hono/node-server@1.19.11(hono@4.12.25)': + '@hono/node-server@1.19.11(hono@4.12.28)': dependencies: - hono: 4.12.25 + hono: 4.12.28 + + '@hono/node-server@1.19.14(hono@4.12.28)': + dependencies: + hono: 4.12.28 '@huggingface/jinja@0.5.9': {} @@ -6243,7 +6335,7 @@ snapshots: '@img/sharp-wasm32@0.34.5': dependencies: - '@emnapi/runtime': 1.11.1 + '@emnapi/runtime': 1.11.2 optional: true '@img/sharp-win32-arm64@0.34.5': @@ -6318,7 +6410,7 @@ snapshots: '@lezer/highlight': 1.2.3 '@lezer/lr': 1.4.10 - '@lezer/css@1.3.3': + '@lezer/css@1.3.4': dependencies: '@lezer/common': 1.5.2 '@lezer/highlight': 1.2.3 @@ -6362,7 +6454,7 @@ snapshots: dependencies: '@lezer/common': 1.5.2 - '@lezer/markdown@1.6.4': + '@lezer/markdown@1.7.1': dependencies: '@lezer/common': 1.5.2 '@lezer/highlight': 1.2.3 @@ -6449,7 +6541,7 @@ snapshots: '@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)': dependencies: - '@hono/node-server': 1.19.11(hono@4.12.25) + '@hono/node-server': 1.19.14(hono@4.12.28) ajv: 8.20.0 ajv-formats: 3.0.1(ajv@8.20.0) content-type: 1.0.5 @@ -6459,7 +6551,7 @@ snapshots: eventsource-parser: 3.1.0 express: 5.2.1 express-rate-limit: 8.5.2(express@5.2.1) - hono: 4.12.25 + hono: 4.12.28 jose: 6.2.3 json-schema-typed: 8.0.2 pkce-challenge: 5.0.1 @@ -6469,10 +6561,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 '@tybys/wasm-util': 0.10.3 optional: true @@ -6483,30 +6575,30 @@ snapshots: - bufferutil - utf-8-validate - '@next/env@16.2.10': {} + '@next/env@16.3.0-preview.5': {} - '@next/swc-darwin-arm64@16.2.10': + '@next/swc-darwin-arm64@16.3.0-preview.5': optional: true - '@next/swc-darwin-x64@16.2.10': + '@next/swc-darwin-x64@16.3.0-preview.5': optional: true - '@next/swc-linux-arm64-gnu@16.2.10': + '@next/swc-linux-arm64-gnu@16.3.0-preview.5': optional: true - '@next/swc-linux-arm64-musl@16.2.10': + '@next/swc-linux-arm64-musl@16.3.0-preview.5': optional: true - '@next/swc-linux-x64-gnu@16.2.10': + '@next/swc-linux-x64-gnu@16.3.0-preview.5': optional: true - '@next/swc-linux-x64-musl@16.2.10': + '@next/swc-linux-x64-musl@16.3.0-preview.5': optional: true - '@next/swc-win32-arm64-msvc@16.2.10': + '@next/swc-win32-arm64-msvc@16.3.0-preview.5': optional: true - '@next/swc-win32-x64-msvc@16.2.10': + '@next/swc-win32-x64-msvc@16.3.0-preview.5': optional: true '@octokit/auth-token@6.0.0': {} @@ -6515,7 +6607,7 @@ snapshots: dependencies: '@octokit/auth-token': 6.0.0 '@octokit/graphql': 9.0.3 - '@octokit/request': 10.0.10 + '@octokit/request': 10.0.11 '@octokit/request-error': 7.1.0 '@octokit/types': 16.0.0 before-after-hook: 4.0.0 @@ -6528,7 +6620,7 @@ snapshots: '@octokit/graphql@9.0.3': dependencies: - '@octokit/request': 10.0.10 + '@octokit/request': 10.0.11 '@octokit/types': 16.0.0 universal-user-agent: 7.0.3 @@ -6552,7 +6644,7 @@ snapshots: dependencies: '@octokit/types': 16.0.0 - '@octokit/request@10.0.10': + '@octokit/request@10.0.11': dependencies: '@octokit/endpoint': 11.0.3 '@octokit/request-error': 7.1.0 @@ -6572,7 +6664,7 @@ snapshots: dependencies: '@octokit/openapi-types': 27.0.0 - '@oxc-project/types@0.133.0': {} + '@oxc-project/types@0.139.0': {} '@oxfmt/binding-android-arm-eabi@0.57.0': optional: true @@ -6631,61 +6723,61 @@ snapshots: '@oxfmt/binding-win32-x64-msvc@0.57.0': optional: true - '@oxlint/binding-android-arm-eabi@1.72.0': + '@oxlint/binding-android-arm-eabi@1.73.0': optional: true - '@oxlint/binding-android-arm64@1.72.0': + '@oxlint/binding-android-arm64@1.73.0': optional: true - '@oxlint/binding-darwin-arm64@1.72.0': + '@oxlint/binding-darwin-arm64@1.73.0': optional: true - '@oxlint/binding-darwin-x64@1.72.0': + '@oxlint/binding-darwin-x64@1.73.0': optional: true - '@oxlint/binding-freebsd-x64@1.72.0': + '@oxlint/binding-freebsd-x64@1.73.0': optional: true - '@oxlint/binding-linux-arm-gnueabihf@1.72.0': + '@oxlint/binding-linux-arm-gnueabihf@1.73.0': optional: true - '@oxlint/binding-linux-arm-musleabihf@1.72.0': + '@oxlint/binding-linux-arm-musleabihf@1.73.0': optional: true - '@oxlint/binding-linux-arm64-gnu@1.72.0': + '@oxlint/binding-linux-arm64-gnu@1.73.0': optional: true - '@oxlint/binding-linux-arm64-musl@1.72.0': + '@oxlint/binding-linux-arm64-musl@1.73.0': optional: true - '@oxlint/binding-linux-ppc64-gnu@1.72.0': + '@oxlint/binding-linux-ppc64-gnu@1.73.0': optional: true - '@oxlint/binding-linux-riscv64-gnu@1.72.0': + '@oxlint/binding-linux-riscv64-gnu@1.73.0': optional: true - '@oxlint/binding-linux-riscv64-musl@1.72.0': + '@oxlint/binding-linux-riscv64-musl@1.73.0': optional: true - '@oxlint/binding-linux-s390x-gnu@1.72.0': + '@oxlint/binding-linux-s390x-gnu@1.73.0': optional: true - '@oxlint/binding-linux-x64-gnu@1.72.0': + '@oxlint/binding-linux-x64-gnu@1.73.0': optional: true - '@oxlint/binding-linux-x64-musl@1.72.0': + '@oxlint/binding-linux-x64-musl@1.73.0': optional: true - '@oxlint/binding-openharmony-arm64@1.72.0': + '@oxlint/binding-openharmony-arm64@1.73.0': optional: true - '@oxlint/binding-win32-arm64-msvc@1.72.0': + '@oxlint/binding-win32-arm64-msvc@1.73.0': optional: true - '@oxlint/binding-win32-ia32-msvc@1.72.0': + '@oxlint/binding-win32-ia32-msvc@1.73.0': optional: true - '@oxlint/binding-win32-x64-msvc@1.72.0': + '@oxlint/binding-win32-x64-msvc@1.73.0': optional: true '@panva/hkdf@1.2.1': {} @@ -6734,7 +6826,7 @@ snapshots: detect-libc: 2.1.2 is-glob: 4.0.3 node-addon-api: 7.1.1 - picomatch: 4.0.4 + picomatch: 4.0.5 optionalDependencies: '@parcel/watcher-android-arm64': 2.5.6 '@parcel/watcher-darwin-arm64': 2.5.6 @@ -6771,19 +6863,19 @@ snapshots: dependencies: '@prisma/driver-adapter-utils': 7.8.0 '@types/pg': 8.20.0 - pg: 8.21.0 + pg: 8.22.0 postgres-array: 3.0.4 transitivePeerDependencies: - pg-native '@prisma/client-runtime-utils@7.8.0': {} - '@prisma/client@7.8.0(prisma@7.8.0(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3))(typescript@6.0.3)': + '@prisma/client@7.8.0(prisma@7.8.0(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@7.0.2))(typescript@7.0.2)': dependencies: '@prisma/client-runtime-utils': 7.8.0 optionalDependencies: - prisma: 7.8.0(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3) - typescript: 6.0.3 + prisma: 7.8.0(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@7.0.2) + typescript: 7.0.2 '@prisma/config@7.8.0': dependencies: @@ -6798,24 +6890,24 @@ snapshots: '@prisma/debug@7.8.0': {} - '@prisma/dev@0.24.3(typescript@6.0.3)': + '@prisma/dev@0.24.3(typescript@7.0.2)': dependencies: '@electric-sql/pglite': 0.4.1 '@electric-sql/pglite-socket': 0.1.1(@electric-sql/pglite@0.4.1) '@electric-sql/pglite-tools': 0.3.1(@electric-sql/pglite@0.4.1) - '@hono/node-server': 1.19.11(hono@4.12.25) + '@hono/node-server': 1.19.11(hono@4.12.28) '@prisma/get-platform': 7.2.0 '@prisma/query-plan-executor': 7.2.0 '@prisma/streams-local': 0.1.2 foreground-child: 3.3.1 get-port-please: 3.2.0 - hono: 4.12.25 + hono: 4.12.28 http-status-codes: 2.3.0 pathe: 2.0.3 proper-lockfile: 4.1.2 remeda: 2.33.4 std-env: 3.10.0 - valibot: 1.2.0(typescript@6.0.3) + valibot: 1.2.0(typescript@7.0.2) zeptomatch: 2.1.0 transitivePeerDependencies: - typescript @@ -6893,8 +6985,8 @@ snapshots: progress: 2.0.3 proxy-agent: 6.5.0 semver: 7.8.5 - tar-fs: 3.1.2 - yargs: 17.7.2 + tar-fs: 3.1.3 + yargs: 17.7.3 transitivePeerDependencies: - bare-abort-controller - bare-buffer @@ -6955,53 +7047,53 @@ snapshots: optionalDependencies: '@types/react': 19.2.17 - '@rolldown/binding-android-arm64@1.0.3': + '@rolldown/binding-android-arm64@1.1.5': optional: true - '@rolldown/binding-darwin-arm64@1.0.3': + '@rolldown/binding-darwin-arm64@1.1.5': optional: true - '@rolldown/binding-darwin-x64@1.0.3': + '@rolldown/binding-darwin-x64@1.1.5': optional: true - '@rolldown/binding-freebsd-x64@1.0.3': + '@rolldown/binding-freebsd-x64@1.1.5': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.3': + '@rolldown/binding-linux-arm-gnueabihf@1.1.5': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.3': + '@rolldown/binding-linux-arm64-gnu@1.1.5': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.3': + '@rolldown/binding-linux-arm64-musl@1.1.5': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.0.3': + '@rolldown/binding-linux-ppc64-gnu@1.1.5': optional: true - '@rolldown/binding-linux-s390x-gnu@1.0.3': + '@rolldown/binding-linux-s390x-gnu@1.1.5': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.3': + '@rolldown/binding-linux-x64-gnu@1.1.5': optional: true - '@rolldown/binding-linux-x64-musl@1.0.3': + '@rolldown/binding-linux-x64-musl@1.1.5': optional: true - '@rolldown/binding-openharmony-arm64@1.0.3': + '@rolldown/binding-openharmony-arm64@1.1.5': optional: true - '@rolldown/binding-wasm32-wasi@1.0.3': + '@rolldown/binding-wasm32-wasi@1.1.5': dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.3': + '@rolldown/binding-win32-arm64-msvc@1.1.5': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.3': + '@rolldown/binding-win32-x64-msvc@1.1.5': optional: true '@rolldown/pluginutils@1.0.1': {} @@ -7049,7 +7141,7 @@ snapshots: '@shikijs/primitive': 4.3.1 '@shikijs/types': 4.3.1 '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 hast-util-to-html: 9.0.5 '@shikijs/engine-javascript@4.3.1': @@ -7071,7 +7163,7 @@ snapshots: dependencies: '@shikijs/types': 4.3.1 '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 '@shikijs/themes@4.3.1': dependencies: @@ -7080,43 +7172,43 @@ snapshots: '@shikijs/types@4.3.1': dependencies: '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 '@shikijs/vscode-textmate@10.0.2': {} '@standard-schema/spec@1.1.0': {} - '@supabase/auth-js@2.110.0': + '@supabase/auth-js@2.110.2': dependencies: tslib: 2.8.1 - '@supabase/functions-js@2.110.0': + '@supabase/functions-js@2.110.2': dependencies: tslib: 2.8.1 '@supabase/phoenix@0.4.4': {} - '@supabase/postgrest-js@2.110.0': + '@supabase/postgrest-js@2.110.2': dependencies: tslib: 2.8.1 - '@supabase/realtime-js@2.110.0': + '@supabase/realtime-js@2.110.2': dependencies: '@supabase/phoenix': 0.4.4 tslib: 2.8.1 - '@supabase/storage-js@2.110.0': + '@supabase/storage-js@2.110.2': dependencies: iceberg-js: 0.8.1 tslib: 2.8.1 - '@supabase/supabase-js@2.110.0': + '@supabase/supabase-js@2.110.2': dependencies: - '@supabase/auth-js': 2.110.0 - '@supabase/functions-js': 2.110.0 - '@supabase/postgrest-js': 2.110.0 - '@supabase/realtime-js': 2.110.0 - '@supabase/storage-js': 2.110.0 + '@supabase/auth-js': 2.110.2 + '@supabase/functions-js': 2.110.2 + '@supabase/postgrest-js': 2.110.2 + '@supabase/realtime-js': 2.110.2 + '@supabase/storage-js': 2.110.2 '@swc/core-darwin-arm64@1.15.43': optional: true @@ -7154,7 +7246,7 @@ snapshots: '@swc/core-win32-x64-msvc@1.15.43': optional: true - '@swc/core@1.15.43': + '@swc/core@1.15.43(@swc/helpers@0.5.23)': dependencies: '@swc/counter': 0.1.3 '@swc/types': 0.1.27 @@ -7171,6 +7263,7 @@ snapshots: '@swc/core-win32-arm64-msvc': 1.15.43 '@swc/core-win32-ia32-msvc': 1.15.43 '@swc/core-win32-x64-msvc': 1.15.43 + '@swc/helpers': 0.5.23 '@swc/counter@0.1.3': {} @@ -7178,11 +7271,15 @@ snapshots: dependencies: tslib: 2.8.1 + '@swc/helpers@0.5.23': + dependencies: + tslib: 2.8.1 + '@swc/types@0.1.27': dependencies: '@swc/counter': 0.1.3 - '@swc/wasm@1.15.41': {} + '@swc/wasm@1.15.43': {} '@tailwindcss/node@4.3.2': dependencies: @@ -7291,7 +7388,7 @@ snapshots: '@types/estree@1.0.9': {} - '@types/hast@3.0.4': + '@types/hast@3.0.5': dependencies: '@types/unist': 3.0.3 @@ -7307,22 +7404,22 @@ snapshots: '@types/ms@2.1.0': {} - '@types/node@24.13.2': + '@types/node@24.13.3': dependencies: undici-types: 7.18.2 - '@types/node@26.1.0': + '@types/node@26.1.1': dependencies: undici-types: 8.3.0 '@types/papaparse@5.5.2': dependencies: - '@types/node': 26.1.0 + '@types/node': 26.1.1 '@types/pg@8.20.0': dependencies: - '@types/node': 26.1.0 - pg-protocol: 1.14.0 + '@types/node': 26.1.1 + pg-protocol: 1.15.0 pg-types: 2.2.0 '@types/react@19.2.17': @@ -7331,7 +7428,7 @@ snapshots: '@types/stats.js@0.17.4': {} - '@types/three@0.185.0': + '@types/three@0.185.1': dependencies: '@dimforge/rapier3d-compat': 0.12.0 '@tweenjs/tween.js': 23.1.3 @@ -7350,27 +7447,87 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 26.1.0 + '@types/node': 26.1.1 + optional: true + + '@typescript/typescript-aix-ppc64@7.0.2': optional: true - '@uiw/codemirror-extensions-basic-setup@4.25.10(@codemirror/autocomplete@6.20.3)(@codemirror/commands@6.10.3)(@codemirror/language@6.12.3)(@codemirror/lint@6.9.7)(@codemirror/search@6.7.0)(@codemirror/state@6.6.0)(@codemirror/view@6.43.6)': + '@typescript/typescript-darwin-arm64@7.0.2': + optional: true + + '@typescript/typescript-darwin-x64@7.0.2': + optional: true + + '@typescript/typescript-freebsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-freebsd-x64@7.0.2': + optional: true + + '@typescript/typescript-linux-arm64@7.0.2': + optional: true + + '@typescript/typescript-linux-arm@7.0.2': + optional: true + + '@typescript/typescript-linux-loong64@7.0.2': + optional: true + + '@typescript/typescript-linux-mips64el@7.0.2': + optional: true + + '@typescript/typescript-linux-ppc64@7.0.2': + optional: true + + '@typescript/typescript-linux-riscv64@7.0.2': + optional: true + + '@typescript/typescript-linux-s390x@7.0.2': + optional: true + + '@typescript/typescript-linux-x64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-sunos-x64@7.0.2': + optional: true + + '@typescript/typescript-win32-arm64@7.0.2': + optional: true + + '@typescript/typescript-win32-x64@7.0.2': + optional: true + + '@uiw/codemirror-extensions-basic-setup@4.25.11(@codemirror/autocomplete@6.20.3)(@codemirror/commands@6.10.4)(@codemirror/language@6.12.4)(@codemirror/lint@6.9.7)(@codemirror/search@6.7.1)(@codemirror/state@6.7.1)(@codemirror/view@6.43.6)': dependencies: '@codemirror/autocomplete': 6.20.3 - '@codemirror/commands': 6.10.3 - '@codemirror/language': 6.12.3 + '@codemirror/commands': 6.10.4 + '@codemirror/language': 6.12.4 '@codemirror/lint': 6.9.7 - '@codemirror/search': 6.7.0 - '@codemirror/state': 6.6.0 + '@codemirror/search': 6.7.1 + '@codemirror/state': 6.7.1 '@codemirror/view': 6.43.6 - '@uiw/react-codemirror@4.25.10(@babel/runtime@7.29.7)(@codemirror/autocomplete@6.20.3)(@codemirror/language@6.12.3)(@codemirror/lint@6.9.7)(@codemirror/search@6.7.0)(@codemirror/state@6.6.0)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.43.6)(codemirror@6.0.2)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + '@uiw/react-codemirror@4.25.11(@babel/runtime@7.29.7)(@codemirror/autocomplete@6.20.3)(@codemirror/language@6.12.4)(@codemirror/lint@6.9.7)(@codemirror/search@6.7.1)(@codemirror/state@6.7.1)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.43.6)(codemirror@6.0.2)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: '@babel/runtime': 7.29.7 - '@codemirror/commands': 6.10.3 - '@codemirror/state': 6.6.0 + '@codemirror/commands': 6.10.4 + '@codemirror/state': 6.7.1 '@codemirror/theme-one-dark': 6.1.3 '@codemirror/view': 6.43.6 - '@uiw/codemirror-extensions-basic-setup': 4.25.10(@codemirror/autocomplete@6.20.3)(@codemirror/commands@6.10.3)(@codemirror/language@6.12.3)(@codemirror/lint@6.9.7)(@codemirror/search@6.7.0)(@codemirror/state@6.6.0)(@codemirror/view@6.43.6) + '@uiw/codemirror-extensions-basic-setup': 4.25.11(@codemirror/autocomplete@6.20.3)(@codemirror/commands@6.10.4)(@codemirror/language@6.12.4)(@codemirror/lint@6.9.7)(@codemirror/search@6.7.1)(@codemirror/state@6.7.1)(@codemirror/view@6.43.6) codemirror: 6.0.2 react: 19.2.7 react-dom: 19.2.7(react@19.2.7) @@ -7380,16 +7537,16 @@ snapshots: - '@codemirror/lint' - '@codemirror/search' - '@ungap/structured-clone@1.3.1': {} + '@ungap/structured-clone@1.3.2': {} - '@vercel/analytics@2.0.1(next@16.2.10(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7)': + '@vercel/analytics@2.0.1(next@16.3.0-preview.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7)': optionalDependencies: - next: 16.2.10(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + next: 16.3.0-preview.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) react: 19.2.7 - '@vercel/blob@2.5.0': + '@vercel/blob@2.6.1': dependencies: - '@vercel/oidc': 3.7.1 + '@vercel/oidc': 3.8.0 async-retry: 1.3.3 is-buffer: 2.0.5 is-node-process: 1.2.0 @@ -7405,15 +7562,15 @@ snapshots: dependencies: execa: 5.1.1 - '@vercel/oidc@3.7.1': + '@vercel/oidc@3.8.0': dependencies: '@vercel/cli-config': 0.2.0 '@vercel/cli-exec': 1.0.0 jose: 5.10.0 - '@vercel/speed-insights@2.0.0(next@16.2.10(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7)': + '@vercel/speed-insights@2.0.0(next@16.3.0-preview.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7)': optionalDependencies: - next: 16.2.10(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + next: 16.3.0-preview.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) react: 19.2.7 '@vitest/expect@4.1.10': @@ -7425,13 +7582,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.10(vite@8.0.16(@types/node@26.1.0)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0))': + '@vitest/mocker@4.1.10(vite@8.1.4(@types/node@26.1.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.10 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.0.16(@types/node@26.1.0)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0) + vite: 8.1.4(@types/node@26.1.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0) '@vitest/pretty-format@4.1.10': dependencies: @@ -7495,7 +7652,7 @@ snapshots: ajv@8.20.0: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.1.2 + fast-uri: 3.1.3 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 @@ -7532,10 +7689,10 @@ snapshots: apache-arrow@21.1.0: dependencies: - '@swc/helpers': 0.5.15 + '@swc/helpers': 0.5.23 '@types/command-line-args': 5.2.3 '@types/command-line-usage': 5.0.4 - '@types/node': 24.13.2 + '@types/node': 24.13.3 command-line-args: 6.0.2 command-line-usage: 7.0.4 flatbuffers: 25.9.23 @@ -7568,7 +7725,7 @@ snapshots: aws-ssl-profiles@1.1.2: {} - axe-core@4.12.0: {} + axe-core@4.12.1: {} b4a@1.8.1: {} @@ -7580,26 +7737,23 @@ snapshots: bare-events@2.9.1: {} - bare-fs@4.7.2: + bare-fs@4.7.4: dependencies: bare-events: 2.9.1 - bare-path: 3.0.1 - bare-stream: 2.13.1(bare-events@2.9.1) + bare-path: 3.1.1 + bare-stream: 2.13.3(bare-events@2.9.1) bare-url: 2.4.5 fast-fifo: 1.3.2 transitivePeerDependencies: - bare-abort-controller - react-native-b4a - bare-os@3.9.1: {} - - bare-path@3.0.1: - dependencies: - bare-os: 3.9.1 + bare-path@3.1.1: {} - bare-stream@2.13.1(bare-events@2.9.1): + bare-stream@2.13.3(bare-events@2.9.1): dependencies: - streamx: 2.27.0 + b4a: 1.8.1 + streamx: 2.28.0 teex: 1.0.1 optionalDependencies: bare-events: 2.9.1 @@ -7608,11 +7762,11 @@ snapshots: bare-url@2.4.5: dependencies: - bare-path: 3.0.1 + bare-path: 3.1.1 base64-js@1.5.1: {} - baseline-browser-mapping@2.10.40: {} + baseline-browser-mapping@2.10.42: {} basic-ftp@5.3.1: {} @@ -7622,7 +7776,7 @@ snapshots: binary-extensions@2.3.0: {} - body-parser@1.20.5: + body-parser@1.20.6: dependencies: bytes: 3.1.2 content-type: 1.0.5 @@ -7632,7 +7786,7 @@ snapshots: http-errors: 2.0.1 iconv-lite: 0.4.24 on-finished: 2.4.1 - qs: 6.15.2 + qs: 6.15.3 raw-body: 2.5.3 type-is: 1.6.18 unpipe: 1.0.0 @@ -7645,9 +7799,9 @@ snapshots: content-type: 2.0.0 debug: 4.4.3 http-errors: 2.0.1 - iconv-lite: 0.7.2 + iconv-lite: 0.7.3 on-finished: 2.4.1 - qs: 6.15.2 + qs: 6.15.3 raw-body: 3.0.2 type-is: 2.1.0 transitivePeerDependencies: @@ -7655,7 +7809,7 @@ snapshots: boolean@3.2.0: {} - brace-expansion@1.1.15: + brace-expansion@1.1.16: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 @@ -7691,8 +7845,8 @@ snapshots: confbox: 0.2.4 defu: 6.1.7 dotenv: 17.4.2 - exsolve: 1.0.8 - giget: 3.2.0 + exsolve: 1.1.0 + giget: 3.3.0 jiti: 2.7.0 ohash: 2.0.11 pathe: 2.0.3 @@ -7712,7 +7866,7 @@ snapshots: camelcase@5.3.1: {} - caniuse-lite@1.0.30001800: {} + caniuse-lite@1.0.30001803: {} ccount@2.0.1: {} @@ -7767,7 +7921,7 @@ snapshots: chrome-launcher@0.13.4: dependencies: - '@types/node': 26.1.0 + '@types/node': 26.1.1 escape-string-regexp: 1.0.5 is-wsl: 2.2.0 lighthouse-logger: 1.2.0 @@ -7778,7 +7932,7 @@ snapshots: chrome-launcher@1.2.1: dependencies: - '@types/node': 26.1.0 + '@types/node': 26.1.1 escape-string-regexp: 4.0.0 is-wsl: 2.2.0 lighthouse-logger: 2.0.2 @@ -7806,7 +7960,7 @@ snapshots: cli-truncate@5.2.0: dependencies: slice-ansi: 8.0.0 - string-width: 8.2.1 + string-width: 8.2.2 cli-width@2.2.1: {} @@ -7829,14 +7983,14 @@ snapshots: cmake-js@8.0.0: dependencies: debug: 4.4.3 - fs-extra: 11.3.5 + fs-extra: 11.3.6 node-api-headers: 1.9.0 rc: 1.2.8 semver: 7.8.5 tar: 7.5.19 url-join: 4.0.1 which: 6.0.1 - yargs: 17.7.2 + yargs: 17.7.3 transitivePeerDependencies: - supports-color @@ -7844,9 +7998,9 @@ snapshots: dependencies: '@codemirror/autocomplete': 6.20.3 '@codemirror/commands': 6.10.4 - '@codemirror/language': 6.12.3 + '@codemirror/language': 6.12.4 '@codemirror/lint': 6.9.7 - '@codemirror/search': 6.7.0 + '@codemirror/search': 6.7.1 '@codemirror/state': 6.7.1 '@codemirror/view': 6.43.6 @@ -7910,11 +8064,11 @@ snapshots: date-fns: 2.30.0 lodash: 4.18.1 rxjs: 7.8.2 - shell-quote: 1.8.4 + shell-quote: 1.9.0 spawn-command: 0.0.2 supports-color: 8.1.1 tree-kill: 1.2.2 - yargs: 17.7.2 + yargs: 17.7.3 confbox@0.2.4: {} @@ -8213,7 +8367,7 @@ snapshots: dependencies: accepts: 1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.5 + body-parser: 1.20.6 content-disposition: 0.5.4 content-type: 1.0.5 cookie: 0.7.2 @@ -8232,7 +8386,7 @@ snapshots: parseurl: 1.3.3 path-to-regexp: 0.1.13 proxy-addr: 2.0.7 - qs: 6.15.2 + qs: 6.15.3 range-parser: 1.2.1 safe-buffer: 5.2.1 send: 0.19.2 @@ -8267,8 +8421,8 @@ snapshots: once: 1.4.0 parseurl: 1.3.3 proxy-addr: 2.0.7 - qs: 6.15.2 - range-parser: 1.2.1 + qs: 6.15.3 + range-parser: 1.3.0 router: 2.2.0 send: 1.2.1 serve-static: 2.2.1 @@ -8278,7 +8432,7 @@ snapshots: transitivePeerDependencies: - supports-color - exsolve@1.0.8: {} + exsolve@1.1.0: {} extend-shallow@2.0.1: dependencies: @@ -8306,7 +8460,7 @@ snapshots: dependencies: pure-rand: 6.1.0 - fast-copy@4.0.3: {} + fast-copy@4.0.4: {} fast-deep-equal@3.1.3: {} @@ -8316,7 +8470,7 @@ snapshots: fast-safe-stringify@2.1.1: {} - fast-uri@3.1.2: {} + fast-uri@3.1.3: {} fd-slicer@1.1.0: dependencies: @@ -8390,7 +8544,7 @@ snapshots: fresh@2.0.0: {} - fs-extra@11.3.5: + fs-extra@11.3.6: dependencies: graceful-fs: 4.2.11 jsonfile: 6.2.1 @@ -8450,7 +8604,7 @@ snapshots: gif.js.optimized@1.0.1: {} - giget@3.2.0: {} + giget@3.3.0: {} github-slugger@2.0.0: {} @@ -8599,20 +8753,20 @@ snapshots: hast-util-from-dom@5.0.1: dependencies: - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 hastscript: 9.0.1 web-namespaces: 2.0.1 hast-util-from-html-isomorphic@2.0.0: dependencies: - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 hast-util-from-dom: 5.0.1 hast-util-from-html: 2.0.3 unist-util-remove-position: 5.0.0 hast-util-from-html@2.0.3: dependencies: - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 devlop: 1.1.0 hast-util-from-parse5: 8.0.3 parse5: 7.3.0 @@ -8621,7 +8775,7 @@ snapshots: hast-util-from-parse5@8.0.3: dependencies: - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 '@types/unist': 3.0.3 devlop: 1.1.0 hastscript: 9.0.1 @@ -8632,21 +8786,21 @@ snapshots: hast-util-heading-rank@3.0.0: dependencies: - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 hast-util-is-element@3.0.0: dependencies: - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 hast-util-parse-selector@4.0.0: dependencies: - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 hast-util-raw@9.1.0: dependencies: - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 '@types/unist': 3.0.3 - '@ungap/structured-clone': 1.3.1 + '@ungap/structured-clone': 1.3.2 hast-util-from-parse5: 8.0.3 hast-util-to-parse5: 8.0.1 html-void-elements: 3.0.0 @@ -8660,7 +8814,7 @@ snapshots: hast-util-to-html@9.0.5: dependencies: - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 '@types/unist': 3.0.3 ccount: 2.0.1 comma-separated-tokens: 2.0.3 @@ -8675,7 +8829,7 @@ snapshots: hast-util-to-jsx-runtime@2.3.6: dependencies: '@types/estree': 1.0.9 - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 '@types/unist': 3.0.3 comma-separated-tokens: 2.0.3 devlop: 1.1.0 @@ -8694,7 +8848,7 @@ snapshots: hast-util-to-parse5@8.0.1: dependencies: - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 comma-separated-tokens: 2.0.3 devlop: 1.1.0 property-information: 7.2.0 @@ -8704,22 +8858,22 @@ snapshots: hast-util-to-string@3.0.1: dependencies: - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 hast-util-to-text@4.0.2: dependencies: - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 '@types/unist': 3.0.3 hast-util-is-element: 3.0.0 unist-util-find-after: 5.0.0 hast-util-whitespace@3.0.0: dependencies: - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 hastscript@9.0.1: dependencies: - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 comma-separated-tokens: 2.0.3 hast-util-parse-selector: 4.0.0 property-information: 7.2.0 @@ -8727,7 +8881,7 @@ snapshots: help-me@5.0.0: {} - hono@4.12.25: {} + hono@4.12.28: {} html-escaper@2.0.2: {} @@ -8786,13 +8940,13 @@ snapshots: dependencies: safer-buffer: 2.1.2 - iconv-lite@0.7.2: + iconv-lite@0.7.3: dependencies: safer-buffer: 2.1.2 - icu-minify@4.13.1: + icu-minify@4.13.2: dependencies: - '@formatjs/icu-messageformat-parser': 3.5.12 + '@formatjs/icu-messageformat-parser': 3.5.14 ieee754@1.2.1: {} @@ -8838,10 +8992,10 @@ snapshots: '@formatjs/icu-messageformat-parser': 2.11.4 tslib: 2.8.1 - intl-messageformat@11.2.9: + intl-messageformat@11.2.11: dependencies: - '@formatjs/fast-memoize': 3.1.6 - '@formatjs/icu-messageformat-parser': 3.5.12 + '@formatjs/fast-memoize': 3.1.7 + '@formatjs/icu-messageformat-parser': 3.5.14 ip-address@10.2.0: {} @@ -9009,7 +9163,7 @@ snapshots: dependencies: '@paulirish/trace_engine': 0.0.53 '@sentry/node': 7.120.4 - axe-core: 4.12.0 + axe-core: 4.12.1 chrome-launcher: 1.2.1 configstore: 5.0.1 csp_evaluator: 1.1.5 @@ -9033,7 +9187,7 @@ snapshots: third-party-web: 0.26.7 tldts-icann: 6.1.86 ws: 7.5.11 - yargs: 17.7.2 + yargs: 17.7.3 yargs-parser: 21.1.1 transitivePeerDependencies: - bare-abort-controller @@ -9097,7 +9251,7 @@ snapshots: lint-staged@17.0.8: dependencies: listr2: 10.2.2 - picomatch: 4.0.4 + picomatch: 4.0.5 string-argv: 0.3.2 tinyexec: 1.2.4 optionalDependencies: @@ -9141,7 +9295,7 @@ snapshots: lookup-closest-locale@6.2.0: {} - lru-cache@11.5.1: {} + lru-cache@11.5.2: {} lru-cache@7.18.3: {} @@ -9252,7 +9406,7 @@ snapshots: mdast-util-math@3.0.0: dependencies: - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 '@types/mdast': 4.0.4 devlop: 1.1.0 longest-streak: 3.1.0 @@ -9265,7 +9419,7 @@ snapshots: mdast-util-mdx-expression@2.0.1: dependencies: '@types/estree-jsx': 1.0.5 - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 '@types/mdast': 4.0.4 devlop: 1.1.0 mdast-util-from-markdown: 2.0.3 @@ -9276,7 +9430,7 @@ snapshots: mdast-util-mdx-jsx@3.2.0: dependencies: '@types/estree-jsx': 1.0.5 - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 '@types/mdast': 4.0.4 '@types/unist': 3.0.3 ccount: 2.0.1 @@ -9293,7 +9447,7 @@ snapshots: mdast-util-mdxjs-esm@2.0.1: dependencies: '@types/estree-jsx': 1.0.5 - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 '@types/mdast': 4.0.4 devlop: 1.1.0 mdast-util-from-markdown: 2.0.3 @@ -9313,9 +9467,9 @@ snapshots: mdast-util-to-hast@13.2.1: dependencies: - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 '@types/mdast': 4.0.4 - '@ungap/structured-clone': 1.3.1 + '@ungap/structured-clone': 1.3.2 devlop: 1.1.0 micromark-util-sanitize-uri: 2.0.1 trim-lines: 3.0.1 @@ -9343,7 +9497,7 @@ snapshots: dependencies: '@types/mdast': 4.0.4 '@types/ungap__structured-clone': 1.2.0 - '@ungap/structured-clone': 1.3.1 + '@ungap/structured-clone': 1.3.2 github-slugger: 2.0.0 mdast-util-to-string: 4.0.0 unist-util-is: 6.0.1 @@ -9592,7 +9746,7 @@ snapshots: minimatch@3.1.5: dependencies: - brace-expansion: 1.1.15 + brace-expansion: 1.1.16 minimist@1.2.8: {} @@ -9645,16 +9799,16 @@ snapshots: aws-ssl-profiles: 1.1.2 denque: 2.1.0 generate-function: 2.3.1 - iconv-lite: 0.7.2 + iconv-lite: 0.7.3 long: 5.3.2 lru.min: 1.1.4 named-placeholders: 1.1.6 seq-queue: 0.0.5 sqlstring: 2.3.3 - n8ao@1.10.2(postprocessing@6.39.1(three@0.184.0))(three@0.184.0): + n8ao@1.10.3(postprocessing@6.39.2(three@0.184.0))(three@0.184.0): dependencies: - postprocessing: 6.39.1(three@0.184.0) + postprocessing: 6.39.2(three@0.184.0) three: 0.184.0 named-placeholders@1.1.6: @@ -9671,50 +9825,50 @@ snapshots: netmask@2.1.1: {} - next-auth@5.0.0-beta.31(next@16.2.10(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7): + next-auth@5.0.0-beta.31(next@16.3.0-preview.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7): dependencies: '@auth/core': 0.41.2 - next: 16.2.10(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + next: 16.3.0-preview.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) react: 19.2.7 - next-intl-swc-plugin-extractor@4.13.1: {} + next-intl-swc-plugin-extractor@4.13.2: {} - next-intl@4.13.1(next@16.2.10(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7)(typescript@6.0.3): + next-intl@4.13.2(@swc/helpers@0.5.23)(next@16.3.0-preview.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7)(typescript@7.0.2): dependencies: - '@formatjs/intl-localematcher': 0.8.10 + '@formatjs/intl-localematcher': 0.8.12 '@parcel/watcher': 2.5.6 - '@swc/core': 1.15.43 - icu-minify: 4.13.1 + '@swc/core': 1.15.43(@swc/helpers@0.5.23) + icu-minify: 4.13.2 negotiator: 1.0.0 - next: 16.2.10(react-dom@19.2.7(react@19.2.7))(react@19.2.7) - next-intl-swc-plugin-extractor: 4.13.1 + next: 16.3.0-preview.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + next-intl-swc-plugin-extractor: 4.13.2 po-parser: 2.1.1 react: 19.2.7 - use-intl: 4.13.1(react@19.2.7) + use-intl: 4.13.2(react@19.2.7) optionalDependencies: - typescript: 6.0.3 + typescript: 7.0.2 transitivePeerDependencies: - '@swc/helpers' - next@16.2.10(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + next@16.3.0-preview.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: - '@next/env': 16.2.10 + '@next/env': 16.3.0-preview.5 '@swc/helpers': 0.5.15 - baseline-browser-mapping: 2.10.40 - caniuse-lite: 1.0.30001800 - postcss: 8.4.31 + baseline-browser-mapping: 2.10.42 + caniuse-lite: 1.0.30001803 + postcss: 8.5.10 react: 19.2.7 react-dom: 19.2.7(react@19.2.7) styled-jsx: 5.1.6(react@19.2.7) optionalDependencies: - '@next/swc-darwin-arm64': 16.2.10 - '@next/swc-darwin-x64': 16.2.10 - '@next/swc-linux-arm64-gnu': 16.2.10 - '@next/swc-linux-arm64-musl': 16.2.10 - '@next/swc-linux-x64-gnu': 16.2.10 - '@next/swc-linux-x64-musl': 16.2.10 - '@next/swc-win32-arm64-msvc': 16.2.10 - '@next/swc-win32-x64-msvc': 16.2.10 + '@next/swc-darwin-arm64': 16.3.0-preview.5 + '@next/swc-darwin-x64': 16.3.0-preview.5 + '@next/swc-linux-arm64-gnu': 16.3.0-preview.5 + '@next/swc-linux-arm64-musl': 16.3.0-preview.5 + '@next/swc-linux-x64-gnu': 16.3.0-preview.5 + '@next/swc-linux-x64-musl': 16.3.0-preview.5 + '@next/swc-win32-arm64-msvc': 16.3.0-preview.5 + '@next/swc-win32-x64-msvc': 16.3.0-preview.5 sharp: 0.34.5 transitivePeerDependencies: - '@babel/core' @@ -9742,7 +9896,7 @@ snapshots: dependencies: path-key: 3.1.1 - nucleation@0.2.13: {} + nucleation@0.2.17: {} oauth4webapi@3.8.6: {} @@ -9858,27 +10012,27 @@ snapshots: '@oxfmt/binding-win32-ia32-msvc': 0.57.0 '@oxfmt/binding-win32-x64-msvc': 0.57.0 - oxlint@1.72.0: + oxlint@1.73.0: optionalDependencies: - '@oxlint/binding-android-arm-eabi': 1.72.0 - '@oxlint/binding-android-arm64': 1.72.0 - '@oxlint/binding-darwin-arm64': 1.72.0 - '@oxlint/binding-darwin-x64': 1.72.0 - '@oxlint/binding-freebsd-x64': 1.72.0 - '@oxlint/binding-linux-arm-gnueabihf': 1.72.0 - '@oxlint/binding-linux-arm-musleabihf': 1.72.0 - '@oxlint/binding-linux-arm64-gnu': 1.72.0 - '@oxlint/binding-linux-arm64-musl': 1.72.0 - '@oxlint/binding-linux-ppc64-gnu': 1.72.0 - '@oxlint/binding-linux-riscv64-gnu': 1.72.0 - '@oxlint/binding-linux-riscv64-musl': 1.72.0 - '@oxlint/binding-linux-s390x-gnu': 1.72.0 - '@oxlint/binding-linux-x64-gnu': 1.72.0 - '@oxlint/binding-linux-x64-musl': 1.72.0 - '@oxlint/binding-openharmony-arm64': 1.72.0 - '@oxlint/binding-win32-arm64-msvc': 1.72.0 - '@oxlint/binding-win32-ia32-msvc': 1.72.0 - '@oxlint/binding-win32-x64-msvc': 1.72.0 + '@oxlint/binding-android-arm-eabi': 1.73.0 + '@oxlint/binding-android-arm64': 1.73.0 + '@oxlint/binding-darwin-arm64': 1.73.0 + '@oxlint/binding-darwin-x64': 1.73.0 + '@oxlint/binding-freebsd-x64': 1.73.0 + '@oxlint/binding-linux-arm-gnueabihf': 1.73.0 + '@oxlint/binding-linux-arm-musleabihf': 1.73.0 + '@oxlint/binding-linux-arm64-gnu': 1.73.0 + '@oxlint/binding-linux-arm64-musl': 1.73.0 + '@oxlint/binding-linux-ppc64-gnu': 1.73.0 + '@oxlint/binding-linux-riscv64-gnu': 1.73.0 + '@oxlint/binding-linux-riscv64-musl': 1.73.0 + '@oxlint/binding-linux-s390x-gnu': 1.73.0 + '@oxlint/binding-linux-x64-gnu': 1.73.0 + '@oxlint/binding-linux-x64-musl': 1.73.0 + '@oxlint/binding-openharmony-arm64': 1.73.0 + '@oxlint/binding-win32-arm64-msvc': 1.73.0 + '@oxlint/binding-win32-ia32-msvc': 1.73.0 + '@oxlint/binding-win32-x64-msvc': 1.73.0 p-limit@2.3.0: dependencies: @@ -9910,7 +10064,7 @@ snapshots: pako@1.0.11: {} - pako@2.1.0: {} + pako@2.2.0: {} pandemonium@2.4.1: dependencies: @@ -9946,7 +10100,7 @@ snapshots: path-scurry@2.0.2: dependencies: - lru-cache: 11.5.1 + lru-cache: 11.5.2 minipass: 7.1.3 path-to-regexp@0.1.13: {} @@ -9969,15 +10123,15 @@ snapshots: pg-cloudflare@1.4.0: optional: true - pg-connection-string@2.13.0: {} + pg-connection-string@2.14.0: {} pg-int8@1.0.1: {} - pg-pool@3.14.0(pg@8.21.0): + pg-pool@3.14.0(pg@8.22.0): dependencies: - pg: 8.21.0 + pg: 8.22.0 - pg-protocol@1.14.0: {} + pg-protocol@1.15.0: {} pg-types@2.2.0: dependencies: @@ -9987,11 +10141,11 @@ snapshots: postgres-date: 1.0.7 postgres-interval: 1.2.0 - pg@8.21.0: + pg@8.22.0: dependencies: - pg-connection-string: 2.13.0 - pg-pool: 3.14.0(pg@8.21.0) - pg-protocol: 1.14.0 + pg-connection-string: 2.14.0 + pg-pool: 3.14.0(pg@8.22.0) + pg-protocol: 1.15.0 pg-types: 2.2.0 pgpass: 1.0.5 optionalDependencies: @@ -10005,8 +10159,6 @@ snapshots: picomatch@2.3.2: {} - picomatch@4.0.4: {} - picomatch@4.0.5: {} pino-abstract-transport@3.0.0: @@ -10017,7 +10169,7 @@ snapshots: dependencies: colorette: 2.0.20 dateformat: 4.6.3 - fast-copy: 4.0.3 + fast-copy: 4.0.4 fast-safe-stringify: 2.1.1 help-me: 5.0.0 joycon: 3.1.1 @@ -10050,7 +10202,7 @@ snapshots: pkg-types@2.3.1: dependencies: confbox: 0.2.4 - exsolve: 1.0.8 + exsolve: 1.1.0 pathe: 2.0.3 platform@1.3.6: {} @@ -10065,7 +10217,7 @@ snapshots: po-parser@2.1.1: {} - postcss@8.4.31: + postcss@8.5.10: dependencies: nanoid: 3.3.15 picocolors: 1.1.1 @@ -10091,7 +10243,7 @@ snapshots: postgres@3.4.7: {} - postprocessing@6.39.1(three@0.184.0): + postprocessing@6.39.2(three@0.184.0): dependencies: three: 0.184.0 @@ -10101,16 +10253,16 @@ snapshots: preact@10.24.3: {} - prisma@7.8.0(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3): + prisma@7.8.0(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@7.0.2): dependencies: '@prisma/config': 7.8.0 - '@prisma/dev': 0.24.3(typescript@6.0.3) + '@prisma/dev': 0.24.3(typescript@7.0.2) '@prisma/engines': 7.8.0 '@prisma/studio-core': 0.27.3(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) mysql2: 3.15.3 postgres: 3.4.7 optionalDependencies: - typescript: 6.0.3 + typescript: 7.0.2 transitivePeerDependencies: - '@types/react' - '@types/react-dom' @@ -10149,7 +10301,7 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.2 - '@types/node': 26.1.0 + '@types/node': 26.1.1 long: 5.3.2 protodef-validator@1.4.0: @@ -10210,8 +10362,9 @@ snapshots: pure-rand@6.1.0: {} - qs@6.15.2: + qs@6.15.3: dependencies: + es-define-property: 1.0.1 side-channel: 1.1.1 querystring@0.2.0: {} @@ -10220,6 +10373,8 @@ snapshots: range-parser@1.2.1: {} + range-parser@1.3.0: {} + raw-body@2.5.3: dependencies: bytes: 3.1.2 @@ -10231,7 +10386,7 @@ snapshots: dependencies: bytes: 3.1.2 http-errors: 2.0.1 - iconv-lite: 0.7.2 + iconv-lite: 0.7.3 unpipe: 1.0.0 rc9@3.0.1: @@ -10253,7 +10408,7 @@ snapshots: react-markdown@10.1.0(@types/react@19.2.17)(react@19.2.7): dependencies: - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 '@types/mdast': 4.0.4 '@types/react': 19.2.17 devlop: 1.1.0 @@ -10311,7 +10466,7 @@ snapshots: rehype-katex@7.0.1: dependencies: - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 '@types/katex': 0.16.8 hast-util-from-html-isomorphic: 2.0.0 hast-util-to-text: 4.0.2 @@ -10321,13 +10476,13 @@ snapshots: rehype-raw@7.0.0: dependencies: - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 hast-util-raw: 9.1.0 vfile: 6.0.3 rehype-slug@6.0.0: dependencies: - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 github-slugger: 2.0.0 hast-util-heading-rank: 3.0.0 hast-util-to-string: 3.0.1 @@ -10335,7 +10490,7 @@ snapshots: rehype-stringify@10.0.1: dependencies: - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 hast-util-to-html: 9.0.5 unified: 11.0.5 @@ -10376,7 +10531,7 @@ snapshots: remark-rehype@11.1.2: dependencies: - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 '@types/mdast': 4.0.4 mdast-util-to-hast: 13.2.1 unified: 11.0.5 @@ -10447,26 +10602,26 @@ snapshots: robots-parser@3.0.1: {} - rolldown@1.0.3: + rolldown@1.1.5: dependencies: - '@oxc-project/types': 0.133.0 + '@oxc-project/types': 0.139.0 '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.3 - '@rolldown/binding-darwin-arm64': 1.0.3 - '@rolldown/binding-darwin-x64': 1.0.3 - '@rolldown/binding-freebsd-x64': 1.0.3 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.3 - '@rolldown/binding-linux-arm64-gnu': 1.0.3 - '@rolldown/binding-linux-arm64-musl': 1.0.3 - '@rolldown/binding-linux-ppc64-gnu': 1.0.3 - '@rolldown/binding-linux-s390x-gnu': 1.0.3 - '@rolldown/binding-linux-x64-gnu': 1.0.3 - '@rolldown/binding-linux-x64-musl': 1.0.3 - '@rolldown/binding-openharmony-arm64': 1.0.3 - '@rolldown/binding-wasm32-wasi': 1.0.3 - '@rolldown/binding-win32-arm64-msvc': 1.0.3 - '@rolldown/binding-win32-x64-msvc': 1.0.3 + '@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 router@2.2.0: dependencies: @@ -10498,29 +10653,29 @@ snapshots: scheduler@0.27.0: {} - schematic-renderer@1.6.1(vite@8.0.16(@types/node@26.1.0)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0)): + schematic-renderer@1.6.1(@swc/helpers@0.5.23)(vite@8.1.4(@types/node@26.1.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0)): dependencies: '@ffmpeg/ffmpeg': 0.12.15 '@ffmpeg/util': 0.12.2 chokidar: 3.6.0 concurrently: 8.2.2 deepmerge: 4.3.1 - fs-extra: 11.3.5 + fs-extra: 11.3.6 gif.js.optimized: 1.0.1 gzip-js: 0.3.2 http-proxy-middleware: 0.2.0 jszip: 3.10.1 lil-gui: 0.19.2 - n8ao: 1.10.2(postprocessing@6.39.1(three@0.184.0))(three@0.184.0) - nucleation: 0.2.13 - pako: 2.1.0 - postprocessing: 6.39.1(three@0.184.0) + n8ao: 1.10.3(postprocessing@6.39.2(three@0.184.0))(three@0.184.0) + nucleation: 0.2.17 + pako: 2.2.0 + postprocessing: 6.39.2(three@0.184.0) simplex-noise: 4.0.3 stats-js: 1.0.1 three: 0.184.0 three-creative-controls: 1.0.1 - vite-plugin-top-level-await: 1.6.0(vite@8.0.16(@types/node@26.1.0)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0)) - vite-plugin-wasm: 3.6.0(vite@8.0.16(@types/node@26.1.0)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0)) + vite-plugin-top-level-await: 1.6.0(@swc/helpers@0.5.23)(vite@8.1.4(@types/node@26.1.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0)) + vite-plugin-wasm: 3.6.0(vite@8.1.4(@types/node@26.1.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0)) webm-writer: 1.0.0 transitivePeerDependencies: - '@swc/helpers' @@ -10572,7 +10727,7 @@ snapshots: mime-types: 3.0.2 ms: 2.1.3 on-finished: 2.4.1 - range-parser: 1.2.1 + range-parser: 1.3.0 statuses: 2.0.2 transitivePeerDependencies: - supports-color @@ -10648,7 +10803,7 @@ snapshots: shebang-regex@3.0.0: {} - shell-quote@1.8.4: {} + shell-quote@1.9.0: {} shiki@4.3.1: dependencies: @@ -10659,7 +10814,7 @@ snapshots: '@shikijs/themes': 4.3.1 '@shikijs/types': 4.3.1 '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 + '@types/hast': 3.0.5 side-channel-list@1.0.1: dependencies: @@ -10743,7 +10898,7 @@ snapshots: speedline-core@1.4.3: dependencies: - '@types/node': 26.1.0 + '@types/node': 26.1.1 image-ssim: 0.2.0 jpeg-js: 0.4.4 @@ -10763,11 +10918,11 @@ snapshots: std-env@3.10.0: {} - std-env@4.1.0: {} + std-env@4.2.0: {} streamsearch@1.1.0: {} - streamx@2.27.0: + streamx@2.28.0: dependencies: events-universal: 1.0.1 fast-fifo: 1.3.2 @@ -10795,7 +10950,7 @@ snapshots: get-east-asian-width: 1.6.0 strip-ansi: 7.2.0 - string-width@8.2.1: + string-width@8.2.2: dependencies: get-east-asian-width: 1.6.0 strip-ansi: 7.2.0 @@ -10883,13 +11038,13 @@ snapshots: tapable@2.3.3: {} - tar-fs@3.1.2: + tar-fs@3.1.3: dependencies: pump: 3.0.4 tar-stream: 3.2.0 optionalDependencies: - bare-fs: 4.7.2 - bare-path: 3.0.1 + bare-fs: 4.7.4 + bare-path: 3.1.1 transitivePeerDependencies: - bare-abort-controller - bare-buffer @@ -10898,9 +11053,9 @@ snapshots: tar-stream@3.2.0: dependencies: b4a: 1.8.1 - bare-fs: 4.7.2 + bare-fs: 4.7.4 fast-fifo: 1.3.2 - streamx: 2.27.0 + streamx: 2.28.0 transitivePeerDependencies: - bare-abort-controller - bare-buffer @@ -10916,7 +11071,7 @@ snapshots: teex@1.0.1: dependencies: - streamx: 2.27.0 + streamx: 2.28.0 transitivePeerDependencies: - bare-abort-controller - react-native-b4a @@ -11099,7 +11254,28 @@ snapshots: dependencies: is-typedarray: 1.0.0 - typescript@6.0.3: {} + typescript@7.0.2: + optionalDependencies: + '@typescript/typescript-aix-ppc64': 7.0.2 + '@typescript/typescript-darwin-arm64': 7.0.2 + '@typescript/typescript-darwin-x64': 7.0.2 + '@typescript/typescript-freebsd-arm64': 7.0.2 + '@typescript/typescript-freebsd-x64': 7.0.2 + '@typescript/typescript-linux-arm': 7.0.2 + '@typescript/typescript-linux-arm64': 7.0.2 + '@typescript/typescript-linux-loong64': 7.0.2 + '@typescript/typescript-linux-mips64el': 7.0.2 + '@typescript/typescript-linux-ppc64': 7.0.2 + '@typescript/typescript-linux-riscv64': 7.0.2 + '@typescript/typescript-linux-s390x': 7.0.2 + '@typescript/typescript-linux-x64': 7.0.2 + '@typescript/typescript-netbsd-arm64': 7.0.2 + '@typescript/typescript-netbsd-x64': 7.0.2 + '@typescript/typescript-openbsd-arm64': 7.0.2 + '@typescript/typescript-openbsd-x64': 7.0.2 + '@typescript/typescript-sunos-x64': 7.0.2 + '@typescript/typescript-win32-arm64': 7.0.2 + '@typescript/typescript-win32-x64': 7.0.2 typical@7.3.0: {} @@ -11175,12 +11351,12 @@ snapshots: punycode: 1.3.2 querystring: 0.2.0 - use-intl@4.13.1(react@19.2.7): + use-intl@4.13.2(react@19.2.7): dependencies: - '@formatjs/fast-memoize': 3.1.6 + '@formatjs/fast-memoize': 3.1.7 '@schummar/icu-type-parser': 1.21.5 - icu-minify: 4.13.1 - intl-messageformat: 11.2.9 + icu-minify: 4.13.2 + intl-messageformat: 11.2.11 react: 19.2.7 util-deprecate@1.0.2: {} @@ -11195,9 +11371,9 @@ snapshots: uzip@0.20201231.0: {} - valibot@1.2.0(typescript@6.0.3): + valibot@1.2.0(typescript@7.0.2): optionalDependencies: - typescript: 6.0.3 + typescript: 7.0.2 vary@1.1.2: {} @@ -11216,40 +11392,40 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite-plugin-top-level-await@1.6.0(vite@8.0.16(@types/node@26.1.0)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0)): + vite-plugin-top-level-await@1.6.0(@swc/helpers@0.5.23)(vite@8.1.4(@types/node@26.1.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0)): dependencies: '@rollup/plugin-virtual': 3.0.2 - '@swc/core': 1.15.43 - '@swc/wasm': 1.15.41 + '@swc/core': 1.15.43(@swc/helpers@0.5.23) + '@swc/wasm': 1.15.43 uuid: 10.0.0 - vite: 8.0.16(@types/node@26.1.0)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0) + vite: 8.1.4(@types/node@26.1.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0) transitivePeerDependencies: - '@swc/helpers' - rollup - vite-plugin-wasm@3.6.0(vite@8.0.16(@types/node@26.1.0)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0)): + vite-plugin-wasm@3.6.0(vite@8.1.4(@types/node@26.1.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0)): dependencies: - vite: 8.0.16(@types/node@26.1.0)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0) + vite: 8.1.4(@types/node@26.1.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0) - vite@8.0.16(@types/node@26.1.0)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0): + vite@8.1.4(@types/node@26.1.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0): dependencies: lightningcss: 1.32.0 picomatch: 4.0.5 postcss: 8.5.16 - rolldown: 1.0.3 + rolldown: 1.1.5 tinyglobby: 0.2.17 optionalDependencies: - '@types/node': 26.1.0 + '@types/node': 26.1.1 esbuild: 0.28.1 fsevents: 2.3.3 jiti: 2.7.0 tsx: 4.23.0 yaml: 2.9.0 - vitest@4.1.10(@types/node@26.1.0)(vite@8.0.16(@types/node@26.1.0)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0)): + vitest@4.1.10(@types/node@26.1.1)(vite@8.1.4(@types/node@26.1.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0)): dependencies: '@vitest/expect': 4.1.10 - '@vitest/mocker': 4.1.10(vite@8.0.16(@types/node@26.1.0)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0)) + '@vitest/mocker': 4.1.10(vite@8.1.4(@types/node@26.1.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0)) '@vitest/pretty-format': 4.1.10 '@vitest/runner': 4.1.10 '@vitest/snapshot': 4.1.10 @@ -11261,15 +11437,15 @@ snapshots: obug: 2.1.3 pathe: 2.0.3 picomatch: 4.0.5 - std-env: 4.1.0 + std-env: 4.2.0 tinybench: 2.9.0 tinyexec: 1.2.4 tinyglobby: 0.2.17 tinyrainbow: 3.1.0 - vite: 8.0.16(@types/node@26.1.0)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0) + vite: 8.1.4(@types/node@26.1.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.0)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 26.1.0 + '@types/node': 26.1.1 transitivePeerDependencies: - msw @@ -11329,7 +11505,7 @@ snapshots: wrap-ansi@10.0.0: dependencies: ansi-styles: 6.2.3 - string-width: 8.2.1 + string-width: 8.2.2 strip-ansi: 7.2.0 wrap-ansi@6.2.0: @@ -11411,7 +11587,7 @@ snapshots: y18n: 4.0.3 yargs-parser: 18.1.3 - yargs@17.7.2: + yargs@17.7.3: dependencies: cliui: 8.0.1 escalade: 3.2.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 7226afd6..0c6e4023 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -22,15 +22,13 @@ allowBuilds: tree-sitter-rust: true tree-sitter-typescript: true minimumReleaseAgeExclude: - - '@next/bundle-analyzer@16.2.9' - - '@next/env@16.2.9' - - '@next/swc-darwin-arm64@16.2.9' - - '@next/swc-darwin-x64@16.2.9' - - '@next/swc-linux-arm64-gnu@16.2.9' - - '@next/swc-linux-arm64-musl@16.2.9' - - '@next/swc-linux-x64-gnu@16.2.9' - - '@next/swc-linux-x64-musl@16.2.9' - - '@next/swc-win32-arm64-msvc@16.2.9' - - '@next/swc-win32-x64-msvc@16.2.9' - - next@16.2.9 - - schematic-renderer@1.4.5 + - '@next/env@16.3.0-canary.83' + - '@next/swc-darwin-arm64@16.3.0-canary.83' + - '@next/swc-darwin-x64@16.3.0-canary.83' + - '@next/swc-linux-arm64-gnu@16.3.0-canary.83' + - '@next/swc-linux-arm64-musl@16.3.0-canary.83' + - '@next/swc-linux-x64-gnu@16.3.0-canary.83' + - '@next/swc-linux-x64-musl@16.3.0-canary.83' + - '@next/swc-win32-arm64-msvc@16.3.0-canary.83' + - '@next/swc-win32-x64-msvc@16.3.0-canary.83' + - next@16.3.0-canary.83 diff --git a/scripts/article-frontmatter.schema.json b/scripts/article-frontmatter.schema.json deleted file mode 100644 index 07a9cf20..00000000 --- a/scripts/article-frontmatter.schema.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "title": "ArticleFrontmatter", - "description": "Schema for article YAML frontmatter — validates both source (zh) and translation (en) branches. At runtime, kebab-case keys are mapped to camelCase (e.g. chapter-title → chapterTitle). Each branch uses additionalProperties: false to reject unknown keys.", - "oneOf": [ - { - "title": "SourceFrontmatter", - "description": "Source article frontmatter (e.g. *.zh.md). Required: slug, title. Forbidden: author, co-authors, date, lastmod, title-en, chapter-title-en, intro-title-en, translates, translated-from-revision.", - "type": "object", - "properties": { - "slug": { - "type": "string", - "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$", - "description": "URL slug, must match SLUG_REGEX in lib/slug-validator.ts" - }, - "title": { - "type": "string", - "description": "Article title in source locale" - }, - "chapter-title": { - "type": "string", - "description": "Chapter-level title for grouped articles" - }, - "intro-title": { - "type": "string", - "description": "Introduction / subtitle for the article" - }, - "description": { - "type": "string", - "description": "Short description or summary" - }, - "index": { - "type": "integer", - "minimum": -1, - "description": "Sort order index (-1 for floating/excluded)" - }, - "is-advanced": { - "type": "boolean", - "description": "Flag for advanced-level content" - }, - "banner": { - "type": "object", - "description": "Banner image for OG/twitter cards", - "properties": { - "src": { - "type": "string", - "description": "Banner image URL" - }, - "alt": { - "type": "string", - "description": "Accessible alt text" - } - }, - "required": ["src"], - "additionalProperties": false - } - }, - "required": ["slug", "title"], - "additionalProperties": false - }, - { - "title": "TranslationFrontmatter", - "description": "Translation article frontmatter (e.g. *.en.md). Required: translates, translated-from-revision. Forbidden: slug, index, is-advanced, author, co-authors, date, lastmod, title-en, chapter-title-en, intro-title-en.", - "type": "object", - "properties": { - "translates": { - "type": "string", - "description": "Source slug that this article translates" - }, - "translated-from-revision": { - "type": "string", - "pattern": "^[0-9a-f]{7,40}$", - "description": "Git commit SHA (short or full) of the translated source revision" - }, - "title": { - "type": "string", - "description": "Translated article title (override)" - }, - "chapter-title": { - "type": "string", - "description": "Translated chapter title (override)" - }, - "intro-title": { - "type": "string", - "description": "Translated intro title (override)" - }, - "description": { - "type": "string", - "description": "Translated description (override)" - }, - "banner": { - "type": "object", - "description": "Banner image override for translation", - "properties": { - "src": { - "type": "string", - "description": "Banner image URL" - }, - "alt": { - "type": "string", - "description": "Accessible alt text" - } - }, - "required": ["src"], - "additionalProperties": false - } - }, - "required": ["translates", "translated-from-revision"], - "additionalProperties": false - } - ] -} diff --git a/scripts/generate-article-content.ts b/scripts/generate-article-content.ts index 5460b015..c3ed50d8 100644 --- a/scripts/generate-article-content.ts +++ b/scripts/generate-article-content.ts @@ -12,11 +12,15 @@ import { resolveArticleAssetPath, } from "@/lib/articles/banner-assets" import { + parseSourceReadmeFrontMatter, parseSourceFrontMatter, + parseTranslationReadmeFrontMatter, parseTranslationFrontMatter, } from "@/lib/articles/frontmatter-parser" import type { + SourceReadmeFrontMatter, SourceFrontMatter, + TranslationReadmeFrontMatter, TranslationFrontMatter, } from "@/lib/articles/frontmatter-parser" @@ -38,6 +42,11 @@ const IS_PRODUCTION = process.env.NODE_ENV !== "development" * regenerated, matching prior behaviour. */ type ContentCache = Record +type EnglishFrontMatter = + | TranslationFrontMatter + | TranslationReadmeFrontMatter + | SourceFrontMatter + | SourceReadmeFrontMatter function loadCache(): ContentCache { try { @@ -88,11 +97,12 @@ function readCachedFrontmatter( * Strip YAML frontmatter delimited by `---` and return the body text. */ function stripFrontMatter(raw: string): string { - const idx = raw.indexOf("\n---\n") - if (raw.startsWith("---\n") && idx !== -1) { - return raw.slice(idx + 5) + const normalized = raw.startsWith("\uFEFF") ? raw.slice(1) : raw + const match = /^---\r?\n[\s\S]*?\r?\n---\r?\n?/.exec(normalized) + if (match) { + return normalized.slice(match[0].length) } - return raw + return normalized } function copyBannerAssetToPublic( @@ -126,6 +136,27 @@ function copyBannerAssetToPublic( } } +function parseEnglishFrontMatter( + fileContent: string, + isFolder: boolean +): EnglishFrontMatter { + try { + return isFolder + ? parseTranslationReadmeFrontMatter(fileContent) + : parseTranslationFrontMatter(fileContent) + } catch (error) { + if ( + error instanceof Error && + error.message === "missing required key 'translates'" + ) { + return isFolder + ? parseSourceReadmeFrontMatter(fileContent) + : parseSourceFrontMatter(fileContent) + } + throw error + } +} + function main(): void { let generatedCount = 0 let reusedCount = 0 @@ -250,57 +281,66 @@ function renderArtifact( let frontmatter: Record if (locale === "zh") { - let fm: SourceFrontMatter + let fm: SourceFrontMatter | SourceReadmeFrontMatter try { - fm = parseSourceFrontMatter(fileContent, { - allowTitlelessFolder: entry.isFolder, - }) + fm = entry.isFolder + ? parseSourceReadmeFrontMatter(fileContent) + : parseSourceFrontMatter(fileContent) } catch (error) { process.stderr.write( - `Error: Failed to parse source frontmatter for "${entry.slug}" (${locale}): ${(error as Error).message}\n` + `Error: Failed to parse source frontmatter for "${entry.slug}" (${locale}): ${error instanceof Error ? error.message : String(error)}\n` ) return null } artifactContent = stripFrontMatter(fileContent) + const chapterTitle = "chapter-title" in fm ? fm["chapter-title"] : undefined + const introTitle = "intro-title" in fm ? fm["intro-title"] : undefined frontmatter = { - title: fm.title, - ...(fm["chapter-title"] && { - "chapter-title": fm["chapter-title"], + ...("title" in fm && { title: fm.title }), + ...(chapterTitle && { + "chapter-title": chapterTitle, }), - ...(fm["intro-title"] && { "intro-title": fm["intro-title"] }), - ...(fm.description && { description: fm.description }), + ...(introTitle && { "intro-title": introTitle }), + ...("description" in fm && + fm.description && { description: fm.description }), index: fm.index, - ...(fm["is-advanced"] !== undefined && { - "is-advanced": fm["is-advanced"], - }), - ...(fm.banner && { banner: fm.banner }), + ...("is-advanced" in fm && + fm["is-advanced"] !== undefined && { + "is-advanced": fm["is-advanced"], + }), + ...("banner" in fm && fm.banner && { banner: fm.banner }), author: entry.author || undefined, coAuthors: entry.coAuthors || undefined, created: entry.created || undefined, lastmod: entry.lastmodByLocale.zh || undefined, } } else if (locale === "en") { - let fm: TranslationFrontMatter + let fm: EnglishFrontMatter try { - fm = parseTranslationFrontMatter(fileContent) + fm = parseEnglishFrontMatter(fileContent, entry.isFolder) } catch (error) { process.stderr.write( - `Error: Failed to parse translation frontmatter for "${entry.slug}" (${locale}): ${(error as Error).message}\n` + `Error: Failed to parse English frontmatter for "${entry.slug}" (${locale}): ${error instanceof Error ? error.message : String(error)}\n` ) return null } artifactContent = stripFrontMatter(fileContent) + const chapterTitle = "chapter-title" in fm ? fm["chapter-title"] : undefined + const introTitle = "intro-title" in fm ? fm["intro-title"] : undefined frontmatter = { - ...(fm.title && { title: fm.title }), - ...(fm["chapter-title"] && { - "chapter-title": fm["chapter-title"], + ...("title" in fm && fm.title && { title: fm.title }), + ...(chapterTitle && { + "chapter-title": chapterTitle, + }), + ...(introTitle && { "intro-title": introTitle }), + ...("description" in fm && + fm.description && { description: fm.description }), + ...("banner" in fm && fm.banner && { banner: fm.banner }), + ...("translated-from-revision" in fm && { + translatedFromRevision: fm["translated-from-revision"], }), - ...(fm["intro-title"] && { "intro-title": fm["intro-title"] }), - ...(fm.description && { description: fm.description }), - ...(fm.banner && { banner: fm.banner }), - translatedFromRevision: fm["translated-from-revision"], translationFreshness: entry.translationFreshnessByLocale.en || undefined, created: entry.created || undefined, lastmod: entry.lastmodByLocale.en || undefined, @@ -310,7 +350,7 @@ function renderArtifact( }), author: entry.author || undefined, coAuthors: entry.coAuthors || undefined, - ...(!fm.banner && + ...(!("banner" in fm && fm.banner) && entry.bannerByLocale?.zh && { banner: entry.bannerByLocale.zh }), } } else { diff --git a/scripts/generate-article-manifest.ts b/scripts/generate-article-manifest.ts index 6102adaf..05bf31e9 100644 --- a/scripts/generate-article-manifest.ts +++ b/scripts/generate-article-manifest.ts @@ -1,14 +1,19 @@ import fs from "fs" import path from "path" -import Ajv2020, { type AnySchema } from "ajv/dist/2020" +import { spawnSync } from "node:child_process" import type { ArticleEntry } from "@/lib/articles/manifest" import { shouldIgnoreDirectory, shouldIgnoreFile } from "@/lib/articles/ignore" import { buildGenerationSummary } from "./manifest-preview" import { + parseSourceReadmeFrontMatter, parseSourceFrontMatter, + parseTranslationReadmeFrontMatter, parseTranslationFrontMatter, + type SourceReadmeFrontMatter, type SourceFrontMatter, + type TranslationReadmeFrontMatter, + type TranslationFrontMatter, } from "@/lib/articles/frontmatter-parser" import { loadMaintainers, @@ -21,63 +26,35 @@ import { } from "@/lib/articles/git-metadata" const MANIFEST_FILE_NAME = "manifest.json" -const ARTICLES_PATH = path.join(process.cwd(), "articles") +const ARTICLES_PATH = + process.env.ARTICLES_PATH ?? path.join(process.cwd(), "articles") const OUTPUT_FILE = path.join(process.cwd(), "data", MANIFEST_FILE_NAME) +const ARTICLES_REPO_URL = "https://github.com/techmc-wiki/Articles.git" const SLUG_REGEX = /^[a-z0-9]+(?:-[a-z0-9]+)*$/ const MAX_DEPTH = 3 type ArticleManifest = Record -let ajv: Ajv2020 -let validateFrontmatter: ReturnType - function isReadmeLocaleFile(filename: string): boolean { return /^README(?:\.\w{2})?\.md$/i.test(filename) } -async function initAjv(): Promise { - ajv = new Ajv2020({ strict: false }) - const schemaPath = path.join( - process.cwd(), - "scripts", - "article-frontmatter.schema.json" - ) - const schemaContent = fs.readFileSync(schemaPath, "utf-8") - const schema = normalizeNullableOptionalFields( - JSON.parse(schemaContent) - ) as AnySchema - validateFrontmatter = ajv.compile(schema) +function parseSourceMetadata( + content: string, + isReadme: boolean +): SourceFrontMatter | SourceReadmeFrontMatter { + return isReadme + ? parseSourceReadmeFrontMatter(content) + : parseSourceFrontMatter(content) } -function normalizeNullableOptionalFields(value: unknown): unknown { - if (Array.isArray(value)) { - return value.map(normalizeNullableOptionalFields) - } - - if (typeof value !== "object" || value === null) { - return value - } - - const input = value as Record - const output: Record = {} - - for (const [key, childValue] of Object.entries(input)) { - output[key] = normalizeNullableOptionalFields(childValue) - } - - if (output.type === "string") { - output.type = ["string", "null"] - } - - return output -} - -function sanitizeForSchema( - value: T -): Record { - return Object.fromEntries( - Object.entries(value).filter(([, fieldValue]) => fieldValue !== undefined) - ) +function parseTranslationMetadata( + content: string, + isReadme: boolean +): TranslationFrontMatter | TranslationReadmeFrontMatter { + return isReadme + ? parseTranslationReadmeFrontMatter(content) + : parseTranslationFrontMatter(content) } function getParentSlug(slug: string): string | undefined { @@ -118,7 +95,7 @@ function getParentSlugFromRelPath(relPath: string): string { if (!readmeSource) continue - const slug = getSlugFromFile(readmeSource) + const slug = tryReadSlugFromFile(readmeSource) if (slug) slugs.push(slug) } @@ -141,19 +118,12 @@ async function processSourceFile( ): Promise> { const content = fs.readFileSync(filePath, "utf-8") - let fm: SourceFrontMatter + let fm: SourceFrontMatter | SourceReadmeFrontMatter try { - fm = parseSourceFrontMatter(content, { allowTitlelessFolder: isFolder }) - if (!validateFrontmatter(sanitizeForSchema(fm))) { - const errors = validateFrontmatter.errors || [] - const errorMsg = errors - .map((e) => `${e.instancePath} ${e.message}`) - .join(", ") - throw new Error(`${relPath}: validation failed: ${errorMsg}`) - } + fm = parseSourceMetadata(content, isFolder) } catch (error) { const errMsg = error instanceof Error ? error.message : String(error) - if (errMsg.includes("legacy key") || errMsg.includes("unknown key")) { + if (errMsg.includes("unknown key")) { throw new Error(`${relPath}: ${errMsg}`, { cause: error }) } throw error @@ -170,19 +140,20 @@ async function processSourceFile( relPath, maintainers ) + const chapterTitle = "chapter-title" in fm ? fm["chapter-title"] : undefined + const introTitle = "intro-title" in fm ? fm["intro-title"] : undefined const entry: Partial = { filePath: relPath, slug, - titleByLocale: { zh: fm.title }, + titleByLocale: "title" in fm ? { zh: fm.title } : {}, availableLocales: ["zh"], localizedFilePaths: { zh: relPath }, - chapterTitleByLocale: fm["chapter-title"] - ? { zh: fm["chapter-title"] } - : {}, - introTitleByLocale: fm["intro-title"] ? { zh: fm["intro-title"] } : {}, - descriptionByLocale: fm.description ? { zh: fm.description } : {}, - hasIntro: !!fm["intro-title"], + chapterTitleByLocale: chapterTitle ? { zh: chapterTitle } : {}, + introTitleByLocale: introTitle ? { zh: introTitle } : {}, + descriptionByLocale: + "description" in fm && fm.description ? { zh: fm.description } : {}, + hasIntro: !!introTitle, index: fm.index, isFolder, isAppendix: @@ -197,10 +168,10 @@ async function processSourceFile( lastmodByLocale: lastmod ? { zh: lastmod } : {}, translatedFromRevisionByLocale: {}, translationFreshnessByLocale: {}, - isAdvanced: fm["is-advanced"], + isAdvanced: "is-advanced" in fm ? fm["is-advanced"] : undefined, } - if (fm.banner) { + if ("banner" in fm && fm.banner) { entry.bannerByLocale = { zh: fm.banner } } @@ -215,14 +186,27 @@ async function processTranslationFile( manifest: ArticleManifest ): Promise { const content = fs.readFileSync(filePath, "utf-8") - const fm = parseTranslationFrontMatter(content) - - if (!validateFrontmatter(sanitizeForSchema(fm))) { - const errors = validateFrontmatter.errors || [] - const errorMsg = errors - .map((e) => `${e.instancePath} ${e.message}`) - .join(", ") - throw new Error(`${relPath}: validation failed: ${errorMsg}`) + const isReadme = isReadmeLocaleFile(path.basename(filePath)) + let fm: TranslationFrontMatter | TranslationReadmeFrontMatter + try { + fm = parseTranslationMetadata(content, isReadme) + } catch (error) { + if ( + error instanceof Error && + error.message === "missing required key 'translates'" + ) { + await processEnglishSourceFile( + content, + filePath, + relPath, + isReadme, + repoCwd, + maintainers, + manifest + ) + return + } + throw error } const dirPath = path.dirname(filePath) @@ -236,12 +220,19 @@ async function processTranslationFile( const translatesRelPath = path.relative(ARTICLES_PATH, translatesPath) const sourceContent = fs.readFileSync(translatesPath, "utf-8") - const sourceFm = parseSourceFrontMatter(sourceContent, { - allowTitlelessFolder: isReadmeLocaleFile(path.basename(translatesPath)), - }) + const sourceIsReadme = isReadmeLocaleFile(path.basename(translatesPath)) + let sourceFm: SourceFrontMatter | SourceReadmeFrontMatter + try { + sourceFm = parseSourceMetadata(sourceContent, sourceIsReadme) + } catch (error) { + throw new Error( + `${relPath}: source frontmatter invalid in ${translatesRelPath}: ${error instanceof Error ? error.message : String(error)}`, + { cause: error } + ) + } const sourceSlug = sourceFm.slug const sourceParentSlug = getParentSlugFromRelPath(translatesRelPath) - const resolvedSourceSlug = isReadmeLocaleFile(path.basename(translatesPath)) + const resolvedSourceSlug = sourceIsReadme ? sourceParentSlug : resolveSourceSlug(sourceParentSlug, sourceSlug) @@ -259,14 +250,19 @@ async function processTranslationFile( } entry.localizedFilePaths.en = relPath - if (fm.title) entry.titleByLocale.en = fm.title - if (fm["chapter-title"]) entry.chapterTitleByLocale.en = fm["chapter-title"] - if (fm["intro-title"]) { - entry.introTitleByLocale.en = fm["intro-title"] + if ("title" in fm && fm.title) entry.titleByLocale.en = fm.title + const chapterTitle = "chapter-title" in fm ? fm["chapter-title"] : undefined + const introTitle = "intro-title" in fm ? fm["intro-title"] : undefined + + if (chapterTitle) entry.chapterTitleByLocale.en = chapterTitle + if (introTitle) { + entry.introTitleByLocale.en = introTitle entry.hasIntro = true } - if (fm.description) entry.descriptionByLocale.en = fm.description - if (fm.banner) { + if ("description" in fm && fm.description) { + entry.descriptionByLocale.en = fm.description + } + if ("banner" in fm && fm.banner) { if (!entry.bannerByLocale) entry.bannerByLocale = {} entry.bannerByLocale.en = fm.banner } @@ -305,16 +301,133 @@ async function processTranslationFile( } } -function getSlugFromFile(filePath: string): string | null { +async function processEnglishSourceFile( + content: string, + filePath: string, + relPath: string, + isReadme: boolean, + repoCwd: string, + maintainers: string[], + manifest: ArticleManifest +): Promise { + const fm = parseSourceMetadata(content, isReadme) + const parentSlug = getParentSlugFromRelPath(relPath) + const sourcePath = isReadme ? null : getSourcePathForEnglishFile(filePath) + const sourceSlug = sourcePath ? tryReadSlugFromFile(sourcePath) : null + const resolvedSlug = isReadme + ? parentSlug + : resolveSourceSlug(parentSlug, sourceSlug ?? fm.slug) + const entry = manifest[resolvedSlug] + if (!entry) { + throw new Error( + `${relPath}: source slug "${resolvedSlug}" not found in manifest` + ) + } + + const { lastmod } = await getArticleDates(repoCwd, relPath, maintainers) + + if (!entry.availableLocales.includes("en")) { + entry.availableLocales.push("en") + } + entry.localizedFilePaths.en = relPath + + if ("title" in fm && fm.title) entry.titleByLocale.en = fm.title + const chapterTitle = "chapter-title" in fm ? fm["chapter-title"] : undefined + const introTitle = "intro-title" in fm ? fm["intro-title"] : undefined + + if (chapterTitle) entry.chapterTitleByLocale.en = chapterTitle + if (introTitle) { + entry.introTitleByLocale.en = introTitle + entry.hasIntro = true + } + if ("description" in fm && fm.description) { + entry.descriptionByLocale.en = fm.description + } + if ("banner" in fm && fm.banner) { + if (!entry.bannerByLocale) entry.bannerByLocale = {} + entry.bannerByLocale.en = fm.banner + } + if (lastmod) entry.lastmodByLocale.en = lastmod + entry.translationFreshnessByLocale.en = "unknown" +} + +function readSlugFromFile(filePath: string): string { + const content = fs.readFileSync(filePath, "utf-8") + return parseSourceMetadata( + content, + isReadmeLocaleFile(path.basename(filePath)) + ).slug +} + +function tryReadSlugFromFile(filePath: string): string | null { try { - const content = fs.readFileSync(filePath, "utf-8") - const fm = parseSourceFrontMatter(content, { allowTitlelessFolder: true }) - return fm.slug || null + return readSlugFromFile(filePath) || null } catch { return null } } +function getSourcePathForEnglishFile(filePath: string): string | null { + const dirname = path.dirname(filePath) + const basename = path.basename(filePath, ".en.md") + const zhPath = path.join(dirname, `${basename}.zh.md`) + if (fs.existsSync(zhPath)) return zhPath + + const sourcePath = path.join(dirname, `${basename}.md`) + return fs.existsSync(sourcePath) ? sourcePath : null +} + +function hasArticleSources(): boolean { + if (!fs.existsSync(ARTICLES_PATH)) return false + const entries = fs.readdirSync(ARTICLES_PATH, { withFileTypes: true }) + return ( + entries.some( + (entry) => + entry.isFile() && + (entry.name.endsWith(".md") || entry.name.endsWith(".zh.md")) + ) || + entries.some( + (entry) => entry.isDirectory() && !shouldIgnoreDirectory(entry.name) + ) + ) +} + +function cloneArticlesRepository(): void { + if (fs.existsSync(ARTICLES_PATH)) { + fs.rmSync(ARTICLES_PATH, { recursive: true, force: true }) + } + + process.stderr.write( + `Warning: articles/ sources missing; cloning ${ARTICLES_REPO_URL}\n` + ) + const result = spawnSync( + "git", + ["clone", "--depth", "1", ARTICLES_REPO_URL, ARTICLES_PATH], + { + stdio: "inherit", + shell: process.platform === "win32", + } + ) + + if (result.status !== 0) { + process.stderr.write( + `Error: Failed to clone articles repository from ${ARTICLES_REPO_URL}\n` + ) + process.exit(result.status ?? 1) + } +} + +function ensureArticleSources(): void { + if (hasArticleSources()) return + cloneArticlesRepository() + if (!hasArticleSources()) { + process.stderr.write( + `Error: articles/ source tree is empty at ${ARTICLES_PATH}\n` + ) + process.exit(1) + } +} + async function processDirectory( dirPath: string, relFromArticles: string, @@ -337,7 +450,7 @@ async function processDirectory( if (readmeSource) { const readmePath = path.join(dirPath, readmeSource.name) - const readmeSlug = getSlugFromFile(readmePath) + const readmeSlug = tryReadSlugFromFile(readmePath) if (readmeSlug) { const parentSlug = getParentSlug(slugPrefix) @@ -381,7 +494,7 @@ async function processDirectory( const sourcePath = path.join(dirPath, sourceFile.name) const relPath = `${relFromArticles}/${sourceFile.name}` - const articleSlug = getSlugFromFile(sourcePath) + const articleSlug = tryReadSlugFromFile(sourcePath) if (!articleSlug) { process.stderr.write( `WARN: Skipping file without slug: articles/${relPath}\n` @@ -511,7 +624,7 @@ async function processDirectory( if (!subReadmeExists) continue - const subSlug = getSlugFromFile(subReadmeExists) + const subSlug = tryReadSlugFromFile(subReadmeExists) if (!subSlug) { if (depth < 1) { process.stderr.write( @@ -565,17 +678,10 @@ async function processDirectory( } async function main(): Promise { - await initAjv() - let manifest: ArticleManifest = {} let hasError = false - if (!fs.existsSync(ARTICLES_PATH)) { - process.stderr.write( - `Error: articles/ directory not found at ${ARTICLES_PATH}\n` - ) - process.exit(1) - } + ensureArticleSources() const maintainers = await loadMaintainers() const aliases = await loadAuthorAliases() @@ -608,7 +714,16 @@ async function main(): Promise { continue } - const folderSlug = getSlugFromFile(readmeExists) + let folderSlug: string + try { + folderSlug = readSlugFromFile(readmeExists) + } catch (error) { + process.stderr.write( + `Error: articles/${folderName}/README.zh.md: ${error instanceof Error ? error.message : String(error)}\n` + ) + hasError = true + continue + } if (!folderSlug) { process.stderr.write( @@ -664,7 +779,7 @@ async function main(): Promise { }> = [] for (const rootFile of rootFiles) { const rootFilePath = path.join(ARTICLES_PATH, rootFile) - const rawSlug = getSlugFromFile(rootFilePath) + const rawSlug = tryReadSlugFromFile(rootFilePath) if (!rawSlug) { process.stderr.write( diff --git a/scripts/generate-glossary-manifest.ts b/scripts/generate-glossary-manifest.ts index adc026c7..b73412ab 100644 --- a/scripts/generate-glossary-manifest.ts +++ b/scripts/generate-glossary-manifest.ts @@ -1,5 +1,7 @@ import fs from "fs" +import https from "https" import path from "path" +import { fileURLToPath } from "url" import { parseGlossaryCsv } from "@/lib/glossary/csv" import type { @@ -8,9 +10,18 @@ import type { GlossarySummaryEntry, } from "@/lib/glossary/manifest" -const CSV_FILE = path.join(process.cwd(), "glossary", "TechMC Glossary.csv") -const OUTPUT_FILE = path.join(process.cwd(), "data", "glossary.json") -const SUMMARY_FILE = path.join(process.cwd(), "data", "glossary-summary.json") +const PROJECT_ROOT = path.resolve( + path.dirname(fileURLToPath(import.meta.url)), + ".." +) +const CSV_FILE = path.join(PROJECT_ROOT, "glossary", "TechMC Glossary.csv") +const CSV_URL = new URL( + "https://raw.githubusercontent.com/TechMC-Glossary/TechMC-Glossary/main/TechMC%20Glossary.csv" +) +const FETCH_ATTEMPTS = 3 +const FETCH_TIMEOUT_MS = 20_000 +const OUTPUT_FILE = path.join(PROJECT_ROOT, "data", "glossary.json") +const SUMMARY_FILE = path.join(PROJECT_ROOT, "data", "glossary-summary.json") const LOCALE_COLUMNS: Array<{ locale: GlossaryLocale @@ -55,18 +66,71 @@ function writeJson(filePath: string, data: unknown): void { fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n") } -function main(): void { - if (!fs.existsSync(CSV_FILE)) { - process.stderr.write(`Error: CSV file not found at ${CSV_FILE}\n`) - process.exit(1) +function fetchTextOnce(url: URL): Promise { + return new Promise((resolve, reject) => { + const request = https + .get(url, (response) => { + if (response.statusCode !== 200) { + reject(new Error(`HTTP ${response.statusCode ?? "unknown"}`)) + response.resume() + return + } + + response.setEncoding("utf8") + let body = "" + response.on("data", (chunk: string) => { + body += chunk + }) + response.on("end", () => { + resolve(body) + }) + }) + .on("error", reject) + + request.setTimeout(FETCH_TIMEOUT_MS, () => { + request.destroy(new Error(`timeout after ${FETCH_TIMEOUT_MS}ms`)) + }) + }) +} + +async function fetchText(url: URL, attempt = 1): Promise { + try { + return await fetchTextOnce(url) + } catch (error) { + const lastError = error instanceof Error ? error : new Error(String(error)) + process.stderr.write( + `Warning: CSV fetch attempt ${attempt}/${FETCH_ATTEMPTS} failed: ${lastError.message}\n` + ) + if (attempt >= FETCH_ATTEMPTS) { + throw lastError + } + + return fetchText(url, attempt + 1) } +} + +async function readCsvText(): Promise<{ source: string; text: string }> { + if (fs.existsSync(CSV_FILE)) { + return { + source: path.relative(PROJECT_ROOT, CSV_FILE), + text: fs.readFileSync(CSV_FILE, "utf-8"), + } + } + + process.stderr.write( + `Warning: CSV file not found at ${CSV_FILE}; fetching ${CSV_URL.href}\n` + ) + return { source: CSV_URL.href, text: await fetchText(CSV_URL) } +} +async function main(): Promise { let csvText: string + let source: string try { - csvText = fs.readFileSync(CSV_FILE, "utf-8") + ;({ source, text: csvText } = await readCsvText()) } catch (error) { process.stderr.write( - `Error: Failed to read CSV: ${error instanceof Error ? error.message : String(error)}\n` + `Error: Failed to load CSV: ${error instanceof Error ? error.message : String(error)}\n` ) process.exit(1) } @@ -144,13 +208,13 @@ function main(): void { process.stdout.write( [ "[glossary-manifest] Glossary manifest generated", - `Source: ${path.relative(process.cwd(), CSV_FILE)}`, - `Output: ${path.relative(process.cwd(), OUTPUT_FILE)}`, - ` ${path.relative(process.cwd(), SUMMARY_FILE)}`, + `Source: ${source}`, + `Output: ${path.relative(PROJECT_ROOT, OUTPUT_FILE)}`, + ` ${path.relative(PROJECT_ROOT, SUMMARY_FILE)}`, `Entries: ${entries.length} total (${controversial} controversial, ${withTranslations} with translations)`, "", ].join("\n") ) } -main() +void main() diff --git a/scripts/migrate-article-frontmatter.ts b/scripts/migrate-article-frontmatter.ts deleted file mode 100644 index e6f88990..00000000 --- a/scripts/migrate-article-frontmatter.ts +++ /dev/null @@ -1,695 +0,0 @@ -import { execFileSync } from "child_process" -import fs from "fs" -import path from "path" -import { fileURLToPath } from "url" -import matter from "gray-matter" -import { dump as yamlDump } from "js-yaml" -import { shouldIgnoreDirectory, shouldIgnoreFile } from "@/lib/articles/ignore" - -type ArticleLocale = "zh" | "en" - -type Logger = Pick - -export interface MigrationOptions { - repoPath?: string - apply?: boolean - logger?: Logger -} - -export interface MigrationResult { - repoPath: string - dryRun: boolean - renamed: number - rewritten: number - skipped: number - warnings: string[] - errors: string[] - plannedActions: string[] -} - -interface MarkdownFile { - absolutePath: string - relativePath: string - directory: string - filename: string - locale: ArticleLocale - isBareZh: boolean - normalizedPath: string - normalizedRelativePath: string - frontmatter: Record - body: string - hasSlug: boolean - slug?: string - alreadyNewSchema: boolean -} - -interface ZhSource { - sourcePath: string - normalizedPath: string - normalizedRelativePath: string - directory: string - filename: string - slug: string -} - -type Operation = - | { type: "rename"; from: string; to: string } - | { - type: "rewrite" - filePath: string - frontmatter: Record - body: string - } - -const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url)) -const DEFAULT_ARTICLES_REPO = path.resolve(SCRIPT_DIR, "..", "articles") - -const ROOT_EXCLUDED_FILES = new Set([ - "contributing.md", - "contributing_cn.md", - "readme.md", - "readme_cn.md", - "roadmap.md", - "reviewers.md", -]) - -const ZH_FRONTMATTER_ORDER = [ - "slug", - "index", - "is-advanced", - "banner", - "title", - "chapter-title", - "intro-title", - "description", -] as const - -const EN_FRONTMATTER_ORDER = [ - "translates", - "translated-from-revision", - "banner", - "title", - "chapter-title", - "intro-title", - "description", -] as const - -const ZH_ALLOWED_KEYS = new Set(ZH_FRONTMATTER_ORDER) -const EN_ALLOWED_KEYS = new Set(EN_FRONTMATTER_ORDER) - -const ZH_FORBIDDEN_KEYS = new Set([ - "title-en", - "chapter-title-en", - "intro-title-en", - "date", - "lastmod", - "author", - "co-authors", - "translates", - "translated-from-revision", -]) - -const EN_FORBIDDEN_KEYS = new Set([ - "slug", - "index", - "is-advanced", - "author", - "co-authors", - "date", - "lastmod", - "title-en", - "chapter-title-en", - "intro-title-en", -]) - -function detectLocale(filename: string): ArticleLocale { - return filename.endsWith(".en.md") ? "en" : "zh" -} - -function normalizeZhFilename(filename: string): string { - if (filename.endsWith(".zh.md")) return filename - return filename.replace(/\.md$/i, ".zh.md") -} - -function toPosixPath(value: string): string { - return value.split(path.sep).join("/") -} - -function hasOwn(data: Record, key: string): boolean { - return Object.prototype.hasOwnProperty.call(data, key) -} - -function hasString(data: Record, key: string): boolean { - return typeof data[key] === "string" -} - -function isInside(root: string, candidate: string): boolean { - const relativePath = path.relative(root, candidate) - return ( - relativePath === "" || - (!relativePath.startsWith("..") && !path.isAbsolute(relativePath)) - ) -} - -function assertInsideRepo(repoRoot: string, candidate: string): void { - if (!isInside(repoRoot, candidate)) { - throw new Error( - `Refusing to access path outside articles repo: ${candidate}` - ) - } -} - -function shouldSkipDirectory(name: string): boolean { - return name === "_Drafts" || shouldIgnoreDirectory(name) -} - -function shouldSkipRootFile(name: string): boolean { - const lowerName = name.toLowerCase() - if (ROOT_EXCLUDED_FILES.has(lowerName)) return true - if (lowerName.startsWith("license")) return true - return shouldIgnoreFile(name, true) -} - -function shouldSkipMarkdownFile(name: string, isRoot: boolean): boolean { - if (!name.endsWith(".md")) return true - if (isRoot && shouldSkipRootFile(name)) return true - return shouldIgnoreFile(name, false) -} - -function isNewZhSchema(data: Record): boolean { - if (!hasString(data, "slug")) return false - return Object.keys(data).every( - (key) => ZH_ALLOWED_KEYS.has(key) && !ZH_FORBIDDEN_KEYS.has(key) - ) -} - -function isNewEnSchema(data: Record): boolean { - if (!hasString(data, "translates")) return false - if (!hasString(data, "translated-from-revision")) return false - return Object.keys(data).every( - (key) => EN_ALLOWED_KEYS.has(key) && !EN_FORBIDDEN_KEYS.has(key) - ) -} - -function isAlreadyNewSchema( - filename: string, - locale: ArticleLocale, - data: Record -): boolean { - if (locale === "zh") { - return filename.endsWith(".zh.md") && isNewZhSchema(data) - } - return filename.endsWith(".en.md") && isNewEnSchema(data) -} - -function readMarkdownFile( - repoRoot: string, - absolutePath: string -): MarkdownFile { - assertInsideRepo(repoRoot, absolutePath) - const rawContent = fs.readFileSync(absolutePath, "utf8") - const parsed = matter(rawContent) - const filename = path.basename(absolutePath) - const relativePath = toPosixPath(path.relative(repoRoot, absolutePath)) - const directory = path.dirname(absolutePath) - const locale = detectLocale(filename) - const isBareZh = locale === "zh" && !filename.endsWith(".zh.md") - const normalizedPath = isBareZh - ? path.join(directory, normalizeZhFilename(filename)) - : absolutePath - - return { - absolutePath, - relativePath, - directory, - filename, - locale, - isBareZh, - normalizedPath, - normalizedRelativePath: toPosixPath( - path.relative(repoRoot, normalizedPath) - ), - frontmatter: parsed.data, - body: parsed.content, - hasSlug: hasString(parsed.data, "slug"), - slug: hasString(parsed.data, "slug") ? parsed.data.slug : undefined, - alreadyNewSchema: isAlreadyNewSchema(filename, locale, parsed.data), - } -} - -function walkMarkdownFiles( - repoRoot: string, - directory = repoRoot -): MarkdownFile[] { - assertInsideRepo(repoRoot, directory) - const entries = fs - .readdirSync(directory, { withFileTypes: true }) - .toSorted((a, b) => - a.name.localeCompare(b.name, undefined, { numeric: true }) - ) - const isRoot = directory === repoRoot - const files: MarkdownFile[] = [] - - for (const entry of entries) { - const absolutePath = path.join(directory, entry.name) - if (entry.isDirectory()) { - if (!shouldSkipDirectory(entry.name)) { - files.push(...walkMarkdownFiles(repoRoot, absolutePath)) - } - continue - } - - if (entry.isFile() && !shouldSkipMarkdownFile(entry.name, isRoot)) { - files.push(readMarkdownFile(repoRoot, absolutePath)) - } - } - - return files -} - -function orderedPick( - data: Record, - order: readonly string[] -): Record { - const nextData: Record = {} - for (const key of order) { - if (hasOwn(data, key)) { - nextData[key] = data[key] - } - } - return nextData -} - -function rewriteZhFrontmatter( - data: Record -): Record { - return orderedPick(data, ZH_FRONTMATTER_ORDER) -} - -function copyLocalizedField( - source: Record, - target: Record, - legacyKey: string, - newKey: string -): void { - if ( - hasOwn(source, legacyKey) && - source[legacyKey] !== null && - source[legacyKey] !== undefined - ) { - target[newKey] = source[legacyKey] - return - } - - if (hasOwn(source, newKey)) { - target[newKey] = source[newKey] - } -} - -function getRelativeTranslationPath(fromFile: string, toFile: string): string { - const relativePath = toPosixPath( - path.relative(path.dirname(fromFile), toFile) - ) - if (relativePath.startsWith(".")) return relativePath - return `./${relativePath}` -} - -function rewriteEnFrontmatter( - data: Record, - translates: string, - translatedFromRevision: string -): Record { - const nextData: Record = { - translates, - "translated-from-revision": translatedFromRevision, - } - - if (hasOwn(data, "banner")) { - nextData.banner = data.banner - } - - copyLocalizedField(data, nextData, "title-en", "title") - copyLocalizedField(data, nextData, "chapter-title-en", "chapter-title") - copyLocalizedField(data, nextData, "intro-title-en", "intro-title") - - if (hasOwn(data, "description")) { - nextData.description = data.description - } - - return orderedPick(nextData, EN_FRONTMATTER_ORDER) -} - -function dumpMarkdown( - frontmatter: Record, - body: string -): string { - const frontmatterYaml = yamlDump(frontmatter, { - sortKeys: false, - lineWidth: -1, - noRefs: true, - }) - return `---\n${frontmatterYaml}---\n${body}` -} - -function getLastRevision(repoRoot: string, filePath: string): string { - const revision = execFileSync( - "git", - ["-C", repoRoot, "log", "-1", "--format=%H", "--", filePath], - { encoding: "utf8" } - ).trim() - - if (revision === "") { - throw new Error( - `No git history found for ${toPosixPath(path.relative(repoRoot, filePath))}` - ) - } - - return revision -} - -function gitMove(repoRoot: string, from: string, to: string): void { - execFileSync("git", ["-C", repoRoot, "mv", "--", from, to], { - encoding: "utf8", - stdio: "pipe", - }) -} - -function addWarning(result: MigrationResult, message: string): void { - result.warnings.push(message) -} - -function addError(result: MigrationResult, message: string): void { - result.errors.push(message) -} - -function addSkip(result: MigrationResult, message: string): void { - result.skipped += 1 - result.plannedActions.push(`INFO ${message}`) -} - -function addOperation( - result: MigrationResult, - operations: Operation[], - operation: Operation -): void { - operations.push(operation) - if (operation.type === "rename") { - result.renamed += 1 - result.plannedActions.push( - `RENAME ${toPosixPath(path.relative(result.repoPath, operation.from))} -> ${toPosixPath(path.relative(result.repoPath, operation.to))}` - ) - } else { - result.rewritten += 1 - result.plannedActions.push( - `REWRITE ${toPosixPath(path.relative(result.repoPath, operation.filePath))}` - ) - } -} - -function collectZhSources( - files: MarkdownFile[], - result: MigrationResult -): Map { - const sources = new Map() - - for (const file of files) { - if (file.locale !== "zh" || !file.hasSlug || file.alreadyNewSchema) { - continue - } - - const key = `${file.directory}\0${file.slug}` - const existingSource = sources.get(key) - if (existingSource !== undefined) { - addError( - result, - `Duplicate zh source for slug "${file.slug}" in ${toPosixPath(path.relative(result.repoPath, file.directory))}: ${existingSource.filename} and ${file.filename}` - ) - continue - } - - sources.set(key, { - sourcePath: file.absolutePath, - normalizedPath: file.normalizedPath, - normalizedRelativePath: file.normalizedRelativePath, - directory: file.directory, - filename: file.filename, - slug: file.slug!, - }) - } - - return sources -} - -function planMigration( - files: MarkdownFile[], - result: MigrationResult -): Operation[] { - const operations: Operation[] = [] - const zhSourcesByDirectoryAndSlug = collectZhSources(files, result) - - for (const file of files) { - if (file.alreadyNewSchema) { - addSkip( - result, - `${file.relativePath} already uses the new ${file.locale} schema` - ) - continue - } - - if (file.locale === "zh") { - if (file.isBareZh) { - if (fs.existsSync(file.normalizedPath)) { - addError( - result, - `Cannot rename ${file.relativePath}: target ${file.normalizedRelativePath} already exists` - ) - continue - } - addOperation(result, operations, { - type: "rename", - from: file.absolutePath, - to: file.normalizedPath, - }) - } - - if (!file.hasSlug) { - addWarning( - result, - `WARN ${file.relativePath}: missing slug; renamed only, frontmatter left unchanged` - ) - continue - } - - addOperation(result, operations, { - type: "rewrite", - filePath: file.normalizedPath, - frontmatter: rewriteZhFrontmatter(file.frontmatter), - body: file.body, - }) - continue - } - - if (!file.hasSlug) { - addError( - result, - `Orphan en translation without legacy slug: ${file.relativePath}` - ) - continue - } - - const zhSource = zhSourcesByDirectoryAndSlug.get( - `${file.directory}\0${file.slug}` - ) - if (zhSource === undefined) { - addError( - result, - `Orphan en translation: ${file.relativePath} has no zh sibling with slug "${file.slug}"` - ) - continue - } - - let translatedFromRevision: string - try { - translatedFromRevision = getLastRevision( - result.repoPath, - zhSource.sourcePath - ) - } catch (error) { - addError(result, error instanceof Error ? error.message : String(error)) - continue - } - - addOperation(result, operations, { - type: "rewrite", - filePath: file.absolutePath, - frontmatter: rewriteEnFrontmatter( - file.frontmatter, - getRelativeTranslationPath(file.absolutePath, zhSource.normalizedPath), - translatedFromRevision - ), - body: file.body, - }) - } - - return operations -} - -function applyOperations(repoRoot: string, operations: Operation[]): void { - const renameOperations = operations.filter( - (operation): operation is Extract => - operation.type === "rename" - ) - const rewriteOperations = operations.filter( - (operation): operation is Extract => - operation.type === "rewrite" - ) - - for (const operation of renameOperations) { - assertInsideRepo(repoRoot, operation.from) - assertInsideRepo(repoRoot, operation.to) - gitMove(repoRoot, operation.from, operation.to) - } - - for (const operation of rewriteOperations) { - assertInsideRepo(repoRoot, operation.filePath) - fs.writeFileSync( - operation.filePath, - dumpMarkdown(operation.frontmatter, operation.body), - "utf8" - ) - } -} - -export function formatMigrationReport(result: MigrationResult): string { - const lines = [ - result.dryRun - ? "[migrate-frontmatter] dry run" - : "[migrate-frontmatter] applied", - `Repo: ${result.repoPath}`, - `Counts: ${result.renamed} renamed, ${result.rewritten} rewritten, ${result.skipped} skipped, ${result.warnings.length} warnings`, - ] - - if (result.plannedActions.length > 0) { - lines.push( - "", - "Actions:", - ...result.plannedActions.map((action) => `- ${action}`) - ) - } - - if (result.warnings.length > 0) { - lines.push( - "", - "Warnings:", - ...result.warnings.map((warning) => `- ${warning}`) - ) - } - - if (result.errors.length > 0) { - lines.push("", "Errors:", ...result.errors.map((error) => `- ${error}`)) - } - - return `${lines.join("\n")}\n` -} - -export function runMigration(options: MigrationOptions = {}): MigrationResult { - const repoPath = path.resolve(options.repoPath ?? DEFAULT_ARTICLES_REPO) - const result: MigrationResult = { - repoPath, - dryRun: options.apply !== true, - renamed: 0, - rewritten: 0, - skipped: 0, - warnings: [], - errors: [], - plannedActions: [], - } - - if (!fs.existsSync(repoPath) || !fs.statSync(repoPath).isDirectory()) { - addError(result, `Articles repo not found: ${repoPath}`) - return result - } - - const files = walkMarkdownFiles(repoPath) - const operations = planMigration(files, result) - - if (result.errors.length === 0 && options.apply === true) { - try { - applyOperations(repoPath, operations) - } catch (error) { - addError(result, error instanceof Error ? error.message : String(error)) - } - } - - const logger = options.logger - if (logger !== undefined) { - for (const warning of result.warnings) logger.warn(warning) - for (const error of result.errors) logger.error(error) - } - - return result -} - -interface CliArgs { - apply: boolean - repoPath?: string -} - -function parseCliArgs(argv: string[]): CliArgs { - const args: CliArgs = { apply: false } - - for (let index = 0; index < argv.length; index += 1) { - const arg = argv[index] - if (arg === "--dry-run") { - args.apply = false - continue - } - if (arg === "--apply") { - args.apply = true - continue - } - if (arg === "--repo") { - const repoPath = argv[index + 1] - if (repoPath === undefined || repoPath.startsWith("--")) { - throw new Error("Missing value for --repo") - } - args.repoPath = repoPath - index += 1 - continue - } - throw new Error(`Unknown argument: ${arg}`) - } - - return args -} - -function main(): void { - let cliArgs: CliArgs - try { - cliArgs = parseCliArgs(process.argv.slice(2)) - } catch (error) { - process.stderr.write( - `${error instanceof Error ? error.message : String(error)}\n` - ) - process.exit(1) - } - - const result = runMigration({ - apply: cliArgs.apply, - repoPath: cliArgs.repoPath, - }) - const report = formatMigrationReport(result) - if (result.errors.length > 0) { - process.stderr.write(report) - process.exit(1) - } - - process.stdout.write(report) -} - -if ( - process.argv[1] !== undefined && - path.resolve(process.argv[1]) === fileURLToPath(import.meta.url) -) { - main() -} diff --git a/scripts/postinstall.mjs b/scripts/postinstall.ts similarity index 56% rename from scripts/postinstall.mjs rename to scripts/postinstall.ts index ac384dc9..c8892e5d 100644 --- a/scripts/postinstall.mjs +++ b/scripts/postinstall.ts @@ -1,9 +1,9 @@ -import { existsSync, readdirSync } from "node:fs" -import { spawnSync } from "node:child_process" +import { existsSync } from "node:fs" +import { spawnSync, type SpawnSyncOptions } from "node:child_process" const placeholderDatabaseUrl = "postgresql://localhost:5432/placeholder" -function run(command, args, options = {}) { +function run(command: string, args: string[], options: SpawnSyncOptions = {}) { const result = spawnSync(command, args, { stdio: "inherit", shell: process.platform === "win32", @@ -25,26 +25,44 @@ function isGitWorkTree() { return result.status === 0 } -if (isGitWorkTree()) { - run("git", ["config", "--local", "include.path", ".gitconfig"]) +function getSubmoduleStatus(path: string) { + return spawnSync("git", ["submodule", "status", "--recursive", path], { + encoding: "utf-8", + }) +} + +function isSubmoduleInitialized(path: string) { + const result = getSubmoduleStatus(path) + if (result.status !== 0) return false + + const lines = result.stdout.split("\n").filter(Boolean) + return ( + lines.length > 0 && + lines.every((line) => line.startsWith(" ") || line.startsWith("+")) + ) +} - if (!existsSync("articles") || readdirSync("articles").length === 0) { - run("git", ["submodule", "update", "--init", "--recursive"]) - } else { - process.stdout.write( - "Skipping article submodule checkout because articles/ already exists\n" - ) +function ensureSubmoduleInitialized(path: string) { + if (!isSubmoduleInitialized(path)) { + run("git", ["submodule", "update", "--init", "--recursive", path]) } - if (!existsSync("glossary") || readdirSync("glossary").length === 0) { - run("git", ["submodule", "update", "--init", "--recursive"]) - } else { - process.stdout.write( - "Skipping glossary submodule checkout because glossary/ already exists\n" - ) - process.stdout.write(" Generating glossary manifest...\n") - run("tsx", ["scripts/generate-glossary-manifest.ts"]) + if (!isSubmoduleInitialized(path)) { + process.stderr.write(`Submodule ${path} is not correctly initialized\n`) + process.exit(1) } + + process.stdout.write(`Submodule ${path} is initialized\n`) +} + +if (isGitWorkTree()) { + run("git", ["config", "--local", "include.path", ".gitconfig"]) + + ensureSubmoduleInitialized("articles") + ensureSubmoduleInitialized("glossary") + + process.stdout.write(" Generating glossary manifest...\n") + run("tsx", ["scripts/generate-glossary-manifest.ts"]) } else { process.stdout.write("Skipping Git submodule setup outside a Git work tree\n") } diff --git a/scripts/prepare-articles-for-build.ts b/scripts/prepare-articles-for-build.ts new file mode 100644 index 00000000..ce96ad33 --- /dev/null +++ b/scripts/prepare-articles-for-build.ts @@ -0,0 +1,50 @@ +import { spawnSync } from "node:child_process" + +type ArticleSourceMode = "pinned" | "latest" + +const sourceMode = parseArticleSourceMode(process.env.GTMC_ARTICLES_SOURCE) + +function parseArticleSourceMode( + value: string | undefined +): ArticleSourceMode | undefined { + const trimmedValue = value?.trim() + + if (!trimmedValue) return undefined + if (trimmedValue === "pinned") return "pinned" + if (trimmedValue === "latest") return "latest" + + process.stderr.write( + `Invalid GTMC_ARTICLES_SOURCE=${trimmedValue}. Expected "pinned" or "latest".\n` + ) + process.exit(1) +} + +function runGitSubmoduleUpdate(mode: ArticleSourceMode): void { + const args = + mode === "latest" + ? ["submodule", "update", "--init", "--recursive", "--remote", "articles"] + : ["submodule", "update", "--init", "--recursive", "articles"] + + process.stdout.write( + mode === "latest" + ? "Preparing articles from latest configured submodule branch\n" + : "Preparing articles from pinned submodule commit\n" + ) + + const result = spawnSync("git", args, { + stdio: "inherit", + shell: process.platform === "win32", + }) + + if (result.status !== 0) { + process.exit(result.status ?? 1) + } +} + +if (sourceMode) { + runGitSubmoduleUpdate(sourceMode) +} else { + process.stdout.write( + "GTMC_ARTICLES_SOURCE is unset; leaving articles submodule unchanged\n" + ) +} diff --git a/skills-lock.json b/skills-lock.json index feaea8ea..b74d5c86 100644 --- a/skills-lock.json +++ b/skills-lock.json @@ -55,17 +55,23 @@ "skillPath": "manual-frontend-qa/SKILL.md", "computedHash": "ddbbeec4944fd7d2a2c59c6aa4e5e8298d78c986e79f62c499795a837c7b122c" }, - "next-best-practices": { - "computedHash": "f4678aef4ffc10a5ea64a91e57abe5a5081af813b06d58d565caf3e8ef56e26c", - "skillPath": "skills/next-best-practices/SKILL.md", - "source": "vercel-labs/next-skills", - "sourceType": "github" - }, - "next-cache-components": { - "computedHash": "f835d8226c28abf012cc013928e2627c8a7a046de61127ef229be1711bd1f255", - "skillPath": "skills/next-cache-components/SKILL.md", - "source": "vercel-labs/next-skills", - "sourceType": "github" + "next-cache-components-adoption": { + "source": "vercel/next.js", + "sourceType": "github", + "skillPath": "skills/next-cache-components-adoption/SKILL.md", + "computedHash": "aaee0946eff1ddcdeee10525953d32a11310e470ef4a13a2ebb3aa79bc1ae769" + }, + "next-cache-components-optimizer": { + "source": "vercel/next.js", + "sourceType": "github", + "skillPath": "skills/next-cache-components-optimizer/SKILL.md", + "computedHash": "b8d757a1fe10ebe7b10de1d5ee83f9bcdbd1de1e1147efc68cf249377f471067" + }, + "next-dev-loop": { + "source": "vercel/next.js", + "sourceType": "github", + "skillPath": "skills/next-dev-loop/SKILL.md", + "computedHash": "aad97b32ba6efd31e92d063ec77120a694fe0d4a9401daf9af4c205cd5e21b07" }, "performance": { "source": "addyosmani/web-quality-skills", @@ -137,13 +143,13 @@ "source": "nextlevelbuilder/ui-ux-pro-max-skill", "sourceType": "github", "skillPath": ".claude/skills/ui-ux-pro-max/SKILL.md", - "computedHash": "c0e71f1ea9d80c74f710960c2b4d9ab0f8a6d14c331f8d361df2c28d1879846e" + "computedHash": "b0f78bc58cc5a3ac68afdf6f2de214e147b09a3f8686447cb3804a921fa198c2" }, "vercel-cli": { "source": "vercel/vercel", "sourceType": "github", "skillPath": "skills/vercel-cli/SKILL.md", - "computedHash": "089bc076ac3d1e9be59a2ab87798e2095a15b4c311db1b40cea9b2f5481d457d" + "computedHash": "c24c129a9f87cef301cde4516ca2f9d1a184ba419abed64f216596b6186a91b9" }, "vercel-cli-with-tokens": { "source": "vercel-labs/agent-skills",