diff --git a/Cargo.lock b/Cargo.lock index 61b89d84..c72343a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,9 +43,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.21" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", "anstyle-parse", @@ -64,9 +64,9 @@ checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" -version = "0.2.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" dependencies = [ "utf8parse", ] @@ -391,9 +391,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.43" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" +checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" dependencies = [ "iana-time-zone", "num-traits", @@ -403,9 +403,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.60" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2797f34da339ce31042b27d23607e051786132987f595b02ba4f6a6dffb7030a" +checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" dependencies = [ "clap_builder", "clap_derive", @@ -413,9 +413,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.60" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24a241312cea5059b13574bb9b3861cabf758b879c15190b37b6d6fd63ab6876" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" dependencies = [ "anstream", "anstyle", @@ -425,9 +425,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.55" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" +checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -2071,7 +2071,7 @@ dependencies = [ [[package]] name = "memory-sync-gui" -version = "2026.10319.10359" +version = "2026.10322.104" dependencies = [ "dirs", "proptest", @@ -2298,38 +2298,8 @@ checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" dependencies = [ "bitflags 2.11.0", "block2", - "libc", "objc2", - "objc2-cloud-kit", - "objc2-core-data", "objc2-core-foundation", - "objc2-core-graphics", - "objc2-core-image", - "objc2-core-text", - "objc2-core-video", - "objc2-foundation", - "objc2-quartz-core", -] - -[[package]] -name = "objc2-cloud-kit" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" -dependencies = [ - "bitflags 2.11.0", - "objc2", - "objc2-foundation", -] - -[[package]] -name = "objc2-core-data" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa" -dependencies = [ - "bitflags 2.11.0", - "objc2", "objc2-foundation", ] @@ -2357,41 +2327,6 @@ dependencies = [ "objc2-io-surface", ] -[[package]] -name = "objc2-core-image" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006" -dependencies = [ - "objc2", - "objc2-foundation", -] - -[[package]] -name = "objc2-core-text" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" -dependencies = [ - "bitflags 2.11.0", - "objc2", - "objc2-core-foundation", - "objc2-core-graphics", -] - -[[package]] -name = "objc2-core-video" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6" -dependencies = [ - "bitflags 2.11.0", - "objc2", - "objc2-core-foundation", - "objc2-core-graphics", - "objc2-io-surface", -] - [[package]] name = "objc2-encode" version = "4.1.0" @@ -2431,16 +2366,6 @@ dependencies = [ "objc2-core-foundation", ] -[[package]] -name = "objc2-javascript-core" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a1e6550c4caed348956ce3370c9ffeca70bb1dbed4fa96112e7c6170e074586" -dependencies = [ - "objc2", - "objc2-core-foundation", -] - [[package]] name = "objc2-osa-kit" version = "0.3.2" @@ -2465,17 +2390,6 @@ dependencies = [ "objc2-foundation", ] -[[package]] -name = "objc2-security" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "709fe137109bd1e8b5a99390f77a7d8b2961dafc1a1c5db8f2e60329ad6d895a" -dependencies = [ - "bitflags 2.11.0", - "objc2", - "objc2-core-foundation", -] - [[package]] name = "objc2-ui-kit" version = "0.3.2" @@ -2500,8 +2414,6 @@ dependencies = [ "objc2-app-kit", "objc2-core-foundation", "objc2-foundation", - "objc2-javascript-core", - "objc2-security", ] [[package]] @@ -3002,9 +2914,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.44" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] @@ -3226,9 +3138,9 @@ checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" [[package]] name = "reqwest" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04e9018c9d814e5f30cc16a0f03271aeab3571e609612d9fe78c1aa8d11c2f62" +checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" dependencies = [ "base64 0.22.1", "bytes", @@ -3247,7 +3159,6 @@ dependencies = [ "pin-project-lite", "quinn", "rustls", - "rustls-native-certs", "rustls-pki-types", "rustls-platform-verifier", "serde", @@ -4033,9 +3944,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tauri" -version = "2.10.2" +version = "2.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463ae8677aa6d0f063a900b9c41ecd4ac2b7ca82f0b058cc4491540e55b20129" +checksum = "da77cc00fb9028caf5b5d4650f75e31f1ef3693459dfca7f7e506d1ecef0ba2d" dependencies = [ "anyhow", "bytes", @@ -4084,9 +3995,9 @@ dependencies = [ [[package]] name = "tauri-build" -version = "2.5.5" +version = "2.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca7bd893329425df750813e95bd2b643d5369d929438da96d5bbb7cc2c918f74" +checksum = "4bbc990d1dbf57a8e1c7fa2327f2a614d8b757805603c1b9ba5c81bade09fd4d" dependencies = [ "anyhow", "cargo_toml", @@ -4106,9 +4017,9 @@ dependencies = [ [[package]] name = "tauri-codegen" -version = "2.5.4" +version = "2.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aac423e5859d9f9ccdd32e3cf6a5866a15bedbf25aa6630bcb2acde9468f6ae3" +checksum = "d4a24476afd977c5d5d169f72425868613d82747916dd29e0a357c84c4bd6d29" dependencies = [ "base64 0.22.1", "brotli", @@ -4133,9 +4044,9 @@ dependencies = [ [[package]] name = "tauri-macros" -version = "2.5.4" +version = "2.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6a1bd2861ff0c8766b1d38b32a6a410f6dc6532d4ef534c47cfb2236092f59" +checksum = "d39b349a98dadaffebb73f0a40dcd1f23c999211e5a2e744403db384d0c33de7" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -4218,9 +4129,9 @@ dependencies = [ [[package]] name = "tauri-runtime" -version = "2.10.0" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b885ffeac82b00f1f6fd292b6e5aabfa7435d537cef57d11e38a489956535651" +checksum = "2826d79a3297ed08cd6ea7f412644ef58e32969504bc4fbd8d7dbeabc4445ea2" dependencies = [ "cookie", "dpi", @@ -4243,9 +4154,9 @@ dependencies = [ [[package]] name = "tauri-runtime-wry" -version = "2.10.0" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5204682391625e867d16584fedc83fc292fb998814c9f7918605c789cd876314" +checksum = "e11ea2e6f801d275fdd890d6c9603736012742a1c33b96d0db788c9cdebf7f9e" dependencies = [ "gtk", "http", @@ -4253,7 +4164,6 @@ dependencies = [ "log", "objc2", "objc2-app-kit", - "objc2-foundation", "once_cell", "percent-encoding", "raw-window-handle", @@ -4270,9 +4180,9 @@ dependencies = [ [[package]] name = "tauri-utils" -version = "2.8.2" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcd169fccdff05eff2c1033210b9b94acd07a47e6fa9a3431cf09cfd4f01c87e" +checksum = "219a1f983a2af3653f75b5747f76733b0da7ff03069c7a41901a5eb3ace4557d" dependencies = [ "anyhow", "brotli", @@ -4319,9 +4229,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.25.0" +version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0136791f7c95b1f6dd99f9cc786b91bb81c3800b639b3478e561ddb7be95e5f1" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", "getrandom 0.4.1", @@ -4439,7 +4349,7 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tnmsc" -version = "2026.10319.10359" +version = "2026.10322.104" dependencies = [ "clap", "dirs", @@ -4459,7 +4369,7 @@ dependencies = [ [[package]] name = "tnmsc-logger" -version = "2026.10319.10359" +version = "2026.10322.104" dependencies = [ "chrono", "napi", @@ -4471,7 +4381,7 @@ dependencies = [ [[package]] name = "tnmsc-md-compiler" -version = "2026.10319.10359" +version = "2026.10322.104" dependencies = [ "markdown", "napi", @@ -4486,7 +4396,7 @@ dependencies = [ [[package]] name = "tnmsc-script-runtime" -version = "2026.10319.10359" +version = "2026.10322.104" dependencies = [ "napi", "napi-build", @@ -5039,9 +4949,9 @@ dependencies = [ [[package]] name = "wasm-streams" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb" dependencies = [ "futures-util", "js-sys", diff --git a/Cargo.toml b/Cargo.toml index 710980f5..cfb2e8c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ members = [ ] [workspace.package] -version = "2026.10319.10359" +version = "2026.10322.104" edition = "2024" license = "AGPL-3.0-only" authors = ["TrueNine"] @@ -23,40 +23,40 @@ tnmsc-md-compiler = { path = "libraries/md-compiler" } tnmsc-script-runtime = { path = "libraries/script-runtime" } # Serialization -serde = { version = "1", features = ["derive"] } -serde_json = "1" +serde = { version = "1.0.228", features = ["derive"] } +serde_json = "1.0.149" serde_yml = "0.0.12" # CLI -clap = { version = "4", features = ["derive"] } +clap = { version = "4.6.0", features = ["derive"] } # Filesystem & system -dirs = "6" -glob = "0.3" +dirs = "6.0.0" +glob = "0.3.3" # Crypto & encoding sha2 = "0.10" -base64 = "0.22" +base64 = "0.22.1" # HTTP -reqwest = { version = "0.13", features = ["blocking", "json"] } +reqwest = { version = "0.13.2", features = ["blocking", "json"] } # Markdown / MDX markdown = "1.0.0" # NAPI-RS (Node.js native addon bindings) -napi = { version = "3", features = ["napi4"] } -napi-derive = "3" -napi-build = "2" +napi = { version = "3.8.3", features = ["napi4"] } +napi-derive = "3.5.2" +napi-build = "2.3.1" # Tauri -tauri = { version = "2", features = ["tray-icon"] } -tauri-build = { version = "2", features = [] } +tauri = { version = "2.10.3", features = ["tray-icon"] } +tauri-build = { version = "2.5.6", features = [] } tauri-plugin-shell = "2" tauri-plugin-updater = "2" # JSON5 (for GUI log parsing compat) -json5 = "1" +json5 = "1.3.1" [profile.release] strip = true diff --git a/README.md b/README.md index 61ef467e..93ba46f6 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,10 @@ What can it help you do? npm install -g @truenine/memory-sync ``` +## Docs + +`https://docs.truenine.org/tnmsc` + ## Supported Tools | Type | Tools | diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 33d523bd..c50993d8 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -26,17 +26,17 @@ tnmsc-logger = { workspace = true } tnmsc-md-compiler = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } -thiserror = "2" +thiserror = "2.0.18" clap = { workspace = true } dirs = { workspace = true } sha2 = { workspace = true } napi = { workspace = true, optional = true } napi-derive = { workspace = true, optional = true } -reqwest = { version = "0.13", default-features = false, features = ["blocking", "json", "rustls", "rustls-native-certs"] } +reqwest = { version = "0.13.2", default-features = false, features = ["blocking", "json", "rustls"] } [dev-dependencies] -proptest = "1" -tempfile = "3" +proptest = "1.10.0" +tempfile = "3.27.0" [build-dependencies] napi-build = { workspace = true } diff --git a/cli/eslint.config.ts b/cli/eslint.config.ts index 6ee69077..bfe7f6c3 100644 --- a/cli/eslint.config.ts +++ b/cli/eslint.config.ts @@ -5,7 +5,7 @@ import eslint10 from '@truenine/eslint10-config' const configDir = dirname(fileURLToPath(import.meta.url)) -const config = eslint10({ +const config = await eslint10({ type: 'lib', typescript: { strictTypescriptEslint: true, @@ -34,4 +34,12 @@ const config = eslint10({ ] }) -export default config as unknown +const overrides = { + files: ['src/**/*.ts', 'src/**/*.tsx'], + rules: { + 'e18e/prefer-static-regex': 'off', + 'ts/member-ordering': 'off' + } +} + +export default [...config, overrides] as unknown diff --git a/cli/npm/darwin-arm64/package.json b/cli/npm/darwin-arm64/package.json index 92987d80..af384daa 100644 --- a/cli/npm/darwin-arm64/package.json +++ b/cli/npm/darwin-arm64/package.json @@ -1,6 +1,6 @@ { "name": "@truenine/memory-sync-cli-darwin-arm64", - "version": "2026.10319.10359", + "version": "2026.10322.104", "os": [ "darwin" ], diff --git a/cli/npm/darwin-x64/package.json b/cli/npm/darwin-x64/package.json index 3dec9327..e8b54220 100644 --- a/cli/npm/darwin-x64/package.json +++ b/cli/npm/darwin-x64/package.json @@ -1,6 +1,6 @@ { "name": "@truenine/memory-sync-cli-darwin-x64", - "version": "2026.10319.10359", + "version": "2026.10322.104", "os": [ "darwin" ], diff --git a/cli/npm/linux-arm64-gnu/package.json b/cli/npm/linux-arm64-gnu/package.json index 55157ed1..0709fca8 100644 --- a/cli/npm/linux-arm64-gnu/package.json +++ b/cli/npm/linux-arm64-gnu/package.json @@ -1,6 +1,6 @@ { "name": "@truenine/memory-sync-cli-linux-arm64-gnu", - "version": "2026.10319.10359", + "version": "2026.10322.104", "os": [ "linux" ], diff --git a/cli/npm/linux-x64-gnu/package.json b/cli/npm/linux-x64-gnu/package.json index 4357834d..8bd0fe71 100644 --- a/cli/npm/linux-x64-gnu/package.json +++ b/cli/npm/linux-x64-gnu/package.json @@ -1,6 +1,6 @@ { "name": "@truenine/memory-sync-cli-linux-x64-gnu", - "version": "2026.10319.10359", + "version": "2026.10322.104", "os": [ "linux" ], diff --git a/cli/npm/win32-x64-msvc/package.json b/cli/npm/win32-x64-msvc/package.json index b1af444c..be5c88ac 100644 --- a/cli/npm/win32-x64-msvc/package.json +++ b/cli/npm/win32-x64-msvc/package.json @@ -1,6 +1,6 @@ { "name": "@truenine/memory-sync-cli-win32-x64-msvc", - "version": "2026.10319.10359", + "version": "2026.10322.104", "os": [ "win32" ], diff --git a/cli/package.json b/cli/package.json index 9f55e517..dd12e8c2 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,7 +1,7 @@ { "name": "@truenine/memory-sync-cli", "type": "module", - "version": "2026.10319.10359", + "version": "2026.10322.104", "description": "TrueNine Memory Synchronization CLI", "author": "TrueNine", "license": "AGPL-3.0-only", @@ -64,7 +64,7 @@ }, "dependencies": { "json5": "catalog:", - "yaml": "2.8.2", + "yaml": "catalog:", "zod": "catalog:" }, "optionalDependencies": { @@ -84,11 +84,11 @@ "@vitest/coverage-v8": "catalog:", "fast-glob": "catalog:", "fs-extra": "catalog:", - "jiti": "2.6.1", - "lightningcss": "1.31.1", + "jiti": "catalog:", + "lightningcss": "catalog:", "picocolors": "catalog:", "picomatch": "catalog:", - "tsx": "4.21.0", + "tsx": "catalog:", "vitest": "catalog:", "zod-to-json-schema": "catalog:" } diff --git a/cli/src/ConfigLoader.ts b/cli/src/ConfigLoader.ts index 587ea121..0a12f99f 100644 --- a/cli/src/ConfigLoader.ts +++ b/cli/src/ConfigLoader.ts @@ -60,11 +60,13 @@ export interface GlobalConfigValidationResult { export class ConfigLoader { private readonly logger: ILogger - constructor(_options: ConfigLoaderOptions = {}) { + constructor(options: ConfigLoaderOptions = {}) { + void options this.logger = createLogger('ConfigLoader') } - getSearchPaths(_cwd: string = process.cwd()): string[] { + getSearchPaths(cwd: string = process.cwd()): string[] { + void cwd return [getGlobalConfigPath()] } diff --git a/cli/src/cli-runtime.test.ts b/cli/src/cli-runtime.test.ts new file mode 100644 index 00000000..ab877f20 --- /dev/null +++ b/cli/src/cli-runtime.test.ts @@ -0,0 +1,67 @@ +import {afterEach, describe, expect, it, vi} from 'vitest' + +const { + createDefaultPluginConfigMock, + pipelineRunMock, + pluginPipelineCtorMock +} = vi.hoisted(() => ({ + createDefaultPluginConfigMock: vi.fn(), + pipelineRunMock: vi.fn(), + pluginPipelineCtorMock: vi.fn() +})) + +vi.mock('./plugin.config', () => ({ + createDefaultPluginConfig: createDefaultPluginConfigMock +})) + +vi.mock('./PluginPipeline', () => ({ + PluginPipeline: function MockPluginPipeline(...args: unknown[]) { + pluginPipelineCtorMock(...args) + return { + run: pipelineRunMock + } + } +})) + +afterEach(() => { + vi.clearAllMocks() + vi.resetModules() +}) + +describe('cli runtime lightweight commands', () => { + it('does not load plugin config for --version', async () => { + const {runCli} = await import('./cli-runtime') + + const exitCode = await runCli(['node', 'tnmsc', '--version']) + + expect(exitCode).toBe(0) + expect(createDefaultPluginConfigMock).not.toHaveBeenCalled() + expect(pluginPipelineCtorMock).not.toHaveBeenCalled() + expect(pipelineRunMock).not.toHaveBeenCalled() + }) + + it('emits JSON for --version --json without loading plugin config', async () => { + const {runCli} = await import('./cli-runtime') + const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true) + + try { + const exitCode = await runCli(['node', 'tnmsc', '--version', '--json']) + + expect(exitCode).toBe(0) + expect(createDefaultPluginConfigMock).not.toHaveBeenCalled() + expect(pluginPipelineCtorMock).not.toHaveBeenCalled() + expect(pipelineRunMock).not.toHaveBeenCalled() + + const payload = JSON.parse(String(writeSpy.mock.calls[0]?.[0])) as { + readonly success: boolean + readonly message?: string + } + + expect(payload.success).toBe(true) + expect(payload.message).toBe('Version displayed') + } + finally { + writeSpy.mockRestore() + } + }) +}) diff --git a/cli/src/cli-runtime.ts b/cli/src/cli-runtime.ts index d6bc5cee..213b8bdf 100644 --- a/cli/src/cli-runtime.ts +++ b/cli/src/cli-runtime.ts @@ -1,9 +1,15 @@ +import type {Command, CommandContext, CommandResult} from '@/commands/Command' +import * as path from 'node:path' import process from 'node:process' -import {toJsonCommandResult} from '@/commands/JsonOutputCommand' +import {JsonOutputCommand, toJsonCommandResult} from '@/commands/JsonOutputCommand' import {buildUnhandledExceptionDiagnostic} from '@/diagnostics' import {PluginPipeline} from '@/PluginPipeline' +import {mergeConfig} from './config' +import {extractUserArgs, parseArgs, resolveCommand} from './pipeline/CliArgumentParser' import {createDefaultPluginConfig} from './plugin.config' -import {createLogger, drainBufferedDiagnostics} from './plugins/plugin-core' +import {createLogger, drainBufferedDiagnostics, FilePathKind, setGlobalLogLevel} from './plugins/plugin-core' + +const LIGHTWEIGHT_COMMAND_NAMES = new Set(['help', 'version', 'unknown']) export function isJsonMode(argv: readonly string[]): boolean { return argv.some(arg => arg === '--json' || arg === '-j' || /^-[^-]*j/.test(arg)) @@ -21,8 +27,67 @@ function writeJsonFailure(error: unknown): void { }, drainBufferedDiagnostics()))}\n`) } +function createUnavailableContext(kind: 'cleanup' | 'write'): never { + throw new Error(`${kind} context is unavailable for lightweight commands`) +} + +function createLightweightCommandContext(logLevel: ReturnType['logLevel']): CommandContext { + const workspaceDir = process.cwd() + const userConfigOptions = mergeConfig({ + workspaceDir, + ...logLevel != null ? {logLevel} : {} + }) + + return { + logger: createLogger('PluginPipeline', logLevel), + outputPlugins: [], + collectedOutputContext: { + workspace: { + directory: { + pathKind: FilePathKind.Absolute, + path: workspaceDir, + getDirectoryName: () => path.basename(workspaceDir) + }, + projects: [] + } + }, + userConfigOptions, + createCleanContext: () => createUnavailableContext('cleanup'), + createWriteContext: () => createUnavailableContext('write') + } +} + +function resolveLightweightCommand(argv: readonly string[]): { + readonly command: Command + readonly context: CommandContext +} | undefined { + const filteredArgs = argv.filter((arg): arg is string => arg != null) + const parsedArgs = parseArgs(extractUserArgs(filteredArgs)) + let command: Command = resolveCommand(parsedArgs) + + if (!LIGHTWEIGHT_COMMAND_NAMES.has(command.name)) return void 0 + + if (parsedArgs.logLevel != null) setGlobalLogLevel(parsedArgs.logLevel) + + if (parsedArgs.jsonFlag) { + setGlobalLogLevel('silent') + command = new JsonOutputCommand(command) + } + + return { + command, + context: createLightweightCommandContext(parsedArgs.logLevel) + } +} + export async function runCli(argv: readonly string[] = process.argv): Promise { try { + const lightweightCommand = resolveLightweightCommand(argv) + if (lightweightCommand != null) { + const result: CommandResult = await lightweightCommand.command.execute(lightweightCommand.context) + return result.success ? 0 : 1 + } + const pipeline = new PluginPipeline(...argv) const userPluginConfig = await createDefaultPluginConfig(argv) const result = await pipeline.run(userPluginConfig) diff --git a/cli/src/commands/CleanupUtils.ts b/cli/src/commands/CleanupUtils.ts index 5b7d1413..662f1485 100644 --- a/cli/src/commands/CleanupUtils.ts +++ b/cli/src/commands/CleanupUtils.ts @@ -1,4 +1,4 @@ -import type {ILogger, OutputCleanContext, OutputCleanupDeclarations, OutputCleanupPathDeclaration, OutputPlugin, PluginOptions} from '../plugins/plugin-core' +import type {ILogger, OutputCleanContext, OutputCleanupDeclarations, OutputCleanupPathDeclaration, OutputFileDeclaration, OutputPlugin, PluginOptions} from '../plugins/plugin-core' import type {ProtectedPathRule, ProtectionMode, ProtectionRuleMatcher} from '../ProtectedDeletionGuard' import * as fs from 'node:fs' import * as path from 'node:path' @@ -130,14 +130,18 @@ async function collectPluginCleanupDeclarations( async function collectPluginCleanupSnapshot( plugin: OutputPlugin, - cleanCtx: OutputCleanContext + cleanCtx: OutputCleanContext, + predeclaredOutputs?: ReadonlyMap ): Promise<{ readonly plugin: OutputPlugin readonly outputs: Awaited> readonly cleanup: OutputCleanupDeclarations }> { + const existingOutputDeclarations = predeclaredOutputs?.get(plugin) const [outputs, cleanup] = await Promise.all([ - plugin.declareOutputFiles({...cleanCtx, dryRun: true}), + existingOutputDeclarations != null + ? Promise.resolve(existingOutputDeclarations) + : plugin.declareOutputFiles({...cleanCtx, dryRun: true}), collectPluginCleanupDeclarations(plugin, cleanCtx) ]) @@ -258,7 +262,8 @@ function logCleanupProtectionConflicts( */ export async function collectDeletionTargets( outputPlugins: readonly OutputPlugin[], - cleanCtx: OutputCleanContext + cleanCtx: OutputCleanContext, + predeclaredOutputs?: ReadonlyMap ): Promise<{ filesToDelete: string[] dirsToDelete: string[] @@ -272,7 +277,9 @@ export async function collectDeletionTargets( const excludeScanGlobSet = new Set(DEFAULT_CLEANUP_SCAN_EXCLUDE_GLOBS) const outputPathOwners = new Map() - const pluginSnapshots = await Promise.all(outputPlugins.map(async plugin => collectPluginCleanupSnapshot(plugin, cleanCtx))) + const pluginSnapshots = await Promise.all( + outputPlugins.map(async plugin => collectPluginCleanupSnapshot(plugin, cleanCtx, predeclaredOutputs)) + ) const addDeletePath = (rawPath: string, kind: 'file' | 'directory'): void => { if (kind === 'directory') deleteDirs.add(resolveAbsolutePath(rawPath)) @@ -491,19 +498,22 @@ function logCleanupPlanDiagnostics( export async function performCleanup( outputPlugins: readonly OutputPlugin[], cleanCtx: OutputCleanContext, - logger: ILogger + logger: ILogger, + predeclaredOutputs?: ReadonlyMap ): Promise { - const outputs = await collectAllPluginOutputs(outputPlugins, cleanCtx) // Collect outputs for logging - logger.debug('Collected outputs for cleanup', { - projectDirs: outputs.projectDirs.length, - projectFiles: outputs.projectFiles.length, - globalDirs: outputs.globalDirs.length, - globalFiles: outputs.globalFiles.length - }) + if (predeclaredOutputs != null) { + const outputs = await collectAllPluginOutputs(outputPlugins, cleanCtx, predeclaredOutputs) + logger.debug('Collected outputs for cleanup', { + projectDirs: outputs.projectDirs.length, + projectFiles: outputs.projectFiles.length, + globalDirs: outputs.globalDirs.length, + globalFiles: outputs.globalFiles.length + }) + } let targets: Awaited> try { - targets = await collectDeletionTargets(outputPlugins, cleanCtx) + targets = await collectDeletionTargets(outputPlugins, cleanCtx, predeclaredOutputs) } catch (error) { if (error instanceof CleanupProtectionConflictError) { diff --git a/cli/src/commands/ConfigCommand.ts b/cli/src/commands/ConfigCommand.ts index abc8e9ff..b1a2934a 100644 --- a/cli/src/commands/ConfigCommand.ts +++ b/cli/src/commands/ConfigCommand.ts @@ -95,12 +95,16 @@ function setNestedValue(obj: ConfigObject, key: string, value: string): void { const parts = key.split('.') let current: ConfigObject = obj for (let i = 0; i < parts.length - 1; i++) { - const part = parts[i]! + const part = parts[i] + if (part == null) continue const next = current[part] if (typeof next !== 'object' || next === null || Array.isArray(next)) current[part] = {} current = current[part] as ConfigObject } - current[parts.at(-1)!] = value + + const lastPart = parts.at(-1) + if (lastPart == null) return + current[lastPart] = value } /** diff --git a/cli/src/commands/ExecuteCommand.ts b/cli/src/commands/ExecuteCommand.ts index 9a8c95d1..65cf5cab 100644 --- a/cli/src/commands/ExecuteCommand.ts +++ b/cli/src/commands/ExecuteCommand.ts @@ -1,5 +1,6 @@ import type {Command, CommandContext, CommandResult} from './Command' import { + collectOutputDeclarations, executeDeclarativeWriteOutputs } from '../plugins/plugin-core' import {performCleanup} from './CleanupUtils' @@ -15,8 +16,10 @@ export class ExecuteCommand implements Command { const {logger, outputPlugins, createCleanContext, createWriteContext} = ctx logger.info('started', {command: 'execute'}) + const writeCtx = createWriteContext(false) + const predeclaredOutputs = await collectOutputDeclarations(outputPlugins, writeCtx) const cleanCtx = createCleanContext(false) // Step 1: Pre-cleanup (non-dry-run only) - const cleanupResult = await performCleanup(outputPlugins, cleanCtx, logger) + const cleanupResult = await performCleanup(outputPlugins, cleanCtx, logger, predeclaredOutputs) if (cleanupResult.violations.length > 0 || cleanupResult.conflicts.length > 0) { return { @@ -29,8 +32,7 @@ export class ExecuteCommand implements Command { logger.info('cleanup complete', {deletedFiles: cleanupResult.deletedFiles, deletedDirs: cleanupResult.deletedDirs}) - const writeCtx = createWriteContext(false) // Step 2: Write outputs - const results = await executeDeclarativeWriteOutputs(outputPlugins, writeCtx) + const results = await executeDeclarativeWriteOutputs(outputPlugins, writeCtx, predeclaredOutputs) // Step 2: Write outputs let totalFiles = 0 let totalDirs = 0 diff --git a/cli/src/commands/ProtectedDeletionCommands.test.ts b/cli/src/commands/ProtectedDeletionCommands.test.ts index 29260f7d..9baa9fea 100644 --- a/cli/src/commands/ProtectedDeletionCommands.test.ts +++ b/cli/src/commands/ProtectedDeletionCommands.test.ts @@ -44,8 +44,10 @@ function createMockOutputPlugin( } } -function createCommandContext(outputPlugins: readonly OutputPlugin[]): CommandContext { - const workspaceDir = path.resolve('tmp-workspace-command') +function createCommandContext( + outputPlugins: readonly OutputPlugin[], + workspaceDir: string = path.resolve('tmp-workspace-command') +): CommandContext { const aindexDir = path.join(workspaceDir, 'aindex') const collectedOutputContext = { workspace: { @@ -180,6 +182,44 @@ describe('protected deletion commands', () => { })) }) + it('reuses declared outputs across cleanup and write during execute', async () => { + const workspaceDir = path.resolve('tmp-workspace-command-cached') + const outputPath = path.join(workspaceDir, 'project-a', 'AGENTS.md') + let declareOutputFilesCalls = 0 + const plugin: OutputPlugin = { + type: PluginKind.Output, + name: 'CachedOutputPlugin', + log: createMockLogger(), + declarativeOutput: true, + outputCapabilities: {}, + async declareOutputFiles() { + declareOutputFilesCalls += 1 + return [{path: outputPath, source: {}}] + }, + async declareCleanupPaths() { + return {} + }, + async convertContent() { + return 'cached-output' + } + } + + fs.rmSync(workspaceDir, {recursive: true, force: true}) + fs.mkdirSync(path.join(workspaceDir, 'project-a'), {recursive: true}) + + try { + const ctx = createCommandContext([plugin], workspaceDir) + const result = await new ExecuteCommand().execute(ctx) + + expect(result.success).toBe(true) + expect(declareOutputFilesCalls).toBe(1) + expect(fs.readFileSync(outputPath, 'utf8')).toBe('cached-output') + } + finally { + fs.rmSync(workspaceDir, {recursive: true, force: true}) + } + }) + it('includes structured diagnostics in JSON output errors', async () => { const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true) const command = new JsonOutputCommand({ diff --git a/cli/src/commands/factories/DryRunCommandFactory.ts b/cli/src/commands/factories/DryRunCommandFactory.ts index eaa4ba7d..232901ea 100644 --- a/cli/src/commands/factories/DryRunCommandFactory.ts +++ b/cli/src/commands/factories/DryRunCommandFactory.ts @@ -12,7 +12,8 @@ export class DryRunCommandFactory implements CommandFactory { return args.subcommand === 'dry-run' } - createCommand(_args: ParsedCliArgs): Command { + createCommand(args: ParsedCliArgs): Command { + void args return new DryRunOutputCommand() } } diff --git a/cli/src/commands/factories/ExecuteCommandFactory.ts b/cli/src/commands/factories/ExecuteCommandFactory.ts index 3a47667c..d7a6f8dc 100644 --- a/cli/src/commands/factories/ExecuteCommandFactory.ts +++ b/cli/src/commands/factories/ExecuteCommandFactory.ts @@ -8,11 +8,13 @@ import {ExecuteCommand} from '../ExecuteCommand' * Handles default execution when no specific subcommand matches */ export class ExecuteCommandFactory implements CommandFactory { - canHandle(_args: ParsedCliArgs): boolean { // This is a catch-all factory with lowest priority + canHandle(args: ParsedCliArgs): boolean { // This is a catch-all factory with lowest priority + void args return true } - createCommand(_args: ParsedCliArgs): Command { + createCommand(args: ParsedCliArgs): Command { + void args return new ExecuteCommand() } } diff --git a/cli/src/commands/factories/HelpCommandFactory.ts b/cli/src/commands/factories/HelpCommandFactory.ts index fa11beb3..3b4174a5 100644 --- a/cli/src/commands/factories/HelpCommandFactory.ts +++ b/cli/src/commands/factories/HelpCommandFactory.ts @@ -15,7 +15,8 @@ export class HelpCommandFactory implements PrioritizedCommandFactory { return args.helpFlag || args.subcommand === 'help' } - createCommand(_args: ParsedCliArgs): Command { + createCommand(args: ParsedCliArgs): Command { + void args return new HelpCommand() } } diff --git a/cli/src/commands/factories/InitCommandFactory.ts b/cli/src/commands/factories/InitCommandFactory.ts index d9622527..71f55fca 100644 --- a/cli/src/commands/factories/InitCommandFactory.ts +++ b/cli/src/commands/factories/InitCommandFactory.ts @@ -8,7 +8,8 @@ export class InitCommandFactory implements CommandFactory { return args.subcommand === 'init' } - createCommand(_args: ParsedCliArgs): Command { + createCommand(args: ParsedCliArgs): Command { + void args return new InitCommand() } } diff --git a/cli/src/commands/factories/PluginsCommandFactory.ts b/cli/src/commands/factories/PluginsCommandFactory.ts index 2992beca..11b25ecb 100644 --- a/cli/src/commands/factories/PluginsCommandFactory.ts +++ b/cli/src/commands/factories/PluginsCommandFactory.ts @@ -12,7 +12,8 @@ export class PluginsCommandFactory implements CommandFactory { return args.subcommand === 'plugins' } - createCommand(_args: ParsedCliArgs): Command { + createCommand(args: ParsedCliArgs): Command { + void args return new PluginsCommand() } } diff --git a/cli/src/commands/factories/UnknownCommandFactory.ts b/cli/src/commands/factories/UnknownCommandFactory.ts index a652ffe5..6c97fb62 100644 --- a/cli/src/commands/factories/UnknownCommandFactory.ts +++ b/cli/src/commands/factories/UnknownCommandFactory.ts @@ -16,6 +16,7 @@ export class UnknownCommandFactory implements PrioritizedCommandFactory { } createCommand(args: ParsedCliArgs): Command { - return new UnknownCommand(args.unknownCommand!) + if (args.unknownCommand == null) return new UnknownCommand('') + return new UnknownCommand(args.unknownCommand) } } diff --git a/cli/src/commands/factories/VersionCommandFactory.ts b/cli/src/commands/factories/VersionCommandFactory.ts index 624a3945..95dbc123 100644 --- a/cli/src/commands/factories/VersionCommandFactory.ts +++ b/cli/src/commands/factories/VersionCommandFactory.ts @@ -15,7 +15,8 @@ export class VersionCommandFactory implements PrioritizedCommandFactory { return args.versionFlag || args.subcommand === 'version' } - createCommand(_args: ParsedCliArgs): Command { + createCommand(args: ParsedCliArgs): Command { + void args return new VersionCommand() } } diff --git a/cli/src/diagnostics.ts b/cli/src/diagnostics.ts index fb9f47c5..15634a9b 100644 --- a/cli/src/diagnostics.ts +++ b/cli/src/diagnostics.ts @@ -21,7 +21,9 @@ export function splitDiagnosticText(text: string): DiagnosticLines { .filter(line => line.length > 0) if (lines.length === 0) return diagnosticLines('No diagnostic details were provided.') - return diagnosticLines(lines[0]!, ...lines.slice(1)) + const [firstLine, ...otherLines] = lines + if (firstLine == null) return diagnosticLines('No diagnostic details were provided.') + return diagnosticLines(firstLine, ...otherLines) } export function buildDiagnostic(input: LoggerDiagnosticInput): LoggerDiagnosticInput { diff --git a/cli/src/inputs/effect-md-cleanup.ts b/cli/src/inputs/effect-md-cleanup.ts index aacc2b9b..b32f9210 100644 --- a/cli/src/inputs/effect-md-cleanup.ts +++ b/cli/src/inputs/effect-md-cleanup.ts @@ -156,7 +156,8 @@ export class MarkdownWhitespaceCleanupEffectInputCapability extends AbstractInpu return '\n' } - collect(_ctx: InputCapabilityContext): Partial { + collect(ctx: InputCapabilityContext): Partial { + void ctx return {} } } diff --git a/cli/src/inputs/effect-orphan-cleanup.ts b/cli/src/inputs/effect-orphan-cleanup.ts index 7ffdfce5..1c47b0cf 100644 --- a/cli/src/inputs/effect-orphan-cleanup.ts +++ b/cli/src/inputs/effect-orphan-cleanup.ts @@ -278,7 +278,8 @@ export class OrphanFileCleanupEffectInputCapability extends AbstractInputCapabil } } - collect(_ctx: InputCapabilityContext): Partial { + collect(ctx: InputCapabilityContext): Partial { + void ctx return {} } } diff --git a/cli/src/inputs/effect-skill-sync.ts b/cli/src/inputs/effect-skill-sync.ts index 3effe6f9..bab39bb4 100644 --- a/cli/src/inputs/effect-skill-sync.ts +++ b/cli/src/inputs/effect-skill-sync.ts @@ -165,7 +165,8 @@ export class SkillDistCleanupEffectInputCapability extends AbstractInputCapabili return fileName.endsWith('.mdx') && !hasSourcePromptExtension(fileName) } - collect(_ctx: InputCapabilityContext): Partial { + collect(ctx: InputCapabilityContext): Partial { + void ctx return {} } } diff --git a/cli/src/inputs/input-agentskills-export-fallback.test.ts b/cli/src/inputs/input-agentskills-export-fallback.test.ts index 2ae3181c..b19ace0d 100644 --- a/cli/src/inputs/input-agentskills-export-fallback.test.ts +++ b/cli/src/inputs/input-agentskills-export-fallback.test.ts @@ -52,14 +52,12 @@ describe('skill input plugin export fallback', () => { fs.mkdirSync(srcSkillDir, {recursive: true}) fs.mkdirSync(distSkillDir, {recursive: true}) fs.writeFileSync(path.join(srcSkillDir, 'skill.src.mdx'), `export default { - name: 'demo', description: 'source export description', } Source skill `, 'utf8') fs.writeFileSync(path.join(distSkillDir, 'skill.mdx'), `export default { - name: 'demo', description: 'dist export description', } diff --git a/cli/src/inputs/input-agentskills.test.ts b/cli/src/inputs/input-agentskills.test.ts index 90e9ab40..f5881e15 100644 --- a/cli/src/inputs/input-agentskills.test.ts +++ b/cli/src/inputs/input-agentskills.test.ts @@ -53,9 +53,11 @@ describe('skill input plugin', () => { const [skill] = result.skills ?? [] expect(result.skills?.length ?? 0).toBe(1) + expect(skill?.skillName).toBe('demo') expect(skill?.content).toContain('Skill dist') expect(skill?.content).not.toContain('Skill source') expect(skill?.content).not.toContain('export const x = 1') + expect(skill?.yamlFrontMatter?.name).toBe('demo') expect(skill?.yamlFrontMatter?.description).toBe('dist skill') expect(skill?.childDocs?.map(childDoc => childDoc.relativePath)).toEqual(['guide.mdx']) expect(skill?.childDocs?.[0]?.content).toContain('Guide dist') @@ -139,7 +141,7 @@ describe('skill input plugin', () => { fs.mkdirSync(srcSkillDir, {recursive: true}) fs.mkdirSync(distSkillDir, {recursive: true}) fs.writeFileSync(path.join(srcSkillDir, 'skill.src.mdx'), '---\ndescription: src skill\n---\nSkill source', 'utf8') - fs.writeFileSync(path.join(distSkillDir, 'skill.mdx'), '---\nname: demo\ndescription: dist skill\nscope: workspace\n---\nSkill dist', 'utf8') + fs.writeFileSync(path.join(distSkillDir, 'skill.mdx'), '---\ndescription: dist skill\nscope: workspace\n---\nSkill dist', 'utf8') const plugin = new SkillInputCapability() await expect(plugin.collect(createContext(tempWorkspace, createMockLogger()))).rejects.toThrow('Field "scope" must be "project" or "global"') @@ -148,4 +150,30 @@ describe('skill input plugin', () => { fs.rmSync(tempWorkspace, {recursive: true, force: true}) } }) + + it('warns and ignores authored skill name metadata', async () => { + const warnings: string[] = [] + const tempWorkspace = fs.mkdtempSync(path.join(os.tmpdir(), 'tnmsc-skill-input-name-warning-test-')) + const srcSkillDir = path.join(tempWorkspace, 'aindex', 'skills', 'demo') + const distSkillDir = path.join(tempWorkspace, 'aindex', 'dist', 'skills', 'demo') + + try { + fs.mkdirSync(srcSkillDir, {recursive: true}) + fs.mkdirSync(distSkillDir, {recursive: true}) + fs.writeFileSync(path.join(srcSkillDir, 'skill.src.mdx'), '---\nname: custom-demo\ndescription: src skill\n---\nSkill source', 'utf8') + fs.writeFileSync(path.join(distSkillDir, 'skill.mdx'), '---\nname: custom-demo\ndescription: dist skill\n---\nSkill dist', 'utf8') + + const plugin = new SkillInputCapability() + const result = await plugin.collect(createContext(tempWorkspace, createMockLogger(warnings))) + const [skill] = result.skills ?? [] + + expect(skill?.skillName).toBe('demo') + expect(skill?.yamlFrontMatter?.name).toBe('demo') + expect(skill?.yamlFrontMatter?.description).toBe('dist skill') + expect(warnings).toContain('SKILL_NAME_IGNORED') + } + finally { + fs.rmSync(tempWorkspace, {recursive: true, force: true}) + } + }) }) diff --git a/cli/src/inputs/input-agentskills.ts b/cli/src/inputs/input-agentskills.ts index 22e5a25f..8ade7018 100644 --- a/cli/src/inputs/input-agentskills.ts +++ b/cli/src/inputs/input-agentskills.ts @@ -111,6 +111,35 @@ function mergeDefinedSkillMetadata( return merged } +function warnIgnoredSkillName(options: { + readonly logger: ILogger + readonly warnedDerivedNames?: Set + readonly sourcePath: string + readonly authoredName: string + readonly skillName: string +}): void { + const {logger, warnedDerivedNames, sourcePath, authoredName, skillName} = options + if (warnedDerivedNames?.has(sourcePath) === true) return + + warnedDerivedNames?.add(sourcePath) + logger.warn(buildConfigDiagnostic({ + code: 'SKILL_NAME_IGNORED', + title: 'Skill authored name is ignored', + reason: diagnosticLines( + `tnmsc ignores the authored skill name "${authoredName}" in favor of the directory-derived name "${skillName}".` + ), + configPath: sourcePath, + exactFix: diagnosticLines( + 'Remove the `name` field from the skill front matter or exported metadata.', + 'Rename the skill directory if you need a different skill name.' + ), + details: { + authoredName, + derivedName: skillName + } + })) +} + const MIME_TYPES: Record = { // MIME types for resources '.ts': 'text/typescript', '.tsx': 'text/typescript', @@ -557,16 +586,21 @@ async function createSkillPrompt( name: string, skillDir: string, skillAbsoluteDir: string, + sourceSkillAbsoluteDir: string, ctx: InputCapabilityContext, mcpConfig?: SkillMcpConfig, childDocs: SkillPrompt['childDocs'] = [], resources: SkillPrompt['resources'] = [], seriName?: string | string[] | null, - compiledMetadata?: Record + compiledMetadata?: Record, + warnedDerivedNames?: Set ): Promise { const {logger, globalScope, fs} = ctx const distFilePath = nodePath.join(skillAbsoluteDir, 'skill.mdx') + const sourceFilePath = fs.existsSync(nodePath.join(sourceSkillAbsoluteDir, 'skill.src.mdx')) + ? nodePath.join(sourceSkillAbsoluteDir, 'skill.src.mdx') + : distFilePath let rawContent = content let parsed: ReturnType> | undefined, distMetadata: Record | undefined @@ -593,6 +627,22 @@ async function createSkillPrompt( distMetadata ) // Merge fallback export parsing with compiled metadata so empty metadata objects do not mask valid fields + const authoredNames = new Set() + const yamlName = parsed?.yamlFrontMatter?.name + if (typeof yamlName === 'string' && yamlName.trim().length > 0) authoredNames.add(yamlName) + const exportedName = exportMetadata.name + if (typeof exportedName === 'string' && exportedName.trim().length > 0) authoredNames.add(exportedName) + + for (const authoredName of authoredNames) { + warnIgnoredSkillName({ + logger, + sourcePath: sourceFilePath, + authoredName, + skillName: name, + ...warnedDerivedNames != null && {warnedDerivedNames} + }) + } + const finalDescription = parsed?.yamlFrontMatter?.description ?? exportMetadata?.description if (finalDescription == null || finalDescription.trim().length === 0) { // Strict validation: description must exist and not be empty @@ -634,6 +684,7 @@ async function createSkillPrompt( content, length: content.length, filePathKind: FilePathKind.Relative, + skillName: name, yamlFrontMatter: mergedFrontMatter, markdownAst: parsed?.markdownAst, markdownContents: parsed?.markdownContents ?? [], @@ -694,6 +745,7 @@ export class SkillInputCapability extends AbstractInputCapability { const flatSkills: SkillPrompt[] = [] const reader = createLocalizedPromptReader(fs, pathModule, logger, globalScope) + const warnedDerivedNames = new Set() const skillArtifactCache = new Map { const srcFile = path.join(srcDir, 'demo.src.mdx') const distFile = path.join(distDir, 'demo.mdx') - fs.writeFileSync(srcFile, '---\nname: demo\ndescription: src\n---\nSubAgent source', 'utf8') - fs.writeFileSync(distFile, '---\nname: demo\ndescription: dist\n---\nexport const x = 1\n\nSubAgent dist', 'utf8') + fs.writeFileSync(srcFile, '---\ndescription: src\n---\nSubAgent source', 'utf8') + fs.writeFileSync(distFile, '---\ndescription: dist\n---\nexport const x = 1\n\nSubAgent dist', 'utf8') const plugin = new SubAgentInputCapability() const result = await plugin.collect(createContext(tempWorkspace)) expect(result.subAgents?.length ?? 0).toBe(1) expect(result.subAgents?.[0]?.agentName).toBe('demo') + expect(result.subAgents?.[0]?.canonicalName).toBe('demo') expect(result.subAgents?.[0]?.content).toContain('SubAgent dist') expect(result.subAgents?.[0]?.content).not.toContain('SubAgent source') expect(result.subAgents?.[0]?.content).not.toContain('export const x = 1') @@ -64,8 +65,8 @@ describe('subagent input plugin', () => { const srcFile = path.join(srcDir, 'boot.src.mdx') const distFile = path.join(distDir, 'boot.mdx') - fs.writeFileSync(srcFile, '---\nname: boot\ndescription: qa boot src\n---\nSubAgent source', 'utf8') - fs.writeFileSync(distFile, '---\nname: boot\ndescription: qa boot dist\n---\nSubAgent dist', 'utf8') + fs.writeFileSync(srcFile, '---\ndescription: qa boot src\n---\nSubAgent source', 'utf8') + fs.writeFileSync(distFile, '---\ndescription: qa boot dist\n---\nSubAgent dist', 'utf8') const plugin = new SubAgentInputCapability() const result = await plugin.collect(createContext(tempWorkspace)) @@ -74,6 +75,7 @@ describe('subagent input plugin', () => { expect(result.subAgents?.length ?? 0).toBe(1) expect(subAgent?.agentPrefix).toBe('qa') expect(subAgent?.agentName).toBe('boot') + expect(subAgent?.canonicalName).toBe('qa-boot') expect(subAgent?.content).toContain('SubAgent dist') expect(subAgent?.content).not.toContain('SubAgent source') } @@ -94,8 +96,8 @@ describe('subagent input plugin', () => { const srcFile = path.join(srcDir, 'demo.src.mdx') const distFile = path.join(distDir, 'demo.mdx') - fs.writeFileSync(srcFile, '---\nname: demo\ndescription: src\n---\nSubAgent source', 'utf8') - fs.writeFileSync(distFile, '---\nname: demo\ndescription: dist\n---\nexport const x = 1\n\nSubAgent dist', 'utf8') + fs.writeFileSync(srcFile, '---\ndescription: src\n---\nSubAgent source', 'utf8') + fs.writeFileSync(distFile, '---\ndescription: dist\n---\nexport const x = 1\n\nSubAgent dist', 'utf8') const plugin = new SubAgentInputCapability() const result = await plugin.collect(createContext(tempWorkspace)) @@ -118,7 +120,7 @@ describe('subagent input plugin', () => { fs.mkdirSync(distDir, {recursive: true}) fs.writeFileSync( path.join(distDir, 'demo.mdx'), - '---\nname: demo\ndescription: dist only\n---\nDist only subagent', + '---\ndescription: dist only\n---\nDist only subagent', 'utf8' ) @@ -127,6 +129,7 @@ describe('subagent input plugin', () => { expect(result.subAgents?.length ?? 0).toBe(1) expect(result.subAgents?.[0]?.agentName).toBe('demo') + expect(result.subAgents?.[0]?.canonicalName).toBe('demo') expect(result.subAgents?.[0]?.content).toContain('Dist only subagent') expect(result.subAgents?.[0]?.yamlFrontMatter?.description).toBe('dist only') } @@ -143,7 +146,7 @@ describe('subagent input plugin', () => { fs.mkdirSync(srcDir, {recursive: true}) fs.writeFileSync( path.join(srcDir, 'demo.src.mdx'), - '---\nname: demo\ndescription: source only\n---\nSource only subagent', + '---\ndescription: source only\n---\nSource only subagent', 'utf8' ) @@ -163,7 +166,7 @@ describe('subagent input plugin', () => { fs.mkdirSync(distDir, {recursive: true}) fs.writeFileSync( path.join(distDir, 'demo.mdx'), - '---\nname: demo\ndescription: dist only\nscope: workspace\n---\nDist only subagent', + '---\ndescription: dist only\nscope: workspace\n---\nDist only subagent', 'utf8' ) @@ -174,4 +177,48 @@ describe('subagent input plugin', () => { fs.rmSync(tempWorkspace, {recursive: true, force: true}) } }) + + it('warns and ignores authored subagent names', async () => { + const tempWorkspace = fs.mkdtempSync(path.join(os.tmpdir(), 'tnmsc-subagent-name-warning-test-')) + const warnings: string[] = [] + const aindexDir = path.join(tempWorkspace, 'aindex') + const srcDir = path.join(aindexDir, 'subagents', 'qa') + const distDir = path.join(aindexDir, 'dist', 'subagents', 'qa') + + try { + fs.mkdirSync(srcDir, {recursive: true}) + fs.mkdirSync(distDir, {recursive: true}) + + fs.writeFileSync(path.join(srcDir, 'boot.src.mdx'), '---\nname: review-helper\ndescription: src\n---\nSubAgent source', 'utf8') + fs.writeFileSync(path.join(distDir, 'boot.mdx'), '---\nname: review-helper\ndescription: dist\n---\nSubAgent dist', 'utf8') + + const logger = { + trace: () => {}, + debug: () => {}, + info: () => {}, + warn: diagnostic => warnings.push(diagnostic.code), + error: () => {}, + fatal: () => {} + } + + const options = mergeConfig({workspaceDir: tempWorkspace}) + const plugin = new SubAgentInputCapability() + const result = await plugin.collect({ + logger, + fs, + path, + glob, + userConfigOptions: options, + dependencyContext: {} + } as InputCapabilityContext) + + const [subAgent] = result.subAgents ?? [] + expect(subAgent?.canonicalName).toBe('qa-boot') + expect('name' in (subAgent?.yamlFrontMatter ?? {})).toBe(false) + expect(warnings).toContain('SUBAGENT_NAME_IGNORED') + } + finally { + fs.rmSync(tempWorkspace, {recursive: true, force: true}) + } + }) }) diff --git a/cli/src/inputs/input-subagent.ts b/cli/src/inputs/input-subagent.ts index 139873c0..bec3b96b 100644 --- a/cli/src/inputs/input-subagent.ts +++ b/cli/src/inputs/input-subagent.ts @@ -5,10 +5,11 @@ import type { SubAgentPrompt, SubAgentYAMLFrontMatter } from '../plugins/plugin-core' -import {buildFileOperationDiagnostic} from '@/diagnostics' +import {buildConfigDiagnostic, buildFileOperationDiagnostic, diagnosticLines} from '@/diagnostics' import { AbstractInputCapability, createLocalizedPromptReader, + deriveSubAgentIdentity, FilePathKind, PromptKind, SourceLocaleExtensions, @@ -25,27 +26,50 @@ export class SubAgentInputCapability extends AbstractInputCapability { content: string, _locale: Locale, name: string, + srcDir: string, distDir: string, ctx: InputCapabilityContext, - metadata?: Record + metadata?: Record, + warnedDerivedNames?: Set ): SubAgentPrompt { - const {path} = ctx - - const normalizedName = name.replaceAll('\\', '/') // Normalize Windows backslashes to forward slashes - const slashIndex = normalizedName.indexOf('/') - const parentDirName = slashIndex !== -1 ? normalizedName.slice(0, slashIndex) : void 0 - const fileName = slashIndex !== -1 ? normalizedName.slice(slashIndex + 1) : normalizedName - - const baseName = fileName.replace(/\.mdx$/, '') - const underscoreIndex = baseName.indexOf('_') - const agentPrefix = parentDirName ?? (underscoreIndex === -1 ? void 0 : baseName.slice(0, Math.max(0, underscoreIndex))) - const agentName = parentDirName != null || underscoreIndex === -1 - ? baseName - : baseName.slice(Math.max(0, underscoreIndex + 1)) + const {fs, logger, path} = ctx + const {agentPrefix, agentName, canonicalName} = deriveSubAgentIdentity(name) const filePath = path.join(distDir, `${name}.mdx`) const entryName = `${name}.mdx` - const yamlFrontMatter = metadata as SubAgentYAMLFrontMatter | undefined + const sourceFilePath = fs.existsSync(path.join(srcDir, `${name}.src.mdx`)) + ? path.join(srcDir, `${name}.src.mdx`) + : filePath + const yamlFrontMatter = metadata == null + ? void 0 + : (() => { + const frontMatter = {...metadata} + const authoredName = frontMatter['name'] + + if (typeof authoredName === 'string' && authoredName.trim().length > 0 && warnedDerivedNames?.has(sourceFilePath) !== true) { + warnedDerivedNames?.add(sourceFilePath) + logger.warn(buildConfigDiagnostic({ + code: 'SUBAGENT_NAME_IGNORED', + title: 'Sub-agent authored name is ignored', + reason: diagnosticLines( + `tnmsc ignores the authored sub-agent name "${authoredName}" in favor of the derived path name "${canonicalName}".` + ), + configPath: sourceFilePath, + exactFix: diagnosticLines( + 'Remove the `name` field from the sub-agent front matter or exported metadata.', + 'Rename the sub-agent directory or file if you need a different sub-agent name.' + ), + details: { + authoredName, + derivedName: canonicalName, + logicalName: name + } + })) + } + + delete frontMatter['name'] + return frontMatter as SubAgentYAMLFrontMatter + })() const prompt: SubAgentPrompt = { type: PromptKind.SubAgent, @@ -60,7 +84,8 @@ export class SubAgentInputCapability extends AbstractInputCapability { getAbsolutePath: () => filePath }, ...agentPrefix != null && {agentPrefix}, - agentName + agentName, + canonicalName } as SubAgentPrompt if (yamlFrontMatter == null) return prompt @@ -87,6 +112,7 @@ export class SubAgentInputCapability extends AbstractInputCapability { }) const reader = createLocalizedPromptReader(fs, path, logger, globalScope) + const warnedDerivedNames = new Set() const {prompts: localizedSubAgents, errors} = await reader.readFlatFiles( srcDir, @@ -99,9 +125,11 @@ export class SubAgentInputCapability extends AbstractInputCapability { content, locale, name, + srcDir, distDir, ctx, - metadata + metadata, + warnedDerivedNames ) } ) @@ -140,7 +168,7 @@ export class SubAgentInputCapability extends AbstractInputCapability { logger.debug('SubAgentInputCapability flattened subAgents', { count: flatSubAgents.length, - agents: flatSubAgents.map(a => a.agentName) + agents: flatSubAgents.map(a => a.canonicalName) }) return { diff --git a/cli/src/pipeline/DependencyResolver.ts b/cli/src/pipeline/DependencyResolver.ts index ed92308d..36a5ef38 100644 --- a/cli/src/pipeline/DependencyResolver.ts +++ b/cli/src/pipeline/DependencyResolver.ts @@ -49,7 +49,9 @@ function findCyclePath( for (const node of cycleNodes) { // Start DFS from any cycle node if (dfs(node)) { - const cycleStart = path.indexOf(path.at(-1)!) // Extract just the cycle portion + const lastNode = path.at(-1) + if (lastNode == null) return [...cycleNodes] + const cycleStart = path.indexOf(lastNode) // Extract just the cycle portion return path.slice(cycleStart) } visited.clear() @@ -106,8 +108,11 @@ export function topologicalSort( } while (queue.length > 0) { - const current = queue.shift()! // Take first element to preserve registration order - const node = nodeMap.get(current)! + const current = queue.shift() // Take first element to preserve registration order + if (current == null) continue + + const node = nodeMap.get(current) + if (node == null) continue result.push(node) const currentDependents = dependents.get(current) ?? [] // Process dependents in registration order diff --git a/cli/src/plugin-runtime.ts b/cli/src/plugin-runtime.ts index 9520a941..c23b0cf8 100644 --- a/cli/src/plugin-runtime.ts +++ b/cli/src/plugin-runtime.ts @@ -88,7 +88,7 @@ async function main(): Promise { pluginOptions: userConfigOptions, runtimeTargets, dryRun: dry, - registeredPluginNames: [...outputPlugins].map(p => p.name) + registeredPluginNames: Array.from(outputPlugins, plugin => plugin.name) }) const commandCtx: CommandContext = { diff --git a/cli/src/plugins/AgentsOutputPlugin.test.ts b/cli/src/plugins/AgentsOutputPlugin.test.ts index 28631ead..b9d9ffab 100644 --- a/cli/src/plugins/AgentsOutputPlugin.test.ts +++ b/cli/src/plugins/AgentsOutputPlugin.test.ts @@ -113,8 +113,12 @@ describe('agentsOutputPlugin prompt-source project exclusion', () => { expect(paths).toContain(path.join(workspaceBase, 'project-a', 'commands', 'AGENTS.md')) expect(paths).not.toContain(path.join(workspaceBase, 'aindex', 'AGENTS.md')) expect(paths).not.toContain(path.join(workspaceBase, 'aindex', 'commands', 'AGENTS.md')) - await expect(plugin.convertContent(workspaceDeclaration!, ctx)).resolves.toBe('workspace root') - await expect(plugin.convertContent(rootDeclaration!, ctx)).resolves.toBe('project root') - await expect(plugin.convertContent(childDeclaration!, ctx)).resolves.toBe('project child') + if (workspaceDeclaration == null || rootDeclaration == null || childDeclaration == null) { + throw new Error('Expected AGENTS.md declarations were not emitted') + } + + await expect(plugin.convertContent(workspaceDeclaration, ctx)).resolves.toBe('workspace root') + await expect(plugin.convertContent(rootDeclaration, ctx)).resolves.toBe('project root') + await expect(plugin.convertContent(childDeclaration, ctx)).resolves.toBe('project child') }) }) diff --git a/cli/src/plugins/CodexCLIOutputPlugin.test.ts b/cli/src/plugins/CodexCLIOutputPlugin.test.ts index 5d3758a5..6a986654 100644 --- a/cli/src/plugins/CodexCLIOutputPlugin.test.ts +++ b/cli/src/plugins/CodexCLIOutputPlugin.test.ts @@ -131,8 +131,8 @@ function createSubAgentPrompt(scope: 'project' | 'global'): SubAgentPrompt { }, agentPrefix: 'qa', agentName: 'reviewer', + canonicalName: 'qa-reviewer', yamlFrontMatter: { - name: 'review-helper', description: 'Review pull requests', scope, model: 'gpt-5.2', @@ -191,8 +191,9 @@ describe('codexCLIOutputPlugin command output', () => { ) expect(commandDeclaration).toBeDefined() + if (commandDeclaration == null) throw new Error('Expected codex command declaration') - const rendered = await codexPlugin.convertContent(commandDeclaration!, writeCtx) + const rendered = await codexPlugin.convertContent(commandDeclaration, writeCtx) expect(String(rendered)).toContain('English dist description') expect(String(rendered)).toContain('English dist command body') expect(String(rendered)).not.toContain('中文源描述') @@ -225,27 +226,28 @@ describe('codexCLIOutputPlugin command output', () => { const declarations = await plugin.declareOutputFiles(writeCtx) const paths = declarations.map(declaration => declaration.path) - expect(paths).toContain(path.join(workspace, 'project-a', '.codex', 'agents', 'review-helper.toml')) - expect(paths).toContain(path.join(workspace, 'project-b', '.codex', 'agents', 'review-helper.toml')) - expect(paths).not.toContain(path.join(homeDir, '.codex', 'agents', 'review-helper.toml')) + expect(paths).toContain(path.join(workspace, 'project-a', '.codex', 'agents', 'qa-reviewer.toml')) + expect(paths).toContain(path.join(workspace, 'project-b', '.codex', 'agents', 'qa-reviewer.toml')) + expect(paths).not.toContain(path.join(homeDir, '.codex', 'agents', 'qa-reviewer.toml')) - const declaration = declarations.find(item => item.path === path.join(workspace, 'project-a', '.codex', 'agents', 'review-helper.toml')) + const declaration = declarations.find(item => item.path === path.join(workspace, 'project-a', '.codex', 'agents', 'qa-reviewer.toml')) expect(declaration).toBeDefined() + if (declaration == null) throw new Error('Expected codex subagent declaration') - const rendered = await plugin.convertContent(declaration!, writeCtx) - expect(String(rendered)).toContain('name = "review-helper"') + const rendered = await plugin.convertContent(declaration, writeCtx) + expect(String(rendered)).toContain('name = "qa-reviewer"') expect(String(rendered)).toContain('description = "Review pull requests"') expect(String(rendered)).toContain([ 'developer_instructions = """', 'Review changes carefully.', 'Focus on concrete regressions."""' ].join('\n')) - expect(String(rendered)).toContain('model = "gpt-5.2"') expect(String(rendered)).toContain('nickname_candidates = ["guard"]') expect(String(rendered)).toContain('sandbox_mode = "workspace-write"') expect(String(rendered)).toContain('allowedTools = "shell"') expect(String(rendered)).toContain('[mcp_servers]') expect(String(rendered)).toContain('[mcp_servers.docs]') + expect(String(rendered)).not.toContain('model = ') expect(String(rendered)).not.toContain('scope = ') expect(String(rendered)).not.toContain('allowTools') expect(String(rendered)).not.toContain('color = ') @@ -260,10 +262,10 @@ describe('codexCLIOutputPlugin command output', () => { const declarations = await plugin.declareOutputFiles(writeCtx) expect(declarations.map(declaration => declaration.path)).toContain( - path.join(workspace, 'project-a', '.codex', 'agents', 'review-helper.toml') + path.join(workspace, 'project-a', '.codex', 'agents', 'qa-reviewer.toml') ) expect(declarations.map(declaration => declaration.path)).not.toContain( - path.join(homeDir, '.codex', 'agents', 'review-helper.toml') + path.join(homeDir, '.codex', 'agents', 'qa-reviewer.toml') ) expect(declarations.every(declaration => declaration.scope === 'project')).toBe(true) }) diff --git a/cli/src/plugins/CodexCLIOutputPlugin.ts b/cli/src/plugins/CodexCLIOutputPlugin.ts index 9be606d7..83146137 100644 --- a/cli/src/plugins/CodexCLIOutputPlugin.ts +++ b/cli/src/plugins/CodexCLIOutputPlugin.ts @@ -1,17 +1,19 @@ import type {AbstractOutputPluginOptions} from './plugin-core' -import {AbstractOutputPlugin, PLUGIN_NAMES} from './plugin-core' +import {AbstractOutputPlugin, PLUGIN_NAMES, resolveSubAgentCanonicalName} from './plugin-core' const PROJECT_MEMORY_FILE = 'AGENTS.md' const GLOBAL_CONFIG_DIR = '.codex' const PROMPTS_SUBDIR = 'prompts' const AGENTS_SUBDIR = 'agents' const CODEX_SUBAGENT_FIELD_ORDER = ['name', 'description', 'developer_instructions'] as const -const CODEX_EXCLUDED_SUBAGENT_FIELDS = ['scope', 'seriName', 'argumentHint', 'color', 'namingCase'] as const +const CODEX_EXCLUDED_SUBAGENT_FIELDS = ['scope', 'seriName', 'argumentHint', 'color', 'namingCase', 'model'] as const function transformCodexSubAgentFrontMatter( + subAgentCanonicalName: string, sourceFrontMatter?: Record ): Record { const frontMatter = {...sourceFrontMatter} + frontMatter['name'] = subAgentCanonicalName if (Array.isArray(frontMatter['allowTools']) && frontMatter['allowTools'].length > 0) frontMatter['allowedTools'] = frontMatter['allowTools'].join(', ') @@ -38,9 +40,8 @@ const CODEX_OUTPUT_OPTIONS = { ext: '.toml', artifactFormat: 'toml', bodyFieldName: 'developer_instructions', - fileNameSource: 'frontMatterName', excludedFrontMatterFields: CODEX_EXCLUDED_SUBAGENT_FIELDS, - transformFrontMatter: (_subAgent, context) => transformCodexSubAgentFrontMatter(context.sourceFrontMatter), + transformFrontMatter: (subAgent, context) => transformCodexSubAgentFrontMatter(resolveSubAgentCanonicalName(subAgent), context.sourceFrontMatter), fieldOrder: CODEX_SUBAGENT_FIELD_ORDER }, cleanup: { diff --git a/cli/src/plugins/CursorOutputPlugin.test.ts b/cli/src/plugins/CursorOutputPlugin.test.ts index 37d5da47..3cc9569f 100644 --- a/cli/src/plugins/CursorOutputPlugin.test.ts +++ b/cli/src/plugins/CursorOutputPlugin.test.ts @@ -99,6 +99,7 @@ function createSkillPrompt( content: 'skill body', length: 10, filePathKind: FilePathKind.Relative, + skillName: name, dir: { pathKind: FilePathKind.Relative, path: `skills/${name}`, @@ -107,7 +108,6 @@ function createSkillPrompt( getAbsolutePath: () => path.resolve('tmp/dist/skills', name) }, yamlFrontMatter: { - name, description: 'Ship release', scope }, diff --git a/cli/src/plugins/CursorOutputPlugin.ts b/cli/src/plugins/CursorOutputPlugin.ts index f434f3ba..60941873 100644 --- a/cli/src/plugins/CursorOutputPlugin.ts +++ b/cli/src/plugins/CursorOutputPlugin.ts @@ -79,10 +79,10 @@ export class CursorOutputPlugin extends AbstractOutputPlugin { }, protect: { project: { - dirs: [...PRESERVED_SKILLS].map(skillName => `.cursor/skills-cursor/${skillName}`) + dirs: Array.from(PRESERVED_SKILLS, skillName => `.cursor/skills-cursor/${skillName}`) }, global: { - dirs: [...PRESERVED_SKILLS].map(skillName => `.cursor/skills-cursor/${skillName}`) + dirs: Array.from(PRESERVED_SKILLS, skillName => `.cursor/skills-cursor/${skillName}`) } } }, @@ -165,7 +165,7 @@ export class CursorOutputPlugin extends AbstractOutputPlugin { filteredSkills: readonly SkillPrompt[] ): void => { for (const skill of filteredSkills) { - const skillName = skill.yamlFrontMatter.name + const skillName = this.getSkillName(skill) if (this.isPreservedSkill(skillName)) continue const skillDir = path.join(baseDir, SKILLS_CURSOR_SUBDIR, skillName) @@ -212,7 +212,7 @@ export class CursorOutputPlugin extends AbstractOutputPlugin { for (const skill of filteredMcpSkills) { if (skill.mcpConfig == null) continue - const skillDir = path.join(baseDir, SKILLS_CURSOR_SUBDIR, skill.yamlFrontMatter.name) + const skillDir = path.join(baseDir, SKILLS_CURSOR_SUBDIR, this.getSkillName(skill)) declarations.push({ path: path.join(skillDir, MCP_CONFIG_FILE), scope, diff --git a/cli/src/plugins/DroidCLIOutputPlugin.ts b/cli/src/plugins/DroidCLIOutputPlugin.ts index c6323983..5845cfc4 100644 --- a/cli/src/plugins/DroidCLIOutputPlugin.ts +++ b/cli/src/plugins/DroidCLIOutputPlugin.ts @@ -48,7 +48,7 @@ export class DroidCLIOutputPlugin extends AbstractOutputPlugin { protected override buildSkillMainContent(skill: SkillPrompt, ctx?: OutputWriteContext): string { // Droid-specific: Simplify front matter const simplifiedFrontMatter = skill.yamlFrontMatter != null // Droid-specific: Simplify front matter - ? {name: skill.yamlFrontMatter.name, description: skill.yamlFrontMatter.description} + ? {name: this.getSkillName(skill), description: skill.yamlFrontMatter.description} : void 0 return this.buildMarkdownContent(skill.content as string, simplifiedFrontMatter, ctx) diff --git a/cli/src/plugins/EditorConfigOutputPlugin.ts b/cli/src/plugins/EditorConfigOutputPlugin.ts index 63dbe215..88038b60 100644 --- a/cli/src/plugins/EditorConfigOutputPlugin.ts +++ b/cli/src/plugins/EditorConfigOutputPlugin.ts @@ -49,8 +49,9 @@ export class EditorConfigOutputPlugin extends AbstractOutputPlugin { override async convertContent( declaration: OutputFileDeclaration, - _ctx: OutputWriteContext + ctx: OutputWriteContext ): Promise { + void ctx const source = declaration.source as {content?: string} if (source.content == null) throw new Error(`Unsupported declaration source for ${this.name}`) return source.content diff --git a/cli/src/plugins/GenericSkillsOutputPlugin.test.ts b/cli/src/plugins/GenericSkillsOutputPlugin.test.ts index 2c7e2219..1100889f 100644 --- a/cli/src/plugins/GenericSkillsOutputPlugin.test.ts +++ b/cli/src/plugins/GenericSkillsOutputPlugin.test.ts @@ -21,6 +21,7 @@ function createSkillPrompt(scope: 'project' | 'global', name: string): SkillProm content: 'skill body', length: 10, filePathKind: FilePathKind.Relative, + skillName: name, dir: { pathKind: FilePathKind.Relative, path: `skills/${name}`, @@ -29,7 +30,6 @@ function createSkillPrompt(scope: 'project' | 'global', name: string): SkillProm getAbsolutePath: () => path.resolve('tmp/dist/skills', name) }, yamlFrontMatter: { - name, description: 'Skill description', scope }, diff --git a/cli/src/plugins/GenericSkillsOutputPlugin.ts b/cli/src/plugins/GenericSkillsOutputPlugin.ts index e61d1094..bc2c027e 100644 --- a/cli/src/plugins/GenericSkillsOutputPlugin.ts +++ b/cli/src/plugins/GenericSkillsOutputPlugin.ts @@ -77,7 +77,7 @@ export class GenericSkillsOutputPlugin extends AbstractOutputPlugin { filteredSkills: readonly SkillPrompt[] ): void => { for (const skill of filteredSkills) { - const skillName = skill.yamlFrontMatter.name + const skillName = this.getSkillName(skill) const skillDir = this.joinPath(baseSkillsDir, skillName) declarations.push({ @@ -124,7 +124,7 @@ export class GenericSkillsOutputPlugin extends AbstractOutputPlugin { if (skill.mcpConfig == null) continue declarations.push({ - path: this.joinPath(baseSkillsDir, skill.yamlFrontMatter.name, MCP_CONFIG_FILE), + path: this.joinPath(baseSkillsDir, this.getSkillName(skill), MCP_CONFIG_FILE), scope, source: { kind: 'skillMcp', diff --git a/cli/src/plugins/GitExcludeOutputPlugin.ts b/cli/src/plugins/GitExcludeOutputPlugin.ts index c3ce3f3a..8f20b92d 100644 --- a/cli/src/plugins/GitExcludeOutputPlugin.ts +++ b/cli/src/plugins/GitExcludeOutputPlugin.ts @@ -47,8 +47,9 @@ export class GitExcludeOutputPlugin extends AbstractOutputPlugin { override async convertContent( declaration: OutputFileDeclaration, - _ctx: OutputWriteContext + ctx: OutputWriteContext ): Promise { + void ctx const source = declaration.source as {content?: string} if (source.content == null) throw new Error(`Unsupported declaration source for ${this.name}`) return source.content diff --git a/cli/src/plugins/JetBrainsAIAssistantCodexOutputPlugin.ts b/cli/src/plugins/JetBrainsAIAssistantCodexOutputPlugin.ts index 19d1e4da..91c0b9c5 100644 --- a/cli/src/plugins/JetBrainsAIAssistantCodexOutputPlugin.ts +++ b/cli/src/plugins/JetBrainsAIAssistantCodexOutputPlugin.ts @@ -125,7 +125,7 @@ export class JetBrainsAIAssistantCodexOutputPlugin extends AbstractOutputPlugin filteredSkills: readonly SkillPrompt[] ): void => { for (const skill of filteredSkills) { - const skillName = skill.yamlFrontMatter?.name ?? skill.dir.getDirectoryName() + const skillName = this.getSkillName(skill) const skillDir = path.join(basePath, SKILLS_SUBDIR, skillName) declarations.push({ path: path.join(skillDir, SKILL_FILE_NAME), @@ -325,7 +325,7 @@ export class JetBrainsAIAssistantCodexOutputPlugin extends AbstractOutputPlugin private buildCodexSkillContent(skill: SkillPrompt, ctx: OutputWriteContext): string { const fm = skill.yamlFrontMatter - const name = this.normalizeSkillName(fm.name, 64) + const name = this.normalizeSkillName(this.getSkillName(skill), 64) const description = this.normalizeToSingleLine(fm.description, 1024) const metadata: Record = {} diff --git a/cli/src/plugins/JetBrainsIDECodeStyleConfigOutputPlugin.ts b/cli/src/plugins/JetBrainsIDECodeStyleConfigOutputPlugin.ts index ba01da57..aa49103c 100644 --- a/cli/src/plugins/JetBrainsIDECodeStyleConfigOutputPlugin.ts +++ b/cli/src/plugins/JetBrainsIDECodeStyleConfigOutputPlugin.ts @@ -46,8 +46,9 @@ export class JetBrainsIDECodeStyleConfigOutputPlugin extends AbstractOutputPlugi override async convertContent( declaration: OutputFileDeclaration, - _ctx: OutputWriteContext + ctx: OutputWriteContext ): Promise { + void ctx const source = declaration.source as {content?: string} if (source.content == null) throw new Error(`Unsupported declaration source for ${this.name}`) return source.content diff --git a/cli/src/plugins/OpencodeCLIOutputPlugin.test.ts b/cli/src/plugins/OpencodeCLIOutputPlugin.test.ts index 67028f38..d610d6c2 100644 --- a/cli/src/plugins/OpencodeCLIOutputPlugin.test.ts +++ b/cli/src/plugins/OpencodeCLIOutputPlugin.test.ts @@ -20,8 +20,8 @@ function createSubAgentPrompt(scope: 'project' | 'global'): SubAgentPrompt { }, agentPrefix: 'ops', agentName: 'reviewer', + canonicalName: 'ops-reviewer', yamlFrontMatter: { - name: 'reviewer', description: 'Reviewer', scope }, diff --git a/cli/src/plugins/OpencodeCLIOutputPlugin.ts b/cli/src/plugins/OpencodeCLIOutputPlugin.ts index 57038887..0d66f20e 100644 --- a/cli/src/plugins/OpencodeCLIOutputPlugin.ts +++ b/cli/src/plugins/OpencodeCLIOutputPlugin.ts @@ -176,7 +176,7 @@ export class OpencodeCLIOutputPlugin extends AbstractOutputPlugin { filteredSkills: readonly SkillPrompt[] ): void => { for (const skill of filteredSkills) { - const normalizedSkillName = this.validateAndNormalizeSkillName((skill.yamlFrontMatter?.name as string | undefined) ?? skill.dir.getDirectoryName()) + const normalizedSkillName = this.validateAndNormalizeSkillName(this.getSkillName(skill)) const skillDir = path.join(basePath, SKILLS_SUBDIR, normalizedSkillName) declarations.push({ diff --git a/cli/src/plugins/QoderIDEPluginOutputPlugin.test.ts b/cli/src/plugins/QoderIDEPluginOutputPlugin.test.ts index dfb5b4ec..9ab63746 100644 --- a/cli/src/plugins/QoderIDEPluginOutputPlugin.test.ts +++ b/cli/src/plugins/QoderIDEPluginOutputPlugin.test.ts @@ -118,6 +118,7 @@ function createSkillPrompt( content: 'skill body', length: 10, filePathKind: FilePathKind.Relative, + skillName: name, dir: { pathKind: FilePathKind.Relative, path: `skills/${name}`, @@ -126,7 +127,6 @@ function createSkillPrompt( getAbsolutePath: () => path.resolve('tmp/dist/skills', name) }, yamlFrontMatter: { - name, description: 'Skill description', scope }, diff --git a/cli/src/plugins/QoderIDEPluginOutputPlugin.ts b/cli/src/plugins/QoderIDEPluginOutputPlugin.ts index 74e1bc17..0ae4d6ad 100644 --- a/cli/src/plugins/QoderIDEPluginOutputPlugin.ts +++ b/cli/src/plugins/QoderIDEPluginOutputPlugin.ts @@ -137,7 +137,7 @@ export class QoderIDEPluginOutputPlugin extends AbstractOutputPlugin { filteredSkills: readonly SkillPrompt[] ): void => { for (const skill of filteredSkills) { - const skillName = skill.yamlFrontMatter.name + const skillName = this.getSkillName(skill) const skillDir = path.join(baseDir, SKILLS_SUBDIR, skillName) declarations.push({ path: path.join(skillDir, SKILL_FILE_NAME), @@ -182,7 +182,7 @@ export class QoderIDEPluginOutputPlugin extends AbstractOutputPlugin { for (const skill of filteredMcpSkills) { if (skill.mcpConfig == null) continue - const skillDir = path.join(baseDir, SKILLS_SUBDIR, skill.yamlFrontMatter.name) + const skillDir = path.join(baseDir, SKILLS_SUBDIR, this.getSkillName(skill)) declarations.push({ path: path.join(skillDir, MCP_CONFIG_FILE), scope, @@ -389,7 +389,7 @@ export class QoderIDEPluginOutputPlugin extends AbstractOutputPlugin { protected override buildSkillFrontMatter(skill: SkillPrompt): Record { const fm = skill.yamlFrontMatter return { - name: fm.name, + name: this.getSkillName(skill), description: fm.description, type: 'user_command', ...fm.displayName != null && {displayName: fm.displayName}, diff --git a/cli/src/plugins/ReadmeMdConfigFileOutputPlugin.ts b/cli/src/plugins/ReadmeMdConfigFileOutputPlugin.ts index 2c1dfa8a..0ae873d9 100644 --- a/cli/src/plugins/ReadmeMdConfigFileOutputPlugin.ts +++ b/cli/src/plugins/ReadmeMdConfigFileOutputPlugin.ts @@ -62,8 +62,9 @@ export class ReadmeMdConfigFileOutputPlugin extends AbstractOutputPlugin { override async convertContent( declaration: OutputFileDeclaration, - _ctx: OutputWriteContext + ctx: OutputWriteContext ): Promise { + void ctx const source = declaration.source as {content?: string} if (source.content == null) throw new Error(`Unsupported declaration source for ${this.name}`) return source.content diff --git a/cli/src/plugins/TraeCNIDEOutputPlugin.ts b/cli/src/plugins/TraeCNIDEOutputPlugin.ts index 353bf1ec..751242c7 100644 --- a/cli/src/plugins/TraeCNIDEOutputPlugin.ts +++ b/cli/src/plugins/TraeCNIDEOutputPlugin.ts @@ -50,8 +50,9 @@ export class TraeCNIDEOutputPlugin extends AbstractOutputPlugin { override async convertContent( declaration: OutputFileDeclaration, - _ctx: OutputWriteContext + ctx: OutputWriteContext ): Promise { + void ctx const source = declaration.source as {content?: string} if (source.content == null) throw new Error(`Unsupported declaration source for ${this.name}`) return source.content diff --git a/cli/src/plugins/TraeIDEOutputPlugin.test.ts b/cli/src/plugins/TraeIDEOutputPlugin.test.ts index fc26a17e..54835979 100644 --- a/cli/src/plugins/TraeIDEOutputPlugin.test.ts +++ b/cli/src/plugins/TraeIDEOutputPlugin.test.ts @@ -66,8 +66,9 @@ describe('traeIDEOutputPlugin steering rule output', () => { const declarations = await plugin.declareOutputFiles(ctx) const steering = declarations.find(d => d.source != null && (d.source as {kind?: string}).kind === 'steeringRule') expect(steering).toBeDefined() + if (steering == null) throw new Error('Expected steering declaration') - const {content} = steering!.source as {content: string} + const {content} = steering.source as {content: string} expect(content).toContain('globs: commands/**') expect(content).toContain('Scope guard: this rule is for the project-root path "commands/" only.') expect(content).toContain('Do not apply this rule to generated output paths such as "dist/commands/"') @@ -115,8 +116,9 @@ describe('traeIDEOutputPlugin steering rule output', () => { const declarations = await plugin.declareOutputFiles(ctx) const steering = declarations.find(d => d.source != null && (d.source as {kind?: string}).kind === 'steeringRule') expect(steering).toBeDefined() + if (steering == null) throw new Error('Expected steering declaration') - const {content} = steering!.source as {content: string} + const {content} = steering.source as {content: string} expect(content).toContain('---\nScope guard:') expect(content).not.toContain('---\n\nScope guard:') }) diff --git a/cli/src/plugins/TraeIDEOutputPlugin.ts b/cli/src/plugins/TraeIDEOutputPlugin.ts index b9a7826c..691cea41 100644 --- a/cli/src/plugins/TraeIDEOutputPlugin.ts +++ b/cli/src/plugins/TraeIDEOutputPlugin.ts @@ -167,7 +167,7 @@ export class TraeIDEOutputPlugin extends AbstractOutputPlugin { filteredSkills: readonly SkillPrompt[] ): void => { for (const skill of filteredSkills) { - const skillName = skill.yamlFrontMatter.name + const skillName = this.getSkillName(skill) const skillDir = path.join(baseDir, SKILLS_SUBDIR, skillName) declarations.push({ path: path.join(skillDir, SKILL_FILE_NAME), diff --git a/cli/src/plugins/VisualStudioCodeIDEConfigOutputPlugin.ts b/cli/src/plugins/VisualStudioCodeIDEConfigOutputPlugin.ts index 7d9a249b..d65290d9 100644 --- a/cli/src/plugins/VisualStudioCodeIDEConfigOutputPlugin.ts +++ b/cli/src/plugins/VisualStudioCodeIDEConfigOutputPlugin.ts @@ -45,8 +45,9 @@ export class VisualStudioCodeIDEConfigOutputPlugin extends AbstractOutputPlugin override async convertContent( declaration: OutputFileDeclaration, - _ctx: OutputWriteContext + ctx: OutputWriteContext ): Promise { + void ctx const source = declaration.source as {content?: string} if (source.content == null) throw new Error(`Unsupported declaration source for ${this.name}`) return source.content diff --git a/cli/src/plugins/WarpIDEOutputPlugin.ts b/cli/src/plugins/WarpIDEOutputPlugin.ts index 632fcbaa..6168955b 100644 --- a/cli/src/plugins/WarpIDEOutputPlugin.ts +++ b/cli/src/plugins/WarpIDEOutputPlugin.ts @@ -100,8 +100,9 @@ export class WarpIDEOutputPlugin extends AbstractOutputPlugin { override async convertContent( declaration: OutputFileDeclaration, - _ctx: OutputWriteContext + ctx: OutputWriteContext ): Promise { + void ctx const source = declaration.source as {content?: string} if (source.content == null) throw new Error(`Unsupported declaration source for ${this.name}`) return source.content diff --git a/cli/src/plugins/WindsurfOutputPlugin.test.ts b/cli/src/plugins/WindsurfOutputPlugin.test.ts index 8a1600a0..dbe7f76d 100644 --- a/cli/src/plugins/WindsurfOutputPlugin.test.ts +++ b/cli/src/plugins/WindsurfOutputPlugin.test.ts @@ -36,6 +36,7 @@ function createSkillPrompt(scope: 'project' | 'global', seriName: string): Skill content: 'skill content', length: 13, filePathKind: FilePathKind.Relative, + skillName: 'ship-it', dir: { pathKind: FilePathKind.Relative, path: 'skills/ship-it', @@ -46,7 +47,6 @@ function createSkillPrompt(scope: 'project' | 'global', seriName: string): Skill seriName, yamlFrontMatter: { namingCase: 'kebabCase', - name: 'ship-it', description: 'Ship release', scope }, diff --git a/cli/src/plugins/WindsurfOutputPlugin.ts b/cli/src/plugins/WindsurfOutputPlugin.ts index a31e8abc..d18a0795 100644 --- a/cli/src/plugins/WindsurfOutputPlugin.ts +++ b/cli/src/plugins/WindsurfOutputPlugin.ts @@ -102,7 +102,7 @@ export class WindsurfOutputPlugin extends AbstractOutputPlugin { scope: 'project' | 'global', skill: SkillPrompt ): void => { - const skillName = skill.yamlFrontMatter.name + const skillName = this.getSkillName(skill) const skillDir = path.join(basePath, SKILLS_SUBDIR, skillName) declarations.push({ path: path.join(skillDir, SKILL_FILE_NAME), diff --git a/cli/src/plugins/plugin-core.ts b/cli/src/plugins/plugin-core.ts index 43d066b4..dd2c5c74 100644 --- a/cli/src/plugins/plugin-core.ts +++ b/cli/src/plugins/plugin-core.ts @@ -106,6 +106,13 @@ export type { TransformedMcpConfig } from './plugin-core/McpConfigManager' +export { + deriveSubAgentIdentity, + flattenPromptPath, + resolveSkillName, + resolveSubAgentCanonicalName +} from './plugin-core/PromptIdentity' + export { RegistryWriter } from './plugin-core/RegistryWriter' diff --git a/cli/src/plugins/plugin-core/AbstractOutputPlugin.frontmatter.test.ts b/cli/src/plugins/plugin-core/AbstractOutputPlugin.frontmatter.test.ts index ecddc0f0..e0393c18 100644 --- a/cli/src/plugins/plugin-core/AbstractOutputPlugin.frontmatter.test.ts +++ b/cli/src/plugins/plugin-core/AbstractOutputPlugin.frontmatter.test.ts @@ -108,6 +108,7 @@ function createSubAgentPrompt(): SubAgentPrompt { }, agentPrefix: 'qa', agentName: 'boot', + canonicalName: 'qa-boot', yamlFrontMatter: { namingCase: 'kebabCase', description: 'subagent desc' @@ -122,6 +123,7 @@ function createSkillPrompt(): SkillPrompt { content: 'skill content', length: 13, filePathKind: FilePathKind.Relative, + skillName: 'ship-it', dir: { pathKind: FilePathKind.Relative, path: 'skills/ship-it', @@ -174,6 +176,13 @@ describe('abstract output plugin front matter formatting', () => { expect(plugin.renderSkill(createSkillPrompt(), ctx)).toMatch(/\n---\n\nskill content$/) }) + it('keeps the derived skill name in raw skill front matter output', () => { + const plugin = new TestFrontMatterOutputPlugin() + const ctx = createWriteContext() + + expect(plugin.renderSkill(createSkillPrompt(), ctx)).toContain('name: ship-it') + }) + it('removes the extra blank line when frontMatter.blankLineAfter is false', async () => { const plugin = new TestFrontMatterOutputPlugin() const ctx = createWriteContext(false) diff --git a/cli/src/plugins/plugin-core/AbstractOutputPlugin.subagents.test.ts b/cli/src/plugins/plugin-core/AbstractOutputPlugin.subagents.test.ts index 1487a29c..79fe1470 100644 --- a/cli/src/plugins/plugin-core/AbstractOutputPlugin.subagents.test.ts +++ b/cli/src/plugins/plugin-core/AbstractOutputPlugin.subagents.test.ts @@ -33,6 +33,7 @@ function createSubAgentPrompt(): SubAgentPrompt { }, agentPrefix: 'qa', agentName: 'boot', + canonicalName: 'qa-boot', yamlFrontMatter: { namingCase: 'kebabCase', description: 'subagent desc' diff --git a/cli/src/plugins/plugin-core/AbstractOutputPlugin.ts b/cli/src/plugins/plugin-core/AbstractOutputPlugin.ts index 91b02fe4..4080230d 100644 --- a/cli/src/plugins/plugin-core/AbstractOutputPlugin.ts +++ b/cli/src/plugins/plugin-core/AbstractOutputPlugin.ts @@ -1,4 +1,5 @@ import type {BuildPromptTomlArtifactOptions} from '@truenine/md-compiler' +import type {ToolPresetName} from './GlobalScopeCollector' import type {RegistryWriter} from './RegistryWriter' import type {CommandPrompt, CommandSeriesPluginOverride, ILogger, OutputCleanContext, OutputCleanupDeclarations, OutputCleanupPathDeclaration, OutputCleanupScope, OutputDeclarationScope, OutputFileDeclaration, OutputPlugin, OutputPluginCapabilities, OutputPluginContext, OutputScopeSelection, OutputScopeTopic, OutputTopicCapability, OutputWriteContext, Path, Project, ProjectConfig, RegistryData, RegistryOperationResult, RulePrompt, RuleScope, SkillPrompt, SubAgentPrompt} from './types' @@ -8,6 +9,7 @@ import * as path from 'node:path' import process from 'node:process' import {buildPromptTomlArtifact, mdxToMd} from '@truenine/md-compiler' import {buildMarkdownWithFrontMatter, buildMarkdownWithRawFrontMatter} from '@truenine/md-compiler/markdown' +import {buildConfigDiagnostic, diagnosticLines} from '@/diagnostics' import {AbstractPlugin} from './AbstractPlugin' import {FilePathKind, PluginKind} from './enums' import { @@ -15,6 +17,7 @@ import { filterByProjectConfig } from './filters' import {GlobalScopeCollector} from './GlobalScopeCollector' +import {resolveSkillName, resolveSubAgentCanonicalName} from './PromptIdentity' import {resolveTopicScopes} from './scopePolicy' import {OUTPUT_SCOPE_TOPICS} from './types' @@ -186,7 +189,7 @@ export interface AbstractOutputPluginOptions { /** Skills output configuration (declarative) */ skills?: SkillsOutputConfig - toolPreset?: string + toolPreset?: ToolPresetName /** Rule output configuration (declarative) */ rules?: RuleOutputConfig @@ -278,7 +281,7 @@ export abstract class AbstractOutputPlugin extends AbstractPlugin implements Out protected readonly skillOutputEnabled: boolean - protected readonly toolPreset: string | undefined + protected readonly toolPreset: ToolPresetName | undefined /** Rule output configuration */ protected readonly rulesConfig: RuleOutputConfig @@ -291,6 +294,8 @@ export abstract class AbstractOutputPlugin extends AbstractPlugin implements Out private readonly registryWriterCache: Map> = new Map() + private warnedDeprecatedSubAgentFileNameSource = false + protected constructor(name: string, options?: AbstractOutputPluginOptions) { super(name, PluginKind.Output, options?.dependsOn) this.globalConfigDir = options?.globalConfigDir ?? '' @@ -512,8 +517,9 @@ export abstract class AbstractOutputPlugin extends AbstractPlugin implements Out protected createRelativePath( pathStr: string, basePath: string, - _dirNameFn: () => string + dirNameFn: () => string ): string { + void dirNameFn return path.join(basePath, pathStr) } @@ -688,6 +694,14 @@ export abstract class AbstractOutputPlugin extends AbstractPlugin implements Out return `${effectiveGlobalContent}${separator}${projectContent}` // Default: 'before' } + protected getSkillName(skill: SkillPrompt): string { + return resolveSkillName(skill) + } + + protected getSubAgentCanonicalName(subAgent: SubAgentPrompt): string { + return resolveSubAgentCanonicalName(subAgent) + } + protected transformCommandName( cmd: CommandPrompt, options?: CommandNameTransformOptions @@ -709,12 +723,7 @@ export abstract class AbstractOutputPlugin extends AbstractPlugin implements Out const ext = options?.ext ?? this.subAgentsConfig.ext const normalizedExt = ext.startsWith('.') ? ext : `.${ext}` if (fileNameSource === 'frontMatterName') { - const configuredName = subAgent.yamlFrontMatter?.name - if (configuredName == null || configuredName.trim().length === 0) { - throw new Error(`Sub-agent "${subAgent.agentName}" is missing yamlFrontMatter.name required for fileNameSource="frontMatterName"`) - } - - return `${this.normalizeOutputFileStem(configuredName)}${normalizedExt}` + this.warnDeprecatedSubAgentFileNameSource() } const hasPrefix = includePrefix && subAgent.agentPrefix != null && subAgent.agentPrefix.length > 0 @@ -723,7 +732,7 @@ export abstract class AbstractOutputPlugin extends AbstractPlugin implements Out } protected normalizeOutputFileStem(value: string): string { - const sanitizedCharacters = [...value.trim()].map(character => { + const sanitizedCharacters = Array.from(value.trim(), character => { const codePoint = character.codePointAt(0) ?? 0 if (codePoint <= 31 || '<>:"/\\|?*'.includes(character)) return '-' return character @@ -737,6 +746,27 @@ export abstract class AbstractOutputPlugin extends AbstractPlugin implements Out return normalized } + private warnDeprecatedSubAgentFileNameSource(): void { + if (this.warnedDeprecatedSubAgentFileNameSource) return + this.warnedDeprecatedSubAgentFileNameSource = true + + this.log.warn(buildConfigDiagnostic({ + code: 'SUBAGENT_FRONTMATTER_NAME_SOURCE_DEPRECATED', + title: 'Sub-agent fileNameSource="frontMatterName" now resolves from derived names', + reason: diagnosticLines( + `The ${this.name} plugin no longer reads authored sub-agent front matter names.`, + 'tnmsc now derives sub-agent names from the sub-agent path.' + ), + exactFix: diagnosticLines( + 'Remove authored `name` fields from sub-agent sources.', + 'Keep using `fileNameSource="frontMatterName"` only as a temporary alias for the derived-path naming behavior.' + ), + details: { + plugin: this.name + } + })) + } + protected appendSubAgentDeclarations( declarations: OutputFileDeclaration[], basePath: string, @@ -752,11 +782,11 @@ export abstract class AbstractOutputPlugin extends AbstractPlugin implements Out if (existingAgentName != null) { throw new Error( - `Sub-agent output collision in ${this.name}: "${subAgent.yamlFrontMatter?.name ?? subAgent.agentName}" and "${existingAgentName}" both resolve to ${targetPath}` + `Sub-agent output collision in ${this.name}: "${this.getSubAgentCanonicalName(subAgent)}" and "${existingAgentName}" both resolve to ${targetPath}` ) } - seenPaths.set(targetPath, subAgent.yamlFrontMatter?.name ?? subAgent.agentName) + seenPaths.set(targetPath, this.getSubAgentCanonicalName(subAgent)) declarations.push({ path: targetPath, scope, @@ -789,7 +819,7 @@ export abstract class AbstractOutputPlugin extends AbstractPlugin implements Out scopedSkills: readonly SkillPrompt[] ): void { for (const skill of scopedSkills) { - const skillName = skill.yamlFrontMatter?.name ?? skill.dir.getDirectoryName() + const skillName = this.getSkillName(skill) const skillDir = path.join(basePath, this.skillsConfig.subDir, skillName) declarations.push({ @@ -1014,7 +1044,7 @@ export abstract class AbstractOutputPlugin extends AbstractPlugin implements Out ): Record { const fm = skill.yamlFrontMatter const result: Record = { - name: fm.name, + name: this.getSkillName(skill), description: fm.description } @@ -1289,8 +1319,7 @@ export abstract class AbstractOutputPlugin extends AbstractPlugin implements Out toolPreset: this.toolPreset, hasRawContent: true }) - // eslint-disable-next-line ts/no-unsafe-assignment - const scopeCollector = new GlobalScopeCollector({toolPreset: this.toolPreset as any}) + const scopeCollector = new GlobalScopeCollector({toolPreset: this.toolPreset}) const globalScope = scopeCollector.collect() const result = await mdxToMd(cmd.rawMdxContent, { globalScope, diff --git a/cli/src/plugins/plugin-core/ExportMetadataTypes.ts b/cli/src/plugins/plugin-core/ExportMetadataTypes.ts index 3b023a05..fb969539 100644 --- a/cli/src/plugins/plugin-core/ExportMetadataTypes.ts +++ b/cli/src/plugins/plugin-core/ExportMetadataTypes.ts @@ -18,7 +18,7 @@ export interface BaseExportMetadata { } export interface SkillExportMetadata extends BaseExportMetadata { - readonly name: string + readonly name?: string readonly description: string readonly keywords?: readonly string[] readonly enabled?: boolean @@ -47,7 +47,6 @@ export interface RuleExportMetadata extends BaseExportMetadata { } export interface SubAgentExportMetadata extends BaseExportMetadata { - readonly name: string readonly description: string readonly role?: string readonly model?: string @@ -156,10 +155,6 @@ export function validateSkillMetadata( const errors: string[] = [] const warnings: string[] = [] - if (!('name' in metadata) || metadata['name'] == null) { // Check name field - errors.push(`Missing required field "name"${prefix}`) - } - if (!('description' in metadata) || metadata['description'] == null) { // Check description field - must exist and not be empty errors.push(`Missing required field "description"${prefix}`) } else if (typeof metadata['description'] !== 'string' || metadata['description'].trim().length === 0) { @@ -218,7 +213,7 @@ export function validateSubAgentMetadata( filePath?: string ): MetadataValidationResult { const result = validateExportMetadata(metadata, { - requiredFields: ['name', 'description'], + requiredFields: ['description'], optionalDefaults: {}, filePath }) diff --git a/cli/src/plugins/plugin-core/InputTypes.ts b/cli/src/plugins/plugin-core/InputTypes.ts index 761772cd..25b9d90f 100644 --- a/cli/src/plugins/plugin-core/InputTypes.ts +++ b/cli/src/plugins/plugin-core/InputTypes.ts @@ -145,6 +145,7 @@ export interface SubAgentPrompt extends Prompt { readonly type: PromptKind.Skill readonly dir: RelativePath + readonly skillName: string readonly yamlFrontMatter: SkillYAMLFrontMatter readonly mcpConfig?: SkillMcpConfig readonly childDocs?: SkillChildDoc[] diff --git a/cli/src/plugins/plugin-core/McpConfigManager.ts b/cli/src/plugins/plugin-core/McpConfigManager.ts index 33228282..83943308 100644 --- a/cli/src/plugins/plugin-core/McpConfigManager.ts +++ b/cli/src/plugins/plugin-core/McpConfigManager.ts @@ -1,6 +1,7 @@ import type {ILogger, McpServerConfig, SkillPrompt} from './types' import * as path from 'node:path' import {buildFileOperationDiagnostic} from '@/diagnostics' +import {resolveSkillName} from './PromptIdentity' /** * MCP configuration format type @@ -49,7 +50,7 @@ export function collectMcpServersFromSkills( for (const [name, config] of Object.entries(skill.mcpConfig.mcpServers)) { merged.set(name, config) - logger?.debug('mcp server collected', {skill: skill.yamlFrontMatter.name, mcpName: name}) + logger?.debug('mcp server collected', {skill: resolveSkillName(skill), mcpName: name}) } } diff --git a/cli/src/plugins/plugin-core/PromptIdentity.ts b/cli/src/plugins/plugin-core/PromptIdentity.ts new file mode 100644 index 00000000..f7ccf0ee --- /dev/null +++ b/cli/src/plugins/plugin-core/PromptIdentity.ts @@ -0,0 +1,59 @@ +import type {SkillPrompt, SubAgentPrompt} from './types' + +function normalizePromptPath(value: string): string { + return value + .replaceAll('\\', '/') + .replaceAll(/^\/+|\/+$/gu, '') +} + +export function flattenPromptPath(value: string): string { + const normalized = normalizePromptPath(value) + if (normalized.length === 0) return '' + + return normalized + .split('/') + .filter(segment => segment.length > 0) + .join('-') +} + +export function deriveSubAgentIdentity(relativeName: string): { + readonly agentPrefix?: string + readonly agentName: string + readonly canonicalName: string +} { + const normalizedName = normalizePromptPath(relativeName) + const segments = normalizedName + .split('/') + .filter(segment => segment.length > 0) + + const agentName = segments.at(-1) ?? normalizedName + const prefixSegments = segments.slice(0, -1) + const canonicalName = flattenPromptPath(normalizedName) + const agentPrefix = prefixSegments.length > 0 + ? prefixSegments.join('-') + : void 0 + + return { + ...agentPrefix != null && {agentPrefix}, + agentName, + canonicalName: canonicalName.length > 0 ? canonicalName : agentName + } +} + +export function resolveSkillName(skill: Pick): string { + return skill.skillName.trim().length > 0 + ? skill.skillName + : skill.dir.getDirectoryName() +} + +export function resolveSubAgentCanonicalName( + subAgent: Pick +): string { + if (subAgent.canonicalName.trim().length > 0) return subAgent.canonicalName + + const fallback = subAgent.agentPrefix != null && subAgent.agentPrefix.length > 0 + ? `${subAgent.agentPrefix}-${subAgent.agentName}` + : subAgent.agentName + + return flattenPromptPath(fallback) +} diff --git a/cli/src/plugins/plugin-core/PromptTypes.ts b/cli/src/plugins/plugin-core/PromptTypes.ts index e18d333c..03de03ff 100644 --- a/cli/src/plugins/plugin-core/PromptTypes.ts +++ b/cli/src/plugins/plugin-core/PromptTypes.ts @@ -91,7 +91,6 @@ export interface ProjectChildrenMemoryPrompt extends Prompt = {} for (const [key, values] of Object.entries(topLevel ?? {})) merged[key] = [...values] for (const [key, values] of Object.entries(typeSpecific ?? {})) { - merged[key] = Object.hasOwn(merged, key) ? [...new Set([...merged[key]!, ...values])] : [...values] + const existingValues = merged[key] ?? [] + merged[key] = Object.hasOwn(merged, key) ? [...new Set([...existingValues, ...values])] : [...values] } return merged } diff --git a/cli/src/plugins/plugin-core/plugin.ts b/cli/src/plugins/plugin-core/plugin.ts index 0e92c8e0..4c287fbf 100644 --- a/cli/src/plugins/plugin-core/plugin.ts +++ b/cli/src/plugins/plugin-core/plugin.ts @@ -389,20 +389,33 @@ export function validateOutputScopeOverridesForPlugins( } } +export async function collectOutputDeclarations( + plugins: readonly OutputPlugin[], + ctx: OutputWriteContext +): Promise> { + validateOutputScopeOverridesForPlugins(plugins, ctx.pluginOptions) + + const declarationEntries = await Promise.all( + plugins.map(async plugin => [plugin, await plugin.declareOutputFiles(ctx)] as const) + ) + + return new Map(declarationEntries) +} + /** * Execute declarative write operations for output plugins. * Core runtime owns file system writes; plugins only declare and convert content. */ export async function executeDeclarativeWriteOutputs( plugins: readonly OutputPlugin[], - ctx: OutputWriteContext + ctx: OutputWriteContext, + predeclaredOutputs?: ReadonlyMap ): Promise> { const results = new Map() - - validateOutputScopeOverridesForPlugins(plugins, ctx.pluginOptions) + const outputDeclarations = predeclaredOutputs ?? await collectOutputDeclarations(plugins, ctx) for (const plugin of plugins) { - const declarations = await plugin.declareOutputFiles(ctx) + const declarations = outputDeclarations.get(plugin) ?? [] const fileResults: WriteResult[] = [] for (const declaration of declarations) { @@ -464,18 +477,20 @@ export interface CollectedOutputs { */ export async function collectAllPluginOutputs( plugins: readonly OutputPlugin[], - ctx: OutputPluginContext + ctx: OutputPluginContext, + predeclaredOutputs?: ReadonlyMap ): Promise { const projectDirs: string[] = [] const projectFiles: string[] = [] const globalDirs: string[] = [] const globalFiles: string[] = [] - validateOutputScopeOverridesForPlugins(plugins, ctx.pluginOptions) - - const declarationGroups = await Promise.all( - plugins.map(async plugin => plugin.declareOutputFiles({...ctx, dryRun: true})) - ) + const declarationGroups = predeclaredOutputs != null + ? [...predeclaredOutputs.values()] + : Array.from( + await collectOutputDeclarations(plugins, {...ctx, dryRun: true}), + ([, declarations]) => declarations + ) for (const declarations of declarationGroups) { for (const declaration of declarations) { diff --git a/cli/src/prompts.ts b/cli/src/prompts.ts index 5050d0ec..2e27eb69 100644 --- a/cli/src/prompts.ts +++ b/cli/src/prompts.ts @@ -388,13 +388,27 @@ function buildPromptDefinitionFromId( switch (descriptor.kind) { case 'global-memory': return buildGlobalMemoryDefinition(env) case 'workspace-memory': return buildWorkspaceMemoryDefinition(env) - case 'project-memory': return buildProjectMemoryDefinition(env, descriptor.projectName!) - case 'project-child-memory': return buildProjectMemoryDefinition(env, descriptor.projectName!, descriptor.relativeName) - case 'skill': return buildSkillDefinition(env, descriptor.skillName!) - case 'skill-child-doc': return buildSkillChildDocDefinition(env, descriptor.skillName!, descriptor.relativeName!) + case 'project-memory': + if (descriptor.projectName == null) throw new Error('project-memory promptId must include a project name') + return buildProjectMemoryDefinition(env, descriptor.projectName) + case 'project-child-memory': + if (descriptor.projectName == null || descriptor.relativeName == null) { + throw new Error('project-child-memory promptId must include project and child path') + } + return buildProjectMemoryDefinition(env, descriptor.projectName, descriptor.relativeName) + case 'skill': + if (descriptor.skillName == null) throw new Error('skill promptId must include a skill name') + return buildSkillDefinition(env, descriptor.skillName) + case 'skill-child-doc': + if (descriptor.skillName == null || descriptor.relativeName == null) { + throw new Error('skill-child-doc promptId must include skill and child path') + } + return buildSkillChildDocDefinition(env, descriptor.skillName, descriptor.relativeName) case 'command': case 'subagent': - case 'rule': return buildFlatPromptDefinition(env, descriptor.kind, descriptor.relativeName!) + case 'rule': + if (descriptor.relativeName == null) throw new Error(`${descriptor.kind} promptId must include a relative path`) + return buildFlatPromptDefinition(env, descriptor.kind, descriptor.relativeName) } } diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 00000000..7073b897 --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1,18 @@ +# Dependencies +node_modules/ + +# Next.js / Nextra build output +.next/ +out/ + +# Generated search index +public/_pagefind/ + +# Task runner cache +.turbo/ + +# TypeScript +*.tsbuildinfo + +# Logs +*.log diff --git a/doc/app/advanced.mdx b/doc/app/advanced.mdx deleted file mode 100644 index 5fbd1b7a..00000000 --- a/doc/app/advanced.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: 进阶用法 -description: 介绍 workspace 分组、Shadow Project、高级同步策略以及多 AI 客户端协作。 -lastUpdated: 2026-02-18 ---- - -
-

工作区与项目分层

-

- memory-sync 推荐使用「全局规则仓库 + 各项目本地规则」的结构,通过 workspace 配置和 aindex - 组合,实现既统一又可扩展的管理方式。 -

- -

与多 AI 客户端协作

-

- 你可以用同一套 Global Memory / Skills 同时服务于 Cursor、Claude CLI、Gemini CLI、Warp、Kiro - 等工具,本章后续会给出地图式的联动说明。 -

- -

变更摘要(Changelog)

-

- 建议你在每次发布重要版本时,在这里记录一条简短的变更摘要,方便未来回溯。 -

-
- diff --git a/doc/app/cli.mdx b/doc/app/cli.mdx deleted file mode 100644 index cd7d7430..00000000 --- a/doc/app/cli.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: CLI 使用指南 -description: 介绍 memory-sync CLI(tnmsc)的核心概念、插件管线和典型命令。 -lastUpdated: 2026-02-18 ---- - -
-

概览

-

- memory-sync 的 CLI 命令通常通过 tnmsc 调用,核心是「Input → Transform → Output」插件管线。 -

- -

核心能力

-
    -
  • 从本地规则仓库读取 Global Memory / Skills / Fast Commands / Sub-agents / Rules
  • -
  • 根据配置选择不同输出目标(Cursor、Claude CLI、Gemini CLI、Warp、Kiro 等)
  • -
  • 保持一份配置,多端适配,减少手工复制粘贴
  • -
- -

典型命令结构

-

本章暂时只描述概念,后续会根据实际 CLI 命令补充具体示例:

- - ```bash - tnmsc run --config path/to/tnmsc.json --target cursor - ``` - -

- 关于配置文件字段和 shadow 项目的详细说明,请查看 - 配置文件说明。 -

-
- diff --git a/doc/app/components/Callout.tsx b/doc/app/components/Callout.tsx deleted file mode 100644 index 52fa4a8a..00000000 --- a/doc/app/components/Callout.tsx +++ /dev/null @@ -1,46 +0,0 @@ -'use client' - -import type {ReactNode} from 'react' - -type CalloutType = 'info' | 'warning' | 'tip' - -const typeStyles: Record = { - info: { - label: '提示', - className: 'border-sky-500/60 bg-sky-950/40 text-sky-100' - }, - warning: { - label: '注意', - className: 'border-amber-500/70 bg-amber-950/40 text-amber-100' - }, - tip: { - label: '小技巧', - className: 'border-emerald-500/70 bg-emerald-950/40 text-emerald-100' - } -} - -interface CalloutProps { - readonly type?: CalloutType - readonly title?: string - readonly children: ReactNode -} - -export function Callout({type = 'info', title, children}: CalloutProps) { - const style = typeStyles[type] - - return ( -
-
- - {title ?? style.label} -
-
{children}
-
- ) -} diff --git a/doc/app/components/Steps.tsx b/doc/app/components/Steps.tsx deleted file mode 100644 index 334ec4a1..00000000 --- a/doc/app/components/Steps.tsx +++ /dev/null @@ -1,30 +0,0 @@ -'use client' - -import type {ReactNode} from 'react' - -interface StepsProps { - readonly children: ReactNode -} - -export function Steps({children}: StepsProps) { - return ( -
    - {children} -
- ) -} - -interface StepProps { - readonly title: string - readonly children?: ReactNode -} - -export function Step({title, children}: StepProps) { - return ( -
  • - -
    {title}
    - {children != null ?
    {children}
    : null} -
  • - ) -} diff --git a/doc/app/config.mdx b/doc/app/config.mdx deleted file mode 100644 index 03cc91c8..00000000 --- a/doc/app/config.mdx +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: 配置文件说明(tnmsc.example.json) -description: 逐项解释 tnmsc.example.json 的字段含义,并给出推荐模板。 -lastUpdated: 2026-02-18 ---- - -
    -

    配置文件位置与示例来源

    -

    - 本页基于初始化模板 tnmsc.example.json 展开说明,该文件通常由 - tnmsc init 生成,并作为你个人配置的起点。 -

    - -

    基础字段

    - -

    version

    -

    - 使用 CalVer 风格的版本号,例如: - 2026.10218.12101。建议与项目发布版本保持一致,方便排查问题。 -

    - -

    workspaceDir

    -

    - 工作区根目录,支持 ~ 展开,例如: -

    - - ```json - { - "workspaceDir": "~/project" - } - ``` - -

    aindex 配置

    -

    - aindex 描述了一套 Aindex 目录结构,用于统一管理 Skills、Commands、Agents、Rules 以及 Global Memory 等文件。 -

    - - ```json - { - "aindex": { - "name": "aindex", - "skill": { "src": "src/skills", "dist": "dist/skills" }, - "command": { "src": "src/commands", "dist": "dist/commands" }, - "subAgent": { "src": "src/agents", "dist": "dist/agents" }, - "rule": { "src": "src/rules", "dist": "dist/rules" }, - "globalMemory": { - "src": "app/global.src.mdx", - "dist": "dist/global.mdx" - }, - "workspaceMemory": { - "src": "app/workspace.src.mdx", - "dist": "dist/app/workspace.mdx" - }, - "project": { "src": "app", "dist": "dist/app" } - } - } - ``` - -

    推荐保持上述结构不变,仅在确有需要时调整路径。

    - -

    profile 字段

    - - ```json - { - "profile": { - "name": "Your Name", - "username": "your_username", - "gender": "male", - "birthday": "1990-01-01" - } - } - ``` - -

    - 这些信息通常用于在 Global Memory 或 Skills 中做变量替换,避免多处手写姓名/昵称等个人信息。 -

    - -

    - 后续页面会进一步介绍不同类型 Prompt 文件的写法,详见 - Prompt 规则与结构。 -

    -
    - diff --git a/doc/app/docs/[[...mdxPath]]/page.tsx b/doc/app/docs/[[...mdxPath]]/page.tsx new file mode 100644 index 00000000..782b76d2 --- /dev/null +++ b/doc/app/docs/[[...mdxPath]]/page.tsx @@ -0,0 +1,50 @@ +import type {ComponentType, ReactNode} from 'react' +import {generateStaticParamsFor, importPage} from 'nextra/pages' +import {useMDXComponents as getMDXComponents} from '../../../mdx-components' + +export const generateStaticParams = generateStaticParamsFor('mdxPath') + +export async function generateMetadata(props: { + readonly params: Promise<{readonly mdxPath?: string[]}> +}) { + const params = await props.params + const {metadata} = await importPage(params.mdxPath) + return metadata +} + +interface WrapperProps { + readonly children: ReactNode + readonly metadata: unknown + readonly sourceCode: string + readonly toc: unknown +} + +const components = getMDXComponents() as { + readonly wrapper?: ComponentType +} + +const Wrapper = components.wrapper + +export default async function DocsPage(props: { + readonly params: Promise<{readonly mdxPath?: string[]}> +}) { + const params = await props.params + const { + default: MDXContent, + toc, + metadata, + sourceCode + } = await importPage(params.mdxPath) + + const page = + + if (!Wrapper) { + return page + } + + return ( + + {page} + + ) +} diff --git a/doc/app/docs/layout.tsx b/doc/app/docs/layout.tsx new file mode 100644 index 00000000..c5a98b41 --- /dev/null +++ b/doc/app/docs/layout.tsx @@ -0,0 +1,78 @@ +import type {ReactNode} from 'react' +import Link from 'next/link' +import {Footer, Layout, Navbar} from 'nextra-theme-docs' +import {getPageMap} from 'nextra/page-map' +import {siteConfig} from '../../lib/site' + +export default async function DocsLayout({children}: {readonly children: ReactNode}) { + const pageMap = await getPageMap('/docs') + const sectionLinks = [ + {href: '/docs/cli', label: 'CLI'}, + {href: '/docs/mcp', label: 'MCP'}, + {href: '/docs/gui', label: 'GUI'}, + {href: '/docs/technical-details', label: '技术细节'}, + {href: '/docs/design-rationale', label: '设计初衷'} + ] as const + + return ( + + memory-sync + + )} + align="left" + > + + + )} + footer={( +
    + AGPL-3.0-only · 面向当前仓库实现、命令表面与配置边界 +
    + )} + docsRepositoryBase={`${siteConfig.docsRepositoryBase}/content`} + editLink="在 GitHub 上编辑此页" + feedback={{ + content: '有遗漏或过时信息?提交 issue', + link: siteConfig.issueUrl, + labels: 'documentation' + }} + sidebar={{ + autoCollapse: false, + defaultMenuCollapseLevel: 99, + defaultOpen: true, + toggleButton: false + }} + toc={{ + float: true, + title: '本页目录', + backToTop: '回到顶部' + }} + themeSwitch={{ + dark: '暗色', + light: '亮色', + system: '系统' + }} + nextThemes={{ + attribute: 'class', + defaultTheme: 'dark', + disableTransitionOnChange: true, + storageKey: 'memory-sync-docs-theme' + }} + > + {children} +
    + ) +} diff --git a/doc/app/getting-started.mdx b/doc/app/getting-started.mdx deleted file mode 100644 index 83636dcf..00000000 --- a/doc/app/getting-started.mdx +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: 快速上手(Getting Started) -description: 介绍如何安装 memory-sync、初始化配置,并在本地完成第一次规则同步。 -lastUpdated: 2026-02-18 ---- - -import { Callout } from './components/Callout'; -import { Steps, Step } from './components/Steps'; - -
    -

    安装与环境要求

    -

    - memory-sync 是一个基于 Node.js 的 CLI + Tauri GUI 工具集,推荐使用 - pnpm 搭配 monorepo 一起管理。 -

    - -

    Node 与包管理器

    -
      -
    • 推荐 Node 版本:>= 20.9.0
    • -
    • 推荐包管理器:pnpm(与项目 pnpm-workspace.yaml 配套)
    • -
    - -

    安装 CLI

    -

    以下命令展示了典型的全局安装与 npx 使用方式,你可以根据自己的偏好调整:

    - - ```bash - # 使用 pnpm 全局安装 - pnpm add -g @truenine/memory-sync - - # 或者通过 npx 临时执行 - npx @truenine/memory-sync@latest --help - ``` - -

    初始化规则仓库

    - - - 建议把「记忆 / 规则仓库」和日常代码仓库分开管理,这样可以在多个项目之间共享同一套 Global - Memory 与 Skills。 - - - - - 例如 ~/aindex 或你习惯的任意路径。 - - - 执行 tnmsc init(或未来提供的类似命令),生成示例配置与 Prompt 文件。 - - - 编辑 tnmsc.example.jsonapp/global.src.mdx,根据自己的工作流调整内容。 - - - -

    - 更具体的配置字段说明见 配置文件说明,规则写法见 - Prompt 规则与结构。 -

    -
    - diff --git a/doc/app/globals.css b/doc/app/globals.css index c3c432ad..f30c6ff6 100644 --- a/doc/app/globals.css +++ b/doc/app/globals.css @@ -1,3 +1,62 @@ +:root { + --nextra-content-width: 1380px; + --page-bg: #ffffff; + --page-fg: #111111; + --page-fg-soft: #5f6670; + --page-fg-muted: #7b818b; + --surface: rgba(255, 255, 255, 0.9); + --surface-strong: #ffffff; + --surface-muted: #f6f7f8; + --surface-subtle: #f3f4f6; + --surface-elevated: #f8f9fb; + --surface-overlay: rgba(255, 255, 255, 0.94); + --surface-border: rgba(17, 17, 17, 0.08); + --surface-border-strong: rgba(17, 17, 17, 0.14); + --surface-separator: rgba(17, 17, 17, 0.06); + --surface-highlight: rgba(17, 17, 17, 0.035); + --surface-highlight-strong: rgba(17, 17, 17, 0.055); + --inline-code-bg: rgba(17, 17, 17, 0.035); + --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.05); + --shadow-md: 0 12px 40px rgba(15, 23, 42, 0.06); + --hero-glow: radial-gradient(circle at top, rgba(0, 0, 0, 0.06), transparent 58%); + --page-gradient: + radial-gradient(circle at top, rgba(0, 0, 0, 0.04), transparent 30%), + linear-gradient(180deg, #ffffff 0%, #fbfbfc 100%); + --button-primary-bg: #111111; + --button-primary-fg: #ffffff; + --button-secondary-bg: rgba(255, 255, 255, 0.82); + --button-secondary-fg: #111111; +} + +html.dark { + --page-bg: #0b0c10; + --page-fg: #fafafa; + --page-fg-soft: #b8bec7; + --page-fg-muted: #8b919a; + --surface: rgba(18, 20, 24, 0.82); + --surface-strong: #101116; + --surface-muted: #14161b; + --surface-subtle: #171a20; + --surface-elevated: #1a1d24; + --surface-overlay: rgba(20, 22, 28, 0.92); + --surface-border: rgba(255, 255, 255, 0.04); + --surface-border-strong: rgba(255, 255, 255, 0.07); + --surface-separator: rgba(255, 255, 255, 0.055); + --surface-highlight: rgba(255, 255, 255, 0.025); + --surface-highlight-strong: rgba(255, 255, 255, 0.045); + --inline-code-bg: rgba(255, 255, 255, 0.032); + --shadow-sm: 0 10px 28px rgba(0, 0, 0, 0.16); + --shadow-md: 0 26px 76px rgba(0, 0, 0, 0.24); + --hero-glow: radial-gradient(circle at top, rgba(255, 255, 255, 0.045), transparent 58%); + --page-gradient: + radial-gradient(circle at top, rgba(255, 255, 255, 0.024), transparent 34%), + linear-gradient(180deg, #0a0b0f 0%, #0d1015 100%); + --button-primary-bg: #fafafa; + --button-primary-fg: #111111; + --button-secondary-bg: rgba(255, 255, 255, 0.028); + --button-secondary-fg: #fafafa; +} + *, *::before, *::after { @@ -6,333 +65,1021 @@ html, body { + min-height: 100%; margin: 0; - padding: 0; + background: var(--page-bg); + color: var(--page-fg); + font-family: + var(--font-sans), + 'PingFang SC', + 'Hiragino Sans GB', + 'Microsoft YaHei', + 'Noto Sans SC', + sans-serif; +} + +html { + font-size: 14px; + scroll-behavior: smooth; } body { - font-family: system-ui, -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', sans-serif; - background-color: #020617; - color: #e5e7eb; + min-height: 100vh; + background-image: var(--page-gradient); + background-attachment: fixed; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; +} + +a { + color: inherit; + text-decoration: none; +} + +code, +pre, +kbd, +samp { + font-family: + var(--font-mono), + 'SFMono-Regular', + Consolas, + 'Liberation Mono', + Menlo, + monospace; } -.docs-shell { - max-width: 960px; +.docs-home, +.not-found-shell { + width: min(1080px, calc(100% - 32px)); margin: 0 auto; - min-height: 100vh; - padding: 24px 20px 32px; - display: flex; - flex-direction: column; - gap: 16px; } -.docs-header { +.docs-home { + padding: 20px 0 88px; +} + +.home-topbar { display: flex; - justify-content: space-between; align-items: center; - padding-bottom: 10px; - border-bottom: 1px solid #1f2937; + justify-content: space-between; + gap: 20px; + padding: 6px 0 18px; } -.docs-header-title { - display: flex; - flex-direction: column; - gap: 4px; +.home-brand, +.docs-brand { + display: inline-flex; + align-items: baseline; + gap: 10px; } -.docs-header-label { - font-size: 11px; - text-transform: uppercase; - letter-spacing: 0.08em; +.home-brand strong, +.docs-brand-title { + font-size: 0.95rem; font-weight: 600; - color: #9ca3af; + letter-spacing: -0.02em; } -.docs-header-main { - display: flex; - align-items: baseline; +.home-brand span { + color: var(--page-fg-muted); + font-size: 0.78rem; + letter-spacing: 0.02em; +} + +.home-topbar-nav { + display: inline-flex; + align-items: center; + gap: 8px; +} + +.home-topbar-nav a, +.docs-nav-link { + display: inline-flex; + align-items: center; + min-height: 34px; + padding: 0 11px; + border: 1px solid transparent; + border-radius: 999px; + color: var(--page-fg-muted); + font-size: 0.86rem; + transition: + border-color 0.2s ease, + background-color 0.2s ease, + color 0.2s ease, + transform 0.2s ease; +} + +.docs-navbar-links { + display: inline-flex; + align-items: center; + flex-wrap: wrap; gap: 8px; } -.docs-header-name { - font-size: 15px; +.home-topbar-nav a:hover, +.docs-nav-link:hover { + border-color: var(--surface-border); + background: var(--surface); + color: var(--page-fg); + transform: translateY(-1px); +} + +.home-hero { + padding: 18px 0 8px; +} + +.home-hero-copy, +.home-link-card, +.capability-card, +.reading-path-card, +.not-found-shell { + position: relative; + overflow: hidden; + border: 1px solid var(--surface-border); + border-radius: 24px; + background: var(--surface); + box-shadow: var(--shadow-sm); +} + +.home-hero-copy { + padding: 34px 34px 30px; + background-image: + linear-gradient(180deg, color-mix(in srgb, var(--surface-strong) 92%, transparent), var(--surface)), + var(--hero-glow); + box-shadow: var(--shadow-md); +} + +.home-hero-copy::before, +.home-link-card::before, +.capability-card::before, +.reading-path-card::before { + content: ''; + position: absolute; + inset: 0 auto auto 0; + width: 100%; + height: 1px; + background: linear-gradient(90deg, transparent, var(--surface-border-strong), transparent); +} + +.section-kicker { + margin: 0 0 10px; + color: var(--page-fg-muted); + font-size: 0.72rem; font-weight: 600; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.home-hero h1, +.section-heading h2, +.not-found-shell h1 { margin: 0; - color: #f9fafb; + letter-spacing: -0.045em; +} + +.home-hero h1 { + max-width: 13ch; + font-size: clamp(1.95rem, 3.2vw, 2.9rem); + line-height: 0.98; } -.docs-header-desc { - font-size: 11px; - color: #9ca3af; +.home-hero-lead { + max-width: 52rem; + margin: 16px 0 0; + color: var(--page-fg-soft); + font-size: 0.97rem; + line-height: 1.72; } -.docs-header-nav { +.home-actions, +.not-found-actions { display: flex; - gap: 6px; - font-size: 11px; - font-weight: 500; - color: #9ca3af; + flex-wrap: wrap; + gap: 12px; + margin-top: 22px; } -.docs-header-link { - padding: 4px 8px; +.hero-button { + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 40px; + padding: 0 15px; + border: 1px solid var(--surface-border-strong); border-radius: 999px; - transition: background-color 0.12s ease, color 0.12s ease; + font-size: 0.88rem; + font-weight: 500; + transition: + border-color 0.2s ease, + background-color 0.2s ease, + color 0.2s ease, + transform 0.2s ease, + box-shadow 0.2s ease; } -.docs-header-link:hover { - background-color: #111827; - color: #f9fafb; - text-decoration: none; +.hero-button:hover { + transform: translateY(-1px); } -.docs-header-link-muted { - color: #6b7280; +.hero-button-primary { + border-color: var(--button-primary-bg); + background: var(--button-primary-bg); + color: var(--button-primary-fg); } -.docs-layout { +.hero-button-primary:hover { + box-shadow: 0 10px 20px rgba(0, 0, 0, 0.08); + opacity: 0.96; +} + +.hero-button-secondary { + background: var(--button-secondary-bg); + color: var(--button-secondary-fg); +} + +.hero-button-secondary:hover { + background: var(--surface-subtle); +} + +.home-proof-strip, +.home-link-grid, +.capability-grid, +.reading-path-grid { display: grid; - grid-template-columns: 180px minmax(0, 1fr); - gap: 20px; - padding-bottom: 16px; - margin-top: 8px; + gap: 14px; +} + +.home-proof-strip { + grid-template-columns: repeat(3, minmax(0, 1fr)); + margin: 24px 0 0; + padding: 0; + list-style: none; } -.docs-sidebar { - font-size: 13px; - color: #9ca3af; +.proof-pill { + padding: 14px 16px; + border: 1px solid var(--surface-border); + border-radius: 18px; + background: color-mix(in srgb, var(--surface-strong) 74%, transparent); } -.docs-sidebar-label { - font-size: 11px; +.proof-pill span, +.home-link-card span, +.capability-card span, +.reading-path-card small { + color: var(--page-fg-muted); + font-size: 0.74rem; + font-weight: 600; + letter-spacing: 0.07em; text-transform: uppercase; - letter-spacing: 0.08em; +} + +.proof-pill strong, +.home-link-card strong, +.capability-card h3, +.reading-path-card strong { + display: block; + margin: 8px 0 0; + font-size: 0.98rem; font-weight: 600; - color: #6b7280; - margin-bottom: 6px; + letter-spacing: -0.02em; } -.docs-sidebar-list { - list-style: none; - padding: 0; +.home-section { + padding-top: 34px; +} + +.section-heading { + display: flex; + flex-direction: column; + gap: 8px; + margin-bottom: 18px; +} + +.section-heading h2 { + max-width: 22ch; + font-size: clamp(1.45rem, 2.2vw, 1.9rem); + line-height: 1.06; +} + +.section-summary { + max-width: 44rem; margin: 0; + color: var(--page-fg-soft); + font-size: 0.93rem; + line-height: 1.66; } -.docs-sidebar-list li + li { - margin-top: 2px; +.home-link-grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); } -.docs-sidebar-link { - display: flex; - align-items: center; - padding: 4px 8px; - border-radius: 6px; - color: #e5e7eb; - transition: background-color 0.12s ease, color 0.12s ease; +.capability-grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); } -.docs-sidebar-link:hover { - background-color: #111827; - color: #f9fafb; - text-decoration: none; +.reading-path-grid { + grid-template-columns: repeat(4, minmax(0, 1fr)); +} + +.home-link-card, +.capability-card, +.reading-path-card { + padding: 20px; + transition: + transform 0.24s ease, + border-color 0.24s ease, + background-color 0.24s ease, + box-shadow 0.24s ease; +} + +.home-link-card:hover, +.capability-card:hover, +.reading-path-card:hover { + border-color: var(--surface-border-strong); + background: color-mix(in srgb, var(--surface-strong) 94%, var(--surface-subtle)); + box-shadow: var(--shadow-md); + transform: translateY(-2px); +} + +.home-link-card p, +.capability-card p, +.reading-path-card p, +.not-found-shell p { + margin: 10px 0 0; + color: var(--page-fg-soft); + font-size: 0.92rem; + line-height: 1.68; +} + +.home-link-card span { + display: inline-flex; + margin-top: 16px; +} + +.capability-card span { + display: inline-flex; +} + +.reading-path-card small { + display: inline-flex; +} + +.not-found-shell { + margin-top: 8vh; + padding: 30px; +} + +.not-found-code { + margin: 0 0 12px; + color: var(--page-fg-muted); + font-size: 0.76rem; + font-weight: 600; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.nextra-content, +.nextra-sidebar, +.nextra-toc, +.nextra-footer, +.nextra-navbar { + font-family: + var(--font-sans), + 'PingFang SC', + 'Hiragino Sans GB', + 'Microsoft YaHei', + 'Noto Sans SC', + sans-serif; +} + +.nextra-nav-container-blur, +.nextra-sidebar-footer, +.nextra-toc, +.nextra-navbar-blur { + backdrop-filter: blur(18px); +} + +.nextra-nav-container-blur, +.nextra-navbar-blur { + background: color-mix(in srgb, var(--page-bg) 84%, transparent); + border-color: var(--surface-border); +} + +.nextra-navbar nav > div:first-of-type { + display: none; +} + +.nextra-sidebar, +.nextra-toc, +.nextra-footer { + border-color: var(--surface-border); +} + +.nextra-sidebar, +.nextra-toc { + background: color-mix(in srgb, var(--surface-strong) 90%, transparent); +} + +.nextra-toc { + display: block; +} + +.nextra-sidebar { + border-right: 1px solid var(--surface-border); +} + +.nextra-sidebar::-webkit-scrollbar { + width: 8px; +} + +.nextra-sidebar::-webkit-scrollbar-thumb { + border-radius: 999px; + background: color-mix(in srgb, var(--page-fg-muted) 45%, transparent); +} + +.nextra-sidebar :is(ul, ol) { + gap: 2px; +} + +.nextra-sidebar > div > ul { + gap: 10px; +} + +.nextra-sidebar > div > ul > li:has(> div) > :is(a, button) { + min-height: auto; + margin-top: 14px; + padding: 0 0 8px; + border: none; + border-radius: 0; + background: transparent; + color: var(--page-fg-muted); + font-size: 0.74rem; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; + pointer-events: none; } -.docs-main { - min-width: 0; +.nextra-sidebar > div > ul > li:first-child:has(> div) > :is(a, button) { + margin-top: 0; } -.docs-main-card { +.nextra-sidebar > div > ul > li:has(> div) > :is(a, button):hover { + border: none; + background: transparent; + color: var(--page-fg-muted); + transform: none; +} + +.nextra-sidebar > div > ul > li:has(> div) > :is(a, button) svg { + display: none; +} + +.nextra-sidebar > div > ul > li:has(> div) > div { + height: auto !important; + overflow: visible !important; + opacity: 1 !important; + transition: none !important; +} + +.nextra-sidebar > div > ul > li:has(> div) > div > ul { + gap: 2px; + padding-left: 0; +} + +.nextra-sidebar a, +.nextra-toc a { + min-height: 34px; + border: 1px solid transparent; border-radius: 10px; - border: 1px solid #1f2937; - background-color: #020617; - padding: 18px 20px 22px; - box-shadow: 0 18px 40px rgba(15, 23, 42, 0.9); + color: var(--page-fg-soft); + font-size: 0.88rem; + transition: + border-color 0.18s ease, + background-color 0.18s ease, + color 0.18s ease, + transform 0.18s ease; } -.docs-footer { - margin-top: auto; - padding-top: 10px; - border-top: 1px solid #1f2937; - font-size: 11px; - color: #6b7280; +.nextra-sidebar a:hover, +.nextra-toc a:hover { + border-color: var(--surface-border); + background: color-mix(in srgb, var(--surface-subtle) 84%, transparent); + color: var(--page-fg); + transform: translateX(1px); } -a { - color: inherit; - text-decoration: none; +.nextra-sidebar :is(a[aria-current='page'], li.active > a) { + border-color: color-mix(in srgb, var(--surface-border-strong) 88%, transparent); + background: color-mix(in srgb, var(--surface-subtle) 88%, transparent); + color: var(--page-fg); +} + +.nextra-sidebar a[href^='#'], +.nextra-sidebar li.active > ul:has(a[href^='#']) { + display: none; +} + +.nextra-sidebar summary, +.nextra-sidebar [data-has-children='true'] { + font-size: 0.88rem; } -a:hover { - text-decoration: underline; +.nextra-sidebar :is(h2, h3, h4, [data-headings]) { + letter-spacing: -0.01em; } -code { - font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', - 'Courier New', monospace; +.nextra-body-typesetting-article { + max-width: 920px; } -.prose { - max-width: 720px; - line-height: 1.7; - color: rgb(226 232 240); +.nextra-body-typesetting-article { + color: var(--page-fg); font-size: 0.95rem; + line-height: 1.78; } -.prose h1, -.prose h2, -.prose h3 { - color: rgb(248 250 252); - letter-spacing: -0.03em; +.nextra-body-typesetting-article :where(h1, h2, h3, h4) { + letter-spacing: -0.035em; + line-height: 1.1; } -.prose h1 { - font-size: 1.8rem; - margin-bottom: 0.75rem; - font-weight: 600; +.nextra-body-typesetting-article h1 { + font-size: clamp(1.9rem, 3vw, 2.35rem); + margin-bottom: 0.95rem; } -.prose h2 { - font-size: 1.5rem; - margin-top: 1.75rem; - margin-bottom: 0.5rem; - font-weight: 600; +.nextra-body-typesetting-article h2 { + font-size: clamp(1.34rem, 2.1vw, 1.66rem); + margin-top: 2.15rem; } -.prose h3 { - font-size: 1.25rem; - margin-top: 1.25rem; - margin-bottom: 0.5rem; - font-weight: 500; +.nextra-body-typesetting-article h3 { + font-size: 1.08rem; + margin-top: 1.6rem; } -.prose p { - margin: 0.5rem 0; +.nextra-body-typesetting-article h4 { + font-size: 0.98rem; + margin-top: 1.3rem; } -.prose ul { - padding-left: 1.25rem; +.nextra-body-typesetting-article :where(p, li, blockquote) { + color: var(--page-fg-soft); } -.prose li { - margin: 0.25rem 0; +.nextra-body-typesetting-article a:not(.nextra-card) { + color: var(--page-fg); + text-decoration-line: underline; + text-decoration-color: var(--surface-border-strong); + text-decoration-thickness: 0.06em; + text-underline-offset: 0.22em; } -.badge { - display: inline-flex; - align-items: center; - border-radius: 999px; - border: 1px solid rgba(56, 189, 248, 0.4); - background-color: rgba(15, 23, 42, 0.9); - padding: 0.125rem 0.55rem; - font-size: 0.7rem; - color: rgb(125 211 252); - gap: 0.35rem; +.nextra-body-typesetting-article a:not(.nextra-card):hover { + text-decoration-color: currentColor; } -.badge-dot { - width: 0.5rem; - height: 0.5rem; - border-radius: 999px; - background-color: rgb(37 99 235); +.nextra-body-typesetting-article :not(pre) > code { + padding: 0.16rem 0.38rem; + border: 1px solid var(--surface-border); + border-radius: 0.45rem; + background: var(--surface-subtle); + color: var(--page-fg); + font-size: 0.88em; +} + +.nextra-body-typesetting-article pre { + border: 1px solid var(--surface-border); + border-radius: 18px; + background: color-mix(in srgb, var(--surface-muted) 90%, transparent) !important; + box-shadow: none; + font-size: 0.87rem; + line-height: 1.64; +} + +.nextra-body-typesetting-article pre code { + color: inherit; +} + +.nextra-body-typesetting-article blockquote, +.nextra-callout { + border: 1px solid var(--surface-border); + border-left: 2px solid var(--surface-border-strong); + border-radius: 0 16px 16px 0; + background: color-mix(in srgb, var(--surface-muted) 90%, transparent); } -.hero-card { - border-radius: 1rem; - border: 1px solid rgba(30, 64, 175, 0.9); +.nextra-body-typesetting-article table { + font-size: 0.92rem; +} + +.nextra-body-typesetting-article :where(th, td) { + border-color: var(--surface-border); +} + +.nextra-body-typesetting-article .nextra-card { + border-color: var(--surface-border); + background: var(--surface); +} + +.nextra-body-typesetting-article .mermaid-diagram { + overflow: hidden; + margin-top: 1.25rem; + border: 1px solid rgba(147, 164, 191, 0.28); + border-radius: 20px; background: - radial-gradient(circle at 0% 0%, rgba(56, 189, 248, 0.12), transparent 55%), - radial-gradient(circle at 100% 100%, rgba(168, 85, 247, 0.16), transparent 55%), - linear-gradient(to bottom right, rgb(15 23 42), rgba(15, 23, 42, 0.96)); - padding: 1.25rem 1.5rem; + linear-gradient(180deg, rgba(15, 17, 23, 0.98) 0%, rgba(17, 24, 39, 0.98) 100%), + radial-gradient(circle at top, rgba(111, 142, 207, 0.16), transparent 48%); box-shadow: - 0 18px 40px rgba(15, 23, 42, 0.9), - 0 0 40px rgba(56, 189, 248, 0.3); + inset 0 1px 0 rgba(255, 255, 255, 0.04), + 0 18px 48px rgba(2, 6, 23, 0.28); } -.hero-title { - font-size: 1.9rem; +.nextra-body-typesetting-article .mermaid-diagram__title { + padding: 14px 18px 0; + color: #9fb0cc; + font-size: 0.76rem; font-weight: 600; - letter-spacing: -0.04em; - margin-bottom: 0.4rem; - color: #f9fafb; + letter-spacing: 0.08em; + text-transform: uppercase; } -.hero-subtitle { - font-size: 0.95rem; - color: rgb(148 163 184); +.nextra-body-typesetting-article .mermaid-diagram__canvas { + overflow-x: auto; + padding: 18px; } -.hero-actions { - display: flex; - flex-wrap: wrap; - gap: 0.75rem; - margin-top: 1.5rem; +.nextra-body-typesetting-article .mermaid-diagram__canvas svg { + display: block; + height: auto; + margin: 0 auto; } -.button-primary { - display: inline-flex; - align-items: center; - justify-content: center; - padding: 0.6rem 1.3rem; - border-radius: 999px; - border: 1px solid rgb(56 189 248); - background: radial-gradient(circle at top left, rgb(56 189 248), rgb(37 99 235)); - color: #0f172a; - font-size: 0.9rem; - font-weight: 600; +.nextra-body-typesetting-article .mermaid-diagram__loading, +.nextra-body-typesetting-article .mermaid-diagram__error { + color: #d7e0ef; + font-size: 0.88rem; +} + +.nextra-body-typesetting-article .mermaid-diagram__fallback { + margin: 0; + border: 1px solid rgba(147, 164, 191, 0.18); + border-radius: 16px; + background: rgba(15, 17, 23, 0.82) !important; +} + +.nextra-body-typesetting-article .mermaid-diagram__error { + margin: 0; + padding: 0 18px 18px; +} + +html.dark .home-topbar-nav a:hover, +html.dark .docs-nav-link:hover { + border-color: var(--surface-border); + background: var(--surface-highlight); +} + +html.dark .home-hero-copy, +html.dark .home-link-card, +html.dark .capability-card, +html.dark .reading-path-card, +html.dark .not-found-shell, +html.dark .proof-pill { + border-color: var(--surface-border); + background: + linear-gradient( + 180deg, + color-mix(in srgb, var(--surface-overlay) 92%, transparent), + color-mix(in srgb, var(--surface) 94%, transparent) + ); box-shadow: - 0 10px 30px rgba(59, 130, 246, 0.7), - 0 0 30px rgba(56, 189, 248, 0.9); + inset 0 1px 0 var(--surface-highlight), + var(--shadow-sm); } -.button-primary:hover { - filter: brightness(1.03); +html.dark .home-hero-copy { + box-shadow: + inset 0 1px 0 var(--surface-highlight), + var(--shadow-md); } -.button-ghost { - display: inline-flex; - align-items: center; - justify-content: center; - padding: 0.55rem 1.15rem; - border-radius: 999px; - border: 1px solid rgb(55 65 81); - background-color: rgba(15, 23, 42, 0.9); - color: rgb(148 163 184); - font-size: 0.85rem; +html.dark .home-hero-copy::before, +html.dark .home-link-card::before, +html.dark .capability-card::before, +html.dark .reading-path-card::before { + background: linear-gradient(90deg, transparent, var(--surface-separator), transparent); } -.button-ghost:hover { - border-color: rgb(148 163 184); - color: rgb(226 232 240); +html.dark .proof-pill { + background: + linear-gradient( + 180deg, + color-mix(in srgb, var(--surface-elevated) 82%, transparent), + color-mix(in srgb, var(--surface-overlay) 88%, transparent) + ); } -.grid-2 { - display: grid; - grid-template-columns: minmax(0, 2.2fr) minmax(0, 1.8fr); - gap: 1.5rem; - margin-top: 1.5rem; +html.dark .home-link-card:hover, +html.dark .capability-card:hover, +html.dark .reading-path-card:hover { + border-color: var(--surface-border); + background: + linear-gradient( + 180deg, + color-mix(in srgb, var(--surface-elevated) 88%, transparent), + color-mix(in srgb, var(--surface-overlay) 96%, transparent) + ); + box-shadow: + inset 0 1px 0 var(--surface-highlight-strong), + 0 22px 54px rgba(0, 0, 0, 0.2); } -@media (max-width: 768px) { - .grid-2 { - grid-template-columns: minmax(0, 1fr); - } +html.dark .hero-button { + border-color: var(--surface-border); + box-shadow: inset 0 1px 0 var(--surface-highlight); } -.card { - border-radius: 0.75rem; - border: 1px solid rgba(30, 64, 175, 0.9); - background-color: rgba(15, 23, 42, 0.9); - padding: 0.9rem 1rem; +html.dark .hero-button-primary { + border-color: rgba(255, 255, 255, 0.08); + background: color-mix(in srgb, var(--button-primary-bg) 95%, transparent); + color: var(--button-primary-fg); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.18), + 0 16px 40px rgba(0, 0, 0, 0.18); } -.card h3 { - font-size: 0.95rem; - margin-bottom: 0.5rem; +html.dark .hero-button-primary:hover { + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.22), + 0 18px 42px rgba(0, 0, 0, 0.22); +} + +html.dark .hero-button-secondary { + border-color: var(--surface-border); + background: var(--button-secondary-bg); + color: var(--button-secondary-fg); +} + +html.dark .hero-button-secondary:hover { + background: color-mix(in srgb, var(--surface-overlay) 72%, var(--surface-highlight)); +} + +html.dark .nextra-nav-container-blur, +html.dark .nextra-navbar-blur { + background: color-mix(in srgb, var(--page-bg) 78%, var(--surface-overlay)); + border-color: var(--surface-separator); +} + +html.dark .nextra-sidebar, +html.dark .nextra-toc { + border-color: var(--surface-separator); + background: + linear-gradient( + 180deg, + color-mix(in srgb, var(--surface-strong) 94%, transparent), + color-mix(in srgb, var(--surface-overlay) 96%, transparent) + ); + box-shadow: inset 0 1px 0 var(--surface-highlight); +} + +html.dark .nextra-sidebar { + border-right-color: var(--surface-separator); +} + +html.dark .nextra-footer { + border-color: var(--surface-separator); + color: var(--page-fg-muted); +} + +html.dark .nextra-sidebar a, +html.dark .nextra-toc a { + border-color: transparent; +} + +html.dark .nextra-sidebar a:hover, +html.dark .nextra-toc a:hover { + border-color: var(--surface-border); + background: color-mix(in srgb, var(--surface-highlight-strong) 100%, var(--surface-overlay)); + transform: translateX(0); } -.card p { - font-size: 0.8rem; - color: rgb(148 163 184); +html.dark .nextra-sidebar :is(a[aria-current='page'], li.active > a), +html.dark .nextra-toc a[data-active='true'] { + border-color: var(--surface-border); + background: + linear-gradient( + 180deg, + color-mix(in srgb, var(--surface-highlight-strong) 100%, var(--surface-elevated)), + color-mix(in srgb, var(--surface-highlight) 100%, var(--surface-overlay)) + ); + box-shadow: inset 0 1px 0 var(--surface-highlight); +} + +html.dark .nextra-body-typesetting-article a:not(.nextra-card) { + text-decoration-color: var(--surface-separator); +} + +html.dark .nextra-body-typesetting-article hr { + border-color: var(--surface-separator); + opacity: 0.72; +} + +html.dark .nextra-body-typesetting-article :not(pre) > code { + border-color: var(--surface-border); + background: var(--inline-code-bg); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.024); +} + +html.dark .nextra-body-typesetting-article pre { + border-color: var(--surface-border); + background: + linear-gradient( + 180deg, + color-mix(in srgb, var(--surface-muted) 94%, transparent), + color-mix(in srgb, var(--surface-elevated) 92%, transparent) + ) !important; + box-shadow: + inset 0 1px 0 var(--surface-highlight), + 0 18px 44px rgba(0, 0, 0, 0.14); +} + +html.dark .nextra-body-typesetting-article blockquote, +html.dark .nextra-callout { + border-color: var(--surface-border); + border-left-color: var(--surface-separator); + background: + linear-gradient( + 180deg, + color-mix(in srgb, var(--surface-highlight) 100%, var(--surface-muted)), + color-mix(in srgb, var(--surface-overlay) 92%, transparent) + ); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.02); +} + +html.dark .nextra-body-typesetting-article table { + overflow: hidden; + border: 1px solid var(--surface-border); + border-collapse: separate; + border-spacing: 0; + border-radius: 18px; + background: color-mix(in srgb, var(--surface-overlay) 96%, transparent); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.02); +} + +html.dark .nextra-body-typesetting-article thead { + background: color-mix(in srgb, var(--surface-highlight-strong) 100%, var(--surface-elevated)); +} + +html.dark .nextra-body-typesetting-article tbody tr { + background: color-mix(in srgb, var(--surface-overlay) 94%, transparent); +} + +html.dark .nextra-body-typesetting-article tbody tr:nth-child(even) { + background: color-mix(in srgb, var(--surface-muted) 82%, transparent); +} + +html.dark .nextra-body-typesetting-article tbody tr:hover { + background: color-mix(in srgb, var(--surface-highlight) 100%, var(--surface-elevated)); +} + +html.dark .nextra-body-typesetting-article :where(th, td) { + border-color: var(--surface-separator); +} + +html.dark .nextra-body-typesetting-article .nextra-card { + border-color: var(--surface-border); + background: + linear-gradient( + 180deg, + color-mix(in srgb, var(--surface-overlay) 94%, transparent), + color-mix(in srgb, var(--surface) 92%, transparent) + ); + box-shadow: + inset 0 1px 0 var(--surface-highlight), + var(--shadow-sm); +} + +html.dark .nextra-body-typesetting-article .mermaid-diagram { + border-color: var(--surface-border); + background: + linear-gradient( + 180deg, + color-mix(in srgb, var(--surface-muted) 96%, transparent), + color-mix(in srgb, var(--surface-elevated) 92%, transparent) + ); + box-shadow: + inset 0 1px 0 var(--surface-highlight), + 0 18px 44px rgba(0, 0, 0, 0.16); +} + +html.dark .nextra-body-typesetting-article .mermaid-diagram__title { + color: var(--page-fg-muted); +} + +html.dark .nextra-body-typesetting-article .mermaid-diagram__loading, +html.dark .nextra-body-typesetting-article .mermaid-diagram__error { + color: var(--page-fg-soft); +} + +html.dark .nextra-body-typesetting-article .mermaid-diagram__fallback { + border-color: var(--surface-border); + background: color-mix(in srgb, var(--surface-overlay) 96%, transparent) !important; } +.nextra-footer { + color: var(--page-fg-muted); +} + +.motion-rise { + animation: rise-in 0.56s cubic-bezier(0.16, 1, 0.3, 1) both; +} + +.motion-stagger > * { + animation: rise-in 0.56s cubic-bezier(0.16, 1, 0.3, 1) both; +} + +.motion-stagger > :nth-child(1) { + animation-delay: 0.04s; +} + +.motion-stagger > :nth-child(2) { + animation-delay: 0.1s; +} + +.motion-stagger > :nth-child(3) { + animation-delay: 0.16s; +} + +.motion-stagger > :nth-child(4) { + animation-delay: 0.22s; +} + +@keyframes rise-in { + from { + opacity: 0; + transform: translateY(16px); + } + + to { + opacity: 1; + transform: translateY(0); + } +} + +@media (max-width: 1080px) { + .reading-path-grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } +} + +@media (max-width: 960px) { + .docs-home, + .not-found-shell { + width: min(100% - 24px, 1080px); + } + + .home-topbar { + flex-direction: column; + align-items: flex-start; + } + + .home-hero-copy { + padding: 28px 24px 24px; + } + + .home-proof-strip, + .home-link-grid, + .capability-grid, + .reading-path-grid { + grid-template-columns: minmax(0, 1fr); + } + + .home-hero h1 { + max-width: 13ch; + font-size: clamp(1.8rem, 10vw, 2.45rem); + } + + .docs-navbar-links { + overflow-x: auto; + max-width: 100%; + padding-bottom: 2px; + } +} + +@media (prefers-reduced-motion: reduce) { + html { + scroll-behavior: auto; + } + + *, + *::before, + *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + scroll-behavior: auto !important; + } +} diff --git a/doc/app/gui.mdx b/doc/app/gui.mdx deleted file mode 100644 index ff34ce15..00000000 --- a/doc/app/gui.mdx +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: GUI(Tauri 桌面应用) -description: 介绍 memory-sync 的 Tauri 2 + React 19 桌面 GUI,作为 CLI 的可视化前端。 -lastUpdated: 2026-02-18 ---- - -
    -

    概览

    -

    - GUI 应用基于 Tauri 2 + React 19 构建,提供对 CLI 同一套规则与配置的可视化管理能力,适合不想记命令行参数的用户。 -

    - -

    主要功能

    -
      -
    • 加载并校验 tnmsc 配置
    • -
    • 编辑 Global Memory / Skills / Fast Commands / Sub-agents
    • -
    • 一键触发同步到指定 AI 客户端
    • -
    - -

    后续章节会补充具体的截图和交互流程。

    -
    - diff --git a/doc/app/home-page.mdx b/doc/app/home-page.mdx new file mode 100644 index 00000000..68b7dc2c --- /dev/null +++ b/doc/app/home-page.mdx @@ -0,0 +1,118 @@ +import Link from 'next/link' +import { + capabilityCards, + heroProofPoints, + homeEntryCards, + readingPath, + siteConfig +} from '../lib/site' + +
    +
    + + {siteConfig.productName} + Docs + + + +
    + +
    +
    +

    Documentation

    +

    面向多 AI 工具的 prompt 与 config sync 文档。

    +

    + {siteConfig.productName} + {' '} + 以 MDX 维护源内容,通过 Rust-first / NAPI-first pipeline 将 prompts、rules、skills、commands + 与 workspace memory 物化为目标工具原生配置。 +

    + + + +
      + {heroProofPoints.map(point => ( +
    • + {point.label} + {point.value} +
    • + ))} +
    +
    +
    + +
    +
    +

    Start Here

    +

    先选门类,再进入具体页面

    +

    + 现在文档按 CLI、MCP、GUI、技术细节、设计初衷五个一级门类组织,避免写作和阅读时把产品入口、实现原理与背景叙事混在一起。 +

    +
    + +
    + {homeEntryCards.map(link => ( + + {link.title} +

    {link.detail}

    + Open + + ))} +
    +
    + +
    +
    +

    Capabilities

    +

    文档重点覆盖的能力边界

    +

    + 先明确项目能做什么,再进入具体配置字段、命令表面与实现边界。 +

    +
    + +
    + {capabilityCards.map(card => ( +
    + {card.label} +

    {card.title}

    +

    {card.detail}

    +
    + ))} +
    +
    + +
    +
    +

    Recommended Path

    +

    按这条路线进入,能最快建立正确心智模型

    +

    + 路线从运行前提开始,先建立真源模型,再回到 CLI 执行与边界验证。 +

    +
    + +
    + {readingPath.map(item => ( + + {item.step} + {item.title} +

    {item.description}

    + + ))} +
    +
    +
    diff --git a/doc/app/icon.svg b/doc/app/icon.svg new file mode 100644 index 00000000..e3534177 --- /dev/null +++ b/doc/app/icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/doc/app/layout.tsx b/doc/app/layout.tsx index 3da354af..bd3becae 100644 --- a/doc/app/layout.tsx +++ b/doc/app/layout.tsx @@ -1,104 +1,54 @@ -import type {ReactNode} from 'react' -import Link from 'next/link' +import type {Metadata} from 'next' +import {JetBrains_Mono} from 'next/font/google' +import {getSiteUrl, siteConfig} from '../lib/site' +import 'nextra-theme-docs/style.css' import './globals.css' -export const metadata = { - title: 'memory-sync Documentation', - description: 'Official documentation for @truenine/memory-sync, the cross-AI prompt synchronisation toolkit.' -} - -export default function RootLayout({children}: {readonly children: ReactNode}) { - return ( - - -
    -
    -
    - Docs -
    -

    memory-sync

    - Cross-AI prompt synchronisation -
    -
    - -
    +const sans = JetBrains_Mono({ + variable: '--font-sans', + preload: true, + subsets: ['latin'] +}) -
    - +const mono = JetBrains_Mono({ + variable: '--font-mono', + subsets: ['latin'], + preload: true +}) -
    -
    - {children} -
    -
    -
    +export const metadata: Metadata = { + metadataBase: getSiteUrl(), + title: { + default: siteConfig.title, + template: `%s | ${siteConfig.productName}` + }, + description: siteConfig.description, + applicationName: siteConfig.shortName, + alternates: { + canonical: '/' + }, + category: 'developer tools', + manifest: '/manifest.webmanifest', + openGraph: { + type: 'website', + url: '/', + title: siteConfig.title, + description: siteConfig.description, + siteName: siteConfig.title, + locale: 'zh_CN' + }, + twitter: { + card: 'summary_large_image', + title: siteConfig.title, + description: siteConfig.description + } +} -
    -

    - © - {new Date().getFullYear()} - {' '} - TrueNine · Built with Next.js 16 + MDX · Deployed on Vercel -

    -
    -
    +export default function RootLayout({children}: {readonly children: React.ReactNode}) { + return ( + + + {children} ) diff --git a/doc/app/manifest.ts b/doc/app/manifest.ts new file mode 100644 index 00000000..9fd19100 --- /dev/null +++ b/doc/app/manifest.ts @@ -0,0 +1,14 @@ +import type {MetadataRoute} from 'next' + +export default function manifest(): MetadataRoute.Manifest { + return { + name: 'memory-sync 文档', + short_name: 'memory-sync', + description: 'Chinese-first manifesto-led docs for memory-sync.', + start_url: '/', + display: 'standalone', + background_color: '#090909', + theme_color: '#cf5d29', + lang: 'zh-CN' + } +} diff --git a/doc/app/not-found.tsx b/doc/app/not-found.tsx new file mode 100644 index 00000000..31909777 --- /dev/null +++ b/doc/app/not-found.tsx @@ -0,0 +1,26 @@ +import Link from 'next/link' + +export default function NotFound() { + return ( +
    +

    404 / ROUTE NOT FOUND

    +

    你摸到了一条不存在的通道。

    +

    + 当前文档已经重构为首页 ` + / + ` 加文档命名空间 ` + /docs/* + `。 + 如果你是从旧链接跳来的,很可能命中了已经移除的平铺 MDX 路径。 +

    +
    + + 返回首页 + + + 打开文档索引 + +
    +
    + ) +} diff --git a/doc/app/opengraph-image.tsx b/doc/app/opengraph-image.tsx new file mode 100644 index 00000000..b235e1ff --- /dev/null +++ b/doc/app/opengraph-image.tsx @@ -0,0 +1,50 @@ +import {ImageResponse} from 'next/og' + +export const alt = 'memory-sync 文档' +export const size = { + width: 1200, + height: 630 +} +export const contentType = 'image/png' + +export default function OpenGraphImage() { + return new ImageResponse( + ( +
    +
    +
    RUST-FIRST / TOOL-RAT DOCS
    +
    +
    memory-sync
    +
    + 为多 AI 工具同步规则、命令、技能与记忆的中文优先文档站 +
    +
    +
    + manifesto homepage + /docs reference system +
    +
    +
    + ), + size + ) +} diff --git a/doc/app/page.mdx b/doc/app/page.mdx deleted file mode 100644 index 6599925a..00000000 --- a/doc/app/page.mdx +++ /dev/null @@ -1,61 +0,0 @@ -export const metadata = { - title: 'memory-sync 文档' -}; - -
    - - - Next.js 16 · React 19 · MDX 文档站 - - -
    -

    memory-sync 文档中心

    -
    - 为多 AI 工具统一配置规则集(Global Memory / Skills / Fast - Commands / 子代理等),一次编写,多端复用。 -
    - - -
    - -

    快速上手

    -
    - 这里将会是你未来写「正式文档」的位置:安装、初始化、配置、与 Cursor / Claude / Gemini / - Warp 等工具联动的完整流程。 -
    -
      -
    • 安装 CLI:使用 pnpm / npm / npx 安装并运行 tnmsc
    • -
    • 初始化规则仓库:生成示例 Global Memory / Skills / Fast Commands
    • -
    • 与编辑器配置联动:Cursor / VS Code / JetBrains 等
    • -
    - -
    - 你可以把现有的 tnmsc.example.jsonglobal.src.mdx{' '} - 等内容按模块拆分成多篇文档,放在 app{' '} - 目录中对应的路由(例如 /getting-started/cli, /gui)。 -
    - -
    -

    部署到 Vercel

    -
    - 在 Vercel 上新建项目时,把根目录设置为 doc,构建命令使用 pnpm build{' '} - 或 npm run build,输出目录保持 Next.js 默认。 -
    -
    - 通过 Preview 部署可以先给少量真实用户访问文档,确认结构和内容后再切换到 Production。 -
    -
    -
    - diff --git a/doc/app/page.tsx b/doc/app/page.tsx new file mode 100644 index 00000000..53312b72 --- /dev/null +++ b/doc/app/page.tsx @@ -0,0 +1,5 @@ +import HomePageContent from './home-page.mdx' + +export default function HomePage() { + return +} diff --git a/doc/app/prompts/commands.mdx b/doc/app/prompts/commands.mdx deleted file mode 100644 index 09495f7c..00000000 --- a/doc/app/prompts/commands.mdx +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Fast Commands 规范 -description: 说明如何为 memory-sync 编写快速命令(Fast Commands),封装高频操作。 -lastUpdated: 2026-02-18 ---- - -
    -

    什么是 Fast Command?

    -

    - Fast Command 更接近「脚本化的快捷键」,封装了某个高频操作的完整上下文和参数,让你通过一个短命令就能触发复杂任务。 -

    - -

    本页将来可以加入具体命令格式、命名规范以及跨工具映射规则。

    -
    - diff --git a/doc/app/prompts/page.mdx b/doc/app/prompts/page.mdx deleted file mode 100644 index 10877b81..00000000 --- a/doc/app/prompts/page.mdx +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: Prompt 规则与结构 -description: 介绍 Global Memory、Skills、Fast Commands、Sub-agents 等不同类型的规则写法与职责划分。 -lastUpdated: 2026-02-18 ---- - -
    -

    概览

    -

    - memory-sync 把不同用途的 Prompt 拆分成多种独立的文件类型,以便在多 AI 工具之间重复使用同一套规则。 -

    - -

    主要类型

    -
      -
    • Global Memory:跨项目、跨会话的长期记忆,例如个人偏好、通用风格。
    • -
    • Skills:针对某一类任务的专用技能卡片,例如「写 README」「生成数据库设计」。
    • -
    • Fast Commands:短命令或一键操作脚本,适合频繁重复的小任务。
    • -
    • Sub-agents:为复杂任务拆分出的子代理配置,每个子代理有独立职责。
    • -
    • Rules:与具体项目或目录绑定的规则文件,例如 `.cursor/rules/*.mdx`。
    • -
    - -

    - 本页给出整体概念,具体写法与风格建议可以参考 - Skills 规范 与 - Fast Commands 规范。 -

    -
    - diff --git a/doc/app/prompts/skills.mdx b/doc/app/prompts/skills.mdx deleted file mode 100644 index 2119af52..00000000 --- a/doc/app/prompts/skills.mdx +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: Skills 规范 -description: 说明如何为 memory-sync 编写可复用的技能卡片(Skills),并与不同 AI 工具共享。 -lastUpdated: 2026-02-18 ---- - -
    -

    什么是 Skill?

    -

    - Skill 是描述某一类任务的「专业说明书」,通常包括适用场景、输入输出、约束条件等,用于指导 AI - 在特定领域内稳定输出。 -

    - -

    本页主要定义结构和写作建议,具体示例可参考你现有的 Skills 文件。

    -
    - diff --git a/doc/app/robots.ts b/doc/app/robots.ts new file mode 100644 index 00000000..7f4353bf --- /dev/null +++ b/doc/app/robots.ts @@ -0,0 +1,14 @@ +import type {MetadataRoute} from 'next' +import {getSiteUrl} from '../lib/site' + +export default function robots(): MetadataRoute.Robots { + const siteUrl = getSiteUrl() + + return { + rules: { + userAgent: '*', + allow: '/' + }, + sitemap: new URL('/sitemap.xml', siteUrl).toString() + } +} diff --git a/doc/app/sitemap.ts b/doc/app/sitemap.ts new file mode 100644 index 00000000..d885c307 --- /dev/null +++ b/doc/app/sitemap.ts @@ -0,0 +1,50 @@ +import type {MetadataRoute} from 'next' +import {readdir} from 'node:fs/promises' +import path from 'node:path' +import process from 'node:process' +import {getSiteUrl} from '../lib/site' + +const MDX_EXTENSION = '.mdx' +const TRAILING_SLASHES_PATTERN = /\/+$/u + +function routeFromContentFile(filePath: string): string { + const relative = filePath.replaceAll('\\', '/') + const withoutExt = relative.endsWith(MDX_EXTENSION) + ? relative.slice(0, -MDX_EXTENSION.length) + : relative + + if (withoutExt.endsWith('/index')) { + return `/docs/${withoutExt.slice(0, -'/index'.length)}` + } + + return `/docs/${withoutExt}` +} + +async function findMdxFiles(directory: string): Promise { + const entries = await readdir(directory, {encoding: 'utf8', recursive: true}) + return entries.filter((entry): entry is string => entry.endsWith(MDX_EXTENSION)) +} + +export default async function sitemap(): Promise { + const contentDir = path.join(process.cwd(), 'content') + const siteUrl = getSiteUrl() + const files = await findMdxFiles(contentDir) + + const routes = files.map(file => { + const route = routeFromContentFile(file).replace(TRAILING_SLASHES_PATTERN, '') || '/docs' + return { + url: new URL(route, siteUrl).toString(), + changeFrequency: 'weekly' as const, + priority: route === '/docs' ? 0.9 : 0.7 + } + }) + + return [ + { + url: new URL('/', siteUrl).toString(), + changeFrequency: 'weekly', + priority: 1 + }, + ...routes + ] +} diff --git a/doc/app/twitter-image.tsx b/doc/app/twitter-image.tsx new file mode 100644 index 00000000..666ceeaa --- /dev/null +++ b/doc/app/twitter-image.tsx @@ -0,0 +1,6 @@ +export { + alt, + contentType, + default, + size +} from './opengraph-image' diff --git a/doc/components/mermaid.tsx b/doc/components/mermaid.tsx new file mode 100644 index 00000000..b6a4f4cc --- /dev/null +++ b/doc/components/mermaid.tsx @@ -0,0 +1,127 @@ +'use client' + +import type {ReactNode} from 'react' +import {useEffect, useId, useRef, useState} from 'react' + +type MermaidModule = typeof import('mermaid') + +interface MermaidProps { + readonly chart: string + readonly title?: string +} + +let mermaidPromise: Promise | undefined +let mermaidInitialized = false + +async function loadMermaid() { + mermaidPromise ??= import('mermaid').then(({default: mermaid}) => { + if (mermaidInitialized) { + return mermaid + } + + mermaid.initialize({ + startOnLoad: false, + securityLevel: 'strict', + theme: 'dark', + themeVariables: { + background: '#0f1117', + darkMode: 'true', + edgeLabelBackground: '#0f1117', + fontFamily: + 'var(--font-mono), "JetBrains Mono", "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace', + lineColor: '#93a4bf', + mainBkg: '#151b28', + nodeBorder: '#5d7398', + primaryBorderColor: '#6f8ecf', + primaryColor: '#151b28', + primaryTextColor: '#f8fafc', + secondaryBorderColor: '#5d7398', + secondaryColor: '#1a2334', + secondaryTextColor: '#f8fafc', + tertiaryBorderColor: '#93a4bf', + tertiaryColor: '#0f1117', + tertiaryTextColor: '#e5edf8', + textColor: '#f8fafc' + } + }) + mermaidInitialized = true + + return mermaid + }) + + return mermaidPromise +} + +export function Mermaid({chart, title}: MermaidProps) { + const containerRef = useRef(null) + const [svg, setSvg] = useState() + const [error, setError] = useState() + const id = useId().replaceAll(':', '') + + useEffect(() => { + let cancelled = false + + setSvg(void 0) + setError(void 0) + + void loadMermaid() + .then(async mermaid => { + const {svg: renderedSvg, bindFunctions} = await mermaid.render( + `mermaid-${id}-${Date.now()}`, + chart.trim() + ) + + if (cancelled) { + return + } + + setSvg(renderedSvg) + + requestAnimationFrame(() => { + if (containerRef.current) { + bindFunctions?.(containerRef.current) + } + }) + }) + .catch(renderError => { + if (cancelled) { + return + } + + setError(renderError instanceof Error ? renderError.message : 'Unknown Mermaid render error') + }) + + return () => { + cancelled = true + } + }, [chart, id]) + + const hasTitle = title !== void 0 && title !== '' + const hasSvg = svg !== void 0 && svg !== '' + const hasError = error !== void 0 && error !== '' + let diagramBody: ReactNode =
    Rendering diagram...
    + + if (hasSvg) { + diagramBody =
    + } else if (hasError) { + diagramBody = ( +
    +        {chart}
    +      
    + ) + } + + return ( +
    + {hasTitle &&
    {title}
    } +
    {diagramBody}
    + {hasError && ( +

    + Mermaid render failed: + {' '} + {error} +

    + )} +
    + ) +} diff --git a/doc/content/_meta.ts b/doc/content/_meta.ts new file mode 100644 index 00000000..097965df --- /dev/null +++ b/doc/content/_meta.ts @@ -0,0 +1,25 @@ +export default { + 'index': { + title: '文档总览' + }, + 'cli': { + title: 'CLI', + display: 'children' + }, + 'mcp': { + title: 'MCP', + display: 'children' + }, + 'gui': { + title: 'GUI', + display: 'children' + }, + 'technical-details': { + title: '技术细节', + display: 'children' + }, + 'design-rationale': { + title: '设计初衷', + display: 'children' + } +} diff --git a/doc/content/cli/_meta.ts b/doc/content/cli/_meta.ts new file mode 100644 index 00000000..b9ddf6f9 --- /dev/null +++ b/doc/content/cli/_meta.ts @@ -0,0 +1,17 @@ +export default { + 'index': '概览', + 'install': '安装与前提', + 'workspace-setup': '工作区与 aindex', + 'first-sync': '第一次同步', + 'migration': '从旧文档迁移', + 'cli-commands': 'CLI 命令', + 'dry-run-and-clean': 'dry-run 与 clean', + 'plugin-config': 'plugin.config.ts', + 'schema': 'JSON Schema', + 'output-scopes': '输出范围', + 'frontmatter': 'Front Matter', + 'cleanup-protection': '清理保护', + 'supported-outputs': '支持的输出目标', + 'troubleshooting': '排障', + 'upgrade-notes': '升级说明' +} diff --git a/doc/content/cli/cleanup-protection.mdx b/doc/content/cli/cleanup-protection.mdx new file mode 100644 index 00000000..e73e23c0 --- /dev/null +++ b/doc/content/cli/cleanup-protection.mdx @@ -0,0 +1,53 @@ +--- +title: 清理保护 +description: 说明 cleanupProtection 规则如何避免 clean 命令误删不该删除的内容。 +sidebarTitle: 清理保护 +status: stable +--- + +# 清理保护 + +`clean` 不是无脑删文件,所以 `cleanupProtection` 也不是可有可无的附属字段。 + +## 规则结构 + +每条保护规则支持这些字段: + +| 字段 | 必填 | 说明 | +| --- | --- | --- | +| `path` | 是 | 目标路径或 glob | +| `protectionMode` | 是 | `direct` 或 `recursive` | +| `matcher` | 否 | `path` 或 `glob` | +| `reason` | 否 | 写明这条保护存在的原因 | + +## 语义 + +- `direct`:只保护这一个目标。 +- `recursive`:保护这一路径下的整棵子树。 + +## 什么时候必须配 + +如果你的输出目录旁边混放了: + +- 手写文件 +- 其他工具生成但不属于 tnmsc 的文件 +- 临时人工补丁 + +那么在启用 `clean` 前最好先加保护规则,否则你迟早会把不该删的内容一起带走。 + +## 推荐写法 + +```json +{ + "cleanupProtection": { + "rules": [ + { + "path": ".cursor/local-notes", + "protectionMode": "recursive", + "matcher": "path", + "reason": "人工维护,不属于 tnmsc 输出" + } + ] + } +} +``` diff --git a/doc/content/cli/cli-commands.mdx b/doc/content/cli/cli-commands.mdx new file mode 100644 index 00000000..b8a4df2c --- /dev/null +++ b/doc/content/cli/cli-commands.mdx @@ -0,0 +1,58 @@ +--- +title: CLI 命令 +description: 基于当前 tnmsc --help 输出整理的命令与行为说明。 +sidebarTitle: CLI 命令 +status: stable +--- + +# CLI 命令 + +当前 `tnmsc --help` 暴露的命令是: + +| 命令 | 说明 | +| --- | --- | +| `tnmsc` | 执行默认同步管线 | +| `tnmsc help` | 查看帮助 | +| `tnmsc version` | 查看版本 | +| `tnmsc init` | 已废弃,不再初始化 aindex | +| `tnmsc dry-run` | 预览会写出的文件 | +| `tnmsc clean` | 删除已生成的输出文件 | +| `tnmsc clean --dry-run` | 预览会清理什么 | +| `tnmsc config key=value` | 修改全局配置 | + +## 关键结论 + +### `init` 已经不应该出现在新流程里 + +当前实现明确把它视为 deprecated,因此新文档不会再把它写成推荐入口。 + +### `config` 只能改一组白名单键 + +当前 `ConfigCommand` 允许的键包括: + +- `workspaceDir` +- `aindex.skills.src/dist` +- `aindex.commands.src/dist` +- `aindex.subAgents.src/dist` +- `aindex.rules.src/dist` +- `aindex.globalPrompt.src/dist` +- `aindex.workspacePrompt.src/dist` +- `aindex.app.src/dist` +- `aindex.ext.src/dist` +- `aindex.arch.src/dist` +- `logLevel` + +### `logLevel` 也有严格枚举 + +只能是: + +```text +trace / debug / info / warn / error +``` + +## 推荐操作习惯 + +1. 新环境先 `tnmsc help` +2. 写出前先 `tnmsc dry-run` +3. 清理前先 `tnmsc clean --dry-run` +4. 真要改全局配置时,用 `tnmsc config`,不要手写出一份和 Schema 漂移的 JSON diff --git a/doc/content/cli/dry-run-and-clean.mdx b/doc/content/cli/dry-run-and-clean.mdx new file mode 100644 index 00000000..499a3b5f --- /dev/null +++ b/doc/content/cli/dry-run-and-clean.mdx @@ -0,0 +1,37 @@ +--- +title: dry-run 与 clean +description: 说明 tnmsc 如何先预览输出,再执行清理,并配合 cleanupProtection 控制风险。 +sidebarTitle: dry-run 与 clean +status: stable +--- + +# dry-run 与 clean + +## `dry-run` 的职责 + +`tnmsc dry-run` 用来预览当前执行会写出哪些文件与目录。它适合在这些场景先跑一遍: + +- 第一次接入某个项目 +- 刚修改过 `plugin.config.ts` +- 刚改过 [输出范围](/docs/cli/output-scopes) +- 准备验证某次批量源内容变更的影响 + +## `clean` 的职责 + +`tnmsc clean` 用来清除已生成的输出文件。它不是“无差别删目录”,而是依据当前输出模型和清理保护规则执行。 + +在真正执行前,优先用: + +```sh +tnmsc clean --dry-run +``` + +## 风险边界 + +如果输出目录里混有人工文件或其他工具产物,必须先看 [清理保护](/docs/cli/cleanup-protection)。没有保护规则时,`clean` 的风险会显著上升。 + +## 推荐习惯 + +1. 改配置或换项目时先 `dry-run` +2. 真要清理时先 `clean --dry-run` +3. 出现异常时再结合 [排障](/docs/cli/troubleshooting) 定位 diff --git a/doc/content/cli/first-sync.mdx b/doc/content/cli/first-sync.mdx new file mode 100644 index 00000000..1aedf1a7 --- /dev/null +++ b/doc/content/cli/first-sync.mdx @@ -0,0 +1,34 @@ +--- +title: 第一次同步 +description: 按最短路径完成 tnmsc help、dry-run、真实同步与结果核对。 +sidebarTitle: 第一次同步 +status: stable +--- + +# 第一次同步 + +## 推荐顺序 + +1. 先运行 `tnmsc help`,确认你面对的是当前命令集。 +2. 再运行 `tnmsc dry-run`,确认会写出哪些文件。 +3. 确认范围无误后,再执行默认同步管线。 + +## 最短流程 + +```sh +tnmsc help +tnmsc dry-run +tnmsc +``` + +## 为什么不能直接跳过 `dry-run` + +因为当前系统不仅会写文件,还会根据配置处理清理边界。第一次接入某个项目时,先看预览比事后回收误写和误删要便宜得多。 + +如果你不确定清理风险,先补读 [dry-run 与 clean](/docs/cli/dry-run-and-clean) 和 [清理保护](/docs/cli/cleanup-protection)。 + +## 同步后应该核对什么 + +- 目标工具是不是出现在 [支持的输出目标](/docs/cli/supported-outputs) 范围内 +- 真实写入范围是否符合 [输出范围](/docs/cli/output-scopes) +- 某些字段行为是否与 [JSON Schema](/docs/cli/schema) 一致 diff --git a/doc/content/cli/frontmatter.mdx b/doc/content/cli/frontmatter.mdx new file mode 100644 index 00000000..be68060c --- /dev/null +++ b/doc/content/cli/frontmatter.mdx @@ -0,0 +1,57 @@ +--- +title: Front Matter +description: 说明当前系统中配置 frontMatter 选项与内容 frontmatter 的不同层次。 +sidebarTitle: Front Matter +status: stable +--- + +# Front Matter + +这里要先分清两层 front matter。 + +## 1. 文档页自己的 frontmatter + +这套文档站的每篇 MDX 页面当前要求至少包含: + +- `title` +- `description` + +可选字段包括: + +- `sidebarTitle` +- `status` +- `keywords` + +## 2. 同步系统的 `frontMatter` 配置 + +Schema 与 `config.ts` 当前公开的配置项只有: + +```json +{ + "frontMatter": { + "blankLineAfter": true + } +} +``` + +它的作用不是描述页面本身,而是控制输出时 front matter 之后是否保留空行。 + +## 3. 源内容 frontmatter + +不同输入类型还会在自己的源文件 frontmatter 中承载描述、触发条件和工具约束等字段。多个输出插件会消费这些字段做目标元数据映射。 + +有一个重要例外: + +- `skills` 不再从 frontmatter 读取 `name`,而是直接使用 skill 目录名 +- `subagents` 不再从 frontmatter 读取 `name`,而是直接使用相对路径推导出的名称 +- 旧的 `name` 字段如果仍然存在,会被忽略并给出告警 + +关于这些输入类型的职责边界,见 [技术细节](/docs/technical-details)。 + +## 结论 + +- 文档 frontmatter 是给 docs site 的 +- `frontMatter` 配置是给输出行为的 +- 源内容 frontmatter 是给同步系统与输出插件的,但 `skills` / `subagents` 的名称现在来自路径而不是 `name` + +三者不是一回事。 diff --git a/doc/content/cli/index.mdx b/doc/content/cli/index.mdx new file mode 100644 index 00000000..7f21022f --- /dev/null +++ b/doc/content/cli/index.mdx @@ -0,0 +1,28 @@ +--- +title: CLI +description: 以 tnmsc 命令面为中心组织安装、工作区准备、同步流程、配置字段与排障信息。 +sidebarTitle: 概览 +status: stable +--- + +# CLI + +这一节围绕 `tnmsc` 这个公开命令面组织。凡是“怎么安装”“怎么准备工作区”“怎么执行同步”“某个配置字段到底是什么意思”这类问题,都优先从这里进入。 + +## 这一节包含什么 + +- [安装与前提](/docs/cli/install):确认 Node、pnpm、Rust 与 GUI 的更高开发引擎边界。 +- [工作区与 aindex](/docs/cli/workspace-setup):准备源文件目录与项目配置入口。 +- [第一次同步](/docs/cli/first-sync):按推荐顺序跑 `help`、`dry-run` 与真实写入。 +- [CLI 命令](/docs/cli/cli-commands):核对 `tnmsc --help` 当前公开的命令表面。 +- [dry-run 与 clean](/docs/cli/dry-run-and-clean):先预览、再写入、再清理。 +- [plugin.config.ts](/docs/cli/plugin-config) 与 [JSON Schema](/docs/cli/schema):集中核对配置事实。 +- [输出范围](/docs/cli/output-scopes)、[Front Matter](/docs/cli/frontmatter)、[清理保护](/docs/cli/cleanup-protection):确认边界控制行为。 +- [支持的输出目标](/docs/cli/supported-outputs)、[排障](/docs/cli/troubleshooting)、[升级说明](/docs/cli/upgrade-notes):应对日常使用与版本迁移。 + +## 推荐顺序 + +1. 先读 [安装与前提](/docs/cli/install)。 +2. 再读 [工作区与 aindex](/docs/cli/workspace-setup)。 +3. 接着用 [第一次同步](/docs/cli/first-sync) 跑通一次真实流程。 +4. 需要核对事实时,再回看 [CLI 命令](/docs/cli/cli-commands) 与 [JSON Schema](/docs/cli/schema)。 diff --git a/doc/content/cli/install.mdx b/doc/content/cli/install.mdx new file mode 100644 index 00000000..d89c0b3f --- /dev/null +++ b/doc/content/cli/install.mdx @@ -0,0 +1,63 @@ +--- +title: 安装与前提 +description: 说明 memory-sync 当前要求的 Node、pnpm、Rust 与 CLI 安装方式。 +sidebarTitle: 安装与前提 +status: stable +keywords: + - install + - pnpm + - node + - rust +--- + +# 安装与前提 + +## 运行时要求 + +根据当前仓库配置: + +- 根工作区要求 `Node.js >= 22` +- 根工作区开发引擎要求 `pnpm 10.30.1` +- Rust workspace 目标基线为 `rust >= 1.87.0` +- `gui/` 的开发引擎要求更高,当前声明为 `rust >= 1.93.1` 与 `node >= 25.2.1` + +如果你只使用文档站与 CLI,先满足根工作区要求即可;如果你还要构建桌面 GUI,再对齐 `gui/` 的更高版本。 + +## 安装 CLI + +README 当前给出的安装方式是: + +```sh +npm install -g @truenine/memory-sync +``` + +如果你在 monorepo 本地开发,通常会直接在仓库根执行: + +```sh +pnpm install +pnpm -C cli exec node dist/index.mjs --help +``` + +## 先确认你装的是当前命令集 + +当前 CLI 帮助里可见的核心命令是: + +- 默认执行同步管线 +- `help` +- `version` +- `init`,但已经废弃 +- `dry-run` +- `clean` +- `config key=value` + +这意味着旧文档里把 `tnmsc init` 当成初始化入口的说法已经过时。现在它只会返回废弃提示,不再为你生成 aindex。 + +## 第一次检查 + +安装后先跑: + +```sh +tnmsc help +``` + +你应该看到 `dry-run`、`clean` 与 `config`,同时看到 `init` 被标记为 deprecated。只要这里不对,后面的文档都不该继续跟。 diff --git a/doc/content/cli/migration.mdx b/doc/content/cli/migration.mdx new file mode 100644 index 00000000..c9f04980 --- /dev/null +++ b/doc/content/cli/migration.mdx @@ -0,0 +1,30 @@ +--- +title: 从旧文档迁移 +description: 说明旧页面、旧命令认知与当前五大门类文档结构之间的映射关系。 +sidebarTitle: 从旧文档迁移 +status: stable +--- + +# 从旧文档迁移 + +## 结构变化 + +旧文档把“快速上手”“概念”“内容编写”“参考”“运维”混在同一层。现在一级结构改成: + +- `CLI` +- `MCP` +- `GUI` +- `技术细节` +- `设计初衷` + +这不是换名字,而是把阅读入口和写作目录按职责重新切开。 + +## 旧入口现在该去哪 + +- 旧的 `quick-start`、`reference`、`operations`,现在主要归到 [CLI](/docs/cli)。 +- 旧的 `concepts` 与 `authoring`,现在主要归到 [技术细节](/docs/technical-details)。 +- manifesto 类页面现在只放在 [设计初衷](/docs/design-rationale)。 + +## 命令认知也要一起迁移 + +旧文档最容易误导人的地方,是把 `tnmsc init` 继续写成推荐入口。当前实现里它已经废弃,新的使用路径应以 [CLI 命令](/docs/cli/cli-commands) 为准。 diff --git a/doc/content/cli/output-scopes.mdx b/doc/content/cli/output-scopes.mdx new file mode 100644 index 00000000..521b4a16 --- /dev/null +++ b/doc/content/cli/output-scopes.mdx @@ -0,0 +1,57 @@ +--- +title: 输出范围 +description: 说明 outputScopes 如何按插件、按 topic 限制 project/global 输出范围。 +sidebarTitle: 输出范围 +status: stable +--- + +# 输出范围 + +`outputScopes` 是当前实现里最重要也最容易被忽视的一个安全阀。 + +## 它解决什么问题 + +不是所有内容都应该被所有插件同时输出到全局和项目级。`outputScopes` 让你可以按插件、按 topic 指定来源范围。 + +## 支持的 topic + +当前核心常量与 Schema 对齐,支持: + +- `prompt` +- `rules` +- `commands` +- `subagents` +- `skills` +- `mcp` + +## 可选范围 + +- `project` +- `global` + +有些 topic 允许多值数组,有些插件会声明为单值 topic。如果你给单值 topic 传多个范围,运行前校验会直接报错。 + +## 示例 + +```json +{ + "outputScopes": { + "plugins": { + "CursorOutputPlugin": { + "prompt": "project", + "rules": ["project", "global"] + } + } + } +} +``` + +## 什么时候该先看它 + +当你遇到这些现象时: + +- 规则被写进了全局配置,但你只想要项目级 +- 全局 Prompt 被错误地带进某个局部目标 +- 技能、命令或 MCP 相关输出出现在不该出现的目标里 + +优先检查 `outputScopes`,不要先改源文件本身。 diff --git a/doc/content/cli/plugin-config.mdx b/doc/content/cli/plugin-config.mdx new file mode 100644 index 00000000..afa295a7 --- /dev/null +++ b/doc/content/cli/plugin-config.mdx @@ -0,0 +1,54 @@ +--- +title: plugin.config.ts +description: 说明项目级 plugin.config.ts 如何装配默认输出插件与运行参数。 +sidebarTitle: plugin.config.ts +status: stable +--- + +# `plugin.config.ts` + +## 它的职责 + +`plugin.config.ts` 是项目级装配入口。它把: + +- 管线参数 +- 插件列表 +- 可能的程序化覆盖 + +交给 `defineConfig()`,最终产出真正执行同步所需的 `PipelineConfig`。 + +## 当前默认输出插件 + +当前仓库 `cli/src/plugin.config.ts` 默认装配的输出插件包括: + +- `AgentsOutputPlugin` +- `ClaudeCodeCLIOutputPlugin` +- `CodexCLIOutputPlugin` +- `JetBrainsAIAssistantCodexOutputPlugin` +- `DroidCLIOutputPlugin` +- `GeminiCLIOutputPlugin` +- `GenericSkillsOutputPlugin` +- `OpencodeCLIOutputPlugin` +- `QoderIDEPluginOutputPlugin` +- `TraeIDEOutputPlugin` +- `TraeCNIDEOutputPlugin` +- `WarpIDEOutputPlugin` +- `WindsurfOutputPlugin` +- `CursorOutputPlugin` +- `GitExcludeOutputPlugin` +- `JetBrainsIDECodeStyleConfigOutputPlugin` +- `EditorConfigOutputPlugin` +- `VisualStudioCodeIDEConfigOutputPlugin` +- `ReadmeMdConfigFileOutputPlugin` + +## 这意味着什么 + +这份配置不是“文档示意”,而是当前默认同步现实。只要这里有插件,就意味着默认执行里会考虑该目标。 + +## 最小认知模型 + +你可以把 `plugin.config.ts` 理解为: + +- 选择要输出到哪些目标 +- 决定是否在项目里追加程序化配置 +- 保持与全局用户配置合并,而不是完全绕开用户配置 diff --git a/doc/content/cli/schema.mdx b/doc/content/cli/schema.mdx new file mode 100644 index 00000000..45e3f455 --- /dev/null +++ b/doc/content/cli/schema.mdx @@ -0,0 +1,74 @@ +--- +title: JSON Schema +description: 梳理 tnmsc.schema.json 当前公开的配置字段与约束。 +sidebarTitle: JSON Schema +status: stable +--- + +# JSON Schema + +`cli/dist/tnmsc.schema.json` 当前公开的根字段有: + +| 字段 | 类型 | 说明 | +| --- | --- | --- | +| `version` | `string` | 配置版本或发布版本标记 | +| `workspaceDir` | `string` | 工作区根目录 | +| `aindex` | `object` | 输入源与导出目录映射 | +| `logLevel` | enum | `trace` / `debug` / `info` / `warn` / `error` | +| `commandSeriesOptions` | `object` | command 系列命名与插件覆盖 | +| `outputScopes` | `object` | 各插件输出范围覆盖 | +| `frontMatter` | `object` | 输出时的 front matter 处理选项 | +| `cleanupProtection` | `object` | 清理保护规则 | +| `profile` | `object` | 个人资料字段 | + +## `aindex` 下的关键子项 + +- `skills` +- `commands` +- `subAgents` +- `rules` +- `globalPrompt` +- `workspacePrompt` +- `app` +- `ext` +- `arch` + +每个子项都由 `src` / `dist` 组成。 + +## `outputScopes` 支持的 topic + +Schema 当前允许的 topic 包括: + +- `prompt` +- `rules` +- `commands` +- `subagents` +- `skills` +- `mcp` + +详细行为见 [输出范围](/docs/cli/output-scopes)。 + +## `frontMatter` + +当前公开字段只有一个: + +```json +{ + "frontMatter": { + "blankLineAfter": true + } +} +``` + +详细区分见 [Front Matter](/docs/cli/frontmatter)。 + +## `cleanupProtection` + +每条规则支持: + +- `path` +- `protectionMode`: `direct` / `recursive` +- `matcher`: `path` / `glob` +- `reason` + +详细语义见 [清理保护](/docs/cli/cleanup-protection)。 diff --git a/doc/content/cli/supported-outputs.mdx b/doc/content/cli/supported-outputs.mdx new file mode 100644 index 00000000..f94b7b3c --- /dev/null +++ b/doc/content/cli/supported-outputs.mdx @@ -0,0 +1,39 @@ +--- +title: 支持的输出目标 +description: 按当前默认 plugin.config.ts 汇总 memory-sync 已接入的输出目标。 +sidebarTitle: 支持的输出目标 +status: stable +--- + +# 支持的输出目标 + +当前默认插件配置说明,项目已经接入的输出目标至少包括: + +## AI / IDE / CLI 目标 + +- AGENTS.md 风格输出 +- Claude Code CLI +- OpenAI Codex CLI +- Gemini CLI +- Droid CLI +- Opencode CLI +- Cursor +- Windsurf +- Warp +- Qoder +- Trae +- Trae CN +- JetBrains AI Assistant Codex + +## 通用辅助输出 + +- Generic Skills 导出 +- `.git/info/exclude` +- `.editorconfig` +- VS Code 配置 +- JetBrains code style 配置 +- README 类输出 + +## 一件要特别记住的事 + +README 里的 “Supported Tools” 表是面向用户的高层描述;真正影响默认同步行为的,是 [plugin.config.ts](/docs/cli/plugin-config) 里装配了哪些插件。两者冲突时,以后者为准。 diff --git a/doc/content/cli/troubleshooting.mdx b/doc/content/cli/troubleshooting.mdx new file mode 100644 index 00000000..268f12c5 --- /dev/null +++ b/doc/content/cli/troubleshooting.mdx @@ -0,0 +1,43 @@ +--- +title: 排障 +description: 整理当前最可能遇到的版本、命令与输出范围问题。 +sidebarTitle: 排障 +status: stable +--- + +# 排障 + +## 现象:我以为有某个页面,结果 404 + +新文档已经从旧的混合分组改成五个一级门类。优先从 [/docs](/docs) 或 [CLI](/docs/cli) 开始找,而不是沿用旧路径。 + +## 现象:`tnmsc init` 没帮我生成任何内容 + +这是当前实现预期行为。它已经废弃,不再初始化 aindex。请改为手动维护你的源目录和全局配置。 + +## 现象:规则、Prompt 或 MCP 相关内容输出到了不该出现的地方 + +先检查: + +1. [plugin.config.ts](/docs/cli/plugin-config) 中到底装了哪些输出插件。 +2. [输出范围](/docs/cli/output-scopes) 有没有按 topic 限制范围。 +3. 你写的是 global 还是 workspace 源。 + +## 现象:`clean` 不敢执行或执行后删过头 + +先回看 [清理保护](/docs/cli/cleanup-protection)。如果目录里混有人工文件,却没配置保护规则,`clean` 风险就会明显升高。 + +## 现象:文档页构建失败 + +先跑: + +```sh +pnpm -C doc run validate:content +``` + +这套校验会先检查: + +- 每个 MDX 是否有 `title` / `description` +- 每个内容目录是否有 `_meta.ts` +- `_meta.ts` 是否覆盖当前文件与子目录 +- 文档内部链接是否指向存在的页面 diff --git a/doc/content/cli/upgrade-notes.mdx b/doc/content/cli/upgrade-notes.mdx new file mode 100644 index 00000000..2e886827 --- /dev/null +++ b/doc/content/cli/upgrade-notes.mdx @@ -0,0 +1,30 @@ +--- +title: 升级说明 +description: 汇总当前文档结构、命令认知与运行边界中最需要注意的升级点。 +sidebarTitle: 升级说明 +status: stable +--- + +# 升级说明 + +## 文档结构升级 + +文档站已经从“快速上手 / 概念 / 内容编写 / 参考 / 运维”的混合结构,重排为: + +- `CLI` +- `MCP` +- `GUI` +- `技术细节` +- `设计初衷` + +如果你在维护页面或补文档,请先按这五类放置目录,再开始写内容。 + +## 命令认知升级 + +- `tnmsc init` 不再是初始化入口 +- `dry-run` 应作为默认验证动作 +- `clean --dry-run` 应作为默认清理前检查 + +## 运行边界升级 + +仓库的长期方向仍然是 Rust-first / NAPI-first。TypeScript 在这里更偏接口暴露、配置装配、桥接运行时和声明层,而不是长期核心实现中心。 diff --git a/doc/content/cli/workspace-setup.mdx b/doc/content/cli/workspace-setup.mdx new file mode 100644 index 00000000..b598858d --- /dev/null +++ b/doc/content/cli/workspace-setup.mdx @@ -0,0 +1,39 @@ +--- +title: 工作区与 aindex +description: 说明 aindex 源目录、全局配置与项目配置入口在当前仓库中的职责分工。 +sidebarTitle: 工作区与 aindex +status: stable +--- + +# 工作区与 aindex + +## 先记住这件事 + +`memory-sync` 不是把目标工具配置文件当真源维护,而是围绕 aindex 源目录与项目配置入口来生成目标输出。 + +## 你至少需要准备什么 + +- 一个工作区根目录 +- aindex 风格的源内容目录 +- 全局配置文件 +- 项目级 `plugin.config.ts` + +## 源内容通常怎么分 + +当前文档里单独拆出的输入资产包括: + +- 全局 Prompt 与工作区 Prompt +- `skills/` +- `commands/` +- `subagents/` +- `rules/` + +这些输入资产的职责说明在 [技术细节](/docs/technical-details) 里统一解释,而 CLI 侧只负责告诉你它们会被怎样读取、校验和写出。 + +## 项目配置入口 + +项目级装配入口是 [plugin.config.ts](/docs/cli/plugin-config)。它决定默认装配哪些输出插件,以及项目级运行参数如何并入真实执行配置。 + +## 下一步 + +目录准备完后,直接进入 [第一次同步](/docs/cli/first-sync),先用 `dry-run` 验证输出范围,再做真实写入。 diff --git a/doc/content/design-rationale/_meta.ts b/doc/content/design-rationale/_meta.ts new file mode 100644 index 00000000..a100bf3b --- /dev/null +++ b/doc/content/design-rationale/_meta.ts @@ -0,0 +1,4 @@ +export default { + index: '概览', + manifesto: '为什么要做这个工具' +} diff --git a/doc/content/design-rationale/index.mdx b/doc/content/design-rationale/index.mdx new file mode 100644 index 00000000..bde1fa7d --- /dev/null +++ b/doc/content/design-rationale/index.mdx @@ -0,0 +1,21 @@ +--- +title: 设计初衷 +description: 单独收纳项目动机、设计理由与 manifesto 类内容,避免与使用说明和实现细节混写。 +sidebarTitle: 概览 +status: stable +--- + +# 设计初衷 + +这一节只处理“为什么这样做”,不承担安装、命令、Schema 或页面工作流说明。 + +## 为什么要单独分出来 + +因为背景叙事一旦和操作文档混在一起,会同时伤害两件事: + +- 用户很难快速进入最短使用路径 +- 维护者很容易把理念页写进功能页,导致 IA 再次失焦 + +## 当前入口 + +- [为什么要做这个工具](/docs/design-rationale/manifesto) diff --git a/doc/content/design-rationale/manifesto.mdx b/doc/content/design-rationale/manifesto.mdx new file mode 100644 index 00000000..a2939f66 --- /dev/null +++ b/doc/content/design-rationale/manifesto.mdx @@ -0,0 +1,41 @@ +--- +title: 为什么要做这个工具 +description: 从 README 的 tool-rat 叙事出发,解释 memory-sync 试图解决的真实问题。 +sidebarTitle: 为什么要做这个工具 +status: stable +--- + +# 为什么要做这个工具 + +README 对 `memory-sync` 的核心定位写得很直接:这不是一个等待平台统一标准的工具,而是一个默认世界碎片化、接口私有化、资源分配极不公平时仍然能工作的 “tool-rat”。 + +## 项目不是在卖什么 + +它不承诺: + +- 某个 IDE 或 CLI 最终会给你一套官方统一入口。 +- 某家平台会长久稳定地保存你的工作记忆。 +- 复制粘贴几份提示词就等于真正完成了迁移。 + +## 项目真正要做的事 + +它要做的是: + +1. 把你原本散落在多个工具里的规则源抽离出来。 +2. 让这些规则源有统一的编写方式。 +3. 再把它们重新投送回不同工具的原生落点。 + +## 为什么这件事必须是“同步系统”,不是“模板仓库” + +仅有模板仓库,你依旧要手动: + +- 决定每个工具写到哪里 +- 决定哪些内容是全局的、哪些是项目级的 +- 决定怎样清掉旧产物 +- 决定如何避免多套配置互相踩踏 + +而 `memory-sync` 的重点,是把这些判断前移到可声明的配置与源文件结构里。 + +## 所以文档为什么也要重写 + +如果文档还沿用旧的、松散的、不能映射到真实实现的叙述方式,那它本身就会变成新的“残留物”。这次重构的文档站,本质上也是把 docs 自己纳入“可验证输出”的同一套纪律里。 diff --git a/doc/content/gui/_meta.ts b/doc/content/gui/_meta.ts new file mode 100644 index 00000000..0fdf6aa6 --- /dev/null +++ b/doc/content/gui/_meta.ts @@ -0,0 +1,4 @@ +export default { + 'index': '概览', + 'workflows-and-pages': '页面与工作流' +} diff --git a/doc/content/gui/index.mdx b/doc/content/gui/index.mdx new file mode 100644 index 00000000..b386fe22 --- /dev/null +++ b/doc/content/gui/index.mdx @@ -0,0 +1,36 @@ +--- +title: GUI +description: 说明 Tauri 桌面层的职责、边界,以及它与 tnmsc crate / CLI 的关系。 +sidebarTitle: 概览 +status: stable +--- + +# GUI + +`gui/` 是基于 Tauri + React 的桌面调用层。它的角色不是成为系统架构中心,而是把 `tnmsc` 的配置编辑、执行、展示与日志观察做成桌面工作流。 + +## 这层负责什么 + +- 发起同步、`dry-run` 与清理 +- 编辑或展示配置 +- 浏览文件、插件结果与日志 +- 提供桌面端页面化工作流 + +## 这层不负责什么 + +- 不重新实现 sync core +- 不在前端重新推导 CLI 规则 +- 不改变 Rust-first / NAPI-first 的长期方向 + +## 版本边界 + +当前 `gui/package.json` 对开发引擎要求高于根工作区: + +- `node >= 25.2.1` +- `pnpm >= 10.28.0` +- `rust >= 1.93.1` + +## 推荐阅读 + +- [页面与工作流](/docs/gui/workflows-and-pages):查看当前导航、主要页面与桌面工作流。 +- [技术细节 / 架构边界](/docs/technical-details/architecture):理解 GUI 为什么只能是调用层而不是核心层。 diff --git a/doc/content/gui/workflows-and-pages.mdx b/doc/content/gui/workflows-and-pages.mdx new file mode 100644 index 00000000..096ae8f7 --- /dev/null +++ b/doc/content/gui/workflows-and-pages.mdx @@ -0,0 +1,38 @@ +--- +title: 页面与工作流 +description: 汇总当前 GUI 的导航入口、主要页面和与同步流程直接相关的桌面操作面。 +sidebarTitle: 页面与工作流 +status: stable +--- + +# 页面与工作流 + +## 当前主导航 + +`gui/src/components/Sidebar.tsx` 当前注册的导航项包括: + +- Dashboard +- Pipeline +- Config +- Plugins +- Files +- Logs +- Settings + +## 这些页面说明了什么 + +- Dashboard:展示统计、快速动作和受支持工具概览 +- Pipeline:执行同步、`dry-run`,并查看插件结果与错误 +- Config:查看或编辑配置入口 +- Plugins / Files / Logs:分别面向插件结果、文件视图与日志观察 +- Settings:桌面侧偏好与设置入口 + +## 和 CLI 的关系 + +桌面页面并没有单独定义一套 sync 规则。它主要通过桥接层调用底层能力,把命令式流程转成页面式工作流。 + +因此,遇到这些问题时仍然应先回到 CLI 文档: + +- 命令表面是否变了:看 [CLI 命令](/docs/cli/cli-commands) +- 输出范围是否正确:看 [输出范围](/docs/cli/output-scopes) +- 清理边界是否安全:看 [清理保护](/docs/cli/cleanup-protection) diff --git a/doc/content/index.mdx b/doc/content/index.mdx new file mode 100644 index 00000000..983db4da --- /dev/null +++ b/doc/content/index.mdx @@ -0,0 +1,38 @@ +--- +title: 文档总览 +description: memory-sync 文档入口,按 CLI、MCP、GUI、技术细节与设计初衷五个一级门类组织。 +sidebarTitle: 总览 +status: stable +keywords: + - memory-sync + - docs + - overview +--- + +# 文档总览 + +这套文档站围绕当前仓库事实组织,一级结构固定为 `CLI`、`MCP`、`GUI`、`技术细节`、`设计初衷`。这样写文档时,面向用户的操作入口、面向集成的 server、桌面层说明、实现原理和背景动机不再混在一起。 + +## 五个一级门类 + +| 门类 | 主要回答的问题 | 入口 | +| --- | --- | --- | +| CLI | 如何安装、准备工作区、执行同步、理解命令与配置字段 | [CLI](/docs/cli) | +| MCP | `memory-sync-mcp` 是什么、暴露了哪些工具、适合怎么接入 | [MCP](/docs/mcp) | +| GUI | 桌面层负责什么、有哪些页面、它与 `tnmsc` crate / CLI 如何配合 | [GUI](/docs/gui) | +| 技术细节 | 架构边界、同步管线、真源模型,以及 prompts / skills / commands / rules 等输入资产如何组织 | [技术细节](/docs/technical-details) | +| 设计初衷 | 为什么要做这个项目,为什么文档也要这样分层 | [设计初衷](/docs/design-rationale) | + +## 从哪里开始 + +- 第一次使用 `memory-sync`,从 [CLI](/docs/cli) 开始,先把安装、工作区准备和第一次同步跑通。 +- 需要把 `memory-sync-mcp` 接入到支持 MCP 的宿主里,直接进 [MCP](/docs/mcp)。 +- 关注桌面应用而不是终端入口时,查看 [GUI](/docs/gui)。 +- 需要理解 Rust-first / NAPI-first、真源模型和输入资产职责时,进入 [技术细节](/docs/technical-details)。 +- 需要项目背景、动机和设计理由时,再补读 [设计初衷](/docs/design-rationale)。 + +## 文档边界 + +- 文档以仓库当前可验证实现为准,不把未落地的自动化、页面或工作流写成既成事实。 +- 当前公开文档以中文为权威版本;命令、API 名称和关键术语保持英文。 +- 如果 README、旧页面和当前实现冲突,这里优先跟随 `tnmsc --help`、Schema、目录结构和实际代码。 diff --git a/doc/content/mcp/_meta.ts b/doc/content/mcp/_meta.ts new file mode 100644 index 00000000..b54b703e --- /dev/null +++ b/doc/content/mcp/_meta.ts @@ -0,0 +1,4 @@ +export default { + 'index': '概览', + 'server-tools': 'Server 与 Tools' +} diff --git a/doc/content/mcp/index.mdx b/doc/content/mcp/index.mdx new file mode 100644 index 00000000..57678e13 --- /dev/null +++ b/doc/content/mcp/index.mdx @@ -0,0 +1,28 @@ +--- +title: MCP +description: 说明 memory-sync-mcp 的定位、运行方式,以及它与 CLI prompt service 的关系。 +sidebarTitle: 概览 +status: stable +--- + +# MCP + +`mcp/` 是当前仓库里的独立包,发布名为 `@truenine/memory-sync-mcp`,可执行入口是 `memory-sync-mcp`。它不是文档里的抽象概念,而是一个真实存在的 stdio server。 + +## 它负责什么 + +- 作为 MCP stdio server 暴露 `memory-sync` 的 prompt 管理能力 +- 复用 `@truenine/memory-sync-cli` 导出的 prompt service,而不是重新实现一套独立逻辑 +- 让支持 MCP 的宿主按工具调用方式读取、更新和写回 prompt 资产 + +## 它不负责什么 + +- 它不是新的真源格式 +- 它不是 GUI 的替代品 +- 它不是绕过 CLI 规则的“特权入口” + +## 推荐阅读 + +- [Server 与 Tools](/docs/mcp/server-tools):查看 stdio server 的入口、工具清单与 `workspaceDir` 语义。 +- [CLI](/docs/cli):需要了解工作区准备、Schema 与输出边界时,仍然回到 CLI 侧核对事实。 +- [技术细节](/docs/technical-details/source-of-truth):需要理解 prompt 资产为什么这样建模时,从真源模型开始。 diff --git a/doc/content/mcp/server-tools.mdx b/doc/content/mcp/server-tools.mdx new file mode 100644 index 00000000..b670cadf --- /dev/null +++ b/doc/content/mcp/server-tools.mdx @@ -0,0 +1,47 @@ +--- +title: Server 与 Tools +description: 说明 memory-sync-mcp 的 stdio server 入口、四个已暴露工具,以及 workspaceDir 的作用。 +sidebarTitle: Server 与 Tools +status: stable +--- + +# Server 与 Tools + +## 公开入口 + +`mcp/src/index.ts` 当前只公开两个入口: + +- `createMemorySyncMcpServer` +- `runMemorySyncMcpStdioServer` + +这说明这个包的职责非常明确,就是提供 server 构造与 stdio 运行入口。 + +## 当前已暴露的工具 + +`mcp/src/server.ts` 当前注册的工具包括: + +- `list_prompts` +- `get_prompt` +- `upsert_prompt_src` +- `apply_prompt_translation` + +## 每个工具大致负责什么 + +| 工具 | 职责 | +| --- | --- | +| `list_prompts` | 列出受管 prompt 记录及 zh/en/dist 状态 | +| `get_prompt` | 读取单个 prompt 的 source 与 dist 产物 | +| `upsert_prompt_src` | 更新 zh 或 en 源文件,不直接碰 dist | +| `apply_prompt_translation` | 写入外部生成的 en 或 dist 内容 | + +## `workspaceDir` 的作用 + +这些工具都接受可选的 `workspaceDir`。它的语义不是“随便切目录”,而是把 prompt service 的工作区根显式绑定到某个项目上下文。 + +如果不传,server 会按默认当前工作目录解释;如果传入,则会同时进入 `cwd` 与 `pluginOptions.workspaceDir`。 + +## 使用边界 + +- 先保证 CLI 侧的工作区结构是正确的,再接入 MCP +- MCP 只暴露当前已有的 prompt 管理行为,不替你发明新的 Schema +- 需要确认 prompt 类型与真源职责时,回看 [技术细节](/docs/technical-details) diff --git a/doc/content/technical-details/_meta.ts b/doc/content/technical-details/_meta.ts new file mode 100644 index 00000000..768826ee --- /dev/null +++ b/doc/content/technical-details/_meta.ts @@ -0,0 +1,12 @@ +export default { + 'index': '概览', + 'architecture': '架构边界', + 'pipeline': '同步管线', + 'source-of-truth': '单一真源模型', + 'global-and-workspace-prompts': '全局与工作区 Prompt', + 'skills': 'Skills', + 'commands': 'Commands', + 'subagents': 'Sub-agents', + 'rules': 'Rules', + 'libraries': 'Libraries' +} diff --git a/doc/content/technical-details/architecture.mdx b/doc/content/technical-details/architecture.mdx new file mode 100644 index 00000000..124326a3 --- /dev/null +++ b/doc/content/technical-details/architecture.mdx @@ -0,0 +1,31 @@ +--- +title: 架构边界 +description: 说明 tnmsc、crate、npm 包、MCP 与 GUI 之间的职责边界。 +sidebarTitle: 架构边界 +status: stable +--- + +# 架构边界 + +当前仓库的核心方向不是“继续堆更多纯 TypeScript 兼容层”,而是: + +- `cli/` 作为公开入口与编排层 +- Rust crate / NAPI 作为长期核心实现重心 +- TypeScript 主要负责接口暴露、配置装配、桥接运行时与声明描述 + +## 组件分工 + +| 组件 | 职责 | +| --- | --- | +| `cli/` | `tnmsc` 命令入口、crate 暴露、npm 包暴露 | +| `mcp/` | MCP stdio server,复用 CLI prompt service | +| `gui/` | Tauri 桌面调用层与展示层 | +| `libraries/` | Rust-first / NAPI-first 基础库 | + +## 关键边界 + +- GUI 不是核心实现中心 +- MCP 不是新的真源模型 +- 文档站不是架构真相的唯一来源 + +如果你需要看用户操作面,回到 [CLI](/docs/cli) 或 [GUI](/docs/gui);这里只说明实现分层为什么这样划。 diff --git a/doc/content/technical-details/commands.mdx b/doc/content/technical-details/commands.mdx new file mode 100644 index 00000000..b87418df --- /dev/null +++ b/doc/content/technical-details/commands.mdx @@ -0,0 +1,43 @@ +--- +title: Commands +description: 介绍 commands 的职责,以及它们与 commandSeriesOptions 的关系。 +sidebarTitle: Commands +status: stable +--- + +# Commands + +## Commands 适合什么 + +Commands 适合那些: + +- 会高频复用 +- 执行目标清晰 +- 适合短文本触发 + +的操作入口。 + +典型例子包括“生成发布说明”“复查某类错误”“按某个格式整理上下文”等。 + +## 当前路径约定 + +默认输入路径: + +```text +commands/ +``` + +默认输出路径: + +```text +dist/commands/ +``` + +## `commandSeriesOptions` 是干什么的 + +Schema 里 `commandSeriesOptions` 允许你: + +- 设置 `includeSeriesPrefix` +- 按插件覆盖 `includeSeriesPrefix` 或 `seriesSeparator` + +这说明 commands 不只是平铺输出,还能带有“系列化”命名规则。你可以把它理解成对同一命令簇的分组与命名控制,而不是单一文件名规则。 diff --git a/doc/content/technical-details/global-and-workspace-prompts.mdx b/doc/content/technical-details/global-and-workspace-prompts.mdx new file mode 100644 index 00000000..06129b99 --- /dev/null +++ b/doc/content/technical-details/global-and-workspace-prompts.mdx @@ -0,0 +1,46 @@ +--- +title: 全局与工作区 Prompt +description: 说明 globalPrompt 与 workspacePrompt 的路径职责和适用范围。 +sidebarTitle: 全局与工作区 Prompt +status: stable +--- + +# 全局与工作区 Prompt + +## 默认路径 + +当前默认配置中,这两份源文件分别是: + +```text +app/global.src.mdx +app/workspace.src.mdx +``` + +输出目标默认是: + +```text +dist/global.mdx +dist/workspace.mdx +``` + +## 它们的区别 + +- `globalPrompt` 面向跨项目长期记忆,适合个人工作风格、稳定偏好与跨仓库通用约束。 +- `workspacePrompt` 面向当前项目上下文,适合项目规则、架构限制、技术栈边界与交付约束。 + +## 什么时候不要把内容写进 global + +如果内容明显依赖某个仓库的: + +- 目录结构 +- 业务词汇 +- 交付边界 +- 团队约束 + +那就不该放到 `globalPrompt`。否则你只是把项目噪音扩散到了所有未来目标。 + +## 编写原则 + +1. 能放 workspace 的,不要抢着放 global。 +2. 不要把目标工具特有路径和格式硬编码进真源。 +3. 如果某段内容本质上更像可复用卡片,应优先考虑抽成 skill 或 rule,而不是继续把 Prompt 膨胀成一整面墙。 diff --git a/doc/content/technical-details/index.mdx b/doc/content/technical-details/index.mdx new file mode 100644 index 00000000..ac8978c3 --- /dev/null +++ b/doc/content/technical-details/index.mdx @@ -0,0 +1,29 @@ +--- +title: 技术细节 +description: 集中说明架构边界、同步管线、真源模型与各类输入资产的实现职责。 +sidebarTitle: 概览 +status: stable +--- + +# 技术细节 + +这一节不讲“第一次怎么用”,而是讲当前实现为什么这样分层,以及 prompts、skills、commands、sub-agents、rules 这些输入资产在系统里分别扮演什么角色。 + +## 这一节回答什么问题 + +1. 哪些东西是真源,哪些只是派生输出。 +2. 为什么仓库明确转向 Rust-first / NAPI-first。 +3. 同步为什么必须显式建模写入目标、输出范围和清理边界。 +4. 各类输入资产为什么不能混写成一坨大 Prompt。 + +## 推荐阅读 + +- [架构边界](/docs/technical-details/architecture) +- [单一真源模型](/docs/technical-details/source-of-truth) +- [同步管线](/docs/technical-details/pipeline) +- [全局与工作区 Prompt](/docs/technical-details/global-and-workspace-prompts) +- [Skills](/docs/technical-details/skills) +- [Commands](/docs/technical-details/commands) +- [Sub-agents](/docs/technical-details/subagents) +- [Rules](/docs/technical-details/rules) +- [Libraries](/docs/technical-details/libraries) diff --git a/doc/content/technical-details/libraries.mdx b/doc/content/technical-details/libraries.mdx new file mode 100644 index 00000000..c1669119 --- /dev/null +++ b/doc/content/technical-details/libraries.mdx @@ -0,0 +1,26 @@ +--- +title: Libraries +description: 汇总当前 libraries/ 中几个 Rust-first / NAPI-first 基础库的职责与暴露形态。 +sidebarTitle: Libraries +status: stable +--- + +# Libraries + +`libraries/` 是 Rust-first / NAPI-first 的基础库目录。当前可见的重点库包括: + +- `logger` +- `md-compiler` +- `script-runtime` + +## 各自的大致职责 + +| 库 | 作用 | +| --- | --- | +| `logger` | 日志能力,既有 Rust 实现,也有 TypeScript-facing 接口与 NAPI 产物 | +| `md-compiler` | MDX / Markdown 相关编译与转换能力 | +| `script-runtime` | 脚本运行时相关基础能力,供上层装配使用 | + +## 为什么它们值得单列 + +这些库不是“文档补充材料”,而是仓库长期把核心能力下沉为基础设施的证据。CLI、MCP 和 GUI 都应复用它们,而不是在各自目录里复制一套逻辑。 diff --git a/doc/content/technical-details/pipeline.mdx b/doc/content/technical-details/pipeline.mdx new file mode 100644 index 00000000..8bb2cb8d --- /dev/null +++ b/doc/content/technical-details/pipeline.mdx @@ -0,0 +1,33 @@ +--- +title: 同步管线 +description: 说明插件如何声明目标文件、生成流程、输出范围与清理行为。 +sidebarTitle: 同步管线 +status: stable +--- + +# 同步管线 + +同步不是“把几份 Prompt 文本复制到几个目录里”,而是由插件声明目标文件、输出主题、清理范围与写入方式的管线。 + +## 管线最少包含什么 + +- 读取真源输入资产 +- 合并工作区与全局配置 +- 按插件决定输出目标 +- 应用 `outputScopes` 约束 +- 写入目标文件 +- 在需要时执行清理 + +## 为什么这件事必须显式建模 + +如果不显式建模: + +- 你无法知道哪些内容该写到全局,哪些只该写到项目级 +- 你无法在 `clean` 时给出可靠的删除边界 +- 你很容易把目标工具的偶然格式要求反向污染真源 + +## 相关入口 + +- 配置字段行为:看 [CLI / JSON Schema](/docs/cli/schema) +- 输出范围控制:看 [CLI / 输出范围](/docs/cli/output-scopes) +- 真源与派生关系:看 [单一真源模型](/docs/technical-details/source-of-truth) diff --git a/doc/content/technical-details/rules.mdx b/doc/content/technical-details/rules.mdx new file mode 100644 index 00000000..9eed9cc7 --- /dev/null +++ b/doc/content/technical-details/rules.mdx @@ -0,0 +1,39 @@ +--- +title: Rules +description: 说明 rules 在项目级与全局级之间的作用,以及它们为何适合做持续约束。 +sidebarTitle: Rules +status: stable +--- + +# Rules + +## Rules 适合放什么 + +Rules 更适合表达持续性约束,例如: + +- 目录职责 +- 架构边界 +- 代码风格红线 +- 审查与交付纪律 + +它们比 command 更稳定,比 skill 更偏约束而非能力。 + +## 当前路径约定 + +默认输入路径: + +```text +rules/ +``` + +默认输出路径: + +```text +dist/rules/ +``` + +## Rules 和 output scopes 的关系 + +Schema 允许你对 `rules` 单独设置 `project` 或 `global` 输出范围,这一点很关键。因为某些工具需要全局规则,而另一些规则只应留在当前项目。 + +如果你发现规则被写到了不该出现的地方,不要先怀疑 rule 文件本身,先看 [CLI / 输出范围](/docs/cli/output-scopes)。 diff --git a/doc/content/technical-details/skills.mdx b/doc/content/technical-details/skills.mdx new file mode 100644 index 00000000..d8b8c1f7 --- /dev/null +++ b/doc/content/technical-details/skills.mdx @@ -0,0 +1,44 @@ +--- +title: Skills +description: 介绍 skills 作为可复用能力卡片的定位,以及它们与输出插件之间的关系。 +sidebarTitle: Skills +status: stable +--- + +# Skills + +## Skills 是什么 + +Skills 是按任务主题切分的可复用能力卡片。它们适合表达: + +- 某类交付物的写法 +- 某种架构决策的方法 +- 某个操作流程的步骤化知识 + +## 当前路径约定 + +默认输入路径是: + +```text +skills/ +``` + +默认导出路径是: + +```text +dist/skills/ +``` + +## 为什么它们和 Prompt 不一样 + +Prompt 更像持续上下文,Skills 更像按需调用的模块。两者都能影响模型行为,但不是一个抽象层。 + +## 输出层会关心什么 + +`tnmsc` 现在默认把 skill 目录名当作 skill name。 + +- 不需要在 skill frontmatter 里写 `name` +- 如果写了 `name`,同步时会忽略并给出告警 +- 想修改 skill name,直接修改 `skills//` 的目录名 + +详细字段说明见 [CLI / Front Matter](/docs/cli/frontmatter)。 diff --git a/doc/content/technical-details/source-of-truth.mdx b/doc/content/technical-details/source-of-truth.mdx new file mode 100644 index 00000000..887ed24b --- /dev/null +++ b/doc/content/technical-details/source-of-truth.mdx @@ -0,0 +1,34 @@ +--- +title: 单一真源模型 +description: 解释 .src.mdx、源目录与目标工具产物之间的关系,以及为什么输出文件不应被当作真源维护。 +sidebarTitle: 单一真源模型 +status: stable +--- + +# 单一真源模型 + +`memory-sync` 的关键前提是:真源应该是你维护的输入资产,而不是目标工具最终读到的派生文件。 + +## 哪些通常是真源 + +- 全局 Prompt +- 工作区 Prompt +- `skills/` +- `commands/` +- `subagents/` +- `rules/` + +## 哪些通常不是 + +- 各种工具原生配置落点 +- 导出的 dist 内容 +- 桌面层展示状态 +- MCP 返回的读取结果 + +## 为什么不能把输出文件当真源 + +因为输出文件会天然带上目标工具的路径、命名、格式和能力限制。一旦把它们当真源,迁移成本和清理复杂度都会急剧上升。 + +## 实操含义 + +需要调整行为时,优先改真源和配置,而不是去目标工具目录里热修一份派生文件。 diff --git a/doc/content/technical-details/subagents.mdx b/doc/content/technical-details/subagents.mdx new file mode 100644 index 00000000..ea651be3 --- /dev/null +++ b/doc/content/technical-details/subagents.mdx @@ -0,0 +1,45 @@ +--- +title: Sub-agents +description: 说明 sub-agents 在 memory-sync 中的输入定位以及命名约束。 +sidebarTitle: Sub-agents +status: stable +--- + +# Sub-agents + +## Sub-agents 的角色 + +Sub-agents 用于把复杂任务拆成更专门的角色和边界。它们不是普通 Prompt 复制品,而是更接近“受约束的专职执行单元”。 + +## 当前路径约定 + +默认输入路径: + +```text +subagents/ +``` + +默认输出路径: + +```text +dist/subagents/ +``` + +## 命名为什么重要 + +`tnmsc` 现在默认从 sub-agent 的相对路径推导名称: + +- `subagents/reviewer.src.mdx` -> `reviewer` +- `subagents/qa/boot.src.mdx` -> `qa-boot` + +因此: + +- 不需要在 frontmatter 里写 `name` +- 如果写了 `name`,同步时会忽略并给出告警 +- 想修改 sub-agent name,直接修改目录名或文件名 + +## 什么时候该写成 sub-agent,而不是 skill + +- 你需要一个长期存在、职责边界明确的角色。 +- 这个角色可能需要独立描述输入、行为约束与输出形式。 +- 它不仅是“做一件事的方法”,而是“承担一类工作的代理配置”。 diff --git a/doc/eslint.config.ts b/doc/eslint.config.ts index ffb0d674..70de782b 100644 --- a/doc/eslint.config.ts +++ b/doc/eslint.config.ts @@ -18,6 +18,7 @@ const config = eslint10({ ignores: [ '.turbo/**', '.next/**', + 'public/_pagefind/**', 'next-env.d.ts', '*.md', '**/*.md', diff --git a/doc/lib/site.ts b/doc/lib/site.ts new file mode 100644 index 00000000..c9cb03dd --- /dev/null +++ b/doc/lib/site.ts @@ -0,0 +1,110 @@ +import process from 'node:process' + +export const siteConfig = { + productName: 'memory-sync', + shortName: 'memory-sync Docs', + title: 'memory-sync 文档', + description: + '面向多 AI 工具的 prompt、rule、skill、command 与 workspace memory sync 文档站。', + repoUrl: 'https://github.com/TrueNine/memory-sync', + docsRepositoryBase: 'https://github.com/TrueNine/memory-sync/blob/main/doc', + issueUrl: 'https://github.com/TrueNine/memory-sync/issues/new/choose' +} as const + +export function getSiteUrl(): URL { + return new URL(process.env.NEXT_PUBLIC_DOCS_SITE_URL ?? 'http://localhost:3000') +} + +export const heroProofPoints = [ + { + label: 'Architecture', + value: 'Rust-first / NAPI-first' + }, + { + label: 'Source Model', + value: 'MDX as source of truth' + }, + { + label: 'Output', + value: 'Native config materialization' + } +] as const + +export const homeEntryCards = [ + { + href: '/docs/cli', + title: 'CLI', + detail: '围绕安装、工作区准备、第一次同步、配置字段与命令表面组织。' + }, + { + href: '/docs/mcp', + title: 'MCP', + detail: '独立查看 stdio server、工具列表、workspaceDir 约束与适用边界。' + }, + { + href: '/docs/gui', + title: 'GUI', + detail: '单独查看桌面层的职责、页面结构,以及它与 tnmsc crate / CLI 的关系。' + }, + { + href: '/docs/technical-details', + title: '技术细节', + detail: '集中阅读架构边界、同步管线、真源模型与内容编写约定。' + }, + { + href: '/docs/design-rationale', + title: '设计初衷', + detail: '把项目动机、设计理由与 manifesto 类内容单独收口,不再混入使用文档。' + } +] as const + +export const capabilityCards = [ + { + label: 'Prompt Source', + title: '统一维护输入资产', + detail: + '用 `.src.mdx` 和结构化 front matter 维护 prompt、skill、command、sub-agent 与 rule。' + }, + { + label: 'Pipeline', + title: '按目标工具生成原生输出', + detail: '由插件声明写入目标、清理范围与生成策略,避免手工复制配置。' + }, + { + label: 'Protection', + title: '显式控制删除边界', + detail: '`cleanupProtection` 与 `outputScopes` 用于约束清理范围和风险边界。' + }, + { + label: 'Docs', + title: '文档只记录仓库已存在能力', + detail: '页面内容对齐当前实现、CLI 帮助、Schema 与工作流事实,不延续旧叙事。' + } +] as const + +export const readingPath = [ + { + step: '01', + href: '/docs/cli/install', + title: '确认运行前提', + description: '先核对 Node、Rust、CLI 入口与当前支持边界。' + }, + { + step: '02', + href: '/docs/cli/workspace-setup', + title: '准备工作区结构', + description: '按照 aindex 与项目配置的真实目录约定组织源文件。' + }, + { + step: '03', + href: '/docs/technical-details/source-of-truth', + title: '开始维护源内容', + description: '先建立真源模型,再区分全局 Prompt、工作区 Prompt 与其他输入资产。' + }, + { + step: '04', + href: '/docs/cli/cli-commands', + title: '执行 dry-run 与同步', + description: '在写入目标工具前先验证输出列表、范围与清理行为。' + } +] as const diff --git a/doc/mdx-components.tsx b/doc/mdx-components.tsx index b3d98bc7..720b3f5d 100644 --- a/doc/mdx-components.tsx +++ b/doc/mdx-components.tsx @@ -1,13 +1,52 @@ -import {Callout} from './app/components/Callout' -import {Step, Steps} from './app/components/Steps' +import type {ComponentPropsWithoutRef, ReactElement, ReactNode} from 'react' +import {useMDXComponents as getDocsMDXComponents} from 'nextra-theme-docs' +import {isValidElement} from 'react' +import {Mermaid} from './components/mermaid' -type MDXComponents = Record +const docsComponents = getDocsMDXComponents() +const DocsPre = docsComponents.pre as ((props: MermaidPreProps) => ReactNode) | undefined -export function useMDXComponents(components: MDXComponents): MDXComponents { +type MDXComponents = Record +type MermaidPreProps = ComponentPropsWithoutRef<'pre'> & { + 'data-filename'?: string + 'data-language'?: string +} + +function extractMermaidChart(node: ReactNode): string { + if (typeof node === 'string') { + return node + } + + if (Array.isArray(node)) { + return node.map(extractMermaidChart).join('') + } + + if (isValidElement(node)) { + return extractMermaidChart((node as ReactElement<{children?: ReactNode}>).props.children) + } + + return '' +} + +function MermaidPre(props: MermaidPreProps) { + if (props['data-language'] !== 'mermaid' || !DocsPre) { + return DocsPre ? :
    +  }
    +
    +  const chart = extractMermaidChart(props.children).trim()
    +
    +  if (!chart) {
    +    return 
    +  }
    +
    +  return 
    +}
    +
    +export function useMDXComponents(components: MDXComponents = {}): MDXComponents {
       return {
    -    Callout,
    -    Steps,
    -    Step,
    +    ...docsComponents,
    +    Mermaid,
    +    pre: MermaidPre,
         ...components
       }
     }
    diff --git a/doc/mdx.d.ts b/doc/mdx.d.ts
    new file mode 100644
    index 00000000..d29a9e65
    --- /dev/null
    +++ b/doc/mdx.d.ts
    @@ -0,0 +1,7 @@
    +declare module '*.mdx' {
    +  import type {ComponentType} from 'react'
    +
    +  const MDXComponent: ComponentType>
    +
    +  export default MDXComponent
    +}
    diff --git a/doc/next.config.mjs b/doc/next.config.mjs
    deleted file mode 100644
    index ebda8e28..00000000
    --- a/doc/next.config.mjs
    +++ /dev/null
    @@ -1,14 +0,0 @@
    -import createMDX from '@next/mdx'
    -
    -/** @type {import('next').NextConfig} */
    -const baseConfig = {
    -  reactStrictMode: true,
    -  experimental: {
    -    mdxRs: true
    -  },
    -  pageExtensions: ['tsx', 'ts', 'mdx']
    -}
    -
    -const withMDX = createMDX({})
    -
    -export default withMDX(baseConfig)
    diff --git a/doc/next.config.ts b/doc/next.config.ts
    new file mode 100644
    index 00000000..c87a0582
    --- /dev/null
    +++ b/doc/next.config.ts
    @@ -0,0 +1,95 @@
    +import type {NextConfig} from 'next'
    +import {fileURLToPath} from 'node:url'
    +import nextra from 'nextra'
    +
    +const mermaidTurbopackAlias = './components/mermaid'
    +const mermaidWebpackAlias = fileURLToPath(new URL('./components/mermaid.tsx', import.meta.url))
    +
    +interface WebpackResolveAliasEntry {
    +  readonly alias: string
    +  readonly name: string
    +  readonly onlyModule: boolean
    +  readonly target: string
    +}
    +
    +interface WebpackResolveConfig {
    +  alias?: Record | WebpackResolveAliasEntry[]
    +}
    +
    +interface WebpackConfig {
    +  resolve?: WebpackResolveConfig
    +}
    +
    +const withNextra = nextra({
    +  search: {
    +    codeblocks: false
    +  },
    +  contentDirBasePath: '/docs'
    +})
    +
    +const LEGACY_DOC_REDIRECTS = [
    +  {
    +    source: '/docs/quick-start/:path*',
    +    destination: '/docs/cli/:path*'
    +  },
    +  {
    +    source: '/docs/reference/:path*',
    +    destination: '/docs/cli/:path*'
    +  },
    +  {
    +    source: '/docs/operations/:path*',
    +    destination: '/docs/cli/:path*'
    +  },
    +  {
    +    source: '/docs/authoring/:path*',
    +    destination: '/docs/technical-details/:path*'
    +  },
    +  {
    +    source: '/docs/concepts/manifesto',
    +    destination: '/docs/design-rationale/manifesto'
    +  },
    +  {
    +    source: '/docs/concepts/:path*',
    +    destination: '/docs/technical-details/:path*'
    +  }
    +] as const
    +
    +const nextConfig: NextConfig = {
    +  reactStrictMode: true,
    +  pageExtensions: ['tsx', 'ts', 'mdx'],
    +  async redirects() {
    +    return LEGACY_DOC_REDIRECTS.map(redirect => ({
    +      ...redirect,
    +      permanent: true
    +    }))
    +  },
    +  turbopack: {
    +    resolveAlias: {
    +      '@theguild/remark-mermaid/mermaid': mermaidTurbopackAlias
    +    }
    +  },
    +  webpack(config: WebpackConfig) {
    +    const resolve = config.resolve ?? {}
    +    const {alias} = resolve
    +
    +    config.resolve = resolve
    +
    +    if (Array.isArray(alias)) {
    +      alias.push({
    +        alias: '@theguild/remark-mermaid/mermaid',
    +        name: '@theguild/remark-mermaid/mermaid',
    +        onlyModule: false,
    +        target: mermaidWebpackAlias
    +      })
    +    } else {
    +      resolve.alias = {
    +        ...alias,
    +        '@theguild/remark-mermaid/mermaid': mermaidWebpackAlias
    +      }
    +    }
    +
    +    return config
    +  }
    +}
    +
    +export default withNextra(nextConfig)
    diff --git a/doc/package.json b/doc/package.json
    index 15b0668c..d2eff9f4 100644
    --- a/doc/package.json
    +++ b/doc/package.json
    @@ -1,26 +1,41 @@
     {
       "name": "@truenine/memory-sync-docs",
    -  "version": "2026.10319.10359",
    +  "version": "2026.10322.104",
       "private": true,
    -  "description": "Documentation site for @truenine/memory-sync, built with Next.js 16 and MDX.",
    +  "description": "Chinese-first manifesto-led documentation site for @truenine/memory-sync.",
       "engines": {
    -    "node": ">=20.9.0"
    +    "node": ">=22"
       },
       "scripts": {
         "dev": "next dev",
    -    "build": "next build",
    +    "build": "pnpm run validate:content && next build --webpack",
    +    "postbuild": "pagefind --site .next/server/app --output-path public/_pagefind",
    +    "check": "run-p lint typecheck",
    +    "validate:content": "tsx scripts/validate-content.ts",
    +    "typecheck": "next typegen && tsc --noEmit --incremental false",
         "start": "next start",
    -    "lint": "eslint ."
    +    "lint": "pnpm run validate:content && eslint ."
    +  },
    +  "dependencies": {
    +    "@theguild/remark-mermaid": "catalog:",
    +    "mermaid": "catalog:",
    +    "next": "catalog:",
    +    "nextra": "catalog:",
    +    "nextra-theme-docs": "catalog:",
    +    "react": "catalog:",
    +    "react-dom": "catalog:"
       },
       "devDependencies": {
    -    "@mdx-js/react": "catalog:",
    -    "@next/mdx": "catalog:",
         "@truenine/eslint10-config": "catalog:",
    +    "@types/node": "catalog:",
         "@types/react": "catalog:",
         "@types/react-dom": "catalog:",
         "eslint": "catalog:",
    -    "next": "catalog:",
    -    "react": "catalog:",
    -    "react-dom": "catalog:"
    +    "fast-glob": "catalog:",
    +    "npm-run-all2": "catalog:",
    +    "pagefind": "catalog:",
    +    "tsx": "catalog:",
    +    "typescript": "catalog:",
    +    "yaml": "catalog:"
       }
     }
    diff --git a/doc/scripts/validate-content.ts b/doc/scripts/validate-content.ts
    new file mode 100644
    index 00000000..3ec4b406
    --- /dev/null
    +++ b/doc/scripts/validate-content.ts
    @@ -0,0 +1,207 @@
    +import {readdir, readFile} from 'node:fs/promises'
    +import path from 'node:path'
    +import process from 'node:process'
    +import {pathToFileURL} from 'node:url'
    +import YAML from 'yaml'
    +
    +const cwd = process.cwd()
    +const contentDir = path.join(cwd, 'content')
    +const MDX_EXTENSION = '.mdx'
    +const YAML_FRONT_MATTER_PATTERN = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/u
    +const TRAILING_SLASHES_PATTERN = /\/+$/u
    +const MARKDOWN_LINK_PATTERN = /\[[^\]]+\]\(([^)]+)\)/gu
    +const ATTRIBUTE_LINK_PATTERN = /\bhref=["']([^"']+)["']/gu
    +const META_FILE_PATTERN = /^_meta\.(?:ts|tsx|js|mjs)$/u
    +const REQUIRED_FIELDS = ['title', 'description'] as const
    +
    +type MetaRecord = Record
    +
    +interface CollectedFiles {
    +  readonly mdxFiles: string[]
    +  readonly metaFiles: string[]
    +}
    +
    +function fail(errors: string[]): never {
    +  const report = errors.map(error => `- ${error}`).join('\n')
    +  throw new Error(`Content validation failed:\n${report}`)
    +}
    +
    +function isRecord(value: unknown): value is Record {
    +  return value != null && typeof value === 'object' && !Array.isArray(value)
    +}
    +
    +async function collectContentFiles(directory: string): Promise {
    +  const entries = await readdir(directory, {withFileTypes: true})
    +  const collected: CollectedFiles = {mdxFiles: [], metaFiles: []}
    +
    +  for (const entry of entries) {
    +    const fullPath = path.join(directory, entry.name)
    +
    +    if (entry.isDirectory()) {
    +      const nested = await collectContentFiles(fullPath)
    +      collected.mdxFiles.push(...nested.mdxFiles)
    +      collected.metaFiles.push(...nested.metaFiles)
    +      continue
    +    }
    +
    +    if (entry.isFile() && entry.name.endsWith(MDX_EXTENSION)) {
    +      collected.mdxFiles.push(fullPath)
    +      continue
    +    }
    +
    +    if (entry.isFile() && META_FILE_PATTERN.test(entry.name)) {
    +      collected.metaFiles.push(fullPath)
    +    }
    +  }
    +
    +  return collected
    +}
    +
    +function routeFromRelativePath(relativePath: string): string {
    +  const normalized = relativePath.replaceAll('\\', '/')
    +  const routePath = normalized.endsWith(MDX_EXTENSION)
    +    ? normalized.slice(0, -MDX_EXTENSION.length)
    +    : normalized
    +
    +  if (routePath === 'index') return '/docs'
    +  if (routePath.endsWith('/index')) return `/docs/${routePath.slice(0, -'/index'.length)}`
    +  return `/docs/${routePath}`
    +}
    +
    +function normalizeRoute(route: string): string {
    +  const base = route.split('#', 1)[0]?.split('?', 1)[0] ?? route
    +  return base.replace(TRAILING_SLASHES_PATTERN, '') || '/'
    +}
    +
    +function resolveLinkTarget(currentRoute: string, href: string): string | null {
    +  if (
    +    href.startsWith('http://')
    +    || href.startsWith('https://')
    +    || href.startsWith('mailto:')
    +    || href.startsWith('tel:')
    +    || href.startsWith('#')
    +  ) {
    +    return null
    +  }
    +
    +  if (href.startsWith('/')) return normalizeRoute(href)
    +
    +  const base = currentRoute.endsWith('/') ? currentRoute : `${currentRoute}/`
    +  return normalizeRoute(new URL(href, `https://memory-sync.local${base}`).pathname)
    +}
    +
    +function extractYamlFrontMatter(content: string): Record | null {
    +  const match = YAML_FRONT_MATTER_PATTERN.exec(content)
    +  if (match == null) return null
    +
    +  const parsed: unknown = YAML.parse(match[1] ?? '')
    +  return isRecord(parsed) ? parsed : null
    +}
    +
    +async function readMeta(metaPath: string): Promise {
    +  const importedModule: unknown = await import(pathToFileURL(metaPath).href)
    +  if (!isRecord(importedModule)) {
    +    throw new Error(`Meta file must export a default object: ${metaPath}`)
    +  }
    +
    +  const meta = importedModule.default
    +  if (!isRecord(meta)) {
    +    throw new Error(`Meta file must export a default object: ${metaPath}`)
    +  }
    +
    +  return meta
    +}
    +
    +function extractLinks(content: string, pattern: RegExp): string[] {
    +  return Array.from(content.matchAll(pattern), match => match[1]).filter(
    +    (href): href is string => href != null && href.length > 0
    +  )
    +}
    +
    +async function main() {
    +  const {mdxFiles, metaFiles} = await collectContentFiles(contentDir)
    +  const errors: string[] = []
    +  const validRoutes = new Set(['/', '/docs'])
    +
    +  for (const mdxFile of mdxFiles) {
    +    const relative = path.relative(contentDir, mdxFile)
    +    validRoutes.add(routeFromRelativePath(relative))
    +  }
    +
    +  for (const mdxFile of mdxFiles) {
    +    const relative = path.relative(contentDir, mdxFile)
    +    const route = routeFromRelativePath(relative)
    +    const content = await readFile(mdxFile, 'utf8')
    +    const frontMatter = extractYamlFrontMatter(content)
    +
    +    if (frontMatter == null) {
    +      errors.push(`${relative}: missing YAML frontmatter`)
    +      continue
    +    }
    +
    +    for (const field of REQUIRED_FIELDS) {
    +      const value = frontMatter[field]
    +      if (typeof value !== 'string' || value.trim().length === 0) {
    +        errors.push(`${relative}: frontmatter.${field} must be a non-empty string`)
    +      }
    +    }
    +
    +    const markdownLinks = extractLinks(content, MARKDOWN_LINK_PATTERN)
    +    const attributeLinks = extractLinks(content, ATTRIBUTE_LINK_PATTERN)
    +
    +    for (const href of [...markdownLinks, ...attributeLinks]) {
    +      const target = resolveLinkTarget(route, href)
    +      if (target == null) continue
    +      if (!validRoutes.has(target)) {
    +        errors.push(`${relative}: broken internal link -> ${href}`)
    +      }
    +    }
    +  }
    +
    +  const allDirectories = new Set(['.'])
    +  for (const file of mdxFiles) {
    +    allDirectories.add(path.relative(contentDir, path.dirname(file)) || '.')
    +  }
    +
    +  for (const metaFile of metaFiles) {
    +    allDirectories.add(path.relative(contentDir, path.dirname(metaFile)) || '.')
    +  }
    +
    +  for (const directory of allDirectories) {
    +    const metaPath = metaFiles.find(
    +      file => (path.relative(contentDir, path.dirname(file)) || '.') === directory
    +    )
    +
    +    if (metaPath == null) {
    +      errors.push(`${directory}: missing _meta file`)
    +      continue
    +    }
    +
    +    const meta = await readMeta(metaPath)
    +    const metaKeys = new Set(Object.keys(meta))
    +    const siblingFiles = mdxFiles
    +      .filter(file => (path.relative(contentDir, path.dirname(file)) || '.') === directory)
    +      .map(file => path.basename(file, MDX_EXTENSION))
    +    const childDirs = [...allDirectories]
    +      .filter(dir => path.dirname(dir) === directory && dir !== directory)
    +      .map(dir => path.basename(dir))
    +
    +    for (const expectedKey of [...siblingFiles, ...childDirs]) {
    +      if (!metaKeys.has(expectedKey)) {
    +        errors.push(`${directory}: _meta file does not declare "${expectedKey}"`)
    +      }
    +    }
    +  }
    +
    +  if (errors.length > 0) fail(errors)
    +
    +  process.stdout.write(
    +    `Validated ${mdxFiles.length} MDX files across ${allDirectories.size} content folders.\n`
    +  )
    +}
    +
    +void main().catch((error: unknown) => {
    +  const message = error instanceof Error ? error.message : String(error)
    +  process.stderr.write(`${message}\n`)
    +  process.exitCode = 1
    +})
    diff --git a/doc/tsconfig.json b/doc/tsconfig.json
    index bc17c9e0..10d890c8 100644
    --- a/doc/tsconfig.json
    +++ b/doc/tsconfig.json
    @@ -1,12 +1,12 @@
     {
       "compilerOptions": {
         "incremental": true,
    -    "target": "ES2020",
    +    "target": "ES2022",
         "jsx": "react-jsx",
         "lib": [
           "DOM",
           "DOM.Iterable",
    -      "ES2020"
    +      "ES2022"
         ],
         "module": "ESNext",
         "moduleResolution": "Bundler",
    @@ -28,9 +28,11 @@
       },
       "include": [
         "next-env.d.ts",
    +    "**/*.d.ts",
         "**/*.ts",
         "**/*.tsx",
         "**/*.mdx",
    +    "**/_meta.ts",
         ".next/types/**/*.ts",
         ".next/dev/types/**/*.ts"
       ],
    diff --git a/gui/package.json b/gui/package.json
    index 75149082..02d6bbb0 100644
    --- a/gui/package.json
    +++ b/gui/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@truenine/memory-sync-gui",
    -  "version": "2026.10319.10359",
    +  "version": "2026.10322.104",
       "private": true,
       "engines": {
         "node": ">=25.2.1",
    @@ -26,7 +26,7 @@
         "@monaco-editor/react": "catalog:",
         "@tailwindcss/vite": "catalog:",
         "@tanstack/react-router": "catalog:",
    -    "@tanstack/router-generator": "^1.164.0",
    +    "@tanstack/router-generator": "catalog:",
         "@tanstack/router-plugin": "catalog:",
         "@tauri-apps/api": "catalog:",
         "@tauri-apps/cli": "catalog:",
    @@ -39,11 +39,11 @@
         "clsx": "catalog:",
         "fast-check": "catalog:",
         "lucide-react": "catalog:",
    -    "material-icon-theme": "^5.31.0",
    +    "material-icon-theme": "catalog:",
         "monaco-editor": "catalog:",
         "react": "catalog:",
         "react-dom": "catalog:",
    -    "recharts": "^3.7.0",
    +    "recharts": "catalog:",
         "tailwindcss": "catalog:",
         "tailwind-merge": "catalog:",
         "tw-animate-css": "catalog:",
    diff --git a/gui/src-tauri/Cargo.toml b/gui/src-tauri/Cargo.toml
    index 3aa32bb1..f4b3024b 100644
    --- a/gui/src-tauri/Cargo.toml
    +++ b/gui/src-tauri/Cargo.toml
    @@ -1,6 +1,6 @@
     [package]
     name = "memory-sync-gui"
    -version = "2026.10319.10359"
    +version = "2026.10322.104"
     description = "Memory Sync desktop GUI application"
     authors.workspace = true
     edition.workspace = true
    @@ -24,4 +24,4 @@ dirs = { workspace = true }
     tnmsc = { workspace = true }
     
     [dev-dependencies]
    -proptest = "1"
    +proptest = "1.10.0"
    diff --git a/gui/src-tauri/tauri.conf.json b/gui/src-tauri/tauri.conf.json
    index a76e2b7c..a9dc683b 100644
    --- a/gui/src-tauri/tauri.conf.json
    +++ b/gui/src-tauri/tauri.conf.json
    @@ -1,6 +1,6 @@
     {
       "$schema": "https://schema.tauri.app/config/2",
    -  "version": "2026.10319.10359",
    +  "version": "2026.10322.104",
       "productName": "Memory Sync",
       "identifier": "org.truenine.memory-sync",
       "build": {
    diff --git a/libraries/logger/Cargo.toml b/libraries/logger/Cargo.toml
    index f97cc63f..2943d524 100644
    --- a/libraries/logger/Cargo.toml
    +++ b/libraries/logger/Cargo.toml
    @@ -15,7 +15,7 @@ default = []
     napi = ["dep:napi", "dep:napi-derive"]
     
     [dependencies]
    -chrono = { version = "0.4", default-features = false, features = ["clock", "std"] }
    +chrono = { version = "0.4.44", default-features = false, features = ["clock", "std"] }
     serde = { workspace = true }
     serde_json = { workspace = true }
     napi = { workspace = true, optional = true }
    diff --git a/libraries/logger/package.json b/libraries/logger/package.json
    index deba242a..eb93cc18 100644
    --- a/libraries/logger/package.json
    +++ b/libraries/logger/package.json
    @@ -1,7 +1,7 @@
     {
       "name": "@truenine/logger",
       "type": "module",
    -  "version": "2026.10319.10359",
    +  "version": "2026.10322.104",
       "private": true,
       "description": "Rust-powered structured logger for Node.js via N-API",
       "license": "AGPL-3.0-only",
    @@ -43,7 +43,7 @@
         "typecheck": "tsc --noEmit -p tsconfig.lib.json"
       },
       "devDependencies": {
    -    "@napi-rs/cli": "^3.5.1",
    +    "@napi-rs/cli": "catalog:",
         "npm-run-all2": "catalog:",
         "tsdown": "catalog:",
         "typescript": "catalog:",
    diff --git a/libraries/md-compiler/Cargo.toml b/libraries/md-compiler/Cargo.toml
    index 195206f6..9233b04c 100644
    --- a/libraries/md-compiler/Cargo.toml
    +++ b/libraries/md-compiler/Cargo.toml
    @@ -22,7 +22,7 @@ serde_yml = { workspace = true }
     markdown = { workspace = true }
     napi = { workspace = true, optional = true }
     napi-derive = { workspace = true, optional = true }
    -regex-lite = { version = "0.1", optional = true }
    +regex-lite = { version = "0.1.9", optional = true }
     
     [build-dependencies]
     napi-build = { workspace = true }
    diff --git a/libraries/md-compiler/package.json b/libraries/md-compiler/package.json
    index 087f3371..0eb988b5 100644
    --- a/libraries/md-compiler/package.json
    +++ b/libraries/md-compiler/package.json
    @@ -1,7 +1,7 @@
     {
       "name": "@truenine/md-compiler",
       "type": "module",
    -  "version": "2026.10319.10359",
    +  "version": "2026.10322.104",
       "private": true,
       "description": "Rust-powered MDX→Markdown compiler for Node.js with pure-TS fallback",
       "license": "AGPL-3.0-only",
    @@ -55,7 +55,7 @@
         "typecheck": "tsc --noEmit -p tsconfig.lib.json"
       },
       "devDependencies": {
    -    "@napi-rs/cli": "^3.5.1",
    +    "@napi-rs/cli": "catalog:",
         "@types/estree": "catalog:",
         "@types/estree-jsx": "catalog:",
         "@types/mdast": "catalog:",
    diff --git a/libraries/md-compiler/src/compiler/component-registry.property.test.ts b/libraries/md-compiler/src/compiler/component-registry.property.test.ts
    index f567c8a7..76c2a22e 100644
    --- a/libraries/md-compiler/src/compiler/component-registry.property.test.ts
    +++ b/libraries/md-compiler/src/compiler/component-registry.property.test.ts
    @@ -37,7 +37,12 @@ describe('component-registry property tests', () => {
             _element: MdxJsxFlowElement | MdxJsxTextElement,
             _ctx: ProcessingContext,
             _processChildren: (children: RootContent[], ctx: ProcessingContext) => Promise
    -      ): Promise => []
    +      ): Promise => {
    +        void _element
    +        void _ctx
    +        void _processChildren
    +        return []
    +      }
         }
     
         it('should report hasComponent as true after registerComponent for any valid name', () => {
    diff --git a/libraries/md-compiler/src/compiler/component-registry.test.ts b/libraries/md-compiler/src/compiler/component-registry.test.ts
    index 2959033a..5c097734 100644
    --- a/libraries/md-compiler/src/compiler/component-registry.test.ts
    +++ b/libraries/md-compiler/src/compiler/component-registry.test.ts
    @@ -26,7 +26,12 @@ describe('component-registry', () => {
           _element: MdxJsxFlowElement | MdxJsxTextElement,
           _ctx: ProcessingContext,
           _processChildren: (children: RootContent[], ctx: ProcessingContext) => Promise
    -    ): Promise => []
    +    ): Promise => {
    +      void _element
    +      void _ctx
    +      void _processChildren
    +      return []
    +    }
       }
     
       describe('registerComponent', () => {
    diff --git a/libraries/md-compiler/src/compiler/export-parser.ts b/libraries/md-compiler/src/compiler/export-parser.ts
    index 1aa68d4b..e66fdd60 100644
    --- a/libraries/md-compiler/src/compiler/export-parser.ts
    +++ b/libraries/md-compiler/src/compiler/export-parser.ts
    @@ -30,6 +30,14 @@ export interface ParseExportOptions {
       readonly sourceText?: string
     }
     
    +const EXPORT_DEFAULT_PATTERN = /^export\s+default\s+/u
    +const EXPORT_CONST_PATTERN = /export\s+const\s+(\w+)\s*=\s*/gu
    +const NUMBER_LITERAL_PATTERN = /^-?\d+(?:\.\d+)?$/u
    +const VARIABLE_REFERENCE_PATTERN = /^[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*$/iu
    +const WHITESPACE_CHAR_PATTERN = /\s/u
    +const WORD_CHAR_PATTERN = /[\w$]/u
    +const SIMPLE_OBJECT_KEY_PATTERN = /^[\w$]+$/u
    +
     /**
      * Supported literal types for static evaluation
      */
    @@ -111,7 +119,7 @@ function extractExportFromNode(
     
       const code = node.value.trim() // Parse ESM node's value (source code string)
     
    -  const exportDefaultMatch = /^export\s+default\s+/.exec(code)
    +  const exportDefaultMatch = EXPORT_DEFAULT_PATTERN.exec(code)
       if (exportDefaultMatch != null) {
         const valueStartIndex = exportDefaultMatch[0].length
         const valueStr = extractValueString(code, valueStartIndex)
    @@ -142,13 +150,12 @@ function extractExportFromNode(
         return result
       }
     
    -  const exportConstRegex = /export\s+const\s+(\w+)\s*=\s*/g // Handles multiline and various value types // Match export const name = value pattern
    -  let match: RegExpExecArray | null = exportConstRegex.exec(code)
    +  let match: RegExpExecArray | null = EXPORT_CONST_PATTERN.exec(code)
     
       while (match !== null) {
         const name = match[1]
         if (name == null) {
    -      match = exportConstRegex.exec(code)
    +      match = EXPORT_CONST_PATTERN.exec(code)
           continue
         }
     
    @@ -156,7 +163,7 @@ function extractExportFromNode(
         const valueStr = extractValueString(code, valueStartIndex)
     
         if (valueStr == null) {
    -      match = exportConstRegex.exec(code)
    +      match = EXPORT_CONST_PATTERN.exec(code)
           continue
         }
     
    @@ -182,7 +189,7 @@ function extractExportFromNode(
           )
         }
     
    -    match = exportConstRegex.exec(code)
    +    match = EXPORT_CONST_PATTERN.exec(code)
       }
     
       return result
    @@ -289,23 +296,23 @@ export function parseStaticValue(
     
       if (trimmed === 'null') return null // Null literal
     
    -  if (/^-?\d+(?:\.\d+)?$/.test(trimmed)) return Number(trimmed) // Number literals (including negative and decimal)
    +  if (NUMBER_LITERAL_PATTERN.test(trimmed)) return Number(trimmed) // Number literals (including negative and decimal)
     
    -  if (trimmed.startsWith('"') && trimmed.endsWith('"')) return parseStringLiteral(trimmed.slice(1, -1), '"') // String literals with double quotes
    +  if (trimmed.startsWith('"') && trimmed.endsWith('"')) return parseStringLiteral(trimmed.slice(1, -1)) // String literals with double quotes
     
    -  if (trimmed.startsWith('\'') && trimmed.endsWith('\'')) return parseStringLiteral(trimmed.slice(1, -1), '\'') // String literals with single quotes
    +  if (trimmed.startsWith('\'') && trimmed.endsWith('\'')) return parseStringLiteral(trimmed.slice(1, -1)) // String literals with single quotes
     
       if (trimmed.startsWith('`') && trimmed.endsWith('`')) { // Template literals (without expressions)
         const inner = trimmed.slice(1, -1)
         if (inner.includes('${')) throw new Error(`Template literal with expressions cannot be statically evaluated: ${trimmed}`)
    -    return parseStringLiteral(inner, '`')
    +    return parseStringLiteral(inner)
       }
     
       if (trimmed.startsWith('[') && trimmed.endsWith(']')) return parseArrayLiteral(trimmed, scope, filePath) // Array literals
     
       if (trimmed.startsWith('{') && trimmed.endsWith('}')) return parseObjectLiteral(trimmed, scope, filePath) // Object literals
     
    -  if (/^[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*$/i.test(trimmed)) return evaluateVariableReference(trimmed, scope, filePath) // Variable reference (e.g., tool.readFile, profile.name)
    +  if (VARIABLE_REFERENCE_PATTERN.test(trimmed)) return evaluateVariableReference(trimmed, scope, filePath) // Variable reference (e.g., tool.readFile, profile.name)
     
       const fileInfo = filePath != null ? ` in file "${filePath}"` : '' // Cannot statically evaluate
       throw new Error(`Expression "${trimmed}" cannot be statically evaluated${fileInfo}`)
    @@ -315,10 +322,9 @@ export function parseStaticValue(
      * Parses a string literal, handling escape sequences.
      *
      * @param content - String content without quotes
    - * @param _quote - Quote character used (unused but kept for API consistency)
      * @returns Parsed string value
      */
    -function parseStringLiteral(content: string, _quote: string): string {
    +function parseStringLiteral(content: string): string {
       return content // Handle common escape sequences
         .replaceAll('\\n', '\n')
         .replaceAll('\\r', '\r')
    @@ -521,15 +527,15 @@ function convertToJson(jsLiteral: string): string {
           const keyEnd = result.length // Look back to find the key start
           let keyStart = keyEnd - 1
     
    -      while (keyStart >= 0 && /\s/.test(result.charAt(keyStart))) keyStart-- // Skip whitespace
    +      while (keyStart >= 0 && WHITESPACE_CHAR_PATTERN.test(result.charAt(keyStart))) keyStart-- // Skip whitespace
     
           const keyEndPos = keyStart + 1 // Find key start (word characters)
    -      while (keyStart >= 0 && /[\w$]/.test(result.charAt(keyStart))) keyStart--
    +      while (keyStart >= 0 && WORD_CHAR_PATTERN.test(result.charAt(keyStart))) keyStart--
           keyStart++
     
           if (keyStart > 0 && result.charAt(keyStart - 1) !== '"') { // Check if key is already quoted
             const key = result.slice(keyStart, keyEndPos)
    -        if (key.length > 0 && /^[\w$]+$/.test(key)) result = `${result.slice(0, keyStart)}"${key}"`
    +        if (key.length > 0 && SIMPLE_OBJECT_KEY_PATTERN.test(key)) result = `${result.slice(0, keyStart)}"${key}"`
           }
         }
     
    diff --git a/libraries/md-compiler/src/compiler/expression-eval.ts b/libraries/md-compiler/src/compiler/expression-eval.ts
    index 51ed7353..4be0fe19 100644
    --- a/libraries/md-compiler/src/compiler/expression-eval.ts
    +++ b/libraries/md-compiler/src/compiler/expression-eval.ts
    @@ -15,6 +15,9 @@ export interface EvaluateExpressionOptions {
       readonly nodeType?: string | undefined
     }
     
    +const SIMPLE_REFERENCE_PATTERN = /^[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*$/iu
    +const UNDEFINED_REFERENCE_PATTERN = /(\w+) is not defined/u
    +
     /**
      * Evaluates a JavaScript expression within a given scope.
      * Uses Function constructor for safe evaluation with controlled scope.
    @@ -37,7 +40,7 @@ export function evaluateExpression(
     
       if (trimmed === '') return ''
     
    -  if (/^[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*$/i.test(trimmed)) {
    +  if (SIMPLE_REFERENCE_PATTERN.test(trimmed)) {
         return evaluateSimpleReference(trimmed, scope, diagnosticContext) // Matches: identifier, identifier.property, identifier.property.nested // Handle simple variable references directly for better error messages
       }
     
    @@ -113,7 +116,7 @@ function evaluateComplexExpression(
       catch (error) {
         const message = error instanceof Error ? error.message : String(error)
         if (message.includes('is not defined')) { // Check if the error is about undefined variable
    -      const match = /(\w+) is not defined/.exec(message)
    +      const match = UNDEFINED_REFERENCE_PATTERN.exec(message)
           if (match?.[1] != null) {
             throw new UndefinedNamespaceError(match[1], expression, {
               ...diagnosticContext,
    diff --git a/libraries/md-compiler/src/compiler/jsx-converter.ts b/libraries/md-compiler/src/compiler/jsx-converter.ts
    index d30f6eb4..61e42450 100644
    --- a/libraries/md-compiler/src/compiler/jsx-converter.ts
    +++ b/libraries/md-compiler/src/compiler/jsx-converter.ts
    @@ -17,6 +17,8 @@ import type {EvaluateExpressionOptions} from './expression-eval'
     import type {ExpressionDiagnosticContext, ProcessingContext} from './types'
     import {evaluateExpression} from './expression-eval'
     
    +const LANGUAGE_CLASS_PATTERN = /language-(\w+)/u
    +
     function createExpressionOptions(
       ctx: ProcessingContext,
       nodeType: string,
    @@ -156,7 +158,7 @@ function convertPreElement(
       if (codeChild == null) return null
     
       const className = getAttributeValue(codeChild, 'className', ctx) ?? ''
    -  const langMatch = /language-(\w+)/.exec(className)
    +  const langMatch = LANGUAGE_CLASS_PATTERN.exec(className)
       const lang = langMatch?.[1]
     
       const code = extractTextContent(codeChild, ctx)
    diff --git a/libraries/md-compiler/src/compiler/jsx-expression-eval.ts b/libraries/md-compiler/src/compiler/jsx-expression-eval.ts
    index bcc8f97d..8a0602a3 100644
    --- a/libraries/md-compiler/src/compiler/jsx-expression-eval.ts
    +++ b/libraries/md-compiler/src/compiler/jsx-expression-eval.ts
    @@ -18,6 +18,8 @@ import {convertJsxToMarkdown} from './jsx-converter'
     type ProcessAstFn = (children: RootContent[], ctx: ProcessingContext) => Promise
     type JSXChild = JSXText | JSXExpressionContainer | JSXSpreadChild | JSXElement | JSXFragment
     
    +const NUMBER_RESULT_PATTERN = /^-?\d+(?:\.\d+)?$/u
    +
     function createExpressionOptions(
       ctx: ProcessingContext,
       node: MdxFlowExpression | MdxTextExpression
    @@ -64,7 +66,7 @@ async function evaluateEstreeExpression(
       processAstFn: ProcessAstFn,
       ownerNode: MdxFlowExpression | MdxTextExpression
     ): Promise {
    -  if (expr.type === 'JSXElement') return processJsxElement(expr as unknown as JSXElement, ctx, processAstFn, ownerNode) // Handle JSX types first
    +  if (expr.type === 'JSXElement') return processJsxElement(expr as unknown as JSXElement, ctx, processAstFn) // Handle JSX types first
       if (expr.type === 'JSXFragment') return processJsxFragment(expr as unknown as JSXFragment, ctx, processAstFn, ownerNode)
       if (expr.type === 'LogicalExpression') return evaluateLogicalExpression(expr, ctx, processAstFn, ownerNode)
       if (expr.type === 'ConditionalExpression') return evaluateConditionalExpression(expr, ctx, processAstFn, ownerNode)
    @@ -228,7 +230,7 @@ async function evaluateToValue(
         if (result === 'false') return false
         if (result === 'null') return null
         if (result === 'undefined' || result === '') return void 0
    -    if (/^-?\d+(?:\.\d+)?$/.test(result)) return Number(result)
    +    if (NUMBER_RESULT_PATTERN.test(result)) return Number(result)
         return result
       }
       catch {
    @@ -239,8 +241,7 @@ async function evaluateToValue(
     async function processJsxElement(
       jsxElement: JSXElement,
       ctx: ProcessingContext,
    -  processAstFn: ProcessAstFn,
    -  _ownerNode: MdxFlowExpression | MdxTextExpression
    +  processAstFn: ProcessAstFn
     ): Promise {
       const mdxElement = convertEstreeJsxToMdx(jsxElement, ctx)
     
    @@ -277,7 +278,7 @@ async function processJsxChild(
       processAstFn: ProcessAstFn,
       ownerNode: MdxFlowExpression | MdxTextExpression
     ): Promise {
    -  if (child.type === 'JSXElement') return processJsxElement(child, ctx, processAstFn, ownerNode)
    +  if (child.type === 'JSXElement') return processJsxElement(child, ctx, processAstFn)
       if (child.type === 'JSXFragment') return processJsxFragment(child, ctx, processAstFn, ownerNode)
       if (child.type === 'JSXText') {
         const text = child.value.trim()
    diff --git a/libraries/md-compiler/src/compiler/transformer.ts b/libraries/md-compiler/src/compiler/transformer.ts
    index 559e66f6..260f00d6 100644
    --- a/libraries/md-compiler/src/compiler/transformer.ts
    +++ b/libraries/md-compiler/src/compiler/transformer.ts
    @@ -10,6 +10,8 @@ import {evaluateJsxExpression, hasJsxInEstree} from './jsx-expression-eval'
     
     type ChildNode = RootContent | Text
     
    +const FILE_PATH_SUFFIX_PATTERN = /\.\w+$/u
    +
     function createExpressionOptions(
       ctx: ProcessingContext,
       node: {position?: ExpressionDiagnosticContext['position']},
    @@ -31,7 +33,7 @@ function createExpressionOptions(
      * @returns The simplified text (basename only) or original text
      */
     function simplifyLinkText(text: string): string {
    -  if (!(text.includes('/') && /\.\w+$/.test(text))) return text // Check if text looks like a file path (contains / and ends with .ext)
    +  if (!(text.includes('/') && FILE_PATH_SUFFIX_PATTERN.test(text))) return text // Check if text looks like a file path (contains / and ends with .ext)
     
       const lastSlashIndex = text.lastIndexOf('/')
       return text.slice(lastSlashIndex + 1)
    diff --git a/libraries/md-compiler/src/errors/index.ts b/libraries/md-compiler/src/errors/index.ts
    index d4874834..9d4e061b 100644
    --- a/libraries/md-compiler/src/errors/index.ts
    +++ b/libraries/md-compiler/src/errors/index.ts
    @@ -45,6 +45,7 @@ export interface FormatCompilerDiagnosticOptions {
     }
     
     const MAX_SNIPPET_LENGTH = 240
    +const LINE_SPLIT_PATTERN = /\r?\n/u
     
     export function createCompilerDiagnostic(context: CompilerDiagnosticContext = {}): CompilerDiagnostic {
       const {filePath, position, sourceText, expression, exportName, nodeType, phase, hint, cause} = context
    @@ -85,7 +86,7 @@ export function createCompilerDiagnostic(context: CompilerDiagnosticContext = {}
     }
     
     function getSourceLine(sourceText: string, lineNumber: number): string | undefined {
    -  const lines = sourceText.split(/\r?\n/u)
    +  const lines = sourceText.split(LINE_SPLIT_PATTERN)
       return lines[lineNumber - 1]
     }
     
    diff --git a/libraries/md-compiler/src/globals/index.ts b/libraries/md-compiler/src/globals/index.ts
    index 9f2bff4d..95c19cbc 100644
    --- a/libraries/md-compiler/src/globals/index.ts
    +++ b/libraries/md-compiler/src/globals/index.ts
    @@ -4,11 +4,11 @@
      * @example {profile.name}, {profile.username}
      */
     export interface UserProfile {
    +  [key: string]: unknown
       name?: string
       username?: string
       gender?: string
       birthday?: string
    -  [key: string]: unknown
     }
     
     /**
    @@ -16,6 +16,8 @@ export interface UserProfile {
      * @example {tool.websearch}, {tool.webfetch}, {tool.readFile}
      */
     export interface ToolReferences {
    +  /** Allow custom tool references */
    +  [key: string]: string | undefined
       /** Web search tool name */
       websearch?: string
       /** Web fetch tool name */
    @@ -32,8 +34,6 @@ export interface ToolReferences {
       grep?: string
       /** List directory tool name */
       listDirectory?: string
    -  /** Allow custom tool references */
    -  [key: string]: string | undefined
     }
     
     /**
    @@ -107,6 +107,7 @@ export enum OsKind {
      * @example {os.platform}, {os.arch}, {os.shellKind}, {os.kind}
      */
     export interface OsInfo {
    +  [key: string]: string | ShellKind | OsKind | undefined
       platform?: string
       arch?: string
       hostname?: string
    @@ -116,7 +117,6 @@ export interface OsInfo {
       release?: string
       shellKind?: ShellKind
       kind?: OsKind
    -  [key: string]: string | ShellKind | OsKind | undefined
     }
     
     export interface MdProps {
    diff --git a/libraries/md-compiler/src/markdown/index.ts b/libraries/md-compiler/src/markdown/index.ts
    index 54f545b3..f35b0949 100644
    --- a/libraries/md-compiler/src/markdown/index.ts
    +++ b/libraries/md-compiler/src/markdown/index.ts
    @@ -18,6 +18,15 @@ interface NapiMdCompilerModule {
       transformMdxReferencesToMd: (content: string) => string
     }
     
    +const FRONT_MATTER_PATTERN = /^---\r?\n[\s\S]*?\r?\n---(?:(?:\r?\n){1,2}|$)/u
    +const MDX_REFERENCE_PATTERN = /(!?\[)([^\]]*)(\]\()([^)]+)(\))/gu
    +const TRAILING_MDX_EXTENSION_PATTERN = /\.mdx$/u
    +const LINK_TEXT_MDX_EXTENSION_PATTERN = /\.mdx(?=#|\?|$)/gu
    +const EXTERNAL_URL_PATTERN = /^(?:https?:)?\/\//u
    +const URL_TRAILING_MDX_EXTENSION_PATTERN = /\.mdx$/u
    +const URL_HASH_MDX_EXTENSION_PATTERN = /\.mdx#/u
    +const URL_QUERY_MDX_EXTENSION_PATTERN = /\.mdx\?/u
    +
     let napiBinding: NapiMdCompilerModule | null = null
     
     function isNapiMdCompilerModule(value: unknown): value is NapiMdCompilerModule {
    @@ -111,7 +120,7 @@ export function buildFrontMatter(
     ): string {
       if (napiBinding != null && options == null) return napiBinding.buildFrontMatter(JSON.stringify(frontMatter))
       const cleanedFrontMatter = Object.fromEntries(
    -    Object.entries(frontMatter).filter(([_, v]) => v != null)
    +    Object.entries(frontMatter).filter(([, value]) => value != null)
       )
       if (Object.keys(cleanedFrontMatter).length === 0) return '---\n---'
       const yamlStr = YAML.stringify(cleanedFrontMatter, {
    @@ -137,7 +146,7 @@ export function buildRawFrontMatter(
       options?: BuildMarkdownOptions
     ): string {
       const cleanedFrontMatter = Object.fromEntries(
    -    Object.entries(frontMatter).filter(([_, v]) => v != null)
    +    Object.entries(frontMatter).filter(([, value]) => value != null)
       )
       if (Object.keys(cleanedFrontMatter).length === 0) return ''
       return YAML.stringify(cleanedFrontMatter, {
    @@ -188,8 +197,7 @@ export function parseMarkdown>(rawContent: string):
       }
       let contentWithoutFrontMatter = rawContent
       if (rawFrontMatter != null) {
    -    const frontMatterRegex = /^---\r?\n[\s\S]*?\r?\n---(?:(?:\r?\n){1,2}|$)/
    -    contentWithoutFrontMatter = rawContent.replace(frontMatterRegex, '')
    +    contentWithoutFrontMatter = rawContent.replace(FRONT_MATTER_PATTERN, '')
       }
       return {
         ...yamlFrontMatter != null && {yamlFrontMatter},
    @@ -203,16 +211,16 @@ export function parseMarkdown>(rawContent: string):
     export function transformMdxReferencesToMd(content: string): string {
       if (napiBinding != null) return napiBinding.transformMdxReferencesToMd(content)
       return content.replaceAll(
    -    /(!?\[)([^\]]*)(\]\()([^)]+)(\))/g,
    +    MDX_REFERENCE_PATTERN,
         (_match, prefix: string, text: string, middle: string, url: string, suffix: string) => {
           const transformedText = text
    -        .replaceAll(/\.mdx$/g, '.md')
    -        .replaceAll(/\.mdx(?=#|\?|$)/g, '.md')
    -      if (/^(?:https?:)?\/\//.test(url)) return `${prefix}${transformedText}${middle}${url}${suffix}`
    +        .replace(TRAILING_MDX_EXTENSION_PATTERN, '.md')
    +        .replaceAll(LINK_TEXT_MDX_EXTENSION_PATTERN, '.md')
    +      if (EXTERNAL_URL_PATTERN.test(url)) return `${prefix}${transformedText}${middle}${url}${suffix}`
           const transformedUrl = url
    -        .replace(/\.mdx$/, '.md')
    -        .replace(/\.mdx#/, '.md#')
    -        .replace(/\.mdx\?/, '.md?')
    +        .replace(URL_TRAILING_MDX_EXTENSION_PATTERN, '.md')
    +        .replace(URL_HASH_MDX_EXTENSION_PATTERN, '.md#')
    +        .replace(URL_QUERY_MDX_EXTENSION_PATTERN, '.md?')
           return `${prefix}${transformedText}${middle}${transformedUrl}${suffix}`
         }
       )
    diff --git a/libraries/md-compiler/src/mdx-to-md.ts b/libraries/md-compiler/src/mdx-to-md.ts
    index 154b7400..f62569ba 100644
    --- a/libraries/md-compiler/src/mdx-to-md.ts
    +++ b/libraries/md-compiler/src/mdx-to-md.ts
    @@ -20,6 +20,7 @@ interface NativeCompileResult {
     }
     
     const CODE_FENCE_PATTERN = /^\s*(```|~~~)/u
    +const LINE_SPLIT_PATTERN = /\r?\n/u
     const RESIDUAL_MODULE_SYNTAX_PATTERNS = [
       /^\s*export\s+default\b/u,
       /^\s*export\s+const\b/u,
    @@ -181,7 +182,7 @@ function serializeOptions(options?: MdxToMdOptions): string | null {
     function hasResidualModuleSyntax(content: string): boolean {
       let activeFence: string | undefined
     
    -  for (const line of content.split(/\r?\n/u)) {
    +  for (const line of content.split(LINE_SPLIT_PATTERN)) {
         const fenceMatch = CODE_FENCE_PATTERN.exec(line)
         if (fenceMatch?.[1] != null) {
           const marker = fenceMatch[1]
    diff --git a/libraries/md-compiler/src/toml.ts b/libraries/md-compiler/src/toml.ts
    index 96a68f63..bed2ab67 100644
    --- a/libraries/md-compiler/src/toml.ts
    +++ b/libraries/md-compiler/src/toml.ts
    @@ -14,6 +14,9 @@ export interface BuildPromptTomlArtifactOptions extends BuildTomlDocumentOptions
     type TomlScalar = string | number | boolean | Date | bigint
     type TomlObject = Readonly>
     
    +const BARE_TOML_KEY_PATTERN = /^[\w-]+$/u
    +const NEWLINE_PATTERN = /\r\n?/gu
    +
     function isPlainObject(value: unknown): value is TomlObject {
       return value != null && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date)
     }
    @@ -52,7 +55,7 @@ function normalizeValue(value: unknown): unknown {
     }
     
     function isBareTomlKey(key: string): boolean {
    -  return /^[\w-]+$/u.test(key)
    +  return BARE_TOML_KEY_PATTERN.test(key)
     }
     
     function formatTomlKey(key: string): string {
    @@ -66,7 +69,7 @@ function formatTomlKeyPath(path: readonly string[]): string {
     }
     
     function formatMultilineTomlString(value: string): string {
    -  const normalizedValue = value.replaceAll(/\r\n?/gu, '\n')
    +  const normalizedValue = value.replaceAll(NEWLINE_PATTERN, '\n')
       let escapedValue = ''
     
       for (const character of normalizedValue) {
    diff --git a/libraries/script-runtime/Cargo.toml b/libraries/script-runtime/Cargo.toml
    index e848f5ca..d6b84445 100644
    --- a/libraries/script-runtime/Cargo.toml
    +++ b/libraries/script-runtime/Cargo.toml
    @@ -19,8 +19,8 @@ serde = { workspace = true }
     serde_json = { workspace = true }
     napi = { workspace = true, optional = true }
     napi-derive = { workspace = true, optional = true }
    -tempfile = "3"
    -wait-timeout = "0.2"
    +tempfile = "3.27.0"
    +wait-timeout = "0.2.1"
     
     [build-dependencies]
     napi-build = { workspace = true }
    diff --git a/libraries/script-runtime/package.json b/libraries/script-runtime/package.json
    index 13602247..a68d9082 100644
    --- a/libraries/script-runtime/package.json
    +++ b/libraries/script-runtime/package.json
    @@ -1,7 +1,7 @@
     {
       "name": "@truenine/script-runtime",
       "type": "module",
    -  "version": "2026.10319.10359",
    +  "version": "2026.10322.104",
       "private": true,
       "description": "Rust-backed TypeScript proxy runtime for tnmsc",
       "license": "AGPL-3.0-only",
    @@ -43,11 +43,11 @@
         "typecheck": "tsc --noEmit -p tsconfig.lib.json"
       },
       "devDependencies": {
    -    "@napi-rs/cli": "^3.5.1",
    +    "@napi-rs/cli": "catalog:",
         "@truenine/eslint10-config": "catalog:",
         "@types/node": "catalog:",
         "eslint": "catalog:",
    -    "jiti": "2.6.1",
    +    "jiti": "catalog:",
         "npm-run-all2": "catalog:",
         "tsdown": "catalog:",
         "typescript": "catalog:",
    diff --git a/mcp/package.json b/mcp/package.json
    index c29e8a08..952ecf3e 100644
    --- a/mcp/package.json
    +++ b/mcp/package.json
    @@ -1,7 +1,7 @@
     {
       "name": "@truenine/memory-sync-mcp",
       "type": "module",
    -  "version": "2026.10319.10359",
    +  "version": "2026.10322.104",
       "description": "MCP stdio server for managing memory-sync prompt sources and translation artifacts",
       "author": "TrueNine",
       "license": "AGPL-3.0-only",
    diff --git a/package.json b/package.json
    index 7f91796d..4455cd66 100644
    --- a/package.json
    +++ b/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@truenine/memory-sync",
    -  "version": "2026.10319.10359",
    +  "version": "2026.10322.104",
       "description": "Cross-AI-tool prompt synchronisation toolkit (CLI + Tauri desktop GUI) — one ruleset, multi-target adaptation. Monorepo powered by pnpm + Turbo.",
       "license": "AGPL-3.0-only",
       "keywords": [
    @@ -58,17 +58,28 @@
       },
       "packageManager": "pnpm@10.30.1",
       "devDependencies": {
    -    "@napi-rs/cli": "^3.5.1",
    +    "@antfu/eslint-config": "catalog:",
    +    "@eslint/js": "catalog:",
    +    "@napi-rs/cli": "catalog:",
    +    "@next/eslint-plugin-next": "catalog:",
         "@truenine/eslint10-config": "catalog:",
    +    "@unocss/eslint-config": "catalog:",
    +    "@vue/eslint-config-prettier": "catalog:",
    +    "@vue/eslint-config-typescript": "catalog:",
         "@types/node": "catalog:",
         "eslint": "catalog:",
    +    "eslint-plugin-format": "catalog:",
    +    "eslint-plugin-prettier": "catalog:",
    +    "eslint-plugin-vue": "catalog:",
         "fast-check": "catalog:",
         "npm-run-all2": "catalog:",
    +    "prettier": "catalog:",
         "simple-git-hooks": "^2.13.1",
         "tsdown": "catalog:",
         "tsx": "catalog:",
         "turbo": "catalog:",
         "typescript": "catalog:",
    +    "typescript-eslint": "catalog:",
         "vite": "catalog:",
         "vitest": "catalog:"
       }
    diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
    index 734e53fd..fc432ad5 100644
    --- a/pnpm-lock.yaml
    +++ b/pnpm-lock.yaml
    @@ -6,45 +6,57 @@ settings:
     
     catalogs:
       default:
    +    '@antfu/eslint-config':
    +      specifier: ^7.7.3
    +      version: 7.7.3
         '@clack/prompts':
    -      specifier: ^1.0.1
    -      version: 1.0.1
    -    '@mdx-js/react':
    -      specifier: ^3.1.1
    -      version: 3.1.1
    +      specifier: ^1.1.0
    +      version: 1.1.0
    +    '@eslint/js':
    +      specifier: ^10.0.1
    +      version: 10.0.1
         '@modelcontextprotocol/sdk':
           specifier: ^1.27.1
           version: 1.27.1
         '@monaco-editor/react':
           specifier: ^4.7.0
           version: 4.7.0
    -    '@next/mdx':
    -      specifier: ^16.1.6
    -      version: 16.1.6
    +    '@napi-rs/cli':
    +      specifier: ^3.5.1
    +      version: 3.5.1
    +    '@next/eslint-plugin-next':
    +      specifier: ^16.2.0
    +      version: 16.2.0
         '@tailwindcss/vite':
    -      specifier: ^4.2.1
    -      version: 4.2.1
    +      specifier: ^4.2.2
    +      version: 4.2.2
         '@tanstack/react-router':
    -      specifier: ^1.163.3
    -      version: 1.163.3
    +      specifier: ^1.168.1
    +      version: 1.168.1
    +    '@tanstack/router-generator':
    +      specifier: ^1.166.15
    +      version: 1.166.15
         '@tanstack/router-plugin':
    -      specifier: ^1.164.0
    -      version: 1.164.0
    +      specifier: ^1.167.1
    +      version: 1.167.1
         '@tauri-apps/api':
           specifier: ^2.10.1
           version: 2.10.1
         '@tauri-apps/cli':
    -      specifier: ^2.10.0
    -      version: 2.10.0
    +      specifier: ^2.10.1
    +      version: 2.10.1
         '@tauri-apps/plugin-shell':
           specifier: ^2.3.5
           version: 2.3.5
         '@tauri-apps/plugin-updater':
           specifier: ^2.10.0
           version: 2.10.0
    +    '@theguild/remark-mermaid':
    +      specifier: ^0.3.0
    +      version: 0.3.0
         '@truenine/eslint10-config':
    -      specifier: ^2026.10209.11105
    -      version: 2026.10209.11105
    +      specifier: ^2026.10318.10138
    +      version: 2026.10318.10138
         '@types/estree':
           specifier: ^1.0.8
           version: 1.0.8
    @@ -58,8 +70,8 @@ catalogs:
           specifier: ^4.0.4
           version: 4.0.4
         '@types/node':
    -      specifier: ^25.3.3
    -      version: 25.3.3
    +      specifier: ^25.5.0
    +      version: 25.5.0
         '@types/picomatch':
           specifier: ^4.0.2
           version: 4.0.2
    @@ -69,12 +81,21 @@ catalogs:
         '@types/react-dom':
           specifier: ^19.2.3
           version: 19.2.3
    +    '@unocss/eslint-config':
    +      specifier: ^66.6.7
    +      version: 66.6.7
         '@vitejs/plugin-react':
    -      specifier: ^5.1.4
    -      version: 5.1.4
    +      specifier: ^6.0.1
    +      version: 6.0.1
         '@vitest/coverage-v8':
    -      specifier: 4.0.18
    -      version: 4.0.18
    +      specifier: 4.1.0
    +      version: 4.1.0
    +    '@vue/eslint-config-prettier':
    +      specifier: ^10.2.0
    +      version: 10.2.0
    +    '@vue/eslint-config-typescript':
    +      specifier: ^14.7.0
    +      version: 14.7.0
         class-variance-authority:
           specifier: ^0.7.1
           version: 0.7.1
    @@ -82,47 +103,83 @@ catalogs:
           specifier: ^2.1.1
           version: 2.1.1
         eslint:
    -      specifier: ^10.0.2
    -      version: 10.0.2
    +      specifier: ^10.0.3
    +      version: 10.0.3
    +    eslint-plugin-format:
    +      specifier: ^2.0.1
    +      version: 2.0.1
    +    eslint-plugin-prettier:
    +      specifier: ^5.5.5
    +      version: 5.5.5
    +    eslint-plugin-vue:
    +      specifier: ^10.8.0
    +      version: 10.8.0
         fast-check:
    -      specifier: ^4.5.3
    -      version: 4.5.3
    +      specifier: ^4.6.0
    +      version: 4.6.0
         fast-glob:
           specifier: ^3.3.3
           version: 3.3.3
         fs-extra:
    -      specifier: ^11.3.3
    -      version: 11.3.3
    +      specifier: ^11.3.4
    +      version: 11.3.4
    +    jiti:
    +      specifier: ^2.6.1
    +      version: 2.6.1
         json5:
           specifier: ^2.2.3
           version: 2.2.3
    +    lightningcss:
    +      specifier: ^1.32.0
    +      version: 1.32.0
         lucide-react:
    -      specifier: ^0.575.0
    -      version: 0.575.0
    +      specifier: ^0.577.0
    +      version: 0.577.0
    +    material-icon-theme:
    +      specifier: ^5.32.0
    +      version: 5.32.0
         mdast-util-mdx:
           specifier: ^3.0.0
           version: 3.0.0
    +    mermaid:
    +      specifier: ^11.13.0
    +      version: 11.13.0
         monaco-editor:
           specifier: ^0.55.1
           version: 0.55.1
         next:
    -      specifier: ^16.1.6
    -      version: 16.1.6
    +      specifier: ^16.2.0
    +      version: 16.2.0
    +    nextra:
    +      specifier: ^4.6.1
    +      version: 4.6.1
    +    nextra-theme-docs:
    +      specifier: ^4.6.1
    +      version: 4.6.1
         npm-run-all2:
           specifier: ^8.0.4
           version: 8.0.4
    +    pagefind:
    +      specifier: ^1.4.0
    +      version: 1.4.0
         picocolors:
           specifier: ^1.1.1
           version: 1.1.1
         picomatch:
           specifier: ^4.0.3
           version: 4.0.3
    +    prettier:
    +      specifier: ^3.8.1
    +      version: 3.8.1
         react:
           specifier: ^19.2.4
           version: 19.2.4
         react-dom:
           specifier: ^19.2.4
           version: 19.2.4
    +    recharts:
    +      specifier: ^3.8.0
    +      version: 3.8.0
         remark-frontmatter:
           specifier: ^5.0.0
           version: 5.0.0
    @@ -142,32 +199,35 @@ catalogs:
           specifier: ^3.5.0
           version: 3.5.0
         tailwindcss:
    -      specifier: ^4.2.1
    -      version: 4.2.1
    +      specifier: ^4.2.2
    +      version: 4.2.2
         tsdown:
    -      specifier: 0.21.0-beta.2
    -      version: 0.21.0-beta.2
    +      specifier: ^0.21.4
    +      version: 0.21.4
         tsx:
           specifier: ^4.21.0
           version: 4.21.0
         turbo:
    -      specifier: ^2.8.12
    -      version: 2.8.12
    +      specifier: ^2.8.20
    +      version: 2.8.20
         tw-animate-css:
           specifier: ^1.4.0
           version: 1.4.0
         typescript:
           specifier: ^5.9.3
           version: 5.9.3
    +    typescript-eslint:
    +      specifier: ^8.57.1
    +      version: 8.57.1
         unified:
           specifier: ^11.0.5
           version: 11.0.5
         vite:
    -      specifier: ^7.3.1
    -      version: 7.3.1
    +      specifier: ^8.0.1
    +      version: 8.0.1
         vitest:
    -      specifier: ^4.0.18
    -      version: 4.0.18
    +      specifier: ^4.1.0
    +      version: 4.1.0
         yaml:
           specifier: ^2.8.2
           version: 2.8.2
    @@ -182,45 +242,78 @@ importers:
     
       .:
         devDependencies:
    +      '@antfu/eslint-config':
    +        specifier: 'catalog:'
    +        version: 7.7.3(@next/eslint-plugin-next@16.2.0)(@typescript-eslint/rule-tester@8.56.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.57.1(typescript@5.9.3))(@typescript-eslint/utils@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(@unocss/eslint-plugin@66.6.7(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.26)(eslint-plugin-format@2.0.1(eslint@10.0.3(jiti@2.6.1)))(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)(vitest@4.1.0(@types/node@25.5.0)(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)))
    +      '@eslint/js':
    +        specifier: 'catalog:'
    +        version: 10.0.1(eslint@10.0.3(jiti@2.6.1))
           '@napi-rs/cli':
    -        specifier: ^3.5.1
    -        version: 3.5.1(@emnapi/runtime@1.8.1)(@types/node@25.3.3)
    +        specifier: 'catalog:'
    +        version: 3.5.1(@emnapi/runtime@1.8.1)(@types/node@25.5.0)
    +      '@next/eslint-plugin-next':
    +        specifier: 'catalog:'
    +        version: 16.2.0
           '@truenine/eslint10-config':
             specifier: 'catalog:'
    -        version: 2026.10209.11105(e2101efea8a228b7e40cea5868468857)
    +        version: 2026.10318.10138(30aab4e6ca2f6a986fe995bf4241db33)
           '@types/node':
             specifier: 'catalog:'
    -        version: 25.3.3
    +        version: 25.5.0
    +      '@unocss/eslint-config':
    +        specifier: 'catalog:'
    +        version: 66.6.7(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
    +      '@vue/eslint-config-prettier':
    +        specifier: 'catalog:'
    +        version: 10.2.0(eslint@10.0.3(jiti@2.6.1))(prettier@3.8.1)
    +      '@vue/eslint-config-typescript':
    +        specifier: 'catalog:'
    +        version: 14.7.0(eslint-plugin-vue@10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.0.3(jiti@2.6.1)))(@typescript-eslint/parser@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.0.3(jiti@2.6.1))))(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
           eslint:
             specifier: 'catalog:'
    -        version: 10.0.2(jiti@2.6.1)
    +        version: 10.0.3(jiti@2.6.1)
    +      eslint-plugin-format:
    +        specifier: 'catalog:'
    +        version: 2.0.1(eslint@10.0.3(jiti@2.6.1))
    +      eslint-plugin-prettier:
    +        specifier: 'catalog:'
    +        version: 5.5.5(eslint-config-prettier@10.1.8(eslint@10.0.3(jiti@2.6.1)))(eslint@10.0.3(jiti@2.6.1))(prettier@3.8.1)
    +      eslint-plugin-vue:
    +        specifier: 'catalog:'
    +        version: 10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.0.3(jiti@2.6.1)))(@typescript-eslint/parser@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.0.3(jiti@2.6.1)))
           fast-check:
             specifier: 'catalog:'
    -        version: 4.5.3
    +        version: 4.6.0
           npm-run-all2:
             specifier: 'catalog:'
             version: 8.0.4
    +      prettier:
    +        specifier: 'catalog:'
    +        version: 3.8.1
           simple-git-hooks:
             specifier: ^2.13.1
             version: 2.13.1
           tsdown:
             specifier: 'catalog:'
    -        version: 0.21.0-beta.2(synckit@0.11.12)(typescript@5.9.3)
    +        version: 0.21.4(synckit@0.11.12)(typescript@5.9.3)
           tsx:
             specifier: 'catalog:'
             version: 4.21.0
           turbo:
             specifier: 'catalog:'
    -        version: 2.8.12
    +        version: 2.8.20
           typescript:
             specifier: 'catalog:'
             version: 5.9.3
    +      typescript-eslint:
    +        specifier: 'catalog:'
    +        version: 8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
           vite:
             specifier: 'catalog:'
    -        version: 7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2)
    +        version: 8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)
           vitest:
             specifier: 'catalog:'
    -        version: 4.0.18(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2)
    +        version: 4.1.0(@types/node@25.5.0)(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))
     
       cli:
         dependencies:
    @@ -228,7 +321,7 @@ importers:
             specifier: 'catalog:'
             version: 2.2.3
           yaml:
    -        specifier: 2.8.2
    +        specifier: 'catalog:'
             version: 2.8.2
           zod:
             specifier: 'catalog:'
    @@ -236,7 +329,7 @@ importers:
         devDependencies:
           '@clack/prompts':
             specifier: 'catalog:'
    -        version: 1.0.1
    +        version: 1.1.0
           '@truenine/logger':
             specifier: workspace:*
             version: link:../libraries/logger
    @@ -254,19 +347,19 @@ importers:
             version: 4.0.2
           '@vitest/coverage-v8':
             specifier: 'catalog:'
    -        version: 4.0.18(vitest@4.0.18(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2))
    +        version: 4.1.0(vitest@4.1.0(@types/node@25.5.0)(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)))
           fast-glob:
             specifier: 'catalog:'
             version: 3.3.3
           fs-extra:
             specifier: 'catalog:'
    -        version: 11.3.3
    +        version: 11.3.4
           jiti:
    -        specifier: 2.6.1
    +        specifier: 'catalog:'
             version: 2.6.1
           lightningcss:
    -        specifier: 1.31.1
    -        version: 1.31.1
    +        specifier: 'catalog:'
    +        version: 1.32.0
           picocolors:
             specifier: 'catalog:'
             version: 1.1.1
    @@ -274,11 +367,11 @@ importers:
             specifier: 'catalog:'
             version: 4.0.3
           tsx:
    -        specifier: 4.21.0
    +        specifier: 'catalog:'
             version: 4.21.0
           vitest:
             specifier: 'catalog:'
    -        version: 4.0.18(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2)
    +        version: 4.1.0(@types/node@25.5.0)(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))
           zod-to-json-schema:
             specifier: 'catalog:'
             version: 3.25.1(zod@4.3.6)
    @@ -310,16 +403,35 @@ importers:
       cli/npm/win32-x64-msvc: {}
     
       doc:
    -    devDependencies:
    -      '@mdx-js/react':
    +    dependencies:
    +      '@theguild/remark-mermaid':
    +        specifier: 'catalog:'
    +        version: 0.3.0(react@19.2.4)
    +      mermaid:
    +        specifier: 'catalog:'
    +        version: 11.13.0
    +      next:
    +        specifier: 'catalog:'
    +        version: 16.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
    +      nextra:
             specifier: 'catalog:'
    -        version: 3.1.1(@types/react@19.2.14)(react@19.2.4)
    -      '@next/mdx':
    +        version: 4.6.1(next@16.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
    +      nextra-theme-docs:
             specifier: 'catalog:'
    -        version: 16.1.6(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))
    +        version: 4.6.1(@types/react@19.2.14)(immer@11.1.4)(next@16.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(nextra@4.6.1(next@16.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4))
    +      react:
    +        specifier: 'catalog:'
    +        version: 19.2.4
    +      react-dom:
    +        specifier: 'catalog:'
    +        version: 19.2.4(react@19.2.4)
    +    devDependencies:
           '@truenine/eslint10-config':
             specifier: 'catalog:'
    -        version: 2026.10209.11105(57cd6091d29b00e41b508df9848011ef)
    +        version: 2026.10318.10138(30aab4e6ca2f6a986fe995bf4241db33)
    +      '@types/node':
    +        specifier: 'catalog:'
    +        version: 25.5.0
           '@types/react':
             specifier: 'catalog:'
             version: 19.2.14
    @@ -328,16 +440,25 @@ importers:
             version: 19.2.3(@types/react@19.2.14)
           eslint:
             specifier: 'catalog:'
    -        version: 10.0.2(jiti@2.6.1)
    -      next:
    +        version: 10.0.3(jiti@2.6.1)
    +      fast-glob:
             specifier: 'catalog:'
    -        version: 16.1.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
    -      react:
    +        version: 3.3.3
    +      npm-run-all2:
             specifier: 'catalog:'
    -        version: 19.2.4
    -      react-dom:
    +        version: 8.0.4
    +      pagefind:
             specifier: 'catalog:'
    -        version: 19.2.4(react@19.2.4)
    +        version: 1.4.0
    +      tsx:
    +        specifier: 'catalog:'
    +        version: 4.21.0
    +      typescript:
    +        specifier: 'catalog:'
    +        version: 5.9.3
    +      yaml:
    +        specifier: 'catalog:'
    +        version: 2.8.2
     
       gui:
         devDependencies:
    @@ -346,22 +467,22 @@ importers:
             version: 4.7.0(monaco-editor@0.55.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
           '@tailwindcss/vite':
             specifier: 'catalog:'
    -        version: 4.2.1(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2))
    +        version: 4.2.2(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))
           '@tanstack/react-router':
             specifier: 'catalog:'
    -        version: 1.163.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
    +        version: 1.168.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
           '@tanstack/router-generator':
    -        specifier: ^1.164.0
    -        version: 1.164.0
    +        specifier: 'catalog:'
    +        version: 1.166.15
           '@tanstack/router-plugin':
             specifier: 'catalog:'
    -        version: 1.164.0(@tanstack/react-router@1.163.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2))
    +        version: 1.167.1(@tanstack/react-router@1.168.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))
           '@tauri-apps/api':
             specifier: 'catalog:'
             version: 2.10.1
           '@tauri-apps/cli':
             specifier: 'catalog:'
    -        version: 2.10.0
    +        version: 2.10.1
           '@tauri-apps/plugin-shell':
             specifier: 'catalog:'
             version: 2.3.5
    @@ -376,7 +497,7 @@ importers:
             version: 19.2.3(@types/react@19.2.14)
           '@vitejs/plugin-react':
             specifier: 'catalog:'
    -        version: 5.1.4(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2))
    +        version: 6.0.1(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))
           class-variance-authority:
             specifier: 'catalog:'
             version: 0.7.1
    @@ -385,13 +506,13 @@ importers:
             version: 2.1.1
           fast-check:
             specifier: 'catalog:'
    -        version: 4.5.3
    +        version: 4.6.0
           lucide-react:
             specifier: 'catalog:'
    -        version: 0.575.0(react@19.2.4)
    +        version: 0.577.0(react@19.2.4)
           material-icon-theme:
    -        specifier: ^5.31.0
    -        version: 5.31.0
    +        specifier: 'catalog:'
    +        version: 5.32.0
           monaco-editor:
             specifier: 'catalog:'
             version: 0.55.1
    @@ -402,44 +523,44 @@ importers:
             specifier: 'catalog:'
             version: 19.2.4(react@19.2.4)
           recharts:
    -        specifier: ^3.7.0
    -        version: 3.7.0(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react-is@19.2.4)(react@19.2.4)(redux@5.0.1)
    +        specifier: 'catalog:'
    +        version: 3.8.0(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react-is@19.2.4)(react@19.2.4)(redux@5.0.1)
           tailwind-merge:
             specifier: 'catalog:'
             version: 3.5.0
           tailwindcss:
             specifier: 'catalog:'
    -        version: 4.2.1
    +        version: 4.2.2
           tw-animate-css:
             specifier: 'catalog:'
             version: 1.4.0
           vitest:
             specifier: 'catalog:'
    -        version: 4.0.18(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2)
    +        version: 4.1.0(@types/node@25.5.0)(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))
     
       libraries/logger:
         devDependencies:
           '@napi-rs/cli':
    -        specifier: ^3.5.1
    -        version: 3.5.1(@emnapi/runtime@1.8.1)(@types/node@25.3.3)
    +        specifier: 'catalog:'
    +        version: 3.5.1(@emnapi/runtime@1.8.1)(@types/node@25.5.0)
           npm-run-all2:
             specifier: 'catalog:'
             version: 8.0.4
           tsdown:
             specifier: 'catalog:'
    -        version: 0.21.0-beta.2(synckit@0.11.12)(typescript@5.9.3)
    +        version: 0.21.4(synckit@0.11.12)(typescript@5.9.3)
           typescript:
             specifier: 'catalog:'
             version: 5.9.3
           vitest:
             specifier: 'catalog:'
    -        version: 4.0.18(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2)
    +        version: 4.1.0(@types/node@25.5.0)(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))
     
       libraries/md-compiler:
         devDependencies:
           '@napi-rs/cli':
    -        specifier: ^3.5.1
    -        version: 3.5.1(@emnapi/runtime@1.8.1)(@types/node@25.3.3)
    +        specifier: 'catalog:'
    +        version: 3.5.1(@emnapi/runtime@1.8.1)(@types/node@25.5.0)
           '@types/estree':
             specifier: 'catalog:'
             version: 1.0.8
    @@ -472,7 +593,7 @@ importers:
             version: 11.0.0
           tsdown:
             specifier: 'catalog:'
    -        version: 0.21.0-beta.2(synckit@0.11.12)(typescript@5.9.3)
    +        version: 0.21.4(synckit@0.11.12)(typescript@5.9.3)
           typescript:
             specifier: 'catalog:'
             version: 5.9.3
    @@ -481,7 +602,7 @@ importers:
             version: 11.0.5
           vitest:
             specifier: 'catalog:'
    -        version: 4.0.18(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2)
    +        version: 4.1.0(@types/node@25.5.0)(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))
           yaml:
             specifier: 'catalog:'
             version: 2.8.2
    @@ -489,32 +610,32 @@ importers:
       libraries/script-runtime:
         devDependencies:
           '@napi-rs/cli':
    -        specifier: ^3.5.1
    -        version: 3.5.1(@emnapi/runtime@1.8.1)(@types/node@25.3.3)
    +        specifier: 'catalog:'
    +        version: 3.5.1(@emnapi/runtime@1.8.1)(@types/node@25.5.0)
           '@truenine/eslint10-config':
             specifier: 'catalog:'
    -        version: 2026.10209.11105(57cd6091d29b00e41b508df9848011ef)
    +        version: 2026.10318.10138(30aab4e6ca2f6a986fe995bf4241db33)
           '@types/node':
             specifier: 'catalog:'
    -        version: 25.3.3
    +        version: 25.5.0
           eslint:
             specifier: 'catalog:'
    -        version: 10.0.2(jiti@2.6.1)
    +        version: 10.0.3(jiti@2.6.1)
           jiti:
    -        specifier: 2.6.1
    +        specifier: 'catalog:'
             version: 2.6.1
           npm-run-all2:
             specifier: 'catalog:'
             version: 8.0.4
           tsdown:
             specifier: 'catalog:'
    -        version: 0.21.0-beta.2(synckit@0.11.12)(typescript@5.9.3)
    +        version: 0.21.4(synckit@0.11.12)(typescript@5.9.3)
           typescript:
             specifier: 'catalog:'
             version: 5.9.3
           vitest:
             specifier: 'catalog:'
    -        version: 4.0.18(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2)
    +        version: 4.1.0(@types/node@25.5.0)(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))
     
       mcp:
         dependencies:
    @@ -530,19 +651,19 @@ importers:
         devDependencies:
           '@truenine/eslint10-config':
             specifier: 'catalog:'
    -        version: 2026.10209.11105(57cd6091d29b00e41b508df9848011ef)
    +        version: 2026.10318.10138(30aab4e6ca2f6a986fe995bf4241db33)
           '@types/node':
             specifier: 'catalog:'
    -        version: 25.3.3
    +        version: 25.5.0
           eslint:
             specifier: 'catalog:'
    -        version: 10.0.2(jiti@2.6.1)
    +        version: 10.0.3(jiti@2.6.1)
           npm-run-all2:
             specifier: 'catalog:'
             version: 8.0.4
           tsdown:
             specifier: 'catalog:'
    -        version: 0.21.0-beta.2(synckit@0.11.12)(typescript@5.9.3)
    +        version: 0.21.4(synckit@0.11.12)(typescript@5.9.3)
           tsx:
             specifier: 'catalog:'
             version: 4.21.0
    @@ -551,25 +672,28 @@ importers:
             version: 5.9.3
           vitest:
             specifier: 'catalog:'
    -        version: 4.0.18(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2)
    +        version: 4.1.0(@types/node@25.5.0)(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))
     
     packages:
     
    -  '@antfu/eslint-config@6.7.1':
    -    resolution: {integrity: sha512-+8GIMmOfrtAVXoqVK9sfovAlHPkp35ilntqZ6XloO/Rty36gOxaa8dvwCh8/eqwwIsloA/hDJo3Ef95TRbdyEg==}
    +  '@antfu/eslint-config@7.7.3':
    +    resolution: {integrity: sha512-BtroDxTvmWtvr3yJkdWVCvwsKlnEdkreoeOyrdNezc/W5qaiQNf2xjcsQ3N5Yy0x27h+0WFfW8rG8YlVioG6dw==}
         hasBin: true
         peerDependencies:
    -      '@eslint-react/eslint-plugin': ^2.0.1
    +      '@angular-eslint/eslint-plugin': ^21.1.0
    +      '@angular-eslint/eslint-plugin-template': ^21.1.0
    +      '@angular-eslint/template-parser': ^21.1.0
    +      '@eslint-react/eslint-plugin': ^2.11.0
           '@next/eslint-plugin-next': '>=15.0.0'
           '@prettier/plugin-xml': ^3.4.1
           '@unocss/eslint-plugin': '>=0.50.0'
           astro-eslint-parser: ^1.0.2
    -      eslint: ^9.10.0
    +      eslint: ^9.10.0 || ^10.0.0
           eslint-plugin-astro: ^1.2.0
           eslint-plugin-format: '>=0.1.0'
           eslint-plugin-jsx-a11y: '>=6.10.2'
           eslint-plugin-react-hooks: ^7.0.0
    -      eslint-plugin-react-refresh: ^0.4.19
    +      eslint-plugin-react-refresh: ^0.5.0
           eslint-plugin-solid: ^0.14.3
           eslint-plugin-svelte: '>=2.35.1'
           eslint-plugin-vuejs-accessibility: ^2.4.1
    @@ -577,6 +701,12 @@ packages:
           prettier-plugin-slidev: ^1.0.5
           svelte-eslint-parser: '>=0.37.0'
         peerDependenciesMeta:
    +      '@angular-eslint/eslint-plugin':
    +        optional: true
    +      '@angular-eslint/eslint-plugin-template':
    +        optional: true
    +      '@angular-eslint/template-parser':
    +        optional: true
           '@eslint-react/eslint-plugin':
             optional: true
           '@next/eslint-plugin-next':
    @@ -629,8 +759,8 @@ packages:
         resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==}
         engines: {node: '>=6.9.0'}
     
    -  '@babel/generator@8.0.0-rc.1':
    -    resolution: {integrity: sha512-3ypWOOiC4AYHKr8vYRVtWtWmyvcoItHtVqF8paFax+ydpmUdPsJpLBkBBs5ItmhdrwC3a0ZSqqFAdzls4ODP3w==}
    +  '@babel/generator@8.0.0-rc.2':
    +    resolution: {integrity: sha512-oCQ1IKPwkzCeJzAPb7Fv8rQ9k5+1sG8mf2uoHiMInPYvkRfrDJxbTIbH51U+jstlkghus0vAi3EBvkfvEsYNLQ==}
         engines: {node: ^20.19.0 || >=22.12.0}
     
       '@babel/helper-compilation-targets@7.28.6':
    @@ -667,8 +797,8 @@ packages:
         resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
         engines: {node: '>=6.9.0'}
     
    -  '@babel/helper-validator-identifier@8.0.0-rc.1':
    -    resolution: {integrity: sha512-I4YnARytXC2RzkLNVnf5qFNFMzp679qZpmtw/V3Jt2uGnWiIxyJtaukjG7R8pSx8nG2NamICpGfljQsogj+FbQ==}
    +  '@babel/helper-validator-identifier@8.0.0-rc.2':
    +    resolution: {integrity: sha512-xExUBkuXWJjVuIbO7z6q7/BA9bgfJDEhVL0ggrggLMbg0IzCUWGT1hZGE8qUH7Il7/RD/a6cZ3AAFrrlp1LF/A==}
         engines: {node: ^20.19.0 || >=22.12.0}
     
       '@babel/helper-validator-option@7.27.1':
    @@ -684,8 +814,8 @@ packages:
         engines: {node: '>=6.0.0'}
         hasBin: true
     
    -  '@babel/parser@8.0.0-rc.1':
    -    resolution: {integrity: sha512-6HyyU5l1yK/7h9Ki52i5h6mDAx4qJdiLQO4FdCyJNoB/gy3T3GGJdhQzzbZgvgZCugYBvwtQiWRt94QKedHnkA==}
    +  '@babel/parser@8.0.0-rc.2':
    +    resolution: {integrity: sha512-29AhEtcq4x8Dp3T72qvUMZHx0OMXCj4Jy/TEReQa+KWLln524Cj1fWb3QFi0l/xSpptQBR6y9RNEXuxpFvwiUQ==}
         engines: {node: ^20.19.0 || >=22.12.0}
         hasBin: true
     
    @@ -701,18 +831,6 @@ packages:
         peerDependencies:
           '@babel/core': ^7.0.0-0
     
    -  '@babel/plugin-transform-react-jsx-self@7.27.1':
    -    resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-react-jsx-source@7.27.1':
    -    resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
       '@babel/template@7.28.6':
         resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==}
         engines: {node: '>=6.9.0'}
    @@ -725,34 +843,57 @@ packages:
         resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==}
         engines: {node: '>=6.9.0'}
     
    -  '@babel/types@8.0.0-rc.1':
    -    resolution: {integrity: sha512-ubmJ6TShyaD69VE9DQrlXcdkvJbmwWPB8qYj0H2kaJi29O7vJT9ajSdBd2W8CG34pwL9pYA74fi7RHC1qbLoVQ==}
    +  '@babel/types@8.0.0-rc.2':
    +    resolution: {integrity: sha512-91gAaWRznDwSX4E2tZ1YjBuIfnQVOFDCQ2r0Toby0gu4XEbyF623kXLMA8d4ZbCu+fINcrudkmEcwSUHgDDkNw==}
         engines: {node: ^20.19.0 || >=22.12.0}
     
       '@bcoe/v8-coverage@1.0.2':
         resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==}
         engines: {node: '>=18'}
     
    -  '@clack/core@0.5.0':
    -    resolution: {integrity: sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow==}
    +  '@braintree/sanitize-url@7.1.2':
    +    resolution: {integrity: sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==}
     
    -  '@clack/core@1.0.1':
    -    resolution: {integrity: sha512-WKeyK3NOBwDOzagPR5H08rFk9D/WuN705yEbuZvKqlkmoLM2woKtXb10OO2k1NoSU4SFG947i2/SCYh+2u5e4g==}
    +  '@chevrotain/cst-dts-gen@11.1.2':
    +    resolution: {integrity: sha512-XTsjvDVB5nDZBQB8o0o/0ozNelQtn2KrUVteIHSlPd2VAV2utEb6JzyCJaJ8tGxACR4RiBNWy5uYUHX2eji88Q==}
     
    -  '@clack/prompts@0.11.0':
    -    resolution: {integrity: sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==}
    +  '@chevrotain/gast@11.1.2':
    +    resolution: {integrity: sha512-Z9zfXR5jNZb1Hlsd/p+4XWeUFugrHirq36bKzPWDSIacV+GPSVXdk+ahVWZTwjhNwofAWg/sZg58fyucKSQx5g==}
     
    -  '@clack/prompts@1.0.1':
    -    resolution: {integrity: sha512-/42G73JkuYdyWZ6m8d/CJtBrGl1Hegyc7Fy78m5Ob+jF85TOUmLR5XLce/U3LxYAw0kJ8CT5aI99RIvPHcGp/Q==}
    +  '@chevrotain/regexp-to-ast@11.1.2':
    +    resolution: {integrity: sha512-nMU3Uj8naWer7xpZTYJdxbAs6RIv/dxYzkYU8GSwgUtcAAlzjcPfX1w+RKRcYG8POlzMeayOQ/znfwxEGo5ulw==}
     
    -  '@dprint/formatter@0.3.0':
    -    resolution: {integrity: sha512-N9fxCxbaBOrDkteSOzaCqwWjso5iAe+WJPsHC021JfHNj2ThInPNEF13ORDKta3llq5D1TlclODCvOvipH7bWQ==}
    +  '@chevrotain/types@11.1.2':
    +    resolution: {integrity: sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==}
     
    -  '@dprint/markdown@0.17.8':
    -    resolution: {integrity: sha512-ukHFOg+RpG284aPdIg7iPrCYmMs3Dqy43S1ejybnwlJoFiW02b+6Bbr5cfZKFRYNP3dKGM86BqHEnMzBOyLvvA==}
    +  '@chevrotain/utils@11.1.2':
    +    resolution: {integrity: sha512-4mudFAQ6H+MqBTfqLmU7G1ZwRzCLfJEooL/fsF6rCX5eePMbGhoy5n4g+G4vlh2muDcsCTJtL+uKbOzWxs5LHA==}
     
    -  '@dprint/toml@0.6.4':
    -    resolution: {integrity: sha512-bZXIUjxr0LIuHWshZr/5mtUkOrnh0NKVZEF6ACojW5z7zkJu7s9sV2mMXm8XQDqN4cJzdHYUYzUyEGdfciaLJA==}
    +  '@clack/core@1.1.0':
    +    resolution: {integrity: sha512-SVcm4Dqm2ukn64/8Gub2wnlA5nS2iWJyCkdNHcvNHPIeBTGojpdJ+9cZKwLfmqy7irD4N5qLteSilJlE0WLAtA==}
    +
    +  '@clack/prompts@1.1.0':
    +    resolution: {integrity: sha512-pkqbPGtohJAvm4Dphs2M8xE29ggupihHdy1x84HNojZuMtFsHiUlRvqD24tM2+XmI+61LlfNceM3Wr7U5QES5g==}
    +
    +  '@dprint/formatter@0.5.1':
    +    resolution: {integrity: sha512-cdZUrm0iv/FnnY3CKE2dEcVhNEzrC551aE2h2mTFwQCRBrqyARLDnb7D+3PlXTUVp3s34ftlnGOVCmhLT9DeKA==}
    +
    +  '@dprint/markdown@0.21.1':
    +    resolution: {integrity: sha512-XbZ/R7vRrBaZFYXG6vAvLvtaMVXHu8XB+xwie7OYrG+dPoGDP8UADGirIbzUyX8TmrAZcl6QBmalipTGlpzRmQ==}
    +
    +  '@dprint/toml@0.7.0':
    +    resolution: {integrity: sha512-eFaQTcfxKHB+YyTh83x7GEv+gDPuj9q5NFOTaoj5rZmQTbj6OgjjMxUicmS1R8zYcx8YAq5oA9J3YFa5U6x2gA==}
    +
    +  '@e18e/eslint-plugin@0.2.0':
    +    resolution: {integrity: sha512-mXgODVwhuDjTJ+UT+XSvmMmCidtGKfrV5nMIv1UtpWex2pYLsIM3RSpT8HWIMAebS9qANbXPKlSX4BE7ZvuCgA==}
    +    peerDependencies:
    +      eslint: ^9.0.0 || ^10.0.0
    +      oxlint: ^1.41.0
    +    peerDependenciesMeta:
    +      eslint:
    +        optional: true
    +      oxlint:
    +        optional: true
     
       '@emnapi/core@1.8.1':
         resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==}
    @@ -763,10 +904,6 @@ packages:
       '@emnapi/wasi-threads@1.1.0':
         resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==}
     
    -  '@es-joy/jsdoccomment@0.78.0':
    -    resolution: {integrity: sha512-rQkU5u8hNAq2NVRzHnIUUvR6arbO0b6AOlvpTNS48CkiKSn/xtNfOzBK23JE4SiW89DgvU7GtxLVgV4Vn2HBAw==}
    -    engines: {node: '>=20.11.0'}
    -
       '@es-joy/jsdoccomment@0.84.0':
         resolution: {integrity: sha512-0xew1CxOam0gV5OMjh2KjFQZsKL2bByX1+q4j3E73MpYIdyUxcZb/xQct9ccUb+ve5KGUYbCUxyPnYB7RbuP+w==}
         engines: {node: ^20.19.0 || ^22.13.0 || >=24}
    @@ -931,8 +1068,8 @@ packages:
         cpu: [x64]
         os: [win32]
     
    -  '@eslint-community/eslint-plugin-eslint-comments@4.7.0':
    -    resolution: {integrity: sha512-wxyEBQOUAXp4HjnYWucQy7iq58RR1WXJhm6bjw+sGlMDEKJmzJVe2MLnd6iazmQFYGOxoUrw27EsJfpoqiI7tQ==}
    +  '@eslint-community/eslint-plugin-eslint-comments@4.7.1':
    +    resolution: {integrity: sha512-Ql2nJFwA8wUGpILYGOQaT1glPsmvEwE0d+a+l7AALLzQvInqdbXJdx7aSu0DpUX9dB1wMVBMhm99/++S3MdEtQ==}
         engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
         peerDependencies:
           eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0
    @@ -956,42 +1093,82 @@ packages:
           eslint:
             optional: true
     
    -  '@eslint/config-array@0.23.2':
    -    resolution: {integrity: sha512-YF+fE6LV4v5MGWRGj7G404/OZzGNepVF8fxk7jqmqo3lrza7a0uUcDnROGRBG1WFC1omYUS/Wp1f42i0M+3Q3A==}
    +  '@eslint/config-array@0.23.3':
    +    resolution: {integrity: sha512-j+eEWmB6YYLwcNOdlwQ6L2OsptI/LO6lNBuLIqe5R7RetD658HLoF+Mn7LzYmAWWNNzdC6cqP+L6r8ujeYXWLw==}
         engines: {node: ^20.19.0 || ^22.13.0 || >=24}
     
       '@eslint/config-helpers@0.5.2':
         resolution: {integrity: sha512-a5MxrdDXEvqnIq+LisyCX6tQMPF/dSJpCfBgBauY+pNZ28yCtSsTvyTYrMhaI+LK26bVyCJfJkT0u8KIj2i1dQ==}
         engines: {node: ^20.19.0 || ^22.13.0 || >=24}
     
    +  '@eslint/config-helpers@0.5.3':
    +    resolution: {integrity: sha512-lzGN0onllOZCGroKJmRwY6QcEHxbjBw1gwB8SgRSqK8YbbtEXMvKynsXc3553ckIEBxsbMBU7oOZXKIPGZNeZw==}
    +    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
    +
       '@eslint/core@0.17.0':
         resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==}
         engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     
    -  '@eslint/core@1.1.0':
    -    resolution: {integrity: sha512-/nr9K9wkr3P1EzFTdFdMoLuo1PmIxjmwvPozwoSodjNBdefGujXQUF93u1DDZpEaTuDvMsIQddsd35BwtrW9Xw==}
    +  '@eslint/core@1.1.1':
    +    resolution: {integrity: sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ==}
         engines: {node: ^20.19.0 || ^22.13.0 || >=24}
     
    -  '@eslint/js@9.39.2':
    -    resolution: {integrity: sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==}
    -    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    +  '@eslint/js@10.0.1':
    +    resolution: {integrity: sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==}
    +    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
    +    peerDependencies:
    +      eslint: ^10.0.0
    +    peerDependenciesMeta:
    +      eslint:
    +        optional: true
     
       '@eslint/markdown@7.5.1':
         resolution: {integrity: sha512-R8uZemG9dKTbru/DQRPblbJyXpObwKzo8rv1KYGGuPUPtjM4LXBYM9q5CIZAComzZupws3tWbDwam5AFpPLyJQ==}
         engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     
    -  '@eslint/object-schema@3.0.2':
    -    resolution: {integrity: sha512-HOy56KJt48Bx8KmJ+XGQNSUMT/6dZee/M54XyUyuvTvPXJmsERRvBchsUVx1UMe1WwIH49XLAczNC7V2INsuUw==}
    +  '@eslint/object-schema@3.0.3':
    +    resolution: {integrity: sha512-iM869Pugn9Nsxbh/YHRqYiqd23AmIbxJOcpUMOuWCVNdoQJ5ZtwL6h3t0bcZzJUlC3Dq9jCFCESBZnX0GTv7iQ==}
         engines: {node: ^20.19.0 || ^22.13.0 || >=24}
     
       '@eslint/plugin-kit@0.4.1':
         resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==}
         engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     
    -  '@eslint/plugin-kit@0.6.0':
    -    resolution: {integrity: sha512-bIZEUzOI1jkhviX2cp5vNyXQc6olzb2ohewQubuYlMXZ2Q/XjBO0x0XhGPvc9fjSIiUN0vw+0hq53BJ4eQSJKQ==}
    +  '@eslint/plugin-kit@0.6.1':
    +    resolution: {integrity: sha512-iH1B076HoAshH1mLpHMgwdGeTs0CYwL0SPMkGuSebZrwBp16v415e9NZXg2jtrqPVQjf6IANe2Vtlr5KswtcZQ==}
         engines: {node: ^20.19.0 || ^22.13.0 || >=24}
     
    +  '@floating-ui/core@1.7.5':
    +    resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==}
    +
    +  '@floating-ui/dom@1.7.6':
    +    resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==}
    +
    +  '@floating-ui/react-dom@2.1.8':
    +    resolution: {integrity: sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==}
    +    peerDependencies:
    +      react: '>=16.8.0'
    +      react-dom: '>=16.8.0'
    +
    +  '@floating-ui/react@0.26.28':
    +    resolution: {integrity: sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw==}
    +    peerDependencies:
    +      react: '>=16.8.0'
    +      react-dom: '>=16.8.0'
    +
    +  '@floating-ui/utils@0.2.11':
    +    resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==}
    +
    +  '@formatjs/intl-localematcher@0.6.2':
    +    resolution: {integrity: sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA==}
    +
    +  '@headlessui/react@2.2.9':
    +    resolution: {integrity: sha512-Mb+Un58gwBn0/yWZfyrCh0TJyurtT+dETj7YHleylHk5od3dv2XqETPGWMyQ5/7sYN7oWdyM1u9MvC0OC8UmzQ==}
    +    engines: {node: '>=10'}
    +    peerDependencies:
    +      react: ^18 || ^19 || ^19.0.0-rc
    +      react-dom: ^18 || ^19 || ^19.0.0-rc
    +
       '@hono/node-server@1.19.11':
         resolution: {integrity: sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==}
         engines: {node: '>=18.14.1'}
    @@ -1014,6 +1191,12 @@ packages:
         resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
         engines: {node: '>=18.18'}
     
    +  '@iconify/types@2.0.0':
    +    resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
    +
    +  '@iconify/utils@3.1.0':
    +    resolution: {integrity: sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==}
    +
       '@img/colour@1.1.0':
         resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==}
         engines: {node: '>=18'}
    @@ -1317,11 +1500,11 @@ packages:
       '@jridgewell/trace-mapping@0.3.31':
         resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
     
    -  '@mdx-js/react@3.1.1':
    -    resolution: {integrity: sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==}
    -    peerDependencies:
    -      '@types/react': '>=16'
    -      react: '>=16'
    +  '@mdx-js/mdx@3.1.1':
    +    resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==}
    +
    +  '@mermaid-js/parser@1.0.1':
    +    resolution: {integrity: sha512-opmV19kN1JsK0T6HhhokHpcVkqKpF+x2pPDKKM2ThHtZAB5F4PROopk0amuVYK5qMrIA4erzpNm8gmPNJgMDxQ==}
     
       '@modelcontextprotocol/sdk@1.27.1':
         resolution: {integrity: sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA==}
    @@ -1500,6 +1683,106 @@ packages:
         resolution: {integrity: sha512-zS5LuN1OBPAyZpda2ZZgYOEDC+xecUdAGnrvbYzjnLXkrq/OBC3B9qcRvlxbDR3k5H/gVfvef1/jyUqPknqjbg==}
         engines: {node: '>= 10'}
     
    +  '@napi-rs/simple-git-android-arm-eabi@0.1.22':
    +    resolution: {integrity: sha512-JQZdnDNm8o43A5GOzwN/0Tz3CDBQtBUNqzVwEopm32uayjdjxev1Csp1JeaqF3v9djLDIvsSE39ecsN2LhCKKQ==}
    +    engines: {node: '>= 10'}
    +    cpu: [arm]
    +    os: [android]
    +
    +  '@napi-rs/simple-git-android-arm64@0.1.22':
    +    resolution: {integrity: sha512-46OZ0SkhnvM+fapWjzg/eqbJvClxynUpWYyYBn4jAj7GQs1/Yyc8431spzDmkA8mL0M7Xo8SmbkzTDE7WwYAfg==}
    +    engines: {node: '>= 10'}
    +    cpu: [arm64]
    +    os: [android]
    +
    +  '@napi-rs/simple-git-darwin-arm64@0.1.22':
    +    resolution: {integrity: sha512-zH3h0C8Mkn9//MajPI6kHnttywjsBmZ37fhLX/Fiw5XKu84eHA6dRyVtMzoZxj6s+bjNTgaMgMUucxPn9ktxTQ==}
    +    engines: {node: '>= 10'}
    +    cpu: [arm64]
    +    os: [darwin]
    +
    +  '@napi-rs/simple-git-darwin-x64@0.1.22':
    +    resolution: {integrity: sha512-GZN7lRAkGKB6PJxWsoyeYJhh85oOOjVNyl+/uipNX8bR+mFDCqRsCE3rRCFGV9WrZUHXkcuRL2laIRn7lLi3ag==}
    +    engines: {node: '>= 10'}
    +    cpu: [x64]
    +    os: [darwin]
    +
    +  '@napi-rs/simple-git-freebsd-x64@0.1.22':
    +    resolution: {integrity: sha512-xyqX1C5I0WBrUgZONxHjZH5a4LqQ9oki3SKFAVpercVYAcx3pq6BkZy1YUOP4qx78WxU1CCNfHBN7V+XO7D99A==}
    +    engines: {node: '>= 10'}
    +    cpu: [x64]
    +    os: [freebsd]
    +
    +  '@napi-rs/simple-git-linux-arm-gnueabihf@0.1.22':
    +    resolution: {integrity: sha512-4LOtbp9ll93B9fxRvXiUJd1/RM3uafMJE7dGBZGKWBMGM76+BAcCEUv2BY85EfsU/IgopXI6n09TycRfPWOjxA==}
    +    engines: {node: '>= 10'}
    +    cpu: [arm]
    +    os: [linux]
    +
    +  '@napi-rs/simple-git-linux-arm64-gnu@0.1.22':
    +    resolution: {integrity: sha512-GVOjP/JjCzbQ0kSqao7ctC/1sodVtv5VF57rW9BFpo2y6tEYPCqHnkQkTpieuwMNe+TVOhBUC1+wH0d9/knIHg==}
    +    engines: {node: '>= 10'}
    +    cpu: [arm64]
    +    os: [linux]
    +    libc: [glibc]
    +
    +  '@napi-rs/simple-git-linux-arm64-musl@0.1.22':
    +    resolution: {integrity: sha512-MOs7fPyJiU/wqOpKzAOmOpxJ/TZfP4JwmvPad/cXTOWYwwyppMlXFRms3i98EU3HOazI/wMU2Ksfda3+TBluWA==}
    +    engines: {node: '>= 10'}
    +    cpu: [arm64]
    +    os: [linux]
    +    libc: [musl]
    +
    +  '@napi-rs/simple-git-linux-ppc64-gnu@0.1.22':
    +    resolution: {integrity: sha512-L59dR30VBShRUIZ5/cQHU25upNgKS0AMQ7537J6LCIUEFwwXrKORZKJ8ceR+s3Sr/4jempWVvMdjEpFDE4HYww==}
    +    engines: {node: '>= 10'}
    +    cpu: [ppc64]
    +    os: [linux]
    +    libc: [glibc]
    +
    +  '@napi-rs/simple-git-linux-s390x-gnu@0.1.22':
    +    resolution: {integrity: sha512-4FHkPlCSIZUGC6HiADffbe6NVoTBMd65pIwcd40IDbtFKOgFMBA+pWRqKiQ21FERGH16Zed7XHJJoY3jpOqtmQ==}
    +    engines: {node: '>= 10'}
    +    cpu: [s390x]
    +    os: [linux]
    +    libc: [glibc]
    +
    +  '@napi-rs/simple-git-linux-x64-gnu@0.1.22':
    +    resolution: {integrity: sha512-Ei1tM5Ho/dwknF3pOzqkNW9Iv8oFzRxE8uOhrITcdlpxRxVrBVptUF6/0WPdvd7R9747D/q61QG/AVyWsWLFKw==}
    +    engines: {node: '>= 10'}
    +    cpu: [x64]
    +    os: [linux]
    +    libc: [glibc]
    +
    +  '@napi-rs/simple-git-linux-x64-musl@0.1.22':
    +    resolution: {integrity: sha512-zRYxg7it0p3rLyEJYoCoL2PQJNgArVLyNavHW03TFUAYkYi5bxQ/UFNVpgxMaXohr5yu7qCBqeo9j4DWeysalg==}
    +    engines: {node: '>= 10'}
    +    cpu: [x64]
    +    os: [linux]
    +    libc: [musl]
    +
    +  '@napi-rs/simple-git-win32-arm64-msvc@0.1.22':
    +    resolution: {integrity: sha512-XGFR1fj+Y9cWACcovV2Ey/R2xQOZKs8t+7KHPerYdJ4PtjVzGznI4c2EBHXtdOIYvkw7tL5rZ7FN1HJKdD5Quw==}
    +    engines: {node: '>= 10'}
    +    cpu: [arm64]
    +    os: [win32]
    +
    +  '@napi-rs/simple-git-win32-ia32-msvc@0.1.22':
    +    resolution: {integrity: sha512-Gqr9Y0gs6hcNBA1IXBpoqTFnnIoHuZGhrYqaZzEvGMLrTrpbXrXVEtX3DAAD2RLc1b87CPcJ49a7sre3PU3Rfw==}
    +    engines: {node: '>= 10'}
    +    cpu: [ia32]
    +    os: [win32]
    +
    +  '@napi-rs/simple-git-win32-x64-msvc@0.1.22':
    +    resolution: {integrity: sha512-hQjcreHmUcpw4UrtkOron1/TQObfe484lxiXFLLUj7aWnnnOVs1mnXq5/Bo9+3NYZldFpFRJPdPBeHCisXkKJg==}
    +    engines: {node: '>= 10'}
    +    cpu: [x64]
    +    os: [win32]
    +
    +  '@napi-rs/simple-git@0.1.22':
    +    resolution: {integrity: sha512-bMVoAKhpjTOPHkW/lprDPwv5aD4R4C3Irt8vn+SKA9wudLe9COLxOhurrKRsxmZccUbWXRF7vukNeGUAj5P8kA==}
    +    engines: {node: '>= 10'}
    +
       '@napi-rs/tar-android-arm-eabi@1.1.0':
         resolution: {integrity: sha512-h2Ryndraj/YiKgMV/r5by1cDusluYIRT0CaE0/PekQ4u+Wpy2iUVqvzVU98ZPnhXaNeYxEvVJHNGafpOfaD0TA==}
         engines: {node: '>= 10'}
    @@ -1693,71 +1976,60 @@ packages:
         resolution: {integrity: sha512-enkZYyuCdo+9jneCPE/0fjIta4wWnvVN9hBo2HuiMpRF0q3lzv1J6b/cl7i0mxZUKhBrV3aCKDBQnCOhwKbPmQ==}
         engines: {node: '>= 10'}
     
    -  '@next/env@16.1.6':
    -    resolution: {integrity: sha512-N1ySLuZjnAtN3kFnwhAwPvZah8RJxKasD7x1f8shFqhncnWZn4JMfg37diLNuoHsLAlrDfM3g4mawVdtAG8XLQ==}
    +  '@next/env@16.2.0':
    +    resolution: {integrity: sha512-OZIbODWWAi0epQRCRjNe1VO45LOFBzgiyqmTLzIqWq6u1wrxKnAyz1HH6tgY/Mc81YzIjRPoYsPAEr4QV4l9TA==}
     
    -  '@next/eslint-plugin-next@16.1.0':
    -    resolution: {integrity: sha512-sooC/k0LCF4/jLXYHpgfzJot04lZQqsttn8XJpTguP8N3GhqXN3wSkh68no2OcZzS/qeGwKDFTqhZ8WofdXmmQ==}
    +  '@next/eslint-plugin-next@16.2.0':
    +    resolution: {integrity: sha512-3D3pEMcGKfENC9Pzlkr67GOm+205+5hRdYPZvHuNIy5sr9k0ybSU8g+sxOO/R/RLEh/gWZ3UlY+5LmEyZ1xgXQ==}
     
    -  '@next/mdx@16.1.6':
    -    resolution: {integrity: sha512-PT5JR4WPPYOls7WD6xEqUVVI9HDY8kY7XLQsNYB2lSZk5eJSXWu3ECtIYmfR0hZpx8Sg7BKZYKi2+u5OTSEx0w==}
    -    peerDependencies:
    -      '@mdx-js/loader': '>=0.15.0'
    -      '@mdx-js/react': '>=0.15.0'
    -    peerDependenciesMeta:
    -      '@mdx-js/loader':
    -        optional: true
    -      '@mdx-js/react':
    -        optional: true
    -
    -  '@next/swc-darwin-arm64@16.1.6':
    -    resolution: {integrity: sha512-wTzYulosJr/6nFnqGW7FrG3jfUUlEf8UjGA0/pyypJl42ExdVgC6xJgcXQ+V8QFn6niSG2Pb8+MIG1mZr2vczw==}
    +  '@next/swc-darwin-arm64@16.2.0':
    +    resolution: {integrity: sha512-/JZsqKzKt01IFoiLLAzlNqys7qk2F3JkcUhj50zuRhKDQkZNOz9E5N6wAQWprXdsvjRP4lTFj+/+36NSv5AwhQ==}
         engines: {node: '>= 10'}
         cpu: [arm64]
         os: [darwin]
     
    -  '@next/swc-darwin-x64@16.1.6':
    -    resolution: {integrity: sha512-BLFPYPDO+MNJsiDWbeVzqvYd4NyuRrEYVB5k2N3JfWncuHAy2IVwMAOlVQDFjj+krkWzhY2apvmekMkfQR0CUQ==}
    +  '@next/swc-darwin-x64@16.2.0':
    +    resolution: {integrity: sha512-/hV8erWq4SNlVgglUiW5UmQ5Hwy5EW/AbbXlJCn6zkfKxTy/E/U3V8U1Ocm2YCTUoFgQdoMxRyRMOW5jYy4ygg==}
         engines: {node: '>= 10'}
         cpu: [x64]
         os: [darwin]
     
    -  '@next/swc-linux-arm64-gnu@16.1.6':
    -    resolution: {integrity: sha512-OJYkCd5pj/QloBvoEcJ2XiMnlJkRv9idWA/j0ugSuA34gMT6f5b7vOiCQHVRpvStoZUknhl6/UxOXL4OwtdaBw==}
    +  '@next/swc-linux-arm64-gnu@16.2.0':
    +    resolution: {integrity: sha512-GkjL/Q7MWOwqWR9zoxu1TIHzkOI2l2BHCf7FzeQG87zPgs+6WDh+oC9Sw9ARuuL/FUk6JNCgKRkA6rEQYadUaw==}
         engines: {node: '>= 10'}
         cpu: [arm64]
         os: [linux]
         libc: [glibc]
     
    -  '@next/swc-linux-arm64-musl@16.1.6':
    -    resolution: {integrity: sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ==}
    +  '@next/swc-linux-arm64-musl@16.2.0':
    +    resolution: {integrity: sha512-1ffhC6KY5qWLg5miMlKJp3dZbXelEfjuXt1qcp5WzSCQy36CV3y+JT7OC1WSFKizGQCDOcQbfkH/IjZP3cdRNA==}
         engines: {node: '>= 10'}
         cpu: [arm64]
         os: [linux]
         libc: [musl]
     
    -  '@next/swc-linux-x64-gnu@16.1.6':
    -    resolution: {integrity: sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ==}
    +  '@next/swc-linux-x64-gnu@16.2.0':
    +    resolution: {integrity: sha512-FmbDcZQ8yJRq93EJSL6xaE0KK/Rslraf8fj1uViGxg7K4CKBCRYSubILJPEhjSgZurpcPQq12QNOJQ0DRJl6Hg==}
         engines: {node: '>= 10'}
         cpu: [x64]
         os: [linux]
         libc: [glibc]
     
    -  '@next/swc-linux-x64-musl@16.1.6':
    -    resolution: {integrity: sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg==}
    +  '@next/swc-linux-x64-musl@16.2.0':
    +    resolution: {integrity: sha512-HzjIHVkmGAwRbh/vzvoBWWEbb8BBZPxBvVbDQDvzHSf3D8RP/4vjw7MNLDXFF9Q1WEzeQyEj2zdxBtVAHu5Oyw==}
         engines: {node: '>= 10'}
         cpu: [x64]
         os: [linux]
         libc: [musl]
     
    -  '@next/swc-win32-arm64-msvc@16.1.6':
    -    resolution: {integrity: sha512-gQmm8izDTPgs+DCWH22kcDmuUp7NyiJgEl18bcr8irXA5N2m2O+JQIr6f3ct42GOs9c0h8QF3L5SzIxcYAAXXw==}
    +  '@next/swc-win32-arm64-msvc@16.2.0':
    +    resolution: {integrity: sha512-UMiFNQf5H7+1ZsZPxEsA064WEuFbRNq/kEXyepbCnSErp4f5iut75dBA8UeerFIG3vDaQNOfCpevnERPp2V+nA==}
         engines: {node: '>= 10'}
         cpu: [arm64]
         os: [win32]
     
    -  '@next/swc-win32-x64-msvc@16.1.6':
    -    resolution: {integrity: sha512-NRfO39AIrzBnixKbjuo2YiYhB6o9d8v/ymU9m/Xk8cyVk+k7XylniXkHwjs4s70wedVffc6bQNbufk5v0xEm0A==}
    +  '@next/swc-win32-x64-msvc@16.2.0':
    +    resolution: {integrity: sha512-DRrNJKW+/eimrZgdhVN1uvkN1OI4j6Lpefwr44jKQ0YQzztlmOBUUzHuV5GxOMPK3nmodAYElUVCY8ZXo/IWeA==}
         engines: {node: '>= 10'}
         cpu: [x64]
         os: [win32]
    @@ -1826,252 +2098,448 @@ packages:
       '@octokit/types@16.0.0':
         resolution: {integrity: sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==}
     
    -  '@oxc-project/types@0.114.0':
    -    resolution: {integrity: sha512-//nBfbzHQHvJs8oFIjv6coZ6uxQ4alLfiPe6D5vit6c4pmxATHHlVwgB1k+Hv4yoAMyncdxgRBF5K4BYWUCzvA==}
    +  '@ota-meshi/ast-token-store@0.3.0':
    +    resolution: {integrity: sha512-XRO0zi2NIUKq2lUk3T1ecFSld1fMWRKE6naRFGkgkdeosx7IslyUKNv5Dcb5PJTja9tHJoFu0v/7yEpAkrkrTg==}
    +    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
     
    -  '@pkgr/core@0.2.9':
    -    resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==}
    -    engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
    +  '@oxc-project/types@0.115.0':
    +    resolution: {integrity: sha512-4n91DKnebUS4yjUHl2g3/b2T+IUdCfmoZGhmwsovZCDaJSs+QkVAM+0AqqTxHSsHfeiMuueT75cZaZcT/m0pSw==}
     
    -  '@quansync/fs@1.0.0':
    -    resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==}
    +  '@oxc-project/types@0.120.0':
    +    resolution: {integrity: sha512-k1YNu55DuvAip/MGE1FTsIuU3FUCn6v/ujG9V7Nq5Df/kX2CWb13hhwD0lmJGMGqE+bE1MXvv9SZVnMzEXlWcg==}
     
    -  '@reduxjs/toolkit@2.11.2':
    -    resolution: {integrity: sha512-Kd6kAHTA6/nUpp8mySPqj3en3dm0tdMIgbttnQ1xFMVpufoj+ADi8pXLBsd4xzTRHQa7t/Jv8W5UnCuW4kuWMQ==}
    -    peerDependencies:
    -      react: ^16.9.0 || ^17.0.0 || ^18 || ^19
    -      react-redux: ^7.2.1 || ^8.1.3 || ^9.0.0
    -    peerDependenciesMeta:
    -      react:
    -        optional: true
    -      react-redux:
    -        optional: true
    +  '@oxfmt/binding-android-arm-eabi@0.35.0':
    +    resolution: {integrity: sha512-BaRKlM3DyG81y/xWTsE6gZiv89F/3pHe2BqX2H4JbiB8HNVlWWtplzgATAE5IDSdwChdeuWLDTQzJ92Lglw3ZA==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [arm]
    +    os: [android]
     
    -  '@rolldown/binding-android-arm64@1.0.0-rc.5':
    -    resolution: {integrity: sha512-zCEmUrt1bggwgBgeKLxNj217J1OrChrp3jJt24VK9jAharSTeVaHODNL+LpcQVhRz+FktYWfT9cjo5oZ99ZLpg==}
    +  '@oxfmt/binding-android-arm64@0.35.0':
    +    resolution: {integrity: sha512-/O+EbuAJYs6nde/anv+aID6uHsGQApyE9JtYBo/79KyU8e6RBN3DMbT0ix97y1SOnCglurmL2iZ+hlohjP2PnQ==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [arm64]
         os: [android]
     
    -  '@rolldown/binding-darwin-arm64@1.0.0-rc.5':
    -    resolution: {integrity: sha512-ZP9xb9lPAex36pvkNWCjSEJW/Gfdm9I3ssiqOFLmpZ/vosPXgpoGxCmh+dX1Qs+/bWQE6toNFXWWL8vYoKoK9Q==}
    +  '@oxfmt/binding-darwin-arm64@0.35.0':
    +    resolution: {integrity: sha512-pGqRtqlNdn9d4VrmGUWVyQjkw79ryhI6je9y2jfqNUIZCfqceob+R97YYAoG7C5TFyt8ILdLVoN+L2vw/hSFyA==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [arm64]
         os: [darwin]
     
    -  '@rolldown/binding-darwin-x64@1.0.0-rc.5':
    -    resolution: {integrity: sha512-7IdrPunf6dp9mywMgTOKMMGDnMHQ6+h5gRl6LW8rhD8WK2kXX0IwzcM5Zc0B5J7xQs8QWOlKjv8BJsU/1CD3pg==}
    +  '@oxfmt/binding-darwin-x64@0.35.0':
    +    resolution: {integrity: sha512-8GmsDcSozTPjrCJeGpp+sCmS9+9V5yRrdEZ1p/sTWxPG5nYeAfSLuS0nuEYjXSO+CtdSbStIW6dxa+4NM58yRw==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [x64]
         os: [darwin]
     
    -  '@rolldown/binding-freebsd-x64@1.0.0-rc.5':
    -    resolution: {integrity: sha512-o/JCk+dL0IN68EBhZ4DqfsfvxPfMeoM6cJtxORC1YYoxGHZyth2Kb2maXDb4oddw2wu8iIbnYXYPEzBtAF5CAg==}
    +  '@oxfmt/binding-freebsd-x64@0.35.0':
    +    resolution: {integrity: sha512-QyfKfTe0ytHpFKHAcHCGQEzN45QSqq1AHJOYYxQMgLM3KY4xu8OsXHpCnINjDsV4XGnQzczJDU9e04Zmd8XqIQ==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [x64]
         os: [freebsd]
     
    -  '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.5':
    -    resolution: {integrity: sha512-IIBwTtA6VwxQLcEgq2mfrUgam7VvPZjhd/jxmeS1npM+edWsrrpRLHUdze+sk4rhb8/xpP3flemgcZXXUW6ukw==}
    +  '@oxfmt/binding-linux-arm-gnueabihf@0.35.0':
    +    resolution: {integrity: sha512-u+kv3JD6P3J38oOyUaiCqgY5TNESzBRZJ5lyZQ6c2czUW2v5SIN9E/KWWa9vxoc+P8AFXQFUVrdzGy1tK+nbPQ==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [arm]
         os: [linux]
     
    -  '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.5':
    -    resolution: {integrity: sha512-KSol1De1spMZL+Xg7K5IBWXIvRWv7+pveaxFWXpezezAG7CS6ojzRjtCGCiLxQricutTAi/LkNWKMsd2wNhMKQ==}
    +  '@oxfmt/binding-linux-arm-musleabihf@0.35.0':
    +    resolution: {integrity: sha512-1NiZroCiV57I7Pf8kOH4XGR366kW5zir3VfSMBU2D0V14GpYjiYmPYFAoJboZvp8ACnZKUReWyMkNKSa5ad58A==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [arm]
    +    os: [linux]
    +
    +  '@oxfmt/binding-linux-arm64-gnu@0.35.0':
    +    resolution: {integrity: sha512-7Q0Xeg7ZnW2nxnZ4R7aF6DEbCFls4skgHZg+I63XitpNvJCbVIU8MFOTZlvZGRsY9+rPgWPQGeUpLHlyx0wvMA==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [arm64]
         os: [linux]
         libc: [glibc]
     
    -  '@rolldown/binding-linux-arm64-musl@1.0.0-rc.5':
    -    resolution: {integrity: sha512-WFljyDkxtXRlWxMjxeegf7xMYXxUr8u7JdXlOEWKYgDqEgxUnSEsVDxBiNWQ1D5kQKwf8Wo4sVKEYPRhCdsjwA==}
    +  '@oxfmt/binding-linux-arm64-musl@0.35.0':
    +    resolution: {integrity: sha512-5Okqi+uhYFxwKz8hcnUftNNwdm8BCkf6GSCbcz9xJxYMm87k1E4p7PEmAAbhLTk7cjSdDre6TDL0pDzNX+Y22Q==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [arm64]
         os: [linux]
         libc: [musl]
     
    -  '@rolldown/binding-linux-x64-gnu@1.0.0-rc.5':
    -    resolution: {integrity: sha512-CUlplTujmbDWp2gamvrqVKi2Or8lmngXT1WxsizJfts7JrvfGhZObciaY/+CbdbS9qNnskvwMZNEhTPrn7b+WA==}
    +  '@oxfmt/binding-linux-ppc64-gnu@0.35.0':
    +    resolution: {integrity: sha512-9k66pbZQXM/lBJWys3Xbc5yhl4JexyfqkEf/tvtq8976VIJnLAAL3M127xHA3ifYSqxdVHfVGTg84eiBHCGcNw==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [ppc64]
    +    os: [linux]
    +    libc: [glibc]
    +
    +  '@oxfmt/binding-linux-riscv64-gnu@0.35.0':
    +    resolution: {integrity: sha512-aUcY9ofKPtjO52idT6t0SAQvEF6ctjzUQa1lLp7GDsRpSBvuTrBQGeq0rYKz3gN8dMIQ7mtMdGD9tT4LhR8jAQ==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [riscv64]
    +    os: [linux]
    +    libc: [glibc]
    +
    +  '@oxfmt/binding-linux-riscv64-musl@0.35.0':
    +    resolution: {integrity: sha512-C6yhY5Hvc2sGM+mCPek9ZLe5xRUOC/BvhAt2qIWFAeXMn4il04EYIjl3DsWiJr0xDMTJhvMOmD55xTRPlNp39w==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [riscv64]
    +    os: [linux]
    +    libc: [musl]
    +
    +  '@oxfmt/binding-linux-s390x-gnu@0.35.0':
    +    resolution: {integrity: sha512-RG2hlvOMK4OMZpO3mt8MpxLQ0AAezlFqhn5mI/g5YrVbPFyoCv9a34AAvbSJS501ocOxlFIRcKEuw5hFvddf9g==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [s390x]
    +    os: [linux]
    +    libc: [glibc]
    +
    +  '@oxfmt/binding-linux-x64-gnu@0.35.0':
    +    resolution: {integrity: sha512-wzmh90Pwvqj9xOKHJjkQYBpydRkaXG77ZvDz+iFDRRQpnqIEqGm5gmim2s6vnZIkDGsvKCuTdtxm0GFmBjM1+w==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [x64]
         os: [linux]
         libc: [glibc]
     
    -  '@rolldown/binding-linux-x64-musl@1.0.0-rc.5':
    -    resolution: {integrity: sha512-wdf7g9NbVZCeAo2iGhsjJb7I8ZFfs6X8bumfrWg82VK+8P6AlLXwk48a1ASiJQDTS7Svq2xVzZg3sGO2aXpHRA==}
    +  '@oxfmt/binding-linux-x64-musl@0.35.0':
    +    resolution: {integrity: sha512-+HCqYCJPCUy5I+b2cf+gUVaApfgtoQT3HdnSg/l7NIcLHOhKstlYaGyrFZLmUpQt4WkFbpGKZZayG6zjRU0KFA==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [x64]
         os: [linux]
         libc: [musl]
     
    -  '@rolldown/binding-openharmony-arm64@1.0.0-rc.5':
    -    resolution: {integrity: sha512-0CWY7ubu12nhzz+tkpHjoG3IRSTlWYe0wrfJRf4qqjqQSGtAYgoL9kwzdvlhaFdZ5ffVeyYw9qLsChcjUMEloQ==}
    +  '@oxfmt/binding-openharmony-arm64@0.35.0':
    +    resolution: {integrity: sha512-kFYmWfR9YL78XyO5ws+1dsxNvZoD973qfVMNFOS4e9bcHXGF7DvGC2tY5UDFwyMCeB33t3sDIuGONKggnVNSJA==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [arm64]
         os: [openharmony]
     
    -  '@rolldown/binding-wasm32-wasi@1.0.0-rc.5':
    -    resolution: {integrity: sha512-LztXnGzv6t2u830mnZrFLRVqT/DPJ9DL4ZTz/y93rqUVkeHjMMYIYaFj+BUthiYxbVH9dH0SZYufETspKY/NhA==}
    -    engines: {node: '>=14.0.0'}
    -    cpu: [wasm32]
    -
    -  '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.5':
    -    resolution: {integrity: sha512-jUct1XVeGtyjqJXEAfvdFa8xoigYZ2rge7nYEm70ppQxpfH9ze2fbIrpHmP2tNM2vL/F6Dd0CpXhpjPbC6bSxQ==}
    +  '@oxfmt/binding-win32-arm64-msvc@0.35.0':
    +    resolution: {integrity: sha512-uD/NGdM65eKNCDGyTGdO8e9n3IHX+wwuorBvEYrPJXhDXL9qz6gzddmXH8EN04ejUXUujlq4FsoSeCfbg0Y+Jg==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [arm64]
         os: [win32]
     
    -  '@rolldown/binding-win32-x64-msvc@1.0.0-rc.5':
    -    resolution: {integrity: sha512-VQ8F9ld5gw29epjnVGdrx8ugiLTe8BMqmhDYy7nGbdeDo4HAt4bgdZvLbViEhg7DZyHLpiEUlO5/jPSUrIuxRQ==}
    +  '@oxfmt/binding-win32-ia32-msvc@0.35.0':
    +    resolution: {integrity: sha512-oSRD2k8J2uxYDEKR2nAE/YTY9PobOEnhZgCmspHu0+yBQ665yH8lFErQVSTE7fcGJmJp/cC6322/gc8VFuQf7g==}
         engines: {node: ^20.19.0 || >=22.12.0}
    -    cpu: [x64]
    +    cpu: [ia32]
         os: [win32]
     
    -  '@rolldown/pluginutils@1.0.0-rc.3':
    -    resolution: {integrity: sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==}
    -
    -  '@rolldown/pluginutils@1.0.0-rc.5':
    -    resolution: {integrity: sha512-RxlLX/DPoarZ9PtxVrQgZhPoor987YtKQqCo5zkjX+0S0yLJ7Vv515Wk6+xtTL67VONKJKxETWZwuZjss2idYw==}
    -
    -  '@rollup/rollup-android-arm-eabi@4.59.0':
    -    resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==}
    -    cpu: [arm]
    -    os: [android]
    -
    -  '@rollup/rollup-android-arm64@4.59.0':
    -    resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==}
    -    cpu: [arm64]
    -    os: [android]
    +  '@oxfmt/binding-win32-x64-msvc@0.35.0':
    +    resolution: {integrity: sha512-WCDJjlS95NboR0ugI2BEwzt1tYvRDorDRM9Lvctls1SLyKYuNRCyrPwp1urUPFBnwgBNn9p2/gnmo7gFMySRoQ==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [x64]
    +    os: [win32]
     
    -  '@rollup/rollup-darwin-arm64@4.59.0':
    -    resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==}
    +  '@pagefind/darwin-arm64@1.4.0':
    +    resolution: {integrity: sha512-2vMqkbv3lbx1Awea90gTaBsvpzgRs7MuSgKDxW0m9oV1GPZCZbZBJg/qL83GIUEN2BFlY46dtUZi54pwH+/pTQ==}
         cpu: [arm64]
         os: [darwin]
     
    -  '@rollup/rollup-darwin-x64@4.59.0':
    -    resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==}
    +  '@pagefind/darwin-x64@1.4.0':
    +    resolution: {integrity: sha512-e7JPIS6L9/cJfow+/IAqknsGqEPjJnVXGjpGm25bnq+NPdoD3c/7fAwr1OXkG4Ocjx6ZGSCijXEV4ryMcH2E3A==}
         cpu: [x64]
         os: [darwin]
     
    -  '@rollup/rollup-freebsd-arm64@4.59.0':
    -    resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==}
    -    cpu: [arm64]
    -    os: [freebsd]
    -
    -  '@rollup/rollup-freebsd-x64@4.59.0':
    -    resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==}
    +  '@pagefind/freebsd-x64@1.4.0':
    +    resolution: {integrity: sha512-WcJVypXSZ+9HpiqZjFXMUobfFfZZ6NzIYtkhQ9eOhZrQpeY5uQFqNWLCk7w9RkMUwBv1HAMDW3YJQl/8OqsV0Q==}
         cpu: [x64]
         os: [freebsd]
     
    -  '@rollup/rollup-linux-arm-gnueabihf@4.59.0':
    -    resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==}
    -    cpu: [arm]
    +  '@pagefind/linux-arm64@1.4.0':
    +    resolution: {integrity: sha512-PIt8dkqt4W06KGmQjONw7EZbhDF+uXI7i0XtRLN1vjCUxM9vGPdtJc2mUyVPevjomrGz5M86M8bqTr6cgDp1Uw==}
    +    cpu: [arm64]
         os: [linux]
    -    libc: [glibc]
     
    -  '@rollup/rollup-linux-arm-musleabihf@4.59.0':
    -    resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==}
    -    cpu: [arm]
    +  '@pagefind/linux-x64@1.4.0':
    +    resolution: {integrity: sha512-z4oddcWwQ0UHrTHR8psLnVlz6USGJ/eOlDPTDYZ4cI8TK8PgwRUPQZp9D2iJPNIPcS6Qx/E4TebjuGJOyK8Mmg==}
    +    cpu: [x64]
         os: [linux]
    -    libc: [musl]
     
    -  '@rollup/rollup-linux-arm64-gnu@4.59.0':
    -    resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==}
    +  '@pagefind/windows-x64@1.4.0':
    +    resolution: {integrity: sha512-NkT+YAdgS2FPCn8mIA9bQhiBs+xmniMGq1LFPDhcFn0+2yIUEiIG06t7bsZlhdjknEQRTSdT7YitP6fC5qwP0g==}
    +    cpu: [x64]
    +    os: [win32]
    +
    +  '@pkgr/core@0.2.9':
    +    resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==}
    +    engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
    +
    +  '@quansync/fs@1.0.0':
    +    resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==}
    +
    +  '@react-aria/focus@3.21.5':
    +    resolution: {integrity: sha512-V18fwCyf8zqgJdpLQeDU5ZRNd9TeOfBbhLgmX77Zr5ae9XwaoJ1R3SFJG1wCJX60t34AW+aLZSEEK+saQElf3Q==}
    +    peerDependencies:
    +      react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1
    +      react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1
    +
    +  '@react-aria/interactions@3.27.1':
    +    resolution: {integrity: sha512-M3wLpTTmDflI0QGNK0PJNUaBXXfeBXue8ZxLMngfc1piHNiH4G5lUvWd9W14XVbqrSCVY8i8DfGrNYpyyZu0tw==}
    +    peerDependencies:
    +      react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1
    +      react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1
    +
    +  '@react-aria/ssr@3.9.10':
    +    resolution: {integrity: sha512-hvTm77Pf+pMBhuBm760Li0BVIO38jv1IBws1xFm1NoL26PU+fe+FMW5+VZWyANR6nYL65joaJKZqOdTQMkO9IQ==}
    +    engines: {node: '>= 12'}
    +    peerDependencies:
    +      react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1
    +
    +  '@react-aria/utils@3.33.1':
    +    resolution: {integrity: sha512-kIx1Sj6bbAT0pdqCegHuPanR9zrLn5zMRiM7LN12rgRf55S19ptd9g3ncahArifYTRkfEU9VIn+q0HjfMqS9/w==}
    +    peerDependencies:
    +      react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1
    +      react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1
    +
    +  '@react-stately/flags@3.1.2':
    +    resolution: {integrity: sha512-2HjFcZx1MyQXoPqcBGALwWWmgFVUk2TuKVIQxCbRq7fPyWXIl6VHcakCLurdtYC2Iks7zizvz0Idv48MQ38DWg==}
    +
    +  '@react-stately/utils@3.11.0':
    +    resolution: {integrity: sha512-8LZpYowJ9eZmmYLpudbo/eclIRnbhWIJZ994ncmlKlouNzKohtM8qTC6B1w1pwUbiwGdUoyzLuQbeaIor5Dvcw==}
    +    peerDependencies:
    +      react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1
    +
    +  '@react-types/shared@3.33.1':
    +    resolution: {integrity: sha512-oJHtjvLG43VjwemQDadlR5g/8VepK56B/xKO2XORPHt9zlW6IZs3tZrYlvH29BMvoqC7RtE7E5UjgbnbFtDGag==}
    +    peerDependencies:
    +      react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1
    +
    +  '@reduxjs/toolkit@2.11.2':
    +    resolution: {integrity: sha512-Kd6kAHTA6/nUpp8mySPqj3en3dm0tdMIgbttnQ1xFMVpufoj+ADi8pXLBsd4xzTRHQa7t/Jv8W5UnCuW4kuWMQ==}
    +    peerDependencies:
    +      react: ^16.9.0 || ^17.0.0 || ^18 || ^19
    +      react-redux: ^7.2.1 || ^8.1.3 || ^9.0.0
    +    peerDependenciesMeta:
    +      react:
    +        optional: true
    +      react-redux:
    +        optional: true
    +
    +  '@rolldown/binding-android-arm64@1.0.0-rc.10':
    +    resolution: {integrity: sha512-jOHxwXhxmFKuXztiu1ORieJeTbx5vrTkcOkkkn2d35726+iwhrY1w/+nYY/AGgF12thg33qC3R1LMBF5tHTZHg==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [arm64]
    +    os: [android]
    +
    +  '@rolldown/binding-android-arm64@1.0.0-rc.9':
    +    resolution: {integrity: sha512-lcJL0bN5hpgJfSIz/8PIf02irmyL43P+j1pTCfbD1DbLkmGRuFIA4DD3B3ZOvGqG0XiVvRznbKtN0COQVaKUTg==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [arm64]
    +    os: [android]
    +
    +  '@rolldown/binding-darwin-arm64@1.0.0-rc.10':
    +    resolution: {integrity: sha512-gED05Teg/vtTZbIJBc4VNMAxAFDUPkuO/rAIyyxZjTj1a1/s6z5TII/5yMGZ0uLRCifEtwUQn8OlYzuYc0m70w==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [arm64]
    +    os: [darwin]
    +
    +  '@rolldown/binding-darwin-arm64@1.0.0-rc.9':
    +    resolution: {integrity: sha512-J7Zk3kLYFsLtuH6U+F4pS2sYVzac0qkjcO5QxHS7OS7yZu2LRs+IXo+uvJ/mvpyUljDJ3LROZPoQfgBIpCMhdQ==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [arm64]
    +    os: [darwin]
    +
    +  '@rolldown/binding-darwin-x64@1.0.0-rc.10':
    +    resolution: {integrity: sha512-rI15NcM1mA48lqrIxVkHfAqcyFLcQwyXWThy+BQ5+mkKKPvSO26ir+ZDp36AgYoYVkqvMcdS8zOE6SeBsR9e8A==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [x64]
    +    os: [darwin]
    +
    +  '@rolldown/binding-darwin-x64@1.0.0-rc.9':
    +    resolution: {integrity: sha512-iwtmmghy8nhfRGeNAIltcNXzD0QMNaaA5U/NyZc1Ia4bxrzFByNMDoppoC+hl7cDiUq5/1CnFthpT9n+UtfFyg==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [x64]
    +    os: [darwin]
    +
    +  '@rolldown/binding-freebsd-x64@1.0.0-rc.10':
    +    resolution: {integrity: sha512-XZRXHdTa+4ME1MuDVp021+doQ+z6Ei4CCFmNc5/sKbqb8YmkiJdj8QKlV3rCI0AJtAeSB5n0WGPuJWNL9p/L2w==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [x64]
    +    os: [freebsd]
    +
    +  '@rolldown/binding-freebsd-x64@1.0.0-rc.9':
    +    resolution: {integrity: sha512-DLFYI78SCiZr5VvdEplsVC2Vx53lnA4/Ga5C65iyldMVaErr86aiqCoNBLl92PXPfDtUYjUh+xFFor40ueNs4Q==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [x64]
    +    os: [freebsd]
    +
    +  '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.10':
    +    resolution: {integrity: sha512-R0SQMRluISSLzFE20sPWYHVmJdDQnRyc/FzSCN72BqQmh2SOZUFG+N3/vBZpR4C6WpEUVYJLrYUXaj43sJsNLA==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [arm]
    +    os: [linux]
    +
    +  '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.9':
    +    resolution: {integrity: sha512-CsjTmTwd0Hri6iTw/DRMK7kOZ7FwAkrO4h8YWKoX/kcj833e4coqo2wzIFywtch/8Eb5enQ/lwLM7w6JX1W5RQ==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [arm]
    +    os: [linux]
    +
    +  '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.10':
    +    resolution: {integrity: sha512-Y1reMrV/o+cwpduYhJuOE3OMKx32RMYCidf14y+HssARRmhDuWXJ4yVguDg2R/8SyyGNo+auzz64LnPK9Hq6jg==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [arm64]
         os: [linux]
         libc: [glibc]
     
    -  '@rollup/rollup-linux-arm64-musl@4.59.0':
    -    resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==}
    +  '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.9':
    +    resolution: {integrity: sha512-2x9O2JbSPxpxMDhP9Z74mahAStibTlrBMW0520+epJH5sac7/LwZW5Bmg/E6CXuEF53JJFW509uP+lSedaUNxg==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [arm64]
         os: [linux]
    -    libc: [musl]
    +    libc: [glibc]
     
    -  '@rollup/rollup-linux-loong64-gnu@4.59.0':
    -    resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==}
    -    cpu: [loong64]
    +  '@rolldown/binding-linux-arm64-musl@1.0.0-rc.10':
    +    resolution: {integrity: sha512-vELN+HNb2IzuzSBUOD4NHmP9yrGwl1DVM29wlQvx1OLSclL0NgVWnVDKl/8tEks79EFek/kebQKnNJkIAA4W2g==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [arm64]
         os: [linux]
    -    libc: [glibc]
    +    libc: [musl]
     
    -  '@rollup/rollup-linux-loong64-musl@4.59.0':
    -    resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==}
    -    cpu: [loong64]
    +  '@rolldown/binding-linux-arm64-musl@1.0.0-rc.9':
    +    resolution: {integrity: sha512-JA1QRW31ogheAIRhIg9tjMfsYbglXXYGNPLdPEYrwFxdbkQCAzvpSCSHCDWNl4hTtrol8WeboCSEpjdZK8qrCg==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [arm64]
         os: [linux]
         libc: [musl]
     
    -  '@rollup/rollup-linux-ppc64-gnu@4.59.0':
    -    resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==}
    +  '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.10':
    +    resolution: {integrity: sha512-ZqrufYTgzxbHwpqOjzSsb0UV/aV2TFIY5rP8HdsiPTv/CuAgCRjM6s9cYFwQ4CNH+hf9Y4erHW1GjZuZ7WoI7w==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [ppc64]
         os: [linux]
         libc: [glibc]
     
    -  '@rollup/rollup-linux-ppc64-musl@4.59.0':
    -    resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==}
    +  '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.9':
    +    resolution: {integrity: sha512-aOKU9dJheda8Kj8Y3w9gnt9QFOO+qKPAl8SWd7JPHP+Cu0EuDAE5wokQubLzIDQWg2myXq2XhTpOVS07qqvT+w==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [ppc64]
         os: [linux]
    -    libc: [musl]
    +    libc: [glibc]
     
    -  '@rollup/rollup-linux-riscv64-gnu@4.59.0':
    -    resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==}
    -    cpu: [riscv64]
    +  '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.10':
    +    resolution: {integrity: sha512-gSlmVS1FZJSRicA6IyjoRoKAFK7IIHBs7xJuHRSmjImqk3mPPWbR7RhbnfH2G6bcmMEllCt2vQ/7u9e6bBnByg==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [s390x]
         os: [linux]
         libc: [glibc]
     
    -  '@rollup/rollup-linux-riscv64-musl@4.59.0':
    -    resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==}
    -    cpu: [riscv64]
    +  '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.9':
    +    resolution: {integrity: sha512-OalO94fqj7IWRn3VdXWty75jC5dk4C197AWEuMhIpvVv2lw9fiPhud0+bW2ctCxb3YoBZor71QHbY+9/WToadA==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [s390x]
         os: [linux]
    -    libc: [musl]
    +    libc: [glibc]
     
    -  '@rollup/rollup-linux-s390x-gnu@4.59.0':
    -    resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==}
    -    cpu: [s390x]
    +  '@rolldown/binding-linux-x64-gnu@1.0.0-rc.10':
    +    resolution: {integrity: sha512-eOCKUpluKgfObT2pHjztnaWEIbUabWzk3qPZ5PuacuPmr4+JtQG4k2vGTY0H15edaTnicgU428XW/IH6AimcQw==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [x64]
         os: [linux]
         libc: [glibc]
     
    -  '@rollup/rollup-linux-x64-gnu@4.59.0':
    -    resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==}
    +  '@rolldown/binding-linux-x64-gnu@1.0.0-rc.9':
    +    resolution: {integrity: sha512-cVEl1vZtBsBZna3YMjGXNvnYYrOJ7RzuWvZU0ffvJUexWkukMaDuGhUXn0rjnV0ptzGVkvc+vW9Yqy6h8YX4pg==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [x64]
         os: [linux]
         libc: [glibc]
     
    -  '@rollup/rollup-linux-x64-musl@4.59.0':
    -    resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==}
    +  '@rolldown/binding-linux-x64-musl@1.0.0-rc.10':
    +    resolution: {integrity: sha512-Xdf2jQbfQowJnLcgYfD/m0Uu0Qj5OdxKallD78/IPPfzaiaI4KRAwZzHcKQ4ig1gtg1SuzC7jovNiM2TzQsBXA==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [x64]
         os: [linux]
         libc: [musl]
     
    -  '@rollup/rollup-openbsd-x64@4.59.0':
    -    resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==}
    +  '@rolldown/binding-linux-x64-musl@1.0.0-rc.9':
    +    resolution: {integrity: sha512-UzYnKCIIc4heAKgI4PZ3dfBGUZefGCJ1TPDuLHoCzgrMYPb5Rv6TLFuYtyM4rWyHM7hymNdsg5ik2C+UD9VDbA==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [x64]
    -    os: [openbsd]
    +    os: [linux]
    +    libc: [musl]
    +
    +  '@rolldown/binding-openharmony-arm64@1.0.0-rc.10':
    +    resolution: {integrity: sha512-o1hYe8hLi1EY6jgPFyxQgQ1wcycX+qz8eEbVmot2hFkgUzPxy9+kF0u0NIQBeDq+Mko47AkaFFaChcvZa9UX9Q==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [arm64]
    +    os: [openharmony]
     
    -  '@rollup/rollup-openharmony-arm64@4.59.0':
    -    resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==}
    +  '@rolldown/binding-openharmony-arm64@1.0.0-rc.9':
    +    resolution: {integrity: sha512-+6zoiF+RRyf5cdlFQP7nm58mq7+/2PFaY2DNQeD4B87N36JzfF/l9mdBkkmTvSYcYPE8tMh/o3cRlsx1ldLfog==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [arm64]
         os: [openharmony]
     
    -  '@rollup/rollup-win32-arm64-msvc@4.59.0':
    -    resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==}
    +  '@rolldown/binding-wasm32-wasi@1.0.0-rc.10':
    +    resolution: {integrity: sha512-Ugv9o7qYJudqQO5Y5y2N2SOo6S4WiqiNOpuQyoPInnhVzCY+wi/GHltcLHypG9DEUYMB0iTB/huJrpadiAcNcA==}
    +    engines: {node: '>=14.0.0'}
    +    cpu: [wasm32]
    +
    +  '@rolldown/binding-wasm32-wasi@1.0.0-rc.9':
    +    resolution: {integrity: sha512-rgFN6sA/dyebil3YTlL2evvi/M+ivhfnyxec7AccTpRPccno/rPoNlqybEZQBkcbZu8Hy+eqNJCqfBR8P7Pg8g==}
    +    engines: {node: '>=14.0.0'}
    +    cpu: [wasm32]
    +
    +  '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.10':
    +    resolution: {integrity: sha512-7UODQb4fQUNT/vmgDZBl3XOBAIOutP5R3O/rkxg0aLfEGQ4opbCgU5vOw/scPe4xOqBwL9fw7/RP1vAMZ6QlAQ==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [arm64]
         os: [win32]
     
    -  '@rollup/rollup-win32-ia32-msvc@4.59.0':
    -    resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==}
    -    cpu: [ia32]
    +  '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.9':
    +    resolution: {integrity: sha512-lHVNUG/8nlF1IQk1C0Ci574qKYyty2goMiPlRqkC5R+3LkXDkL5Dhx8ytbxq35m+pkHVIvIxviD+TWLdfeuadA==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [arm64]
         os: [win32]
     
    -  '@rollup/rollup-win32-x64-gnu@4.59.0':
    -    resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==}
    +  '@rolldown/binding-win32-x64-msvc@1.0.0-rc.10':
    +    resolution: {integrity: sha512-PYxKHMVHOb5NJuDL53vBUl1VwUjymDcYI6rzpIni0C9+9mTiJedvUxSk7/RPp7OOAm3v+EjgMu9bIy3N6b408w==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [x64]
         os: [win32]
     
    -  '@rollup/rollup-win32-x64-msvc@4.59.0':
    -    resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==}
    +  '@rolldown/binding-win32-x64-msvc@1.0.0-rc.9':
    +    resolution: {integrity: sha512-G0oA4+w1iY5AGi5HcDTxWsoxF509hrFIPB2rduV5aDqS9FtDg1CAfa7V34qImbjfhIcA8C+RekocJZA96EarwQ==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [x64]
         os: [win32]
     
    +  '@rolldown/pluginutils@1.0.0-rc.10':
    +    resolution: {integrity: sha512-UkVDEFk1w3mveXeKgaTuYfKWtPbvgck1dT8TUG3bnccrH0XtLTuAyfCoks4Q/M5ZGToSVJTIQYCzy2g/atAOeg==}
    +
    +  '@rolldown/pluginutils@1.0.0-rc.7':
    +    resolution: {integrity: sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==}
    +
    +  '@rolldown/pluginutils@1.0.0-rc.9':
    +    resolution: {integrity: sha512-w6oiRWgEBl04QkFZgmW+jnU1EC9b57Oihi2ot3HNWIQRqgHp5PnYDia5iZ5FF7rpa4EQdiqMDXjlqKGXBhsoXw==}
    +
    +  '@shikijs/core@3.23.0':
    +    resolution: {integrity: sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==}
    +
    +  '@shikijs/engine-javascript@3.23.0':
    +    resolution: {integrity: sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA==}
    +
    +  '@shikijs/engine-oniguruma@3.23.0':
    +    resolution: {integrity: sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==}
    +
    +  '@shikijs/langs@3.23.0':
    +    resolution: {integrity: sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==}
    +
    +  '@shikijs/themes@3.23.0':
    +    resolution: {integrity: sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==}
    +
    +  '@shikijs/twoslash@3.23.0':
    +    resolution: {integrity: sha512-pNaLJWMA3LU7PhT8tm9OQBZ1epy0jmdgeJzntBtr1EVXLbHxGzTj3mnf9vOdcl84l96qnlJXkJ/NGXZYBpXl5g==}
    +    peerDependencies:
    +      typescript: '>=5.5.0'
    +
    +  '@shikijs/types@3.23.0':
    +    resolution: {integrity: sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==}
    +
    +  '@shikijs/vscode-textmate@10.0.2':
    +    resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==}
    +
       '@sindresorhus/base62@1.0.0':
         resolution: {integrity: sha512-TeheYy0ILzBEI/CO55CP6zJCSdSWeRtGnHy8U8dWSUH4I68iqTsy7HkMktR4xakThc9jotkPQUXT4ITdbV7cHA==}
         engines: {node: '>=18'}
    @@ -2082,8 +2550,8 @@ packages:
       '@standard-schema/utils@0.3.0':
         resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==}
     
    -  '@stylistic/eslint-plugin@5.9.0':
    -    resolution: {integrity: sha512-FqqSkvDMYJReydrMhlugc71M76yLLQWNfmGq+SIlLa7N3kHp8Qq8i2PyWrVNAfjOyOIY+xv9XaaYwvVW7vroMA==}
    +  '@stylistic/eslint-plugin@5.10.0':
    +    resolution: {integrity: sha512-nPK52ZHvot8Ju/0A4ucSX1dcPV2/1clx0kLcH5wDmrE4naKso7TUC/voUyU1O9OTKTrR6MYip6LP0ogEMQ9jPQ==}
         engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
         peerDependencies:
           eslint: ^9.0.0 || ^10.0.0
    @@ -2091,69 +2559,69 @@ packages:
       '@swc/helpers@0.5.15':
         resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
     
    -  '@tailwindcss/node@4.2.1':
    -    resolution: {integrity: sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==}
    +  '@tailwindcss/node@4.2.2':
    +    resolution: {integrity: sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==}
     
    -  '@tailwindcss/oxide-android-arm64@4.2.1':
    -    resolution: {integrity: sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg==}
    +  '@tailwindcss/oxide-android-arm64@4.2.2':
    +    resolution: {integrity: sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==}
         engines: {node: '>= 20'}
         cpu: [arm64]
         os: [android]
     
    -  '@tailwindcss/oxide-darwin-arm64@4.2.1':
    -    resolution: {integrity: sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==}
    +  '@tailwindcss/oxide-darwin-arm64@4.2.2':
    +    resolution: {integrity: sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==}
         engines: {node: '>= 20'}
         cpu: [arm64]
         os: [darwin]
     
    -  '@tailwindcss/oxide-darwin-x64@4.2.1':
    -    resolution: {integrity: sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw==}
    +  '@tailwindcss/oxide-darwin-x64@4.2.2':
    +    resolution: {integrity: sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==}
         engines: {node: '>= 20'}
         cpu: [x64]
         os: [darwin]
     
    -  '@tailwindcss/oxide-freebsd-x64@4.2.1':
    -    resolution: {integrity: sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA==}
    +  '@tailwindcss/oxide-freebsd-x64@4.2.2':
    +    resolution: {integrity: sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==}
         engines: {node: '>= 20'}
         cpu: [x64]
         os: [freebsd]
     
    -  '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.1':
    -    resolution: {integrity: sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw==}
    +  '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2':
    +    resolution: {integrity: sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==}
         engines: {node: '>= 20'}
         cpu: [arm]
         os: [linux]
     
    -  '@tailwindcss/oxide-linux-arm64-gnu@4.2.1':
    -    resolution: {integrity: sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ==}
    +  '@tailwindcss/oxide-linux-arm64-gnu@4.2.2':
    +    resolution: {integrity: sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==}
         engines: {node: '>= 20'}
         cpu: [arm64]
         os: [linux]
         libc: [glibc]
     
    -  '@tailwindcss/oxide-linux-arm64-musl@4.2.1':
    -    resolution: {integrity: sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==}
    +  '@tailwindcss/oxide-linux-arm64-musl@4.2.2':
    +    resolution: {integrity: sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==}
         engines: {node: '>= 20'}
         cpu: [arm64]
         os: [linux]
         libc: [musl]
     
    -  '@tailwindcss/oxide-linux-x64-gnu@4.2.1':
    -    resolution: {integrity: sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==}
    +  '@tailwindcss/oxide-linux-x64-gnu@4.2.2':
    +    resolution: {integrity: sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==}
         engines: {node: '>= 20'}
         cpu: [x64]
         os: [linux]
         libc: [glibc]
     
    -  '@tailwindcss/oxide-linux-x64-musl@4.2.1':
    -    resolution: {integrity: sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==}
    +  '@tailwindcss/oxide-linux-x64-musl@4.2.2':
    +    resolution: {integrity: sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==}
         engines: {node: '>= 20'}
         cpu: [x64]
         os: [linux]
         libc: [musl]
     
    -  '@tailwindcss/oxide-wasm32-wasi@4.2.1':
    -    resolution: {integrity: sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==}
    +  '@tailwindcss/oxide-wasm32-wasi@4.2.2':
    +    resolution: {integrity: sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==}
         engines: {node: '>=14.0.0'}
         cpu: [wasm32]
         bundledDependencies:
    @@ -2164,58 +2632,66 @@ packages:
           - '@emnapi/wasi-threads'
           - tslib
     
    -  '@tailwindcss/oxide-win32-arm64-msvc@4.2.1':
    -    resolution: {integrity: sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA==}
    +  '@tailwindcss/oxide-win32-arm64-msvc@4.2.2':
    +    resolution: {integrity: sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==}
         engines: {node: '>= 20'}
         cpu: [arm64]
         os: [win32]
     
    -  '@tailwindcss/oxide-win32-x64-msvc@4.2.1':
    -    resolution: {integrity: sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ==}
    +  '@tailwindcss/oxide-win32-x64-msvc@4.2.2':
    +    resolution: {integrity: sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==}
         engines: {node: '>= 20'}
         cpu: [x64]
         os: [win32]
     
    -  '@tailwindcss/oxide@4.2.1':
    -    resolution: {integrity: sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==}
    +  '@tailwindcss/oxide@4.2.2':
    +    resolution: {integrity: sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==}
         engines: {node: '>= 20'}
     
    -  '@tailwindcss/vite@4.2.1':
    -    resolution: {integrity: sha512-TBf2sJjYeb28jD2U/OhwdW0bbOsxkWPwQ7SrqGf9sVcoYwZj7rkXljroBO9wKBut9XnmQLXanuDUeqQK0lGg/w==}
    +  '@tailwindcss/vite@4.2.2':
    +    resolution: {integrity: sha512-mEiF5HO1QqCLXoNEfXVA1Tzo+cYsrqV7w9Juj2wdUFyW07JRenqMG225MvPwr3ZD9N1bFQj46X7r33iHxLUW0w==}
         peerDependencies:
    -      vite: ^5.2.0 || ^6 || ^7
    +      vite: ^5.2.0 || ^6 || ^7 || ^8
     
    -  '@tanstack/history@1.161.4':
    -    resolution: {integrity: sha512-Kp/WSt411ZWYvgXy6uiv5RmhHrz9cAml05AQPrtdAp7eUqvIDbMGPnML25OKbzR3RJ1q4wgENxDTvlGPa9+Mww==}
    +  '@tanstack/history@1.161.6':
    +    resolution: {integrity: sha512-NaOGLRrddszbQj9upGat6HG/4TKvXLvu+osAIgfxPYA+eIvYKv8GKDJOrY2D3/U9MRnKfMWD7bU4jeD4xmqyIg==}
         engines: {node: '>=20.19'}
     
    -  '@tanstack/react-router@1.163.3':
    -    resolution: {integrity: sha512-hheBbFVb+PbxtrWp8iy6+TTRTbhx3Pn6hKo8Tv/sWlG89ZMcD1xpQWzx8ukHN9K8YWbh5rdzt4kv6u8X4kB28Q==}
    +  '@tanstack/react-router@1.168.1':
    +    resolution: {integrity: sha512-DsQzbfwcr2Xugqs4G8yShUO9hVQ/tbWhIiLNJSxmZZOgaZCB3JP+ngN1EJBYZz+JBQdvyVHfiEsPXy0P1h3yVA==}
         engines: {node: '>=20.19'}
         peerDependencies:
           react: '>=18.0.0 || >=19.0.0'
           react-dom: '>=18.0.0 || >=19.0.0'
     
    -  '@tanstack/react-store@0.9.1':
    -    resolution: {integrity: sha512-YzJLnRvy5lIEFTLWBAZmcOjK3+2AepnBv/sr6NZmiqJvq7zTQggyK99Gw8fqYdMdHPQWXjz0epFKJXC+9V2xDA==}
    +  '@tanstack/react-store@0.9.2':
    +    resolution: {integrity: sha512-Vt5usJE5sHG/cMechQfmwvwne6ktGCELe89Lmvoxe3LKRoFrhPa8OCKWs0NliG8HTJElEIj7PLtaBQIcux5pAQ==}
    +    peerDependencies:
    +      react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
    +      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
    +
    +  '@tanstack/react-virtual@3.13.23':
    +    resolution: {integrity: sha512-XnMRnHQ23piOVj2bzJqHrRrLg4r+F86fuBcwteKfbIjJrtGxb4z7tIvPVAe4B+4UVwo9G4Giuz5fmapcrnZ0OQ==}
         peerDependencies:
           react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
           react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
     
    -  '@tanstack/router-core@1.163.3':
    -    resolution: {integrity: sha512-jPptiGq/w3nuPzcMC7RNa79aU+b6OjaDzWJnBcV2UAwL4ThJamRS4h42TdhJE+oF5yH9IEnCOGQdfnbw45LbfA==}
    +  '@tanstack/router-core@1.168.1':
    +    resolution: {integrity: sha512-RtpshTLZsMOkwW7rI52WFWGZSSfMAyDR1zWP9kVm91UX28gedc+LXih1CTP6TchS+TvxK4q8oW7ApMTvnpiY1w==}
         engines: {node: '>=20.19'}
    +    hasBin: true
     
    -  '@tanstack/router-generator@1.164.0':
    -    resolution: {integrity: sha512-Uiyj+RtW0kdeqEd8NEd3Np1Z2nhJ2xgLS8U+5mTvFrm/s3xkM2LYjJHoLzc6am7sKPDsmeF9a4/NYq3R7ZJP0Q==}
    +  '@tanstack/router-generator@1.166.15':
    +    resolution: {integrity: sha512-W8ybCktgN/45fc7ohWJKAyG5Al1pnTg7V8Z6RiG8NkSrN7Igo4BqanUmXULnhnkdCID5XhMbkhP84r2hzkXbPw==}
         engines: {node: '>=20.19'}
     
    -  '@tanstack/router-plugin@1.164.0':
    -    resolution: {integrity: sha512-cZPsEMhqzyzmuPuDbsTAzBZaT+cj0pGjwdhjxJfPCM06Ax8v4tFR7n/Ug0UCwnNAUEmKZWN3lA9uT+TxXnk9PQ==}
    +  '@tanstack/router-plugin@1.167.1':
    +    resolution: {integrity: sha512-bPDdwvpoznjyCUWd+w2ss+y9GemXvF3R6Zzi36rxiWUGwuqDhQbvs1fWkjsx2oBqXSG8vkF74yFdUxFEX90o4g==}
         engines: {node: '>=20.19'}
    +    hasBin: true
         peerDependencies:
           '@rsbuild/core': '>=1.0.2'
    -      '@tanstack/react-router': ^1.163.3
    +      '@tanstack/react-router': ^1.168.1
           vite: '>=5.0.0 || >=6.0.0 || >=7.0.0'
           vite-plugin-solid: ^2.11.10
           webpack: '>=5.92.0'
    @@ -2231,93 +2707,97 @@ packages:
           webpack:
             optional: true
     
    -  '@tanstack/router-utils@1.161.4':
    -    resolution: {integrity: sha512-r8TpjyIZoqrXXaf2DDyjd44gjGBoyE+/oEaaH68yLI9ySPO1gUWmQENZ1MZnmBnpUGN24NOZxdjDLc8npK0SAw==}
    +  '@tanstack/router-utils@1.161.6':
    +    resolution: {integrity: sha512-nRcYw+w2OEgK6VfjirYvGyPLOK+tZQz1jkYcmH5AjMamQ9PycnlxZF2aEZtPpNoUsaceX2bHptn6Ub5hGXqNvw==}
         engines: {node: '>=20.19'}
     
    -  '@tanstack/store@0.9.1':
    -    resolution: {integrity: sha512-+qcNkOy0N1qSGsP7omVCW0SDrXtaDcycPqBDE726yryiA5eTDFpjBReaYjghVJwNf1pcPMyzIwTGlYjCSQR0Fg==}
    +  '@tanstack/store@0.9.2':
    +    resolution: {integrity: sha512-K013lUJEFJK2ofFQ/hZKJUmCnpcV00ebLyOyFOWQvyQHUOZp/iYO84BM6aOGiV81JzwbX0APTVmW8YI7yiG5oA==}
    +
    +  '@tanstack/virtual-core@3.13.23':
    +    resolution: {integrity: sha512-zSz2Z2HNyLjCplANTDyl3BcdQJc2k1+yyFoKhNRmCr7V7dY8o8q5m8uFTI1/Pg1kL+Hgrz6u3Xo6eFUB7l66cg==}
     
    -  '@tanstack/virtual-file-routes@1.161.4':
    -    resolution: {integrity: sha512-42WoRePf8v690qG8yGRe/YOh+oHni9vUaUUfoqlS91U2scd3a5rkLtVsc6b7z60w3RogH0I00vdrC5AaeiZ18w==}
    +  '@tanstack/virtual-file-routes@1.161.7':
    +    resolution: {integrity: sha512-olW33+Cn+bsCsZKPwEGhlkqS6w3M2slFv11JIobdnCFKMLG97oAI2kWKdx5/zsywTL8flpnoIgaZZPlQTFYhdQ==}
         engines: {node: '>=20.19'}
    +    hasBin: true
     
       '@tauri-apps/api@2.10.1':
         resolution: {integrity: sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw==}
     
    -  '@tauri-apps/cli-darwin-arm64@2.10.0':
    -    resolution: {integrity: sha512-avqHD4HRjrMamE/7R/kzJPcAJnZs0IIS+1nkDP5b+TNBn3py7N2aIo9LIpy+VQq0AkN8G5dDpZtOOBkmWt/zjA==}
    +  '@tauri-apps/cli-darwin-arm64@2.10.1':
    +    resolution: {integrity: sha512-Z2OjCXiZ+fbYZy7PmP3WRnOpM9+Fy+oonKDEmUE6MwN4IGaYqgceTjwHucc/kEEYZos5GICve35f7ZiizgqEnQ==}
         engines: {node: '>= 10'}
         cpu: [arm64]
         os: [darwin]
     
    -  '@tauri-apps/cli-darwin-x64@2.10.0':
    -    resolution: {integrity: sha512-keDmlvJRStzVFjZTd0xYkBONLtgBC9eMTpmXnBXzsHuawV2q9PvDo2x6D5mhuoMVrJ9QWjgaPKBBCFks4dK71Q==}
    +  '@tauri-apps/cli-darwin-x64@2.10.1':
    +    resolution: {integrity: sha512-V/irQVvjPMGOTQqNj55PnQPVuH4VJP8vZCN7ajnj+ZS8Kom1tEM2hR3qbbIRoS3dBKs5mbG8yg1WC+97dq17Pw==}
         engines: {node: '>= 10'}
         cpu: [x64]
         os: [darwin]
     
    -  '@tauri-apps/cli-linux-arm-gnueabihf@2.10.0':
    -    resolution: {integrity: sha512-e5u0VfLZsMAC9iHaOEANumgl6lfnJx0Dtjkd8IJpysZ8jp0tJ6wrIkto2OzQgzcYyRCKgX72aKE0PFgZputA8g==}
    +  '@tauri-apps/cli-linux-arm-gnueabihf@2.10.1':
    +    resolution: {integrity: sha512-Hyzwsb4VnCWKGfTw+wSt15Z2pLw2f0JdFBfq2vHBOBhvg7oi6uhKiF87hmbXOBXUZaGkyRDkCHsdzJcIfoJC2w==}
         engines: {node: '>= 10'}
         cpu: [arm]
         os: [linux]
     
    -  '@tauri-apps/cli-linux-arm64-gnu@2.10.0':
    -    resolution: {integrity: sha512-YrYYk2dfmBs5m+OIMCrb+JH/oo+4FtlpcrTCgiFYc7vcs6m3QDd1TTyWu0u01ewsCtK2kOdluhr/zKku+KP7HA==}
    +  '@tauri-apps/cli-linux-arm64-gnu@2.10.1':
    +    resolution: {integrity: sha512-OyOYs2t5GkBIvyWjA1+h4CZxTcdz1OZPCWAPz5DYEfB0cnWHERTnQ/SLayQzncrT0kwRoSfSz9KxenkyJoTelA==}
         engines: {node: '>= 10'}
         cpu: [arm64]
         os: [linux]
         libc: [glibc]
     
    -  '@tauri-apps/cli-linux-arm64-musl@2.10.0':
    -    resolution: {integrity: sha512-GUoPdVJmrJRIXFfW3Rkt+eGK9ygOdyISACZfC/bCSfOnGt8kNdQIQr5WRH9QUaTVFIwxMlQyV3m+yXYP+xhSVA==}
    +  '@tauri-apps/cli-linux-arm64-musl@2.10.1':
    +    resolution: {integrity: sha512-MIj78PDDGjkg3NqGptDOGgfXks7SYJwhiMh8SBoZS+vfdz7yP5jN18bNaLnDhsVIPARcAhE1TlsZe/8Yxo2zqg==}
         engines: {node: '>= 10'}
         cpu: [arm64]
         os: [linux]
         libc: [musl]
     
    -  '@tauri-apps/cli-linux-riscv64-gnu@2.10.0':
    -    resolution: {integrity: sha512-JO7s3TlSxshwsoKNCDkyvsx5gw2QAs/Y2GbR5UE2d5kkU138ATKoPOtxn8G1fFT1aDW4LH0rYAAfBpGkDyJJnw==}
    +  '@tauri-apps/cli-linux-riscv64-gnu@2.10.1':
    +    resolution: {integrity: sha512-X0lvOVUg8PCVaoEtEAnpxmnkwlE1gcMDTqfhbefICKDnOTJ5Est3qL0SrWxizDackIOKBcvtpejrSiVpuJI1kw==}
         engines: {node: '>= 10'}
         cpu: [riscv64]
         os: [linux]
         libc: [glibc]
     
    -  '@tauri-apps/cli-linux-x64-gnu@2.10.0':
    -    resolution: {integrity: sha512-Uvh4SUUp4A6DVRSMWjelww0GnZI3PlVy7VS+DRF5napKuIehVjGl9XD0uKoCoxwAQBLctvipyEK+pDXpJeoHng==}
    +  '@tauri-apps/cli-linux-x64-gnu@2.10.1':
    +    resolution: {integrity: sha512-2/12bEzsJS9fAKybxgicCDFxYD1WEI9kO+tlDwX5znWG2GwMBaiWcmhGlZ8fi+DMe9CXlcVarMTYc0L3REIRxw==}
         engines: {node: '>= 10'}
         cpu: [x64]
         os: [linux]
         libc: [glibc]
     
    -  '@tauri-apps/cli-linux-x64-musl@2.10.0':
    -    resolution: {integrity: sha512-AP0KRK6bJuTpQ8kMNWvhIpKUkQJfcPFeba7QshOQZjJ8wOS6emwTN4K5g/d3AbCMo0RRdnZWwu67MlmtJyxC1Q==}
    +  '@tauri-apps/cli-linux-x64-musl@2.10.1':
    +    resolution: {integrity: sha512-Y8J0ZzswPz50UcGOFuXGEMrxbjwKSPgXftx5qnkuMs2rmwQB5ssvLb6tn54wDSYxe7S6vlLob9vt0VKuNOaCIQ==}
         engines: {node: '>= 10'}
         cpu: [x64]
         os: [linux]
         libc: [musl]
     
    -  '@tauri-apps/cli-win32-arm64-msvc@2.10.0':
    -    resolution: {integrity: sha512-97DXVU3dJystrq7W41IX+82JEorLNY+3+ECYxvXWqkq7DBN6FsA08x/EFGE8N/b0LTOui9X2dvpGGoeZKKV08g==}
    +  '@tauri-apps/cli-win32-arm64-msvc@2.10.1':
    +    resolution: {integrity: sha512-iSt5B86jHYAPJa/IlYw++SXtFPGnWtFJriHn7X0NFBVunF6zu9+/zOn8OgqIWSl8RgzhLGXQEEtGBdR4wzpVgg==}
         engines: {node: '>= 10'}
         cpu: [arm64]
         os: [win32]
     
    -  '@tauri-apps/cli-win32-ia32-msvc@2.10.0':
    -    resolution: {integrity: sha512-EHyQ1iwrWy1CwMalEm9z2a6L5isQ121pe7FcA2xe4VWMJp+GHSDDGvbTv/OPdkt2Lyr7DAZBpZHM6nvlHXEc4A==}
    +  '@tauri-apps/cli-win32-ia32-msvc@2.10.1':
    +    resolution: {integrity: sha512-gXyxgEzsFegmnWywYU5pEBURkcFN/Oo45EAwvZrHMh+zUSEAvO5E8TXsgPADYm31d1u7OQU3O3HsYfVBf2moHw==}
         engines: {node: '>= 10'}
         cpu: [ia32]
         os: [win32]
     
    -  '@tauri-apps/cli-win32-x64-msvc@2.10.0':
    -    resolution: {integrity: sha512-NTpyQxkpzGmU6ceWBTY2xRIEaS0ZLbVx1HE1zTA3TY/pV3+cPoPPOs+7YScr4IMzXMtOw7tLw5LEXo5oIG3qaQ==}
    +  '@tauri-apps/cli-win32-x64-msvc@2.10.1':
    +    resolution: {integrity: sha512-6Cn7YpPFwzChy0ERz6djKEmUehWrYlM+xTaNzGPgZocw3BD7OfwfWHKVWxXzdjEW2KfKkHddfdxK1XXTYqBRLg==}
         engines: {node: '>= 10'}
         cpu: [x64]
         os: [win32]
     
    -  '@tauri-apps/cli@2.10.0':
    -    resolution: {integrity: sha512-ZwT0T+7bw4+DPCSWzmviwq5XbXlM0cNoleDKOYPFYqcZqeKY31KlpoMW/MOON/tOFBPgi31a2v3w9gliqwL2+Q==}
    +  '@tauri-apps/cli@2.10.1':
    +    resolution: {integrity: sha512-jQNGF/5quwORdZSSLtTluyKQ+o6SMa/AUICfhf4egCGFdMHqWssApVgYSbg+jmrZoc8e1DscNvjTnXtlHLS11g==}
         engines: {node: '>= 10'}
         hasBin: true
     
    @@ -2327,36 +2807,65 @@ packages:
       '@tauri-apps/plugin-updater@2.10.0':
         resolution: {integrity: sha512-ljN8jPlnT0aSn8ecYhuBib84alxfMx6Hc8vJSKMJyzGbTPFZAC44T2I1QNFZssgWKrAlofvJqCC6Rr472JWfkQ==}
     
    -  '@truenine/eslint10-config@2026.10209.11105':
    -    resolution: {integrity: sha512-BbjoVPIqCHk2czq+1BoALRpSnA3TIIXQ0k6ZPfasx8cSwoua2YbTu5mSsl8+b17mF4bUW9PLN0xmHcdWlkXnCA==}
    +  '@theguild/remark-mermaid@0.3.0':
    +    resolution: {integrity: sha512-Fy1J4FSj8totuHsHFpaeWyWRaRSIvpzGTRoEfnNJc1JmLV9uV70sYE3zcT+Jj5Yw20Xq4iCsiT+3Ho49BBZcBQ==}
    +    peerDependencies:
    +      react: ^18.2.0 || ^19.0.0
    +
    +  '@theguild/remark-npm2yarn@0.3.3':
    +    resolution: {integrity: sha512-ma6DvR03gdbvwqfKx1omqhg9May/VYGdMHvTzB4VuxkyS7KzfZ/lzrj43hmcsggpMje0x7SADA/pcMph0ejRnA==}
    +
    +  '@truenine/eslint10-config@2026.10318.10138':
    +    resolution: {integrity: sha512-kyWjfbSCsPSpqQ0RRT2W+IuojO/eUhVnCzbaK0Z3i6x+rKXRcD3lvIftQfXnqDsvfrM8XvI+/J52kezssOktIg==}
         peerDependencies:
    -      '@antfu/eslint-config': ^7.4.3
    +      '@antfu/eslint-config': ^7.7.2
           '@eslint/js': ^10.0.1
           '@next/eslint-plugin-next': ^16.1.6
    -      '@unocss/eslint-config': ^66.6.0
    +      '@unocss/eslint-config': ^66.6.6
           '@vue/eslint-config-prettier': ^10.2.0
    -      '@vue/eslint-config-typescript': ^14.6.0
    -      eslint: ^10.0.0
    -      eslint-plugin-format: ^1.4.0
    +      '@vue/eslint-config-typescript': ^14.7.0
    +      eslint: ^10.0.3
    +      eslint-plugin-format: ^2.0.1
           eslint-plugin-prettier: ^5.5.5
    -      eslint-plugin-vue: ^10.7.0
    +      eslint-plugin-vue: ^10.8.0
           prettier: ^3.8.1
    -      typescript-eslint: ^8.55.0
    +      typescript-eslint: ^8.57.0
     
    -  '@tybys/wasm-util@0.10.1':
    -    resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==}
    +  '@ts-morph/common@0.28.1':
    +    resolution: {integrity: sha512-W74iWf7ILp1ZKNYXY5qbddNaml7e9Sedv5lvU1V8lftlitkc9Pq1A+jlH23ltDgWYeZFFEqGCD1Ies9hqu3O+g==}
    +
    +  '@turbo/darwin-64@2.8.20':
    +    resolution: {integrity: sha512-FQ9EX1xMU5nbwjxXxM3yU88AQQ6Sqc6S44exPRroMcx9XZHqqppl5ymJF0Ig/z3nvQNwDmz1Gsnvxubo+nXWjQ==}
    +    cpu: [x64]
    +    os: [darwin]
    +
    +  '@turbo/darwin-arm64@2.8.20':
    +    resolution: {integrity: sha512-Gpyh9ATFGThD6/s9L95YWY54cizg/VRWl2B67h0yofG8BpHf67DFAh9nuJVKG7bY0+SBJDAo5cMur+wOl9YOYw==}
    +    cpu: [arm64]
    +    os: [darwin]
    +
    +  '@turbo/linux-64@2.8.20':
    +    resolution: {integrity: sha512-p2QxWUYyYUgUFG0b0kR+pPi8t7c9uaVlRtjTTI1AbCvVqkpjUfCcReBn6DgG/Hu8xrWdKLuyQFaLYFzQskZbcA==}
    +    cpu: [x64]
    +    os: [linux]
     
    -  '@types/babel__core@7.20.5':
    -    resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
    +  '@turbo/linux-arm64@2.8.20':
    +    resolution: {integrity: sha512-Gn5yjlZGLRZWarLWqdQzv0wMqyBNIdq1QLi48F1oY5Lo9kiohuf7BPQWtWxeNVS2NgJ1+nb/DzK1JduYC4AWOA==}
    +    cpu: [arm64]
    +    os: [linux]
     
    -  '@types/babel__generator@7.27.0':
    -    resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==}
    +  '@turbo/windows-64@2.8.20':
    +    resolution: {integrity: sha512-vyaDpYk/8T6Qz5V/X+ihKvKFEZFUoC0oxYpC1sZanK6gaESJlmV3cMRT3Qhcg4D2VxvtC2Jjs9IRkrZGL+exLw==}
    +    cpu: [x64]
    +    os: [win32]
     
    -  '@types/babel__template@7.4.4':
    -    resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==}
    +  '@turbo/windows-arm64@2.8.20':
    +    resolution: {integrity: sha512-voicVULvUV5yaGXo0Iue13BcHGYW3u0VgqSbfQwBaHbpj1zLjYV4KIe+7fYIo6DO8FVUJzxFps3ODCQG/Wy2Qw==}
    +    cpu: [arm64]
    +    os: [win32]
     
    -  '@types/babel__traverse@7.28.0':
    -    resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==}
    +  '@tybys/wasm-util@0.10.1':
    +    resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==}
     
       '@types/chai@5.2.3':
         resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==}
    @@ -2364,30 +2873,96 @@ packages:
       '@types/d3-array@3.2.2':
         resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==}
     
    +  '@types/d3-axis@3.0.6':
    +    resolution: {integrity: sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==}
    +
    +  '@types/d3-brush@3.0.6':
    +    resolution: {integrity: sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==}
    +
    +  '@types/d3-chord@3.0.6':
    +    resolution: {integrity: sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==}
    +
       '@types/d3-color@3.1.3':
         resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==}
     
    +  '@types/d3-contour@3.0.6':
    +    resolution: {integrity: sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==}
    +
    +  '@types/d3-delaunay@6.0.4':
    +    resolution: {integrity: sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==}
    +
    +  '@types/d3-dispatch@3.0.7':
    +    resolution: {integrity: sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==}
    +
    +  '@types/d3-drag@3.0.7':
    +    resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==}
    +
    +  '@types/d3-dsv@3.0.7':
    +    resolution: {integrity: sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==}
    +
       '@types/d3-ease@3.0.2':
         resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==}
     
    +  '@types/d3-fetch@3.0.7':
    +    resolution: {integrity: sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==}
    +
    +  '@types/d3-force@3.0.10':
    +    resolution: {integrity: sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==}
    +
    +  '@types/d3-format@3.0.4':
    +    resolution: {integrity: sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==}
    +
    +  '@types/d3-geo@3.1.0':
    +    resolution: {integrity: sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==}
    +
    +  '@types/d3-hierarchy@3.1.7':
    +    resolution: {integrity: sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==}
    +
       '@types/d3-interpolate@3.0.4':
         resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==}
     
       '@types/d3-path@3.1.1':
         resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==}
     
    +  '@types/d3-polygon@3.0.2':
    +    resolution: {integrity: sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==}
    +
    +  '@types/d3-quadtree@3.0.6':
    +    resolution: {integrity: sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==}
    +
    +  '@types/d3-random@3.0.3':
    +    resolution: {integrity: sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==}
    +
    +  '@types/d3-scale-chromatic@3.1.0':
    +    resolution: {integrity: sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==}
    +
       '@types/d3-scale@4.0.9':
         resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==}
     
    +  '@types/d3-selection@3.0.11':
    +    resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==}
    +
       '@types/d3-shape@3.1.8':
         resolution: {integrity: sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==}
     
    +  '@types/d3-time-format@4.0.3':
    +    resolution: {integrity: sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==}
    +
       '@types/d3-time@3.0.4':
         resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==}
     
       '@types/d3-timer@3.0.2':
         resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==}
     
    +  '@types/d3-transition@3.0.9':
    +    resolution: {integrity: sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==}
    +
    +  '@types/d3-zoom@3.0.8':
    +    resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==}
    +
    +  '@types/d3@7.4.3':
    +    resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==}
    +
       '@types/debug@4.1.12':
         resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
     
    @@ -2406,6 +2981,9 @@ packages:
       '@types/fs-extra@11.0.4':
         resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==}
     
    +  '@types/geojson@7946.0.16':
    +    resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==}
    +
       '@types/hast@3.0.4':
         resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
     
    @@ -2418,6 +2996,9 @@ packages:
       '@types/jsonfile@6.1.4':
         resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==}
     
    +  '@types/katex@0.16.8':
    +    resolution: {integrity: sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==}
    +
       '@types/mdast@4.0.4':
         resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
     
    @@ -2427,9 +3008,15 @@ packages:
       '@types/ms@2.1.0':
         resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
     
    +  '@types/nlcst@2.0.3':
    +    resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==}
    +
       '@types/node@25.3.3':
         resolution: {integrity: sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ==}
     
    +  '@types/node@25.5.0':
    +    resolution: {integrity: sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==}
    +
       '@types/picomatch@4.0.2':
         resolution: {integrity: sha512-qHHxQ+P9PysNEGbALT8f8YOSHW0KJu6l2xU8DYY0fu/EmGxXdVnuTLvFUvBgPJMSqXq29SYHveejeAha+4AYgA==}
     
    @@ -2453,29 +3040,14 @@ packages:
       '@types/use-sync-external-store@0.0.6':
         resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==}
     
    -  '@typescript-eslint/eslint-plugin@8.50.0':
    -    resolution: {integrity: sha512-O7QnmOXYKVtPrfYzMolrCTfkezCJS9+ljLdKW/+DCvRsc3UAz+sbH6Xcsv7p30+0OwUbeWfUDAQE0vpabZ3QLg==}
    -    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    -    peerDependencies:
    -      '@typescript-eslint/parser': ^8.50.0
    -      eslint: ^8.57.0 || ^9.0.0
    -      typescript: '>=4.8.4 <6.0.0'
    -
    -  '@typescript-eslint/eslint-plugin@8.56.1':
    -    resolution: {integrity: sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==}
    +  '@typescript-eslint/eslint-plugin@8.57.1':
    +    resolution: {integrity: sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==}
         engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
         peerDependencies:
    -      '@typescript-eslint/parser': ^8.56.1
    +      '@typescript-eslint/parser': ^8.57.1
           eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
           typescript: '>=4.8.4 <6.0.0'
     
    -  '@typescript-eslint/parser@8.50.0':
    -    resolution: {integrity: sha512-6/cmF2piao+f6wSxUsJLZjck7OQsYyRtcOZS02k7XINSNlz93v6emM8WutDQSXnroG2xwYlEVHJI+cPA7CPM3Q==}
    -    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    -    peerDependencies:
    -      eslint: ^8.57.0 || ^9.0.0
    -      typescript: '>=4.8.4 <6.0.0'
    -
       '@typescript-eslint/parser@8.56.1':
         resolution: {integrity: sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==}
         engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    @@ -2483,10 +3055,11 @@ packages:
           eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
           typescript: '>=4.8.4 <6.0.0'
     
    -  '@typescript-eslint/project-service@8.50.0':
    -    resolution: {integrity: sha512-Cg/nQcL1BcoTijEWyx4mkVC56r8dj44bFDvBdygifuS20f3OZCHmFbjF34DPSi07kwlFvqfv/xOLnJ5DquxSGQ==}
    +  '@typescript-eslint/parser@8.57.1':
    +    resolution: {integrity: sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw==}
         engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
         peerDependencies:
    +      eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
           typescript: '>=4.8.4 <6.0.0'
     
       '@typescript-eslint/project-service@8.56.1':
    @@ -2495,25 +3068,25 @@ packages:
         peerDependencies:
           typescript: '>=4.8.4 <6.0.0'
     
    +  '@typescript-eslint/project-service@8.57.1':
    +    resolution: {integrity: sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg==}
    +    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    +    peerDependencies:
    +      typescript: '>=4.8.4 <6.0.0'
    +
       '@typescript-eslint/rule-tester@8.56.1':
         resolution: {integrity: sha512-EWuV5Vq1EFYJEOVcILyWPO35PjnT0c6tv99PCpD12PgfZae5/Jo+F17hGjsEs2Moe+Dy1J7KIr8y037cK8+/rQ==}
         engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
         peerDependencies:
           eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
     
    -  '@typescript-eslint/scope-manager@8.50.0':
    -    resolution: {integrity: sha512-xCwfuCZjhIqy7+HKxBLrDVT5q/iq7XBVBXLn57RTIIpelLtEIZHXAF/Upa3+gaCpeV1NNS5Z9A+ID6jn50VD4A==}
    -    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    -
       '@typescript-eslint/scope-manager@8.56.1':
         resolution: {integrity: sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==}
         engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     
    -  '@typescript-eslint/tsconfig-utils@8.50.0':
    -    resolution: {integrity: sha512-vxd3G/ybKTSlm31MOA96gqvrRGv9RJ7LGtZCn2Vrc5htA0zCDvcMqUkifcjrWNNKXHUU3WCkYOzzVSFBd0wa2w==}
    +  '@typescript-eslint/scope-manager@8.57.1':
    +    resolution: {integrity: sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==}
         engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    -    peerDependencies:
    -      typescript: '>=4.8.4 <6.0.0'
     
       '@typescript-eslint/tsconfig-utils@8.56.1':
         resolution: {integrity: sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==}
    @@ -2521,33 +3094,26 @@ packages:
         peerDependencies:
           typescript: '>=4.8.4 <6.0.0'
     
    -  '@typescript-eslint/type-utils@8.50.0':
    -    resolution: {integrity: sha512-7OciHT2lKCewR0mFoBrvZJ4AXTMe/sYOe87289WAViOocEmDjjv8MvIOT2XESuKj9jp8u3SZYUSh89QA4S1kQw==}
    +  '@typescript-eslint/tsconfig-utils@8.57.1':
    +    resolution: {integrity: sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==}
         engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
         peerDependencies:
    -      eslint: ^8.57.0 || ^9.0.0
           typescript: '>=4.8.4 <6.0.0'
     
    -  '@typescript-eslint/type-utils@8.56.1':
    -    resolution: {integrity: sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==}
    +  '@typescript-eslint/type-utils@8.57.1':
    +    resolution: {integrity: sha512-+Bwwm0ScukFdyoJsh2u6pp4S9ktegF98pYUU0hkphOOqdMB+1sNQhIz8y5E9+4pOioZijrkfNO/HUJVAFFfPKA==}
         engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
         peerDependencies:
           eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
           typescript: '>=4.8.4 <6.0.0'
     
    -  '@typescript-eslint/types@8.50.0':
    -    resolution: {integrity: sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w==}
    -    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    -
       '@typescript-eslint/types@8.56.1':
         resolution: {integrity: sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==}
         engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     
    -  '@typescript-eslint/typescript-estree@8.50.0':
    -    resolution: {integrity: sha512-W7SVAGBR/IX7zm1t70Yujpbk+zdPq/u4soeFSknWFdXIFuWsBGBOUu/Tn/I6KHSKvSh91OiMuaSnYp3mtPt5IQ==}
    +  '@typescript-eslint/types@8.57.1':
    +    resolution: {integrity: sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==}
         engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    -    peerDependencies:
    -      typescript: '>=4.8.4 <6.0.0'
     
       '@typescript-eslint/typescript-estree@8.56.1':
         resolution: {integrity: sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==}
    @@ -2555,11 +3121,10 @@ packages:
         peerDependencies:
           typescript: '>=4.8.4 <6.0.0'
     
    -  '@typescript-eslint/utils@8.50.0':
    -    resolution: {integrity: sha512-87KgUXET09CRjGCi2Ejxy3PULXna63/bMYv72tCAlDJC3Yqwln0HiFJ3VJMst2+mEtNtZu5oFvX4qJGjKsnAgg==}
    +  '@typescript-eslint/typescript-estree@8.57.1':
    +    resolution: {integrity: sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==}
         engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
         peerDependencies:
    -      eslint: ^8.57.0 || ^9.0.0
           typescript: '>=4.8.4 <6.0.0'
     
       '@typescript-eslint/utils@8.56.1':
    @@ -2569,50 +3134,75 @@ packages:
           eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
           typescript: '>=4.8.4 <6.0.0'
     
    -  '@typescript-eslint/visitor-keys@8.50.0':
    -    resolution: {integrity: sha512-Xzmnb58+Db78gT/CCj/PVCvK+zxbnsw6F+O1oheYszJbBSdEjVhQi3C/Xttzxgi/GLmpvOggRs1RFpiJ8+c34Q==}
    +  '@typescript-eslint/utils@8.57.1':
    +    resolution: {integrity: sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ==}
         engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    +    peerDependencies:
    +      eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
    +      typescript: '>=4.8.4 <6.0.0'
     
       '@typescript-eslint/visitor-keys@8.56.1':
         resolution: {integrity: sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==}
         engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     
    -  '@unocss/config@66.5.10':
    -    resolution: {integrity: sha512-udBhfMe+2MU70ZdjnRLnwLQ+0EHYJ4f5JjjvHsfmQ0If4KeYmSStWBuX+/LHNQidhl487JiwW1lBDQ8pKHmbiw==}
    +  '@typescript-eslint/visitor-keys@8.57.1':
    +    resolution: {integrity: sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==}
    +    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    +
    +  '@typescript/vfs@1.6.4':
    +    resolution: {integrity: sha512-PJFXFS4ZJKiJ9Qiuix6Dz/OwEIqHD7Dme1UwZhTK11vR+5dqW2ACbdndWQexBzCx+CPuMe5WBYQWCsFyGlQLlQ==}
    +    peerDependencies:
    +      typescript: '*'
    +
    +  '@ungap/structured-clone@1.3.0':
    +    resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
    +
    +  '@unocss/config@66.6.7':
    +    resolution: {integrity: sha512-1uleyRLyJc6PNNc2L3hEaKL89zXwvQAtP36oFySgL47RAxZHPZ4vfqFpbwR0eEN4iSqTS24ZFr7CTRWCaEGjzQ==}
         engines: {node: '>=14'}
     
    -  '@unocss/core@66.5.10':
    -    resolution: {integrity: sha512-SEmPE4pWNn9VcCvZqovPwFGuG/j69W3zh+x1Ky4z/I2pnyoB0Y0lBmq22KVu/dwExe+ZKKTQpxa0j5rbE27rDQ==}
    +  '@unocss/core@66.6.7':
    +    resolution: {integrity: sha512-Q8456iWFtdwrUNYKVOQY8ygRggjZOVtLc6Jc8KIkxig7OiNlUWOgXJTfCh4I8g6jBYzC5eHaHFDLgJOmOrxBsg==}
     
    -  '@unocss/eslint-config@66.5.10':
    -    resolution: {integrity: sha512-kDoXTBZcI7RCdWPekKrjgiuRcNYfdwjEkG6HtS1++jM0LhK6QgaMfu4p+4j0gfAz86ZNotghM3u8aWO6Fu0nRA==}
    +  '@unocss/eslint-config@66.6.7':
    +    resolution: {integrity: sha512-l33NbugpKr5twWmRbFwQcvAuD/lWAqT9Nrnguga75geeUBENOVNQialeyEFcZAmR7/eYOeILIrhM8XtFUmtf2g==}
         engines: {node: '>=14'}
     
    -  '@unocss/eslint-plugin@66.5.10':
    -    resolution: {integrity: sha512-Fzvl5ISMoGnALo9tqI15nNNWZza2ICqmzyujQCyzsxDZEVZzajNvt8wACVHoEz+dUZykjMPJqqdmX5ZijcPZ1w==}
    +  '@unocss/eslint-plugin@66.6.7':
    +    resolution: {integrity: sha512-0pNFT918CUOiWSlr3ZmePL5Bb06/g/mmP8zP+/dpl2+Vc/GuW6wHVsP+qn5hT2c5FwCPRZ3CUm0HprTru2/sGA==}
         engines: {node: '>=14'}
     
    -  '@unocss/rule-utils@66.5.10':
    -    resolution: {integrity: sha512-497GPWZpArNG25cto0Yq3/Yw+i0x7/N/ySq1HHeE3lB43sdmCv6+m6QEv14I/9/e5WJhQOmrY5LmHZYXC7xxMw==}
    +  '@unocss/rule-utils@66.6.7':
    +    resolution: {integrity: sha512-4PT/s8yKIShSqP9XPSw4EjbZopcu3wlIB9i3kbGbzQwF91H+0Yy10guK3kHDGtkmWVN6Np6VvaGIj2UcbmaivA==}
         engines: {node: '>=14'}
     
    -  '@vitejs/plugin-react@5.1.4':
    -    resolution: {integrity: sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA==}
    +  '@upsetjs/venn.js@2.0.0':
    +    resolution: {integrity: sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==}
    +
    +  '@vitejs/plugin-react@6.0.1':
    +    resolution: {integrity: sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==}
         engines: {node: ^20.19.0 || >=22.12.0}
         peerDependencies:
    -      vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
    +      '@rolldown/plugin-babel': ^0.1.7 || ^0.2.0
    +      babel-plugin-react-compiler: ^1.0.0
    +      vite: ^8.0.0
    +    peerDependenciesMeta:
    +      '@rolldown/plugin-babel':
    +        optional: true
    +      babel-plugin-react-compiler:
    +        optional: true
     
    -  '@vitest/coverage-v8@4.0.18':
    -    resolution: {integrity: sha512-7i+N2i0+ME+2JFZhfuz7Tg/FqKtilHjGyGvoHYQ6iLV0zahbsJ9sljC9OcFcPDbhYKCet+sG8SsVqlyGvPflZg==}
    +  '@vitest/coverage-v8@4.1.0':
    +    resolution: {integrity: sha512-nDWulKeik2bL2Va/Wl4x7DLuTKAXa906iRFooIRPR+huHkcvp9QDkPQ2RJdmjOFrqOqvNfoSQLF68deE3xC3CQ==}
         peerDependencies:
    -      '@vitest/browser': 4.0.18
    -      vitest: 4.0.18
    +      '@vitest/browser': 4.1.0
    +      vitest: 4.1.0
         peerDependenciesMeta:
           '@vitest/browser':
             optional: true
     
    -  '@vitest/eslint-plugin@1.6.9':
    -    resolution: {integrity: sha512-9WfPx1OwJ19QLCSRLkqVO7//1WcWnK3fE/3fJhKMAmDe8+9G4rB47xCNIIeCq3FdEzkIoLTfDlwDlPBaUTMhow==}
    +  '@vitest/eslint-plugin@1.6.12':
    +    resolution: {integrity: sha512-4kI47BJNFE+EQ5bmPbHzBF+ibNzx2Fj0Jo9xhWsTPxMddlHwIWl6YAxagefh461hrwx/W0QwBZpxGS404kBXyg==}
         engines: {node: '>=18'}
         peerDependencies:
           eslint: '>=8.57.0'
    @@ -2624,34 +3214,34 @@ packages:
           vitest:
             optional: true
     
    -  '@vitest/expect@4.0.18':
    -    resolution: {integrity: sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==}
    +  '@vitest/expect@4.1.0':
    +    resolution: {integrity: sha512-EIxG7k4wlWweuCLG9Y5InKFwpMEOyrMb6ZJ1ihYu02LVj/bzUwn2VMU+13PinsjRW75XnITeFrQBMH5+dLvCDA==}
     
    -  '@vitest/mocker@4.0.18':
    -    resolution: {integrity: sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==}
    +  '@vitest/mocker@4.1.0':
    +    resolution: {integrity: sha512-evxREh+Hork43+Y4IOhTo+h5lGmVRyjqI739Rz4RlUPqwrkFFDF6EMvOOYjTx4E8Tl6gyCLRL8Mu7Ry12a13Tw==}
         peerDependencies:
           msw: ^2.4.9
    -      vite: ^6.0.0 || ^7.0.0-0
    +      vite: ^6.0.0 || ^7.0.0 || ^8.0.0-0
         peerDependenciesMeta:
           msw:
             optional: true
           vite:
             optional: true
     
    -  '@vitest/pretty-format@4.0.18':
    -    resolution: {integrity: sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==}
    +  '@vitest/pretty-format@4.1.0':
    +    resolution: {integrity: sha512-3RZLZlh88Ib0J7NQTRATfc/3ZPOnSUn2uDBUoGNn5T36+bALixmzphN26OUD3LRXWkJu4H0s5vvUeqBiw+kS0A==}
     
    -  '@vitest/runner@4.0.18':
    -    resolution: {integrity: sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw==}
    +  '@vitest/runner@4.1.0':
    +    resolution: {integrity: sha512-Duvx2OzQ7d6OjchL+trw+aSrb9idh7pnNfxrklo14p3zmNL4qPCDeIJAK+eBKYjkIwG96Bc6vYuxhqDXQOWpoQ==}
     
    -  '@vitest/snapshot@4.0.18':
    -    resolution: {integrity: sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==}
    +  '@vitest/snapshot@4.1.0':
    +    resolution: {integrity: sha512-0Vy9euT1kgsnj1CHttwi9i9o+4rRLEaPRSOJ5gyv579GJkNpgJK+B4HSv/rAWixx2wdAFci1X4CEPjiu2bXIMg==}
     
    -  '@vitest/spy@4.0.18':
    -    resolution: {integrity: sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==}
    +  '@vitest/spy@4.1.0':
    +    resolution: {integrity: sha512-pz77k+PgNpyMDv2FV6qmk5ZVau6c3R8HC8v342T2xlFxQKTrSeYw9waIJG8KgV9fFwAtTu4ceRzMivPTH6wSxw==}
     
    -  '@vitest/utils@4.0.18':
    -    resolution: {integrity: sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==}
    +  '@vitest/utils@4.1.0':
    +    resolution: {integrity: sha512-XfPXT6a8TZY3dcGY8EdwsBulFCIw+BeeX0RZn2x/BtiY/75YGh8FeWGG8QISN/WhaqSrE2OrlDgtF8q5uhOTmw==}
     
       '@vue/compiler-core@3.5.26':
         resolution: {integrity: sha512-vXyI5GMfuoBCnv5ucIT7jhHKl55Y477yxP6fc4eUswjP8FG3FFVFd41eNDArR+Uk3QKn2Z85NavjaxLxOC19/w==}
    @@ -2671,11 +3261,11 @@ packages:
           eslint: '>= 8.21.0'
           prettier: '>= 3.0.0'
     
    -  '@vue/eslint-config-typescript@14.6.0':
    -    resolution: {integrity: sha512-UpiRY/7go4Yps4mYCjkvlIbVWmn9YvPGQDxTAlcKLphyaD77LjIu3plH4Y9zNT0GB4f3K5tMmhhtRhPOgrQ/bQ==}
    +  '@vue/eslint-config-typescript@14.7.0':
    +    resolution: {integrity: sha512-iegbMINVc+seZ/QxtzWiOBozctrHiF2WvGedruu2EbLujg9VuU0FQiNcN2z1ycuaoKKpF4m2qzB5HDEMKbxtIg==}
         engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
         peerDependencies:
    -      eslint: ^9.10.0
    +      eslint: ^9.10.0 || ^10.0.0
           eslint-plugin-vue: ^9.28.0 || ^10.0.0
           typescript: '>=4.8.4'
         peerDependenciesMeta:
    @@ -2685,6 +3275,10 @@ packages:
       '@vue/shared@3.5.26':
         resolution: {integrity: sha512-7Z6/y3uFI5PRoKeorTOSXKcDj0MSasfNNltcslbFrPpcw6aXRUALq4IfJlaTRspiWIUOEZbrpM+iQGmCOiWe4A==}
     
    +  '@xmldom/xmldom@0.9.8':
    +    resolution: {integrity: sha512-p96FSY54r+WJ50FIOsCOjyj/wavs8921hG5+kVMmZgKcvIKxMXHTrjNJvRgWa/zuX3B6t2lijLNFaOyuxUH+2A==}
    +    engines: {node: '>=14.6'}
    +
       accepts@2.0.0:
         resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==}
         engines: {node: '>= 0.6'}
    @@ -2729,9 +3323,15 @@ packages:
         resolution: {integrity: sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==}
         engines: {node: '>=14'}
     
    +  arg@5.0.2:
    +    resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
    +
       argparse@2.0.1:
         resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
     
    +  array-iterate@2.0.1:
    +    resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==}
    +
       assertion-error@2.0.1:
         resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
         engines: {node: '>=12'}
    @@ -2744,8 +3344,12 @@ packages:
         resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==}
         engines: {node: '>=4'}
     
    -  ast-v8-to-istanbul@0.3.12:
    -    resolution: {integrity: sha512-BRRC8VRZY2R4Z4lFIL35MwNXmwVqBityvOIwETtsCSwvjl0IdgFsy9NhdaA6j74nUdtJJlIypeRhpDam19Wq3g==}
    +  ast-v8-to-istanbul@1.0.0:
    +    resolution: {integrity: sha512-1fSfIwuDICFA4LKkCzRPO7F0hzFf0B7+Xqrl27ynQaa+Rh0e1Es0v6kWHPott3lU10AyAr7oKHa65OppjLn3Rg==}
    +
    +  astring@1.9.0:
    +    resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==}
    +    hasBin: true
     
       babel-dead-code-elimination@1.0.12:
         resolution: {integrity: sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig==}
    @@ -2753,9 +3357,6 @@ packages:
       bail@2.0.2:
         resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
     
    -  balanced-match@1.0.2:
    -    resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
    -
       balanced-match@4.0.4:
         resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
         engines: {node: 18 || 20 || >=22}
    @@ -2768,6 +3369,11 @@ packages:
       before-after-hook@4.0.0:
         resolution: {integrity: sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==}
     
    +  better-react-mathjax@2.3.0:
    +    resolution: {integrity: sha512-K0ceQC+jQmB+NLDogO5HCpqmYf18AU2FxDbLdduYgkHYWZApFggkHE4dIaXCV1NqeoscESYXXo1GSkY6fA295w==}
    +    peerDependencies:
    +      react: '>=16.8'
    +
       binary-extensions@2.3.0:
         resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
         engines: {node: '>=8'}
    @@ -2782,9 +3388,6 @@ packages:
       boolbase@1.0.0:
         resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
     
    -  brace-expansion@2.0.2:
    -    resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==}
    -
       brace-expansion@5.0.4:
         resolution: {integrity: sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==}
         engines: {node: 18 || 20 || >=22}
    @@ -2806,9 +3409,9 @@ packages:
         resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
         engines: {node: '>= 0.8'}
     
    -  cac@6.7.14:
    -    resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
    -    engines: {node: '>=8'}
    +  cac@7.0.0:
    +    resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==}
    +    engines: {node: '>=20.19.0'}
     
       call-bind-apply-helpers@1.0.2:
         resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
    @@ -2828,6 +3431,10 @@ packages:
         resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==}
         engines: {node: '>=18'}
     
    +  chalk@5.6.2:
    +    resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==}
    +    engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
    +
       change-case@5.4.4:
         resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==}
     
    @@ -2846,6 +3453,14 @@ packages:
       chardet@2.1.1:
         resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==}
     
    +  chevrotain-allstar@0.3.1:
    +    resolution: {integrity: sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==}
    +    peerDependencies:
    +      chevrotain: ^11.0.0
    +
    +  chevrotain@11.1.2:
    +    resolution: {integrity: sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg==}
    +
       chokidar@3.6.0:
         resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
         engines: {node: '>= 8.10.0'}
    @@ -2876,27 +3491,55 @@ packages:
         peerDependencies:
           typanion: '*'
     
    +  clipboardy@4.0.0:
    +    resolution: {integrity: sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w==}
    +    engines: {node: '>=18'}
    +
       clsx@2.1.1:
         resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
         engines: {node: '>=6'}
     
    +  code-block-writer@13.0.3:
    +    resolution: {integrity: sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==}
    +
    +  collapse-white-space@2.1.0:
    +    resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==}
    +
       colorette@2.0.20:
         resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
     
    -  comment-parser@1.4.1:
    -    resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==}
    -    engines: {node: '>= 12.0.0'}
    +  comma-separated-tokens@2.0.3:
    +    resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
    +
    +  commander@13.1.0:
    +    resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==}
    +    engines: {node: '>=18'}
    +
    +  commander@7.2.0:
    +    resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
    +    engines: {node: '>= 10'}
    +
    +  commander@8.3.0:
    +    resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==}
    +    engines: {node: '>= 12'}
     
       comment-parser@1.4.5:
         resolution: {integrity: sha512-aRDkn3uyIlCFfk5NUA+VdwMmMsh8JGhc4hapfV4yxymHGQ3BVskMQfoXGpCo5IoBuQ9tS5iiVKhCpTcB4pW4qw==}
         engines: {node: '>= 12.0.0'}
     
    +  compute-scroll-into-view@3.1.1:
    +    resolution: {integrity: sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==}
    +
       confbox@0.1.8:
         resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==}
     
       confbox@0.2.4:
         resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==}
     
    +  consola@3.4.2:
    +    resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==}
    +    engines: {node: ^14.18.0 || >=16.10.0}
    +
       content-disposition@1.0.1:
         resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==}
         engines: {node: '>=18'}
    @@ -2926,6 +3569,12 @@ packages:
         resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==}
         engines: {node: '>= 0.10'}
     
    +  cose-base@1.0.3:
    +    resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==}
    +
    +  cose-base@2.2.0:
    +    resolution: {integrity: sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==}
    +
       cross-spawn@7.0.6:
         resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
         engines: {node: '>= 8'}
    @@ -2938,34 +3587,129 @@ packages:
       csstype@3.2.3:
         resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
     
    +  cytoscape-cose-bilkent@4.1.0:
    +    resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==}
    +    peerDependencies:
    +      cytoscape: ^3.2.0
    +
    +  cytoscape-fcose@2.2.0:
    +    resolution: {integrity: sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==}
    +    peerDependencies:
    +      cytoscape: ^3.2.0
    +
    +  cytoscape@3.33.1:
    +    resolution: {integrity: sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==}
    +    engines: {node: '>=0.10'}
    +
    +  d3-array@2.12.1:
    +    resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==}
    +
       d3-array@3.2.4:
         resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==}
         engines: {node: '>=12'}
     
    +  d3-axis@3.0.0:
    +    resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==}
    +    engines: {node: '>=12'}
    +
    +  d3-brush@3.0.0:
    +    resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==}
    +    engines: {node: '>=12'}
    +
    +  d3-chord@3.0.1:
    +    resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==}
    +    engines: {node: '>=12'}
    +
       d3-color@3.1.0:
         resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==}
         engines: {node: '>=12'}
     
    +  d3-contour@4.0.2:
    +    resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==}
    +    engines: {node: '>=12'}
    +
    +  d3-delaunay@6.0.4:
    +    resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==}
    +    engines: {node: '>=12'}
    +
    +  d3-dispatch@3.0.1:
    +    resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==}
    +    engines: {node: '>=12'}
    +
    +  d3-drag@3.0.0:
    +    resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==}
    +    engines: {node: '>=12'}
    +
    +  d3-dsv@3.0.1:
    +    resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==}
    +    engines: {node: '>=12'}
    +    hasBin: true
    +
       d3-ease@3.0.1:
         resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==}
         engines: {node: '>=12'}
     
    +  d3-fetch@3.0.1:
    +    resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==}
    +    engines: {node: '>=12'}
    +
    +  d3-force@3.0.0:
    +    resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==}
    +    engines: {node: '>=12'}
    +
       d3-format@3.1.2:
         resolution: {integrity: sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==}
         engines: {node: '>=12'}
     
    +  d3-geo@3.1.1:
    +    resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==}
    +    engines: {node: '>=12'}
    +
    +  d3-hierarchy@3.1.2:
    +    resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==}
    +    engines: {node: '>=12'}
    +
       d3-interpolate@3.0.1:
         resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==}
         engines: {node: '>=12'}
     
    +  d3-path@1.0.9:
    +    resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==}
    +
       d3-path@3.1.0:
         resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==}
         engines: {node: '>=12'}
     
    +  d3-polygon@3.0.1:
    +    resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==}
    +    engines: {node: '>=12'}
    +
    +  d3-quadtree@3.0.1:
    +    resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==}
    +    engines: {node: '>=12'}
    +
    +  d3-random@3.0.1:
    +    resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==}
    +    engines: {node: '>=12'}
    +
    +  d3-sankey@0.12.3:
    +    resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==}
    +
    +  d3-scale-chromatic@3.1.0:
    +    resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==}
    +    engines: {node: '>=12'}
    +
       d3-scale@4.0.2:
         resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==}
         engines: {node: '>=12'}
     
    +  d3-selection@3.0.0:
    +    resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==}
    +    engines: {node: '>=12'}
    +
    +  d3-shape@1.3.7:
    +    resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==}
    +
       d3-shape@3.2.0:
         resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==}
         engines: {node: '>=12'}
    @@ -2982,6 +3726,26 @@ packages:
         resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==}
         engines: {node: '>=12'}
     
    +  d3-transition@3.0.1:
    +    resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==}
    +    engines: {node: '>=12'}
    +    peerDependencies:
    +      d3-selection: 2 - 3
    +
    +  d3-zoom@3.0.0:
    +    resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==}
    +    engines: {node: '>=12'}
    +
    +  d3@7.9.0:
    +    resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==}
    +    engines: {node: '>=12'}
    +
    +  dagre-d3-es@7.0.14:
    +    resolution: {integrity: sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==}
    +
    +  dayjs@1.11.20:
    +    resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==}
    +
       debug@4.4.3:
         resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
         engines: {node: '>=6.0'}
    @@ -3007,6 +3771,9 @@ packages:
       defu@6.1.4:
         resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
     
    +  delaunator@5.0.1:
    +    resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==}
    +
       depd@2.0.0:
         resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
         engines: {node: '>= 0.8'}
    @@ -3022,9 +3789,9 @@ packages:
       devlop@1.1.0:
         resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
     
    -  diff-sequences@27.5.1:
    -    resolution: {integrity: sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==}
    -    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
    +  diff-sequences@29.6.3:
    +    resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
    +    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
     
       diff@8.0.3:
         resolution: {integrity: sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==}
    @@ -3033,6 +3800,9 @@ packages:
       dompurify@3.2.7:
         resolution: {integrity: sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==}
     
    +  dompurify@3.3.3:
    +    resolution: {integrity: sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA==}
    +
       dts-resolver@2.1.3:
         resolution: {integrity: sha512-bihc7jPC90VrosXNzK0LTE2cuLP6jr0Ro8jk+kMugHReJVLIpHz/xadeq3MhuwyO4TD4OA3L1Q8pBBFRc08Tsw==}
         engines: {node: '>=20.19.0'}
    @@ -3072,6 +3842,10 @@ packages:
         resolution: {integrity: sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==}
         engines: {node: '>=10.13.0'}
     
    +  entities@6.0.1:
    +    resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==}
    +    engines: {node: '>=0.12'}
    +
       entities@7.0.1:
         resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==}
         engines: {node: '>=0.12'}
    @@ -3084,8 +3858,8 @@ packages:
         resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
         engines: {node: '>= 0.4'}
     
    -  es-module-lexer@1.7.0:
    -    resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==}
    +  es-module-lexer@2.0.0:
    +    resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==}
     
       es-object-atoms@1.1.1:
         resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
    @@ -3094,6 +3868,12 @@ packages:
       es-toolkit@1.44.0:
         resolution: {integrity: sha512-6penXeZalaV88MM3cGkFZZfOoLGWshWWfdy0tWw/RlVVyhvMaWSBTOvXNeiW3e5FwdS5ePW0LGEu17zT139ktg==}
     
    +  esast-util-from-estree@2.0.0:
    +    resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==}
    +
    +  esast-util-from-js@2.0.1:
    +    resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==}
    +
       esbuild@0.27.3:
         resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==}
         engines: {node: '>=18'}
    @@ -3124,12 +3904,6 @@ packages:
         peerDependencies:
           eslint: '>=6.0.0'
     
    -  eslint-compat-utils@0.6.5:
    -    resolution: {integrity: sha512-vAUHYzue4YAa2hNACjB8HvUQj5yehAZgiClyFVVom9cP8z5NSFq3PwB/TtJslN2zAMgRX6FCFCjYBbQh71g5RQ==}
    -    engines: {node: '>=12'}
    -    peerDependencies:
    -      eslint: '>=6.0.0'
    -
       eslint-config-flat-gitignore@2.2.1:
         resolution: {integrity: sha512-wA5EqN0era7/7Gt5Botlsfin/UNY0etJSEeBgbUlFLFrBi47rAN//+39fI7fpYcl8RENutlFtvp/zRa/M/pZNg==}
         peerDependencies:
    @@ -3141,16 +3915,16 @@ packages:
         peerDependencies:
           eslint: '>=7.0.0'
     
    -  eslint-flat-config-utils@2.1.4:
    -    resolution: {integrity: sha512-bEnmU5gqzS+4O+id9vrbP43vByjF+8KOs+QuuV4OlqAuXmnRW2zfI/Rza1fQvdihQ5h4DUo0NqFAiViD4mSrzQ==}
    +  eslint-flat-config-utils@3.0.2:
    +    resolution: {integrity: sha512-mPvevWSDQFwgABvyCurwIu6ZdKxGI5NW22/BGDwA1T49NO6bXuxbV9VfJK/tkQoNyPogT6Yu1d57iM0jnZVWmg==}
     
       eslint-formatting-reporter@0.0.0:
         resolution: {integrity: sha512-k9RdyTqxqN/wNYVaTk/ds5B5rA8lgoAmvceYN7bcZMBwU7TuXx5ntewJv81eF3pIL/CiJE+pJZm36llG8yhyyw==}
         peerDependencies:
           eslint: '>=8.40.0'
     
    -  eslint-json-compat-utils@0.2.2:
    -    resolution: {integrity: sha512-KcTUifi8VSSHkrOY0FzB7smuTZRU9T2nCrcCy6k2b+Q77+uylBQVIxN4baVCIWvWJEpud+IsrYgco4JJ6io05g==}
    +  eslint-json-compat-utils@0.2.3:
    +    resolution: {integrity: sha512-RbBmDFyu7FqnjE8F0ZxPNzx5UaptdeS9Uu50r7A+D7s/+FCX+ybiyViYEgFUaFIFqSWJgZRTpL5d8Kanxxl2lQ==}
         engines: {node: '>=12'}
         peerDependencies:
           '@eslint/json': '*'
    @@ -3181,38 +3955,39 @@ packages:
           '@typescript-eslint/utils': '*'
           eslint: '*'
     
    +  eslint-plugin-depend@1.5.0:
    +    resolution: {integrity: sha512-i3UeLYmclf1Icp35+6W7CR4Bp2PIpDgBuf/mpmXK5UeLkZlvYJ21VuQKKHHAIBKRTPivPGX/gZl5JGno1o9Y0A==}
    +    peerDependencies:
    +      eslint: '>=8.40.0'
    +
       eslint-plugin-es-x@7.8.0:
         resolution: {integrity: sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==}
         engines: {node: ^14.18.0 || >=16.0.0}
         peerDependencies:
           eslint: '>=8'
     
    -  eslint-plugin-format@1.1.0:
    -    resolution: {integrity: sha512-zjGPZcftddkO9GydBwvTKBV4ICN6a++XK0zIPi3HZHlU8W9EaftTA3XAanJvGAXQUYEqAADtgQi08SX+afbPrg==}
    +  eslint-plugin-format@2.0.1:
    +    resolution: {integrity: sha512-0BA65p5DAiuKtx5MmMJfPk9WaTjoHHbyVW7ZXRhaZoA1fdiMHhay9QRiDL2wr0hJWZxdF7CRThOK/70VUKVg2g==}
         peerDependencies:
    -      eslint: ^8.40.0 || ^9.0.0
    +      eslint: ^8.40.0 || ^9.0.0 || ^10.0.0
     
    -  eslint-plugin-import-lite@0.3.1:
    -    resolution: {integrity: sha512-9+EByHZatvWFn/lRsUja5pwah0U5lhOA6SXqTI/iIzoIJHMgmsHUHEaTlLzKU/ukyCRwKEU5E92aUURPgVWq0A==}
    +  eslint-plugin-import-lite@0.5.2:
    +    resolution: {integrity: sha512-XvfdWOC5dSLEI9krIPRlNmKSI2ViIE9pVylzfV9fCq0ZpDaNeUk6o0wZv0OzN83QdadgXp1NsY0qjLINxwYCsw==}
         engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
         peerDependencies:
           eslint: '>=9.0.0'
    -      typescript: '>=4.5'
    -    peerDependenciesMeta:
    -      typescript:
    -        optional: true
     
    -  eslint-plugin-jsdoc@61.7.1:
    -    resolution: {integrity: sha512-36DpldF95MlTX//n3/naULFVt8d1cV4jmSkx7ZKrE9ikkKHAgMLesuWp1SmwpVwAs5ndIM6abKd6PeOYZUgdWg==}
    -    engines: {node: '>=20.11.0'}
    +  eslint-plugin-jsdoc@62.8.0:
    +    resolution: {integrity: sha512-hu3r9/6JBmPG6wTcqtYzgZAnjEG2eqRUATfkFscokESg1VDxZM21ZaMire0KjeMwfj+SXvgB4Rvh5LBuesj92w==}
    +    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
         peerDependencies:
    -      eslint: ^7.0.0 || ^8.0.0 || ^9.0.0
    +      eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0
     
    -  eslint-plugin-jsonc@2.21.1:
    -    resolution: {integrity: sha512-dbNR5iEnQeORwsK2WZzr3QaMtFCY3kKJVMRHPzUpKzMhmVy2zIpVgFDpX8MNoIdoqz6KCpCfOJavhfiSbZbN+w==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    +  eslint-plugin-jsonc@3.1.2:
    +    resolution: {integrity: sha512-dopTxdB22iuOkgKyJCupEC5IYBItUT4J/teq1H5ddUObcaYhOURxtJElZczdcYnnKCghNU/vccuyPkliy2Wxsg==}
    +    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
         peerDependencies:
    -      eslint: '>=6.0.0'
    +      eslint: '>=9.38.0'
     
       eslint-plugin-n@17.24.0:
         resolution: {integrity: sha512-/gC7/KAYmfNnPNOb3eu8vw+TdVnV0zhdQwexsw6FLXbhzroVj20vRn2qL8lDWDGnAQ2J8DhdfvXxX9EoxvERvw==}
    @@ -3224,19 +3999,19 @@ packages:
         resolution: {integrity: sha512-brcKcxGnISN2CcVhXJ/kEQlNa0MEfGRtwKtWA16SkqXHKitaKIMrfemJKLKX1YqDU5C/5JY3PvZXd5jEW04e0Q==}
         engines: {node: '>=5.0.0'}
     
    -  eslint-plugin-perfectionist@4.15.1:
    -    resolution: {integrity: sha512-MHF0cBoOG0XyBf7G0EAFCuJJu4I18wy0zAoT1OHfx2o6EOx1EFTIzr2HGeuZa1kDcusoX0xJ9V7oZmaeFd773Q==}
    -    engines: {node: ^18.0.0 || >=20.0.0}
    +  eslint-plugin-perfectionist@5.7.0:
    +    resolution: {integrity: sha512-WRHj7OZS/INutQ/gKN5C1ZGnMhkQ3oKZQAA2I7rl5yM8keBtSd9oj/qlJaHuwh5873FhMPqYlttcadF0YsTN7g==}
    +    engines: {node: ^20.0.0 || >=22.0.0}
         peerDependencies:
    -      eslint: '>=8.45.0'
    +      eslint: ^8.45.0 || ^9.0.0 || ^10.0.0
     
       eslint-plugin-pnpm@1.6.0:
         resolution: {integrity: sha512-dxmt9r3zvPaft6IugS4i0k16xag3fTbOvm/road5uV9Y8qUCQT0xzheSh3gMlYAlC6vXRpfArBDsTZ7H7JKCbg==}
         peerDependencies:
           eslint: ^9.0.0 || ^10.0.0
     
    -  eslint-plugin-prettier@5.5.4:
    -    resolution: {integrity: sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==}
    +  eslint-plugin-prettier@5.5.5:
    +    resolution: {integrity: sha512-hscXkbqUZ2sPithAuLm5MXL+Wph+U7wHngPBv9OMWwlP8iaflyxpjTYZkmdgB4/vPIhemRlBEoLrH7UC1n7aUw==}
         engines: {node: ^14.18.0 || >=16.0.0}
         peerDependencies:
           '@types/eslint': '>=8.0.0'
    @@ -3249,20 +4024,20 @@ packages:
           eslint-config-prettier:
             optional: true
     
    -  eslint-plugin-regexp@2.10.0:
    -    resolution: {integrity: sha512-ovzQT8ESVn5oOe5a7gIDPD5v9bCSjIFJu57sVPDqgPRXicQzOnYfFN21WoQBQF18vrhT5o7UMKFwJQVVjyJ0ng==}
    -    engines: {node: ^18 || >=20}
    +  eslint-plugin-regexp@3.1.0:
    +    resolution: {integrity: sha512-qGXIC3DIKZHcK1H9A9+Byz9gmndY6TTSRkSMTZpNXdyCw2ObSehRgccJv35n9AdUakEjQp5VFNLas6BMXizCZg==}
    +    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
         peerDependencies:
    -      eslint: '>=8.44.0'
    +      eslint: '>=9.38.0'
     
    -  eslint-plugin-toml@0.12.0:
    -    resolution: {integrity: sha512-+/wVObA9DVhwZB1nG83D2OAQRrcQZXy+drqUnFJKymqnmbnbfg/UPmEMCKrJNcEboUGxUjYrJlgy+/Y930mURQ==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    +  eslint-plugin-toml@1.3.1:
    +    resolution: {integrity: sha512-1l00fBP03HIt9IPV7ZxBi7x0y0NMdEZmakL1jBD6N/FoKBvfKxPw5S8XkmzBecOnFBTn5Z8sNJtL5vdf9cpRMQ==}
    +    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
         peerDependencies:
    -      eslint: '>=6.0.0'
    +      eslint: '>=9.38.0'
     
    -  eslint-plugin-unicorn@62.0.0:
    -    resolution: {integrity: sha512-HIlIkGLkvf29YEiS/ImuDZQbP12gWyx5i3C6XrRxMvVdqMroCI9qoVYCoIl17ChN+U89pn9sVwLxhIWj5nEc7g==}
    +  eslint-plugin-unicorn@63.0.0:
    +    resolution: {integrity: sha512-Iqecl9118uQEXYh7adylgEmGfkn5es3/mlQTLLkd4pXkIk9CTGrAbeUux+YljSa2ohXCBmQQ0+Ej1kZaFgcfkA==}
         engines: {node: ^20.10.0 || >=21.0.0}
         peerDependencies:
           eslint: '>=9.38.0'
    @@ -3276,13 +4051,13 @@ packages:
           '@typescript-eslint/eslint-plugin':
             optional: true
     
    -  eslint-plugin-vue@10.6.2:
    -    resolution: {integrity: sha512-nA5yUs/B1KmKzvC42fyD0+l9Yd+LtEpVhWRbXuDj0e+ZURcTtyRbMDWUeJmTAh2wC6jC83raS63anNM2YT3NPw==}
    +  eslint-plugin-vue@10.8.0:
    +    resolution: {integrity: sha512-f1J/tcbnrpgC8suPN5AtdJ5MQjuXbSU9pGRSSYAuF3SHoiYCOdEX6O22pLaRyLHXvDcOe+O5ENgc1owQ587agA==}
         engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
         peerDependencies:
           '@stylistic/eslint-plugin': ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0
           '@typescript-eslint/parser': ^7.0.0 || ^8.0.0
    -      eslint: ^8.57.0 || ^9.0.0
    +      eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
           vue-eslint-parser: ^10.0.0
         peerDependenciesMeta:
           '@stylistic/eslint-plugin':
    @@ -3290,11 +4065,11 @@ packages:
           '@typescript-eslint/parser':
             optional: true
     
    -  eslint-plugin-yml@1.19.1:
    -    resolution: {integrity: sha512-bYkOxyEiXh9WxUhVYPELdSHxGG5pOjCSeJOVkfdIyj6tuiHDxrES2WAW1dBxn3iaZQey57XflwLtCYRcNPOiOg==}
    -    engines: {node: ^14.17.0 || >=16.0.0}
    +  eslint-plugin-yml@3.3.1:
    +    resolution: {integrity: sha512-isntsZchaTqDMNNkD+CakrgA/pdUoJ45USWBKpuqfAW1MCuw731xX/vrXfoJFZU3tTFr24nCbDYmDfT2+g4QtQ==}
    +    engines: {node: ^20.19.0 || ^22.13.0 || >=24.0.0}
         peerDependencies:
    -      eslint: '>=6.0.0'
    +      eslint: '>=9.38.0'
     
       eslint-processor-vue-blocks@2.0.0:
         resolution: {integrity: sha512-u4W0CJwGoWY3bjXAuFpc/b6eK3NQEI8MoeW7ritKj3G3z/WtHrKjkqf+wk8mPEy5rlMGS+k6AZYOw2XBoN/02Q==}
    @@ -3302,8 +4077,8 @@ packages:
           '@vue/compiler-sfc': ^3.3.0
           eslint: '>=9.0.0'
     
    -  eslint-scope@9.1.1:
    -    resolution: {integrity: sha512-GaUN0sWim5qc8KVErfPBWmc31LEsOkrUJbvJZV+xuL3u2phMUK4HIvXlWAakfC8W4nzlK+chPEAkYOYb5ZScIw==}
    +  eslint-scope@9.1.2:
    +    resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==}
         engines: {node: ^20.19.0 || ^22.13.0 || >=24}
     
       eslint-visitor-keys@3.4.3:
    @@ -3318,8 +4093,8 @@ packages:
         resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==}
         engines: {node: ^20.19.0 || ^22.13.0 || >=24}
     
    -  eslint@10.0.2:
    -    resolution: {integrity: sha512-uYixubwmqJZH+KLVYIVKY1JQt7tysXhtj21WSvjcSmU5SVNzMus1bgLe+pAt816yQ8opKfheVVoPLqvVMGejYw==}
    +  eslint@10.0.3:
    +    resolution: {integrity: sha512-COV33RzXZkqhG9P2rZCFl9ZmJ7WL+gQSCRzE7RhkbclbQPtLAWReL7ysA0Sh4c8Im2U9ynybdR56PV0XcKvqaQ==}
         engines: {node: ^20.19.0 || ^22.13.0 || >=24}
         hasBin: true
         peerDependencies:
    @@ -3328,6 +4103,10 @@ packages:
           jiti:
             optional: true
     
    +  esm@3.2.25:
    +    resolution: {integrity: sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==}
    +    engines: {node: '>=6'}
    +
       espree@10.4.0:
         resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==}
         engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    @@ -3336,10 +4115,6 @@ packages:
         resolution: {integrity: sha512-AVHPqQoZYc+RUM4/3Ly5udlZY/U4LS8pIG05jEjWM2lQMU/oaZ7qshzAl2YP1tfNmXfftH3ohurfwNAug+MnsQ==}
         engines: {node: ^20.19.0 || ^22.13.0 || >=24}
     
    -  espree@9.6.1:
    -    resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    -
       esprima@4.0.1:
         resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
         engines: {node: '>=4'}
    @@ -3357,9 +4132,24 @@ packages:
         resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
         engines: {node: '>=4.0'}
     
    +  estree-util-attach-comments@3.0.0:
    +    resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==}
    +
    +  estree-util-build-jsx@3.0.1:
    +    resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==}
    +
       estree-util-is-identifier-name@3.0.0:
         resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==}
     
    +  estree-util-scope@1.0.0:
    +    resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==}
    +
    +  estree-util-to-js@2.0.0:
    +    resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==}
    +
    +  estree-util-value-to-estree@3.5.0:
    +    resolution: {integrity: sha512-aMV56R27Gv3QmfmF1MY12GWkGzzeAezAX+UplqHVASfjc9wNzI/X6hC0S9oxq61WT4aQesLGslWP9tKk6ghRZQ==}
    +
       estree-util-visit@2.0.0:
         resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==}
     
    @@ -3395,6 +4185,10 @@ packages:
         resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==}
         engines: {node: '>=18.0.0'}
     
    +  execa@8.0.1:
    +    resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==}
    +    engines: {node: '>=16.17'}
    +
       expect-type@1.3.0:
         resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==}
         engines: {node: '>=12.0.0'}
    @@ -3415,8 +4209,8 @@ packages:
       extend@3.0.2:
         resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
     
    -  fast-check@4.5.3:
    -    resolution: {integrity: sha512-IE9csY7lnhxBnA8g/WI5eg/hygA6MGWJMSNfFRrBlXUciADEhS1EDB0SIsMSvzubzIlOBbVITSsypCsW717poA==}
    +  fast-check@4.6.0:
    +    resolution: {integrity: sha512-h7H6Dm0Fy+H4ciQYFxFjXnXkzR2kr9Fb22c0UBpHnm59K2zpr2t13aPTHlltFiNT6zuxp6HMPAVVvgur4BLdpA==}
         engines: {node: '>=12.17.0'}
     
       fast-content-type-parse@3.0.0:
    @@ -3508,8 +4302,8 @@ packages:
         resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==}
         engines: {node: '>= 0.8'}
     
    -  fs-extra@11.3.3:
    -    resolution: {integrity: sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==}
    +  fs-extra@11.3.4:
    +    resolution: {integrity: sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==}
         engines: {node: '>=14.14'}
     
       fsevents@2.3.3:
    @@ -3532,6 +4326,10 @@ packages:
         resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
         engines: {node: '>= 0.4'}
     
    +  get-stream@8.0.1:
    +    resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==}
    +    engines: {node: '>=16'}
    +
       get-tsconfig@4.13.6:
         resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==}
     
    @@ -3554,6 +4352,10 @@ packages:
         resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==}
         engines: {node: '>=18'}
     
    +  globals@17.4.0:
    +    resolution: {integrity: sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw==}
    +    engines: {node: '>=18'}
    +
       globrex@0.1.2:
         resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==}
     
    @@ -3564,8 +4366,8 @@ packages:
       graceful-fs@4.2.11:
         resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
     
    -  graphemer@1.4.0:
    -    resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
    +  hachure-fill@0.5.2:
    +    resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==}
     
       has-flag@4.0.0:
         resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
    @@ -3579,12 +4381,57 @@ packages:
         resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
         engines: {node: '>= 0.4'}
     
    +  hast-util-from-dom@5.0.1:
    +    resolution: {integrity: sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q==}
    +
    +  hast-util-from-html-isomorphic@2.0.0:
    +    resolution: {integrity: sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==}
    +
    +  hast-util-from-html@2.0.3:
    +    resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==}
    +
    +  hast-util-from-parse5@8.0.3:
    +    resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==}
    +
    +  hast-util-is-element@3.0.0:
    +    resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==}
    +
    +  hast-util-parse-selector@4.0.0:
    +    resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==}
    +
    +  hast-util-raw@9.1.0:
    +    resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==}
    +
    +  hast-util-to-estree@3.1.3:
    +    resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==}
    +
    +  hast-util-to-html@9.0.5:
    +    resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==}
    +
    +  hast-util-to-jsx-runtime@2.3.6:
    +    resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==}
    +
    +  hast-util-to-parse5@8.0.1:
    +    resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==}
    +
    +  hast-util-to-string@3.0.1:
    +    resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==}
    +
    +  hast-util-to-text@4.0.2:
    +    resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==}
    +
    +  hast-util-whitespace@3.0.0:
    +    resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
    +
    +  hastscript@9.0.1:
    +    resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==}
    +
       hono@4.12.8:
         resolution: {integrity: sha512-VJCEvtrezO1IAR+kqEYnxUOoStaQPGrCmX3j4wDTNOcD1uRPFpGlwQUIW8niPuvHXaTUxeOUl5MMDGrl+tmO9A==}
         engines: {node: '>=16.9.0'}
     
    -  hookable@6.0.1:
    -    resolution: {integrity: sha512-uKGyY8BuzN/a5gvzvA+3FVWo0+wUjgtfSdnmjtrOVwQCZPHpHDH2WRO3VZSOeluYrHoDCiXFffZXs8Dj1ULWtw==}
    +  hookable@6.1.0:
    +    resolution: {integrity: sha512-ZoKZSJgu8voGK2geJS+6YtYjvIzu9AOM/KZXsBxr83uhLL++e9pEv/dlgwgy3dvHg06kTz6JOh1hk3C8Ceiymw==}
     
       html-entities@2.6.0:
         resolution: {integrity: sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==}
    @@ -3592,10 +4439,21 @@ packages:
       html-escaper@2.0.2:
         resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
     
    +  html-void-elements@3.0.0:
    +    resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
    +
       http-errors@2.0.1:
         resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==}
         engines: {node: '>= 0.8'}
     
    +  human-signals@5.0.0:
    +    resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==}
    +    engines: {node: '>=16.17.0'}
    +
    +  iconv-lite@0.6.3:
    +    resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
    +    engines: {node: '>=0.10.0'}
    +
       iconv-lite@0.7.2:
         resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==}
         engines: {node: '>=0.10.0'}
    @@ -3629,6 +4487,12 @@ packages:
       inherits@2.0.4:
         resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
     
    +  inline-style-parser@0.2.7:
    +    resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==}
    +
    +  internmap@1.0.1:
    +    resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==}
    +
       internmap@2.0.3:
         resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
         engines: {node: '>=12'}
    @@ -3661,6 +4525,11 @@ packages:
       is-decimal@2.0.1:
         resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==}
     
    +  is-docker@3.0.0:
    +    resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==}
    +    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
    +    hasBin: true
    +
       is-extglob@2.1.1:
         resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
         engines: {node: '>=0.10.0'}
    @@ -3672,6 +4541,11 @@ packages:
       is-hexadecimal@2.0.1:
         resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==}
     
    +  is-inside-container@1.0.0:
    +    resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==}
    +    engines: {node: '>=14.16'}
    +    hasBin: true
    +
       is-number@7.0.0:
         resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
         engines: {node: '>=0.12.0'}
    @@ -3683,6 +4557,18 @@ packages:
       is-promise@4.0.0:
         resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==}
     
    +  is-stream@3.0.0:
    +    resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==}
    +    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
    +
    +  is-wsl@3.1.1:
    +    resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==}
    +    engines: {node: '>=16'}
    +
    +  is64bit@2.0.0:
    +    resolution: {integrity: sha512-jv+8jaWCl0g2lSBkNSVXdzfBA0npK1HGC2KtWM9FumFRoGS94g3NbCCLVnCYHLjp4GrW2KZeeSTMo5ddtznmGw==}
    +    engines: {node: '>=18'}
    +
       isbot@5.1.35:
         resolution: {integrity: sha512-waFfC72ZNfwLLuJ2iLaoVaqcNo+CAaLR7xCpAn0Y5WfGzkNHv7ZN39Vbi1y+kb+Zs46XHOX3tZNExroFUPX+Kg==}
         engines: {node: '>=18'}
    @@ -3723,14 +4609,6 @@ packages:
         resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
         hasBin: true
     
    -  jsdoc-type-pratt-parser@4.8.0:
    -    resolution: {integrity: sha512-iZ8Bdb84lWRuGHamRXFyML07r21pcwBrLkHEuHgEY5UbCouBwv7ECknDRKzsQIXMiqpPymqtIf8TC/shYKB5rw==}
    -    engines: {node: '>=12.0.0'}
    -
    -  jsdoc-type-pratt-parser@7.0.0:
    -    resolution: {integrity: sha512-c7YbokssPOSHmqTbSAmTtnVgAVa/7lumWNYqomgd5KOMyPrRve2anx6lonfOsXEQacqF9FKVUj7bLg4vRSvdYA==}
    -    engines: {node: '>=20.0.0'}
    -
       jsdoc-type-pratt-parser@7.1.1:
         resolution: {integrity: sha512-/2uqY7x6bsrpi3i9LVU6J89352C0rpMk0as8trXxCtvd4kPk1ke/Eyif6wqfSLvoNJqcDG9Vk4UsXgygzCt2xA==}
         engines: {node: '>=20.0.0'}
    @@ -3767,10 +4645,6 @@ packages:
         engines: {node: '>=6'}
         hasBin: true
     
    -  jsonc-eslint-parser@2.4.2:
    -    resolution: {integrity: sha512-1e4qoRgnn448pRuMvKGsFFymUCquZV0mpGgOyIKNgD3JVDTsVJyRBGH/Fm0tBb8WsWGgmB1mDe6/yJMQM37DUA==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    -
       jsonc-eslint-parser@3.1.0:
         resolution: {integrity: sha512-75EA7EWZExL/j+MDKQrRbdzcRI2HOkRlmUw8fZJc1ioqFEOvBsq7Rt+A6yCxOt9w/TYNpkt52gC6nm/g5tFIng==}
         engines: {node: ^20.19.0 || ^22.13.0 || >=24}
    @@ -3778,89 +4652,106 @@ packages:
       jsonfile@6.2.0:
         resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==}
     
    +  katex@0.16.39:
    +    resolution: {integrity: sha512-FR2f6y85+81ZLO0GPhyQ+EJl/E5ILNWltJhpAeOTzRny952Z13x2867lTFDmvMZix//Ux3CuMQ2VkLXRbUwOFg==}
    +    hasBin: true
    +
       keyv@4.5.4:
         resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
     
    +  khroma@2.1.0:
    +    resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==}
    +
       kind-of@3.2.2:
         resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==}
         engines: {node: '>=0.10.0'}
     
    +  langium@4.2.1:
    +    resolution: {integrity: sha512-zu9QWmjpzJcomzdJQAHgDVhLGq5bLosVak1KVa40NzQHXfqr4eAHupvnPOVXEoLkg6Ocefvf/93d//SB7du4YQ==}
    +    engines: {node: '>=20.10.0', npm: '>=10.2.3'}
    +
    +  layout-base@1.0.2:
    +    resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==}
    +
    +  layout-base@2.0.1:
    +    resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==}
    +
       levn@0.4.1:
         resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
         engines: {node: '>= 0.8.0'}
     
    -  lightningcss-android-arm64@1.31.1:
    -    resolution: {integrity: sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==}
    +  lightningcss-android-arm64@1.32.0:
    +    resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==}
         engines: {node: '>= 12.0.0'}
         cpu: [arm64]
         os: [android]
     
    -  lightningcss-darwin-arm64@1.31.1:
    -    resolution: {integrity: sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==}
    +  lightningcss-darwin-arm64@1.32.0:
    +    resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==}
         engines: {node: '>= 12.0.0'}
         cpu: [arm64]
         os: [darwin]
     
    -  lightningcss-darwin-x64@1.31.1:
    -    resolution: {integrity: sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==}
    +  lightningcss-darwin-x64@1.32.0:
    +    resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==}
         engines: {node: '>= 12.0.0'}
         cpu: [x64]
         os: [darwin]
     
    -  lightningcss-freebsd-x64@1.31.1:
    -    resolution: {integrity: sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==}
    +  lightningcss-freebsd-x64@1.32.0:
    +    resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==}
         engines: {node: '>= 12.0.0'}
         cpu: [x64]
         os: [freebsd]
     
    -  lightningcss-linux-arm-gnueabihf@1.31.1:
    -    resolution: {integrity: sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==}
    +  lightningcss-linux-arm-gnueabihf@1.32.0:
    +    resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==}
         engines: {node: '>= 12.0.0'}
         cpu: [arm]
         os: [linux]
     
    -  lightningcss-linux-arm64-gnu@1.31.1:
    -    resolution: {integrity: sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==}
    +  lightningcss-linux-arm64-gnu@1.32.0:
    +    resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==}
         engines: {node: '>= 12.0.0'}
         cpu: [arm64]
         os: [linux]
         libc: [glibc]
     
    -  lightningcss-linux-arm64-musl@1.31.1:
    -    resolution: {integrity: sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==}
    +  lightningcss-linux-arm64-musl@1.32.0:
    +    resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==}
         engines: {node: '>= 12.0.0'}
         cpu: [arm64]
         os: [linux]
         libc: [musl]
     
    -  lightningcss-linux-x64-gnu@1.31.1:
    -    resolution: {integrity: sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==}
    +  lightningcss-linux-x64-gnu@1.32.0:
    +    resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==}
         engines: {node: '>= 12.0.0'}
         cpu: [x64]
         os: [linux]
         libc: [glibc]
     
    -  lightningcss-linux-x64-musl@1.31.1:
    -    resolution: {integrity: sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==}
    +  lightningcss-linux-x64-musl@1.32.0:
    +    resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==}
         engines: {node: '>= 12.0.0'}
         cpu: [x64]
         os: [linux]
         libc: [musl]
     
    -  lightningcss-win32-arm64-msvc@1.31.1:
    -    resolution: {integrity: sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==}
    +  lightningcss-win32-arm64-msvc@1.32.0:
    +    resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==}
         engines: {node: '>= 12.0.0'}
         cpu: [arm64]
         os: [win32]
     
    -  lightningcss-win32-x64-msvc@1.31.1:
    -    resolution: {integrity: sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==}
    +  lightningcss-win32-x64-msvc@1.32.0:
    +    resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==}
         engines: {node: '>= 12.0.0'}
         cpu: [x64]
         os: [win32]
     
    -  lightningcss@1.31.1:
    -    resolution: {integrity: sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==}
    +  lightningcss@1.32.0:
    +    resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==}
         engines: {node: '>= 12.0.0'}
     
       local-pkg@1.1.2:
    @@ -3871,20 +4762,20 @@ packages:
         resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
         engines: {node: '>=10'}
     
    +  lodash-es@4.17.23:
    +    resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==}
    +
       lodash.merge@4.6.2:
         resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
     
    -  lodash@4.17.23:
    -    resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==}
    -
       longest-streak@3.1.0:
         resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
     
       lru-cache@5.1.1:
         resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
     
    -  lucide-react@0.575.0:
    -    resolution: {integrity: sha512-VuXgKZrk0uiDlWjGGXmKV6MSk9Yy4l10qgVvzGn2AWBx1Ylt0iBexKOAoA6I7JO3m+M9oeovJd3yYENfkUbOeg==}
    +  lucide-react@0.577.0:
    +    resolution: {integrity: sha512-4LjoFv2eEPwYDPg/CUdBJQSDfPyzXCRrVW1X7jrx/trgxnxkHFjnVZINbzvzxjN70dxychOfg+FTYwBiS3pQ5A==}
         peerDependencies:
           react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
     
    @@ -3898,6 +4789,10 @@ packages:
         resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
         engines: {node: '>=10'}
     
    +  markdown-extensions@2.0.0:
    +    resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==}
    +    engines: {node: '>=16'}
    +
       markdown-table@3.0.4:
         resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
     
    @@ -3906,14 +4801,23 @@ packages:
         engines: {node: '>= 18'}
         hasBin: true
     
    -  material-icon-theme@5.31.0:
    -    resolution: {integrity: sha512-PPeGSRa+8stQEKvCr2Xym9KIqf2SPwl1chc7cxbK+aY6ORpwOcowtARQEXstZBjQwXTE5GnfE0zg0MFFy+XPzA==}
    +  marked@16.4.2:
    +    resolution: {integrity: sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==}
    +    engines: {node: '>= 20'}
    +    hasBin: true
    +
    +  material-icon-theme@5.32.0:
    +    resolution: {integrity: sha512-SxJxCcnk6cJIbd+AxmoeghXJ24joXGmUzjiGci16sX4mXZdXprGEzM6ZZ0VHGAofxNlMqznEbExINwFLsxf8eQ==}
         engines: {vscode: ^1.55.0}
     
       math-intrinsics@1.1.0:
         resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
         engines: {node: '>= 0.4'}
     
    +  mathjax-full@3.2.2:
    +    resolution: {integrity: sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==}
    +    deprecated: Version 4 replaces this package with the scoped package @mathjax/src
    +
       mdast-util-find-and-replace@3.0.2:
         resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==}
     
    @@ -3941,6 +4845,9 @@ packages:
       mdast-util-gfm@3.1.0:
         resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==}
     
    +  mdast-util-math@3.0.0:
    +    resolution: {integrity: sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==}
    +
       mdast-util-mdx-expression@2.0.1:
         resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==}
     
    @@ -3956,6 +4863,9 @@ packages:
       mdast-util-phrasing@4.1.0:
         resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==}
     
    +  mdast-util-to-hast@13.2.1:
    +    resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==}
    +
       mdast-util-to-markdown@2.1.2:
         resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==}
     
    @@ -3974,10 +4884,19 @@ packages:
         resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==}
         engines: {node: '>=18'}
     
    +  merge-stream@2.0.0:
    +    resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
    +
       merge2@1.4.1:
         resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
         engines: {node: '>= 8'}
     
    +  mermaid@11.13.0:
    +    resolution: {integrity: sha512-fEnci+Immw6lKMFI8sqzjlATTyjLkRa6axrEgLV2yHTfv8r+h1wjFbV6xeRtd4rUV1cS4EpR9rwp3Rci7TRWDw==}
    +
    +  mhchemparser@4.2.1:
    +    resolution: {integrity: sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ==}
    +
       micromark-core-commonmark@2.0.3:
         resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==}
     
    @@ -4005,6 +4924,9 @@ packages:
       micromark-extension-gfm@3.0.0:
         resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==}
     
    +  micromark-extension-math@3.1.0:
    +    resolution: {integrity: sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==}
    +
       micromark-extension-mdx-expression@3.0.1:
         resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==}
     
    @@ -4098,17 +5020,23 @@ packages:
         resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==}
         engines: {node: '>=18'}
     
    +  mimic-fn@4.0.0:
    +    resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==}
    +    engines: {node: '>=12'}
    +
       minimatch@10.2.4:
         resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==}
         engines: {node: 18 || 20 || >=22}
     
    -  minimatch@9.0.9:
    -    resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==}
    -    engines: {node: '>=16 || 14 >=14.17'}
    +  mj-context-menu@0.6.1:
    +    resolution: {integrity: sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA==}
     
       mlly@1.8.0:
         resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==}
     
    +  module-replacements@2.11.0:
    +    resolution: {integrity: sha512-j5sNQm3VCpQQ7nTqGeOZtoJtV3uKERgCBm9QRhmGRiXiqkf7iRFOkfxdJRZWLkqYY8PNf4cDQF/WfXUYLENrRA==}
    +
       monaco-editor@0.55.1:
         resolution: {integrity: sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==}
     
    @@ -4135,8 +5063,14 @@ packages:
         resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==}
         engines: {node: '>= 0.6'}
     
    -  next@16.1.6:
    -    resolution: {integrity: sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw==}
    +  next-themes@0.4.6:
    +    resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==}
    +    peerDependencies:
    +      react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
    +      react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
    +
    +  next@16.2.0:
    +    resolution: {integrity: sha512-NLBVrJy1pbV1Yn00L5sU4vFyAHt5XuSjzrNyFnxo6Com0M0KrL6hHM5B99dbqXb2bE9pm4Ow3Zl1xp6HVY9edQ==}
         engines: {node: '>=20.9.0'}
         hasBin: true
         peerDependencies:
    @@ -4156,6 +5090,25 @@ packages:
           sass:
             optional: true
     
    +  nextra-theme-docs@4.6.1:
    +    resolution: {integrity: sha512-u5Hh8erVcGOXO1FVrwYBgrEjyzdYQY0k/iAhLd8RofKp+Bru3fyLy9V9W34mfJ0KHKHjv/ldlDTlb4KlL4eIuQ==}
    +    peerDependencies:
    +      next: '>=14'
    +      nextra: 4.6.1
    +      react: '>=18'
    +      react-dom: '>=18'
    +
    +  nextra@4.6.1:
    +    resolution: {integrity: sha512-yz5WMJFZ5c58y14a6Rmwt+SJUYDdIgzWSxwtnpD4XAJTq3mbOqOg3VTaJqLiJjwRSxoFRHNA1yAhnhbvbw9zSg==}
    +    engines: {node: '>=18'}
    +    peerDependencies:
    +      next: '>=14'
    +      react: '>=18'
    +      react-dom: '>=18'
    +
    +  nlcst-to-string@4.0.0:
    +    resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==}
    +
       node-releases@2.0.27:
         resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==}
     
    @@ -4172,6 +5125,14 @@ packages:
         engines: {node: ^20.5.0 || >=22.0.0, npm: '>= 10'}
         hasBin: true
     
    +  npm-run-path@5.3.0:
    +    resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==}
    +    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
    +
    +  npm-to-yarn@3.0.1:
    +    resolution: {integrity: sha512-tt6PvKu4WyzPwWUzy/hvPFqn+uwXO0K1ZHka8az3NnrhWJDmSqI8ncWq0fkL0k/lmmi5tAC11FXwXuh0rFbt1A==}
    +    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    +
       nth-check@2.1.1:
         resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
     
    @@ -4189,6 +5150,9 @@ packages:
       obug@2.1.1:
         resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==}
     
    +  ohash@2.0.11:
    +    resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==}
    +
       on-finished@2.4.1:
         resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
         engines: {node: '>= 0.8'}
    @@ -4196,10 +5160,25 @@ packages:
       once@1.4.0:
         resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
     
    +  onetime@6.0.0:
    +    resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==}
    +    engines: {node: '>=12'}
    +
    +  oniguruma-parser@0.12.1:
    +    resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==}
    +
    +  oniguruma-to-es@4.3.5:
    +    resolution: {integrity: sha512-Zjygswjpsewa0NLTsiizVuMQZbp0MDyM6lIt66OxsF21npUDlzpHi1Mgb/qhQdkb+dWFTzJmFbEWdvZgRho8eQ==}
    +
       optionator@0.9.4:
         resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
         engines: {node: '>= 0.8.0'}
     
    +  oxfmt@0.35.0:
    +    resolution: {integrity: sha512-QYeXWkP+aLt7utt5SLivNIk09glWx9QE235ODjgcEZ3sd1VMaUBSpLymh6ZRCA76gD2rMP4bXanUz/fx+nLM9Q==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    hasBin: true
    +
       p-limit@3.1.0:
         resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
         engines: {node: '>=10'}
    @@ -4211,6 +5190,10 @@ packages:
       package-manager-detector@1.6.0:
         resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==}
     
    +  pagefind@1.4.0:
    +    resolution: {integrity: sha512-z2kY1mQlL4J8q5EIsQkLzQjilovKzfNVhX8De6oyE6uHpfFtyBaqUpcl/XzJC/4fjD8vBDyh1zolimIcVrCn9g==}
    +    hasBin: true
    +
       parse-entities@4.0.2:
         resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==}
     
    @@ -4221,13 +5204,28 @@ packages:
       parse-imports-exports@0.2.4:
         resolution: {integrity: sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==}
     
    +  parse-latin@7.0.0:
    +    resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==}
    +
    +  parse-numeric-range@1.3.0:
    +    resolution: {integrity: sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==}
    +
       parse-statements@1.0.11:
         resolution: {integrity: sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==}
     
    +  parse5@7.3.0:
    +    resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==}
    +
       parseurl@1.3.3:
         resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
         engines: {node: '>= 0.8'}
     
    +  path-browserify@1.0.1:
    +    resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
    +
    +  path-data-parser@0.1.0:
    +    resolution: {integrity: sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==}
    +
       path-exists@4.0.0:
         resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
         engines: {node: '>=8'}
    @@ -4236,6 +5234,10 @@ packages:
         resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
         engines: {node: '>=8'}
     
    +  path-key@4.0.0:
    +    resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==}
    +    engines: {node: '>=12'}
    +
       path-to-regexp@8.3.0:
         resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==}
     
    @@ -4275,6 +5277,12 @@ packages:
       pnpm-workspace-yaml@1.6.0:
         resolution: {integrity: sha512-uUy4dK3E11sp7nK+hnT7uAWfkBMe00KaUw8OG3NuNlYQoTk4sc9pcdIy1+XIP85v9Tvr02mK3JPaNNrP0QyRaw==}
     
    +  points-on-curve@0.2.0:
    +    resolution: {integrity: sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==}
    +
    +  points-on-path@0.2.1:
    +    resolution: {integrity: sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==}
    +
       postcss-selector-parser@7.1.1:
         resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==}
         engines: {node: '>=4'}
    @@ -4283,8 +5291,8 @@ packages:
         resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
         engines: {node: ^10 || ^12 || >=14}
     
    -  postcss@8.5.6:
    -    resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
    +  postcss@8.5.8:
    +    resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==}
         engines: {node: ^10 || ^12 || >=14}
     
       prelude-ls@1.2.1:
    @@ -4300,6 +5308,9 @@ packages:
         engines: {node: '>=14'}
         hasBin: true
     
    +  property-information@7.1.0:
    +    resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==}
    +
       proxy-addr@2.0.7:
         resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
         engines: {node: '>= 0.10'}
    @@ -4308,8 +5319,8 @@ packages:
         resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
         engines: {node: '>=6'}
     
    -  pure-rand@7.0.1:
    -    resolution: {integrity: sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==}
    +  pure-rand@8.3.0:
    +    resolution: {integrity: sha512-1ws1Ab8fnsf4bvpL+SujgBnr3KFs5abgCLVzavBp+f2n8Ld5YTOZlkv/ccYPhu3X9s+MEeqPRMqKlJz/kWDK8A==}
     
       qs@6.15.0:
         resolution: {integrity: sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==}
    @@ -4332,6 +5343,11 @@ packages:
         resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==}
         engines: {node: '>= 0.10'}
     
    +  react-compiler-runtime@19.1.0-rc.3:
    +    resolution: {integrity: sha512-Cssogys2XZu6SqxRdX2xd8cQAf57BBvFbLEBlIa77161lninbKUn/EqbecCe7W3eqDQfg3rIoOwzExzgCh7h/g==}
    +    peerDependencies:
    +      react: ^17.0.0 || ^18.0.0 || ^19.0.0 || ^0.0.0-experimental
    +
       react-dom@19.2.4:
         resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==}
         peerDependencies:
    @@ -4340,6 +5356,12 @@ packages:
       react-is@19.2.4:
         resolution: {integrity: sha512-W+EWGn2v0ApPKgKKCy/7s7WHXkboGcsrXE+2joLyVxkbyVQfO3MUEaUQDHoSmb8TFFrSKYa9mw64WZHNHSDzYA==}
     
    +  react-medium-image-zoom@5.4.1:
    +    resolution: {integrity: sha512-DD2iZYaCfAwiQGR8AN62r/cDJYoXhezlYJc5HY4TzBUGuGge43CptG0f7m0PEIM72aN6GfpjohvY1yYdtCJB7g==}
    +    peerDependencies:
    +      react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
    +      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
    +
       react-redux@9.2.0:
         resolution: {integrity: sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==}
         peerDependencies:
    @@ -4352,10 +5374,6 @@ packages:
           redux:
             optional: true
     
    -  react-refresh@0.18.0:
    -    resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==}
    -    engines: {node: '>=0.10.0'}
    -
       react@19.2.4:
         resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==}
         engines: {node: '>=0.10.0'}
    @@ -4368,18 +5386,35 @@ packages:
         resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
         engines: {node: '>=8.10.0'}
     
    +  reading-time@1.5.0:
    +    resolution: {integrity: sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==}
    +
       recast@0.23.11:
         resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==}
         engines: {node: '>= 4'}
     
    -  recharts@3.7.0:
    -    resolution: {integrity: sha512-l2VCsy3XXeraxIID9fx23eCb6iCBsxUQDnE8tWm6DFdszVAO7WVY/ChAD9wVit01y6B2PMupYiMmQwhgPHc9Ew==}
    +  recharts@3.8.0:
    +    resolution: {integrity: sha512-Z/m38DX3L73ExO4Tpc9/iZWHmHnlzWG4njQbxsF5aSjwqmHNDDIm0rdEBArkwsBvR8U6EirlEHiQNYWCVh9sGQ==}
         engines: {node: '>=18'}
         peerDependencies:
           react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
           react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
           react-is: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
     
    +  recma-build-jsx@1.0.0:
    +    resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==}
    +
    +  recma-jsx@1.0.1:
    +    resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==}
    +    peerDependencies:
    +      acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
    +
    +  recma-parse@1.0.0:
    +    resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==}
    +
    +  recma-stringify@1.0.0:
    +    resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==}
    +
       redux-thunk@3.1.0:
         resolution: {integrity: sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==}
         peerDependencies:
    @@ -4392,6 +5427,15 @@ packages:
         resolution: {integrity: sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==}
         engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
     
    +  regex-recursion@6.0.2:
    +    resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==}
    +
    +  regex-utilities@2.3.0:
    +    resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==}
    +
    +  regex@6.1.0:
    +    resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==}
    +
       regexp-ast-analysis@0.7.1:
         resolution: {integrity: sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==}
         engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
    @@ -4404,18 +5448,49 @@ packages:
         resolution: {integrity: sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==}
         hasBin: true
     
    +  rehype-katex@7.0.1:
    +    resolution: {integrity: sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==}
    +
    +  rehype-parse@9.0.1:
    +    resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==}
    +
    +  rehype-pretty-code@0.14.1:
    +    resolution: {integrity: sha512-IpG4OL0iYlbx78muVldsK86hdfNoht0z63AP7sekQNW2QOTmjxB7RbTO+rhIYNGRljgHxgVZoPwUl6bIC9SbjA==}
    +    engines: {node: '>=18'}
    +    peerDependencies:
    +      shiki: ^1.0.0 || ^2.0.0 || ^3.0.0
    +
    +  rehype-raw@7.0.0:
    +    resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==}
    +
    +  rehype-recma@1.0.0:
    +    resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==}
    +
       remark-frontmatter@5.0.0:
         resolution: {integrity: sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==}
     
       remark-gfm@4.0.1:
         resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==}
     
    +  remark-math@6.0.0:
    +    resolution: {integrity: sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==}
    +
       remark-mdx@3.1.1:
         resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==}
     
       remark-parse@11.0.0:
         resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==}
     
    +  remark-reading-time@2.1.0:
    +    resolution: {integrity: sha512-gBsJbQv87TUq4dRMSOgIX6P60Tk9ke8c29KsL7bccmsv2m9AycDfVu3ghRtrNpHLZU3TE5P/vImGOMSPzYU8rA==}
    +
    +  remark-rehype@11.1.2:
    +    resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==}
    +
    +  remark-smartypants@3.0.2:
    +    resolution: {integrity: sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==}
    +    engines: {node: '>=16.0.0'}
    +
       remark-stringify@11.0.0:
         resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
     
    @@ -4437,12 +5512,27 @@ packages:
       resolve-pkg-maps@1.0.0:
         resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
     
    +  retext-latin@4.0.0:
    +    resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==}
    +
    +  retext-smartypants@6.2.0:
    +    resolution: {integrity: sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==}
    +
    +  retext-stringify@4.0.0:
    +    resolution: {integrity: sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==}
    +
    +  retext@9.0.0:
    +    resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==}
    +
       reusify@1.1.0:
         resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
         engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
     
    -  rolldown-plugin-dts@0.22.2:
    -    resolution: {integrity: sha512-Ge+XF962Kobjr0hRPx1neVnLU2jpKkD2zevZTfPKf/0el4eYo9SyGPm0stiHDG2JQuL0Q3HLD0Kn+ST8esvVdA==}
    +  robust-predicates@3.0.2:
    +    resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==}
    +
    +  rolldown-plugin-dts@0.22.5:
    +    resolution: {integrity: sha512-M/HXfM4cboo+jONx9Z0X+CUf3B5tCi7ni+kR5fUW50Fp9AlZk0oVLesibGWgCXDKFp5lpgQ9yhKoImUFjl3VZw==}
         engines: {node: '>=20.19.0'}
         peerDependencies:
           '@ts-macro/tsc': ^0.3.6
    @@ -4460,16 +5550,19 @@ packages:
           vue-tsc:
             optional: true
     
    -  rolldown@1.0.0-rc.5:
    -    resolution: {integrity: sha512-0AdalTs6hNTioaCYIkAa7+xsmHBfU5hCNclZnM/lp7lGGDuUOb6N4BVNtwiomybbencDjq/waKjTImqiGCs5sw==}
    +  rolldown@1.0.0-rc.10:
    +    resolution: {integrity: sha512-q7j6vvarRFmKpgJUT8HCAUljkgzEp4LAhPlJUvQhA5LA1SUL36s5QCysMutErzL3EbNOZOkoziSx9iZC4FddKA==}
         engines: {node: ^20.19.0 || >=22.12.0}
         hasBin: true
     
    -  rollup@4.59.0:
    -    resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==}
    -    engines: {node: '>=18.0.0', npm: '>=8.0.0'}
    +  rolldown@1.0.0-rc.9:
    +    resolution: {integrity: sha512-9EbgWge7ZH+yqb4d2EnELAntgPTWbfL8ajiTW+SyhJEC4qhBbkCKbqFV4Ge4zmu5ziQuVbWxb/XwLZ+RIO7E8Q==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
         hasBin: true
     
    +  roughjs@4.6.6:
    +    resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==}
    +
       router@2.2.0:
         resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==}
         engines: {node: '>= 18'}
    @@ -4477,12 +5570,18 @@ packages:
       run-parallel@1.2.0:
         resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
     
    +  rw@1.3.3:
    +    resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==}
    +
       safer-buffer@2.1.2:
         resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
     
       scheduler@0.27.0:
         resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
     
    +  scroll-into-view-if-needed@3.1.0:
    +    resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==}
    +
       scslre@0.3.0:
         resolution: {integrity: sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==}
         engines: {node: ^14.0.0 || >=16.0.0}
    @@ -4514,6 +5613,9 @@ packages:
         resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==}
         engines: {node: '>= 18'}
     
    +  server-only@0.0.1:
    +    resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==}
    +
       setprototypeof@1.2.0:
         resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
     
    @@ -4533,6 +5635,9 @@ packages:
         resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==}
         engines: {node: '>= 0.4'}
     
    +  shiki@3.23.0:
    +    resolution: {integrity: sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA==}
    +
       side-channel-list@1.0.0:
         resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==}
         engines: {node: '>= 0.4'}
    @@ -4563,6 +5668,10 @@ packages:
       sisteransi@1.0.5:
         resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
     
    +  slash@5.1.0:
    +    resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==}
    +    engines: {node: '>=14.16'}
    +
       source-map-js@1.2.1:
         resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
         engines: {node: '>=0.10.0'}
    @@ -4575,6 +5684,9 @@ packages:
         resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==}
         engines: {node: '>= 12'}
     
    +  space-separated-tokens@2.0.2:
    +    resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
    +
       spdx-exceptions@2.5.0:
         resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==}
     
    @@ -4584,6 +5696,10 @@ packages:
       spdx-license-ids@3.0.23:
         resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==}
     
    +  speech-rule-engine@4.1.2:
    +    resolution: {integrity: sha512-S6ji+flMEga+1QU79NDbwZ8Ivf0S/MpupQQiIC0rTpU/ZTKgcajijJJb1OcByBQDjrXCN1/DJtGz4ZJeBMPGJw==}
    +    hasBin: true
    +
       stackback@0.0.2:
         resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
     
    @@ -4594,16 +5710,26 @@ packages:
         resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==}
         engines: {node: '>= 0.8'}
     
    -  std-env@3.10.0:
    -    resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==}
    +  std-env@4.0.0:
    +    resolution: {integrity: sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==}
     
       stringify-entities@4.0.4:
         resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==}
     
    +  strip-final-newline@3.0.0:
    +    resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==}
    +    engines: {node: '>=12'}
    +
       strip-indent@4.1.1:
         resolution: {integrity: sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==}
         engines: {node: '>=12'}
     
    +  style-to-js@1.1.21:
    +    resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==}
    +
    +  style-to-object@1.0.14:
    +    resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==}
    +
       styled-jsx@5.1.6:
         resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==}
         engines: {node: '>= 12.0.0'}
    @@ -4617,6 +5743,9 @@ packages:
           babel-plugin-macros:
             optional: true
     
    +  stylis@4.3.6:
    +    resolution: {integrity: sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==}
    +
       supports-color@7.2.0:
         resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
         engines: {node: '>=8'}
    @@ -4628,11 +5757,18 @@ packages:
         resolution: {integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==}
         engines: {node: ^14.18.0 || >=16.0.0}
     
    +  system-architecture@0.1.0:
    +    resolution: {integrity: sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA==}
    +    engines: {node: '>=18'}
    +
    +  tabbable@6.4.0:
    +    resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==}
    +
       tailwind-merge@3.5.0:
         resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==}
     
    -  tailwindcss@4.2.1:
    -    resolution: {integrity: sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==}
    +  tailwindcss@4.2.2:
    +    resolution: {integrity: sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==}
     
       tapable@2.3.0:
         resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==}
    @@ -4651,14 +5787,26 @@ packages:
         resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==}
         engines: {node: '>=18'}
     
    +  tinyexec@1.0.4:
    +    resolution: {integrity: sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==}
    +    engines: {node: '>=18'}
    +
       tinyglobby@0.2.15:
         resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==}
         engines: {node: '>=12.0.0'}
     
    +  tinypool@2.1.0:
    +    resolution: {integrity: sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==}
    +    engines: {node: ^20.0.0 || >=22.0.0}
    +
       tinyrainbow@3.0.3:
         resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==}
         engines: {node: '>=14.0.0'}
     
    +  title@4.0.1:
    +    resolution: {integrity: sha512-xRnPkJx9nvE5MF6LkB5e8QJjE2FW8269wTu/LQdf7zZqBgPly0QJPf/CWAo7srj5so4yXfoLEdCFgurlpi47zg==}
    +    hasBin: true
    +
       to-regex-range@5.0.1:
         resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
         engines: {node: '>=8.0'}
    @@ -4671,14 +5819,17 @@ packages:
         resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
         engines: {node: '>=0.6'}
     
    -  toml-eslint-parser@0.10.1:
    -    resolution: {integrity: sha512-9mjy3frhioGIVGcwamlVlUyJ9x+WHw/TXiz9R4YOlmsIuBN43r9Dp8HZ35SF9EKjHrn3BUZj04CF+YqZ2oJ+7w==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    +  toml-eslint-parser@1.0.3:
    +    resolution: {integrity: sha512-A5F0cM6+mDleacLIEUkmfpkBbnHJFV1d2rprHU2MXNk7mlxHq2zGojA+SRvQD1RoMo9gqjZPWEaKG4v1BQ48lw==}
    +    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
     
       tree-kill@1.2.2:
         resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
         hasBin: true
     
    +  trim-lines@3.0.1:
    +    resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
    +
       trough@2.2.0:
         resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==}
     
    @@ -4693,28 +5844,38 @@ packages:
         peerDependencies:
           typescript: '>=4.0.0'
     
    -  tsdown@0.21.0-beta.2:
    -    resolution: {integrity: sha512-OKj8mKf0ws1ucxuEi3mO/OGyfRQxO9MY2D6SoIE/7RZcbojsZSBhJr4xC4MNivMqrQvi3Ke2e+aRZDemPBWPCw==}
    +  ts-dedent@2.2.0:
    +    resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==}
    +    engines: {node: '>=6.10'}
    +
    +  ts-morph@27.0.2:
    +    resolution: {integrity: sha512-fhUhgeljcrdZ+9DZND1De1029PrE+cMkIP7ooqkLRTrRLTqcki2AstsyJm0vRNbTbVCNJ0idGlbBrfqc7/nA8w==}
    +
    +  tsdown@0.21.4:
    +    resolution: {integrity: sha512-Q/kBi8SXkr4X6JI/NAZKZY1UuiEcbuXtIskL4tZCsgpDiEPM/2W6lC+OonNA31S+V3KsWedFvbFDBs23hvt+Aw==}
         engines: {node: '>=20.19.0'}
         hasBin: true
         peerDependencies:
           '@arethetypeswrong/core': ^0.18.1
    +      '@tsdown/css': 0.21.4
    +      '@tsdown/exe': 0.21.4
           '@vitejs/devtools': '*'
           publint: ^0.3.0
           typescript: ^5.0.0
    -      unplugin-lightningcss: ^0.4.0
           unplugin-unused: ^0.5.0
         peerDependenciesMeta:
           '@arethetypeswrong/core':
             optional: true
    +      '@tsdown/css':
    +        optional: true
    +      '@tsdown/exe':
    +        optional: true
           '@vitejs/devtools':
             optional: true
           publint:
             optional: true
           typescript:
             optional: true
    -      unplugin-lightningcss:
    -        optional: true
           unplugin-unused:
             optional: true
     
    @@ -4726,43 +5887,21 @@ packages:
         engines: {node: '>=18.0.0'}
         hasBin: true
     
    -  turbo-darwin-64@2.8.12:
    -    resolution: {integrity: sha512-EiHJmW2MeQQx+21x8hjMHw/uPhXt9PIxvDrxzOtyVwrXzL0tQmsxtO4qHf2l7uA+K6PUJ4+TjY1MHZDuCvWXrw==}
    -    cpu: [x64]
    -    os: [darwin]
    -
    -  turbo-darwin-arm64@2.8.12:
    -    resolution: {integrity: sha512-cbqqGN0vd7ly2TeuaM8k9AK9u1CABO4kBA5KPSqovTiLL3sORccn/mZzJSbvQf0EsYRfU34MgW5FotfwW3kx8Q==}
    -    cpu: [arm64]
    -    os: [darwin]
    -
    -  turbo-linux-64@2.8.12:
    -    resolution: {integrity: sha512-jXKw9j4r4q6s0goSXuKI3aKbQK2qiNeP25lGGEnq018TM6SWRW1CCpPMxyG91aCKrub7wDm/K45sGNT4ZFBcFQ==}
    -    cpu: [x64]
    -    os: [linux]
    -
    -  turbo-linux-arm64@2.8.12:
    -    resolution: {integrity: sha512-BRJCMdyXjyBoL0GYpvj9d2WNfMHwc3tKmJG5ATn2Efvil9LsiOsd/93/NxDqW0jACtHFNVOPnd/CBwXRPiRbwA==}
    -    cpu: [arm64]
    -    os: [linux]
    -
    -  turbo-windows-64@2.8.12:
    -    resolution: {integrity: sha512-vyFOlpFFzQFkikvSVhVkESEfzIopgs2J7J1rYvtSwSHQ4zmHxkC95Q8Kjkus8gg+8X2mZyP1GS5jirmaypGiPw==}
    -    cpu: [x64]
    -    os: [win32]
    -
    -  turbo-windows-arm64@2.8.12:
    -    resolution: {integrity: sha512-9nRnlw5DF0LkJClkIws1evaIF36dmmMEO84J5Uj4oQ8C0QTHwlH7DNe5Kq2Jdmu8GXESCNDNuUYG8Cx6W/vm3g==}
    -    cpu: [arm64]
    -    os: [win32]
    -
    -  turbo@2.8.12:
    -    resolution: {integrity: sha512-auUAMLmi0eJhxDhQrxzvuhfEbICnVt0CTiYQYY8WyRJ5nwCDZxD0JG8bCSxT4nusI2CwJzmZAay5BfF6LmK7Hw==}
    +  turbo@2.8.20:
    +    resolution: {integrity: sha512-Rb4qk5YT8RUwwdXtkLpkVhNEe/lor6+WV7S5tTlLpxSz6MjV5Qi8jGNn4gS6NAvrYGA/rNrE6YUQM85sCZUDbQ==}
         hasBin: true
     
       tw-animate-css@1.4.0:
         resolution: {integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==}
     
    +  twoslash-protocol@0.3.6:
    +    resolution: {integrity: sha512-FHGsJ9Q+EsNr5bEbgG3hnbkvEBdW5STgPU824AHUjB4kw0Dn4p8tABT7Ncg1Ie6V0+mDg3Qpy41VafZXcQhWMA==}
    +
    +  twoslash@0.3.6:
    +    resolution: {integrity: sha512-VuI5OKl+MaUO9UIW3rXKoPgHI3X40ZgB/j12VY6h98Ae1mCBihjPvhOPeJWlxCYcmSbmeZt5ZKkK0dsVtp+6pA==}
    +    peerDependencies:
    +      typescript: ^5.5.0
    +
       typanion@3.14.0:
         resolution: {integrity: sha512-ZW/lVMRabETuYCd9O9ZvMhAh8GslSqaUjxmK/JLPCh6l73CvLBiuXswj/+7LdnWOgYsQ130FqLzFz5aGT4I3Ug==}
     
    @@ -4774,11 +5913,11 @@ packages:
         resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==}
         engines: {node: '>= 0.6'}
     
    -  typescript-eslint@8.50.0:
    -    resolution: {integrity: sha512-Q1/6yNUmCpH94fbgMUMg2/BSAr/6U7GBk61kZTv1/asghQOWOjTlp9K8mixS5NcJmm2creY+UFfGeW/+OcA64A==}
    +  typescript-eslint@8.57.1:
    +    resolution: {integrity: sha512-fLvZWf+cAGw3tqMCYzGIU6yR8K+Y9NT2z23RwOjlNFF2HwSB3KhdEFI5lSBv8tNmFkkBShSjsCjzx1vahZfISA==}
         engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
         peerDependencies:
    -      eslint: ^8.57.0 || ^9.0.0
    +      eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
           typescript: '>=4.8.4 <6.0.0'
     
       typescript@5.9.3:
    @@ -4801,15 +5940,33 @@ packages:
       unified@11.0.5:
         resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==}
     
    +  unist-util-find-after@5.0.0:
    +    resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==}
    +
       unist-util-is@6.0.1:
         resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==}
     
    +  unist-util-modify-children@4.0.0:
    +    resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==}
    +
       unist-util-position-from-estree@2.0.0:
         resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==}
     
    +  unist-util-position@5.0.0:
    +    resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==}
    +
    +  unist-util-remove-position@5.0.0:
    +    resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==}
    +
    +  unist-util-remove@4.0.0:
    +    resolution: {integrity: sha512-b4gokeGId57UVRX/eVKej5gXqGlc9+trkORhFJpu9raqZkZhU0zm8Doi05+HaiBsMEIJowL+2WtQ5ItjsngPXg==}
    +
       unist-util-stringify-position@4.0.0:
         resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==}
     
    +  unist-util-visit-children@3.0.0:
    +    resolution: {integrity: sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==}
    +
       unist-util-visit-parents@6.0.2:
         resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==}
     
    @@ -4831,8 +5988,8 @@ packages:
         resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==}
         engines: {node: '>=18.12.0'}
     
    -  unrun@0.2.28:
    -    resolution: {integrity: sha512-LqMrI3ZEUMZ2476aCsbUTfy95CHByqez05nju4AQv4XFPkxh5yai7Di1/Qb0FoELHEEPDWhQi23EJeFyrBV0Og==}
    +  unrun@0.2.32:
    +    resolution: {integrity: sha512-opd3z6791rf281JdByf0RdRQrpcc7WyzqittqIXodM/5meNWdTwrVxeyzbaCp4/Rgls/um14oUaif1gomO8YGg==}
         engines: {node: '>=20.19.0'}
         hasBin: true
         peerDependencies:
    @@ -4858,10 +6015,17 @@ packages:
       util-deprecate@1.0.2:
         resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
     
    +  uuid@11.1.0:
    +    resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==}
    +    hasBin: true
    +
       vary@1.1.2:
         resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
         engines: {node: '>= 0.8'}
     
    +  vfile-location@5.0.3:
    +    resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==}
    +
       vfile-message@4.0.3:
         resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==}
     
    @@ -4871,15 +6035,16 @@ packages:
       victory-vendor@37.3.6:
         resolution: {integrity: sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==}
     
    -  vite@7.3.1:
    -    resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==}
    +  vite@8.0.1:
    +    resolution: {integrity: sha512-wt+Z2qIhfFt85uiyRt5LPU4oVEJBXj8hZNWKeqFG4gRG/0RaRGJ7njQCwzFVjO+v4+Ipmf5CY7VdmZRAYYBPHw==}
         engines: {node: ^20.19.0 || >=22.12.0}
         hasBin: true
         peerDependencies:
           '@types/node': ^20.19.0 || >=22.12.0
    +      '@vitejs/devtools': ^0.1.0
    +      esbuild: ^0.27.0
           jiti: '>=1.21.0'
           less: ^4.0.0
    -      lightningcss: ^1.21.0
           sass: ^1.70.0
           sass-embedded: ^1.70.0
           stylus: '>=0.54.8'
    @@ -4890,12 +6055,14 @@ packages:
         peerDependenciesMeta:
           '@types/node':
             optional: true
    +      '@vitejs/devtools':
    +        optional: true
    +      esbuild:
    +        optional: true
           jiti:
             optional: true
           less:
             optional: true
    -      lightningcss:
    -        optional: true
           sass:
             optional: true
           sass-embedded:
    @@ -4911,20 +6078,21 @@ packages:
           yaml:
             optional: true
     
    -  vitest@4.0.18:
    -    resolution: {integrity: sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==}
    +  vitest@4.1.0:
    +    resolution: {integrity: sha512-YbDrMF9jM2Lqc++2530UourxZHmkKLxrs4+mYhEwqWS97WJ7wOYEkcr+QfRgJ3PW9wz3odRijLZjHEaRLTNbqw==}
         engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0}
         hasBin: true
         peerDependencies:
           '@edge-runtime/vm': '*'
           '@opentelemetry/api': ^1.9.0
           '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0
    -      '@vitest/browser-playwright': 4.0.18
    -      '@vitest/browser-preview': 4.0.18
    -      '@vitest/browser-webdriverio': 4.0.18
    -      '@vitest/ui': 4.0.18
    +      '@vitest/browser-playwright': 4.1.0
    +      '@vitest/browser-preview': 4.1.0
    +      '@vitest/browser-webdriverio': 4.1.0
    +      '@vitest/ui': 4.1.0
           happy-dom: '*'
           jsdom: '*'
    +      vite: ^6.0.0 || ^7.0.0 || ^8.0.0-0
         peerDependenciesMeta:
           '@edge-runtime/vm':
             optional: true
    @@ -4945,12 +6113,35 @@ packages:
           jsdom:
             optional: true
     
    +  vscode-jsonrpc@8.2.0:
    +    resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==}
    +    engines: {node: '>=14.0.0'}
    +
    +  vscode-languageserver-protocol@3.17.5:
    +    resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==}
    +
    +  vscode-languageserver-textdocument@1.0.12:
    +    resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==}
    +
    +  vscode-languageserver-types@3.17.5:
    +    resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==}
    +
    +  vscode-languageserver@9.0.1:
    +    resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==}
    +    hasBin: true
    +
    +  vscode-uri@3.1.0:
    +    resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==}
    +
       vue-eslint-parser@10.4.0:
         resolution: {integrity: sha512-Vxi9pJdbN3ZnVGLODVtZ7y4Y2kzAAE2Cm0CZ3ZDRvydVYxZ6VrnBhLikBsRS+dpwj4Jv4UCv21PTEwF5rQ9WXg==}
         engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
         peerDependencies:
           eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
     
    +  web-namespaces@2.0.1:
    +    resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
    +
       webpack-virtual-modules@0.6.2:
         resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==}
     
    @@ -4969,6 +6160,9 @@ packages:
         engines: {node: '>=8'}
         hasBin: true
     
    +  wicked-good-xpath@1.3.0:
    +    resolution: {integrity: sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw==}
    +
       word-wrap@1.2.5:
         resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
         engines: {node: '>=0.10.0'}
    @@ -4989,10 +6183,6 @@ packages:
       yallist@3.1.1:
         resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
     
    -  yaml-eslint-parser@1.3.2:
    -    resolution: {integrity: sha512-odxVsHAkZYYglR30aPYRY4nUGJnoJ2y1ww2HDvZALo0BDETv9kWbi16J52eHs+PWRNmF4ub6nZqfVOeesOvntg==}
    -    engines: {node: ^14.17.0 || >=16.0.0}
    -
       yaml-eslint-parser@2.0.0:
         resolution: {integrity: sha512-h0uDm97wvT2bokfwwTmY6kJ1hp6YDFL0nRHwNKz8s/VD1FH/vvZjAKoMUE+un0eaYBSG7/c6h+lJTP+31tjgTw==}
         engines: {node: ^20.19.0 || ^22.13.0 || >=24}
    @@ -5017,60 +6207,79 @@ packages:
       zod@4.3.6:
         resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==}
     
    +  zustand@5.0.12:
    +    resolution: {integrity: sha512-i77ae3aZq4dhMlRhJVCYgMLKuSiZAaUPAct2AksxQ+gOtimhGMdXljRT21P5BNpeT4kXlLIckvkPM029OljD7g==}
    +    engines: {node: '>=12.20.0'}
    +    peerDependencies:
    +      '@types/react': '>=18.0.0'
    +      immer: '>=9.0.6'
    +      react: '>=18.0.0'
    +      use-sync-external-store: '>=1.2.0'
    +    peerDependenciesMeta:
    +      '@types/react':
    +        optional: true
    +      immer:
    +        optional: true
    +      react:
    +        optional: true
    +      use-sync-external-store:
    +        optional: true
    +
       zwitch@2.0.4:
         resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
     
     snapshots:
     
    -  '@antfu/eslint-config@6.7.1(@next/eslint-plugin-next@16.1.0)(@typescript-eslint/rule-tester@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.56.1(typescript@5.9.3))(@typescript-eslint/utils@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(@unocss/eslint-plugin@66.5.10(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.26)(eslint-plugin-format@1.1.0(eslint@10.0.2(jiti@2.6.1)))(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)(vitest@4.0.18(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2))':
    +  '@antfu/eslint-config@7.7.3(@next/eslint-plugin-next@16.2.0)(@typescript-eslint/rule-tester@8.56.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.57.1(typescript@5.9.3))(@typescript-eslint/utils@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(@unocss/eslint-plugin@66.6.7(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.26)(eslint-plugin-format@2.0.1(eslint@10.0.3(jiti@2.6.1)))(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)(vitest@4.1.0(@types/node@25.5.0)(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)))':
         dependencies:
           '@antfu/install-pkg': 1.1.0
    -      '@clack/prompts': 0.11.0
    -      '@eslint-community/eslint-plugin-eslint-comments': 4.7.0(eslint@10.0.2(jiti@2.6.1))
    +      '@clack/prompts': 1.1.0
    +      '@e18e/eslint-plugin': 0.2.0(eslint@10.0.3(jiti@2.6.1))
    +      '@eslint-community/eslint-plugin-eslint-comments': 4.7.1(eslint@10.0.3(jiti@2.6.1))
           '@eslint/markdown': 7.5.1
    -      '@stylistic/eslint-plugin': 5.9.0(eslint@10.0.2(jiti@2.6.1))
    -      '@typescript-eslint/eslint-plugin': 8.56.1(@typescript-eslint/parser@8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      '@typescript-eslint/parser': 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      '@vitest/eslint-plugin': 1.6.9(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)(vitest@4.0.18(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2))
    +      '@stylistic/eslint-plugin': 5.10.0(eslint@10.0.3(jiti@2.6.1))
    +      '@typescript-eslint/eslint-plugin': 8.57.1(@typescript-eslint/parser@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
    +      '@typescript-eslint/parser': 8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
    +      '@vitest/eslint-plugin': 1.6.12(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)(vitest@4.1.0(@types/node@25.5.0)(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)))
           ansis: 4.2.0
    -      cac: 6.7.14
    -      eslint: 10.0.2(jiti@2.6.1)
    -      eslint-config-flat-gitignore: 2.2.1(eslint@10.0.2(jiti@2.6.1))
    -      eslint-flat-config-utils: 2.1.4
    -      eslint-merge-processors: 2.0.0(eslint@10.0.2(jiti@2.6.1))
    -      eslint-plugin-antfu: 3.2.2(eslint@10.0.2(jiti@2.6.1))
    -      eslint-plugin-command: 3.5.2(@typescript-eslint/rule-tester@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.56.1(typescript@5.9.3))(@typescript-eslint/utils@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))
    -      eslint-plugin-import-lite: 0.3.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      eslint-plugin-jsdoc: 61.7.1(eslint@10.0.2(jiti@2.6.1))
    -      eslint-plugin-jsonc: 2.21.1(eslint@10.0.2(jiti@2.6.1))
    -      eslint-plugin-n: 17.24.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    +      cac: 7.0.0
    +      eslint: 10.0.3(jiti@2.6.1)
    +      eslint-config-flat-gitignore: 2.2.1(eslint@10.0.3(jiti@2.6.1))
    +      eslint-flat-config-utils: 3.0.2
    +      eslint-merge-processors: 2.0.0(eslint@10.0.3(jiti@2.6.1))
    +      eslint-plugin-antfu: 3.2.2(eslint@10.0.3(jiti@2.6.1))
    +      eslint-plugin-command: 3.5.2(@typescript-eslint/rule-tester@8.56.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.57.1(typescript@5.9.3))(@typescript-eslint/utils@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))
    +      eslint-plugin-import-lite: 0.5.2(eslint@10.0.3(jiti@2.6.1))
    +      eslint-plugin-jsdoc: 62.8.0(eslint@10.0.3(jiti@2.6.1))
    +      eslint-plugin-jsonc: 3.1.2(eslint@10.0.3(jiti@2.6.1))
    +      eslint-plugin-n: 17.24.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
           eslint-plugin-no-only-tests: 3.3.0
    -      eslint-plugin-perfectionist: 4.15.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      eslint-plugin-pnpm: 1.6.0(eslint@10.0.2(jiti@2.6.1))
    -      eslint-plugin-regexp: 2.10.0(eslint@10.0.2(jiti@2.6.1))
    -      eslint-plugin-toml: 0.12.0(eslint@10.0.2(jiti@2.6.1))
    -      eslint-plugin-unicorn: 62.0.0(eslint@10.0.2(jiti@2.6.1))
    -      eslint-plugin-unused-imports: 4.4.1(@typescript-eslint/eslint-plugin@8.56.1(@typescript-eslint/parser@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))
    -      eslint-plugin-vue: 10.6.2(@stylistic/eslint-plugin@5.9.0(eslint@10.0.2(jiti@2.6.1)))(@typescript-eslint/parser@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.0.2(jiti@2.6.1)))
    -      eslint-plugin-yml: 1.19.1(eslint@10.0.2(jiti@2.6.1))
    -      eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.26)(eslint@10.0.2(jiti@2.6.1))
    -      globals: 16.5.0
    -      jsonc-eslint-parser: 2.4.2
    +      eslint-plugin-perfectionist: 5.7.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
    +      eslint-plugin-pnpm: 1.6.0(eslint@10.0.3(jiti@2.6.1))
    +      eslint-plugin-regexp: 3.1.0(eslint@10.0.3(jiti@2.6.1))
    +      eslint-plugin-toml: 1.3.1(eslint@10.0.3(jiti@2.6.1))
    +      eslint-plugin-unicorn: 63.0.0(eslint@10.0.3(jiti@2.6.1))
    +      eslint-plugin-unused-imports: 4.4.1(@typescript-eslint/eslint-plugin@8.57.1(@typescript-eslint/parser@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))
    +      eslint-plugin-vue: 10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.0.3(jiti@2.6.1)))(@typescript-eslint/parser@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.0.3(jiti@2.6.1)))
    +      eslint-plugin-yml: 3.3.1(eslint@10.0.3(jiti@2.6.1))
    +      eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.26)(eslint@10.0.3(jiti@2.6.1))
    +      globals: 17.4.0
           local-pkg: 1.1.2
           parse-gitignore: 2.0.0
    -      toml-eslint-parser: 0.10.1
    -      vue-eslint-parser: 10.4.0(eslint@10.0.2(jiti@2.6.1))
    -      yaml-eslint-parser: 1.3.2
    +      toml-eslint-parser: 1.0.3
    +      vue-eslint-parser: 10.4.0(eslint@10.0.3(jiti@2.6.1))
    +      yaml-eslint-parser: 2.0.0
         optionalDependencies:
    -      '@next/eslint-plugin-next': 16.1.0
    -      '@unocss/eslint-plugin': 66.5.10(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      eslint-plugin-format: 1.1.0(eslint@10.0.2(jiti@2.6.1))
    +      '@next/eslint-plugin-next': 16.2.0
    +      '@unocss/eslint-plugin': 66.6.7(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
    +      eslint-plugin-format: 2.0.1(eslint@10.0.3(jiti@2.6.1))
         transitivePeerDependencies:
           - '@eslint/json'
           - '@typescript-eslint/rule-tester'
           - '@typescript-eslint/typescript-estree'
           - '@typescript-eslint/utils'
           - '@vue/compiler-sfc'
    +      - oxlint
           - supports-color
           - typescript
           - vitest
    @@ -5078,7 +6287,7 @@ snapshots:
       '@antfu/install-pkg@1.1.0':
         dependencies:
           package-manager-detector: 1.6.0
    -      tinyexec: 1.0.2
    +      tinyexec: 1.0.4
     
       '@babel/code-frame@7.29.0':
         dependencies:
    @@ -5116,10 +6325,10 @@ snapshots:
           '@jridgewell/trace-mapping': 0.3.31
           jsesc: 3.1.0
     
    -  '@babel/generator@8.0.0-rc.1':
    +  '@babel/generator@8.0.0-rc.2':
         dependencies:
    -      '@babel/parser': 8.0.0-rc.1
    -      '@babel/types': 8.0.0-rc.1
    +      '@babel/parser': 8.0.0-rc.2
    +      '@babel/types': 8.0.0-rc.2
           '@jridgewell/gen-mapping': 0.3.13
           '@jridgewell/trace-mapping': 0.3.31
           '@types/jsesc': 2.5.1
    @@ -5159,7 +6368,7 @@ snapshots:
     
       '@babel/helper-validator-identifier@7.28.5': {}
     
    -  '@babel/helper-validator-identifier@8.0.0-rc.1': {}
    +  '@babel/helper-validator-identifier@8.0.0-rc.2': {}
     
       '@babel/helper-validator-option@7.27.1': {}
     
    @@ -5172,9 +6381,9 @@ snapshots:
         dependencies:
           '@babel/types': 7.29.0
     
    -  '@babel/parser@8.0.0-rc.1':
    +  '@babel/parser@8.0.0-rc.2':
         dependencies:
    -      '@babel/types': 8.0.0-rc.1
    +      '@babel/types': 8.0.0-rc.2
     
       '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)':
         dependencies:
    @@ -5186,16 +6395,6 @@ snapshots:
           '@babel/core': 7.29.0
           '@babel/helper-plugin-utils': 7.28.6
     
    -  '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)':
    -    dependencies:
    -      '@babel/core': 7.29.0
    -      '@babel/helper-plugin-utils': 7.28.6
    -
    -  '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.29.0)':
    -    dependencies:
    -      '@babel/core': 7.29.0
    -      '@babel/helper-plugin-utils': 7.28.6
    -
       '@babel/template@7.28.6':
         dependencies:
           '@babel/code-frame': 7.29.0
    @@ -5219,40 +6418,52 @@ snapshots:
           '@babel/helper-string-parser': 7.27.1
           '@babel/helper-validator-identifier': 7.28.5
     
    -  '@babel/types@8.0.0-rc.1':
    +  '@babel/types@8.0.0-rc.2':
         dependencies:
           '@babel/helper-string-parser': 8.0.0-rc.2
    -      '@babel/helper-validator-identifier': 8.0.0-rc.1
    +      '@babel/helper-validator-identifier': 8.0.0-rc.2
     
       '@bcoe/v8-coverage@1.0.2': {}
     
    -  '@clack/core@0.5.0':
    +  '@braintree/sanitize-url@7.1.2': {}
    +
    +  '@chevrotain/cst-dts-gen@11.1.2':
         dependencies:
    -      picocolors: 1.1.1
    -      sisteransi: 1.0.5
    +      '@chevrotain/gast': 11.1.2
    +      '@chevrotain/types': 11.1.2
    +      lodash-es: 4.17.23
     
    -  '@clack/core@1.0.1':
    +  '@chevrotain/gast@11.1.2':
         dependencies:
    -      picocolors: 1.1.1
    -      sisteransi: 1.0.5
    +      '@chevrotain/types': 11.1.2
    +      lodash-es: 4.17.23
     
    -  '@clack/prompts@0.11.0':
    +  '@chevrotain/regexp-to-ast@11.1.2': {}
    +
    +  '@chevrotain/types@11.1.2': {}
    +
    +  '@chevrotain/utils@11.1.2': {}
    +
    +  '@clack/core@1.1.0':
         dependencies:
    -      '@clack/core': 0.5.0
    -      picocolors: 1.1.1
           sisteransi: 1.0.5
     
    -  '@clack/prompts@1.0.1':
    +  '@clack/prompts@1.1.0':
         dependencies:
    -      '@clack/core': 1.0.1
    -      picocolors: 1.1.1
    +      '@clack/core': 1.1.0
           sisteransi: 1.0.5
     
    -  '@dprint/formatter@0.3.0': {}
    +  '@dprint/formatter@0.5.1': {}
    +
    +  '@dprint/markdown@0.21.1': {}
     
    -  '@dprint/markdown@0.17.8': {}
    +  '@dprint/toml@0.7.0': {}
     
    -  '@dprint/toml@0.6.4': {}
    +  '@e18e/eslint-plugin@0.2.0(eslint@10.0.3(jiti@2.6.1))':
    +    dependencies:
    +      eslint-plugin-depend: 1.5.0(eslint@10.0.3(jiti@2.6.1))
    +    optionalDependencies:
    +      eslint: 10.0.3(jiti@2.6.1)
     
       '@emnapi/core@1.8.1':
         dependencies:
    @@ -5270,14 +6481,6 @@ snapshots:
           tslib: 2.8.1
         optional: true
     
    -  '@es-joy/jsdoccomment@0.78.0':
    -    dependencies:
    -      '@types/estree': 1.0.8
    -      '@typescript-eslint/types': 8.56.1
    -      comment-parser: 1.4.1
    -      esquery: 1.7.0
    -      jsdoc-type-pratt-parser: 7.0.0
    -
       '@es-joy/jsdoccomment@0.84.0':
         dependencies:
           '@types/estree': 1.0.8
    @@ -5366,28 +6569,28 @@ snapshots:
       '@esbuild/win32-x64@0.27.3':
         optional: true
     
    -  '@eslint-community/eslint-plugin-eslint-comments@4.7.0(eslint@10.0.2(jiti@2.6.1))':
    +  '@eslint-community/eslint-plugin-eslint-comments@4.7.1(eslint@10.0.3(jiti@2.6.1))':
         dependencies:
           escape-string-regexp: 4.0.0
    -      eslint: 10.0.2(jiti@2.6.1)
    +      eslint: 10.0.3(jiti@2.6.1)
           ignore: 7.0.5
     
    -  '@eslint-community/eslint-utils@4.9.1(eslint@10.0.2(jiti@2.6.1))':
    +  '@eslint-community/eslint-utils@4.9.1(eslint@10.0.3(jiti@2.6.1))':
         dependencies:
    -      eslint: 10.0.2(jiti@2.6.1)
    +      eslint: 10.0.3(jiti@2.6.1)
           eslint-visitor-keys: 3.4.3
     
       '@eslint-community/regexpp@4.12.2': {}
     
    -  '@eslint/compat@2.0.2(eslint@10.0.2(jiti@2.6.1))':
    +  '@eslint/compat@2.0.2(eslint@10.0.3(jiti@2.6.1))':
         dependencies:
    -      '@eslint/core': 1.1.0
    +      '@eslint/core': 1.1.1
         optionalDependencies:
    -      eslint: 10.0.2(jiti@2.6.1)
    +      eslint: 10.0.3(jiti@2.6.1)
     
    -  '@eslint/config-array@0.23.2':
    +  '@eslint/config-array@0.23.3':
         dependencies:
    -      '@eslint/object-schema': 3.0.2
    +      '@eslint/object-schema': 3.0.3
           debug: 4.4.3
           minimatch: 10.2.4
         transitivePeerDependencies:
    @@ -5395,17 +6598,23 @@ snapshots:
     
       '@eslint/config-helpers@0.5.2':
         dependencies:
    -      '@eslint/core': 1.1.0
    +      '@eslint/core': 1.1.1
    +
    +  '@eslint/config-helpers@0.5.3':
    +    dependencies:
    +      '@eslint/core': 1.1.1
     
       '@eslint/core@0.17.0':
         dependencies:
           '@types/json-schema': 7.0.15
     
    -  '@eslint/core@1.1.0':
    +  '@eslint/core@1.1.1':
         dependencies:
           '@types/json-schema': 7.0.15
     
    -  '@eslint/js@9.39.2': {}
    +  '@eslint/js@10.0.1(eslint@10.0.3(jiti@2.6.1))':
    +    optionalDependencies:
    +      eslint: 10.0.3(jiti@2.6.1)
     
       '@eslint/markdown@7.5.1':
         dependencies:
    @@ -5421,18 +6630,57 @@ snapshots:
         transitivePeerDependencies:
           - supports-color
     
    -  '@eslint/object-schema@3.0.2': {}
    +  '@eslint/object-schema@3.0.3': {}
     
       '@eslint/plugin-kit@0.4.1':
         dependencies:
           '@eslint/core': 0.17.0
           levn: 0.4.1
     
    -  '@eslint/plugin-kit@0.6.0':
    +  '@eslint/plugin-kit@0.6.1':
         dependencies:
    -      '@eslint/core': 1.1.0
    +      '@eslint/core': 1.1.1
           levn: 0.4.1
     
    +  '@floating-ui/core@1.7.5':
    +    dependencies:
    +      '@floating-ui/utils': 0.2.11
    +
    +  '@floating-ui/dom@1.7.6':
    +    dependencies:
    +      '@floating-ui/core': 1.7.5
    +      '@floating-ui/utils': 0.2.11
    +
    +  '@floating-ui/react-dom@2.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
    +    dependencies:
    +      '@floating-ui/dom': 1.7.6
    +      react: 19.2.4
    +      react-dom: 19.2.4(react@19.2.4)
    +
    +  '@floating-ui/react@0.26.28(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
    +    dependencies:
    +      '@floating-ui/react-dom': 2.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
    +      '@floating-ui/utils': 0.2.11
    +      react: 19.2.4
    +      react-dom: 19.2.4(react@19.2.4)
    +      tabbable: 6.4.0
    +
    +  '@floating-ui/utils@0.2.11': {}
    +
    +  '@formatjs/intl-localematcher@0.6.2':
    +    dependencies:
    +      tslib: 2.8.1
    +
    +  '@headlessui/react@2.2.9(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
    +    dependencies:
    +      '@floating-ui/react': 0.26.28(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
    +      '@react-aria/focus': 3.21.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
    +      '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
    +      '@tanstack/react-virtual': 3.13.23(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
    +      react: 19.2.4
    +      react-dom: 19.2.4(react@19.2.4)
    +      use-sync-external-store: 1.6.0(react@19.2.4)
    +
       '@hono/node-server@1.19.11(hono@4.12.8)':
         dependencies:
           hono: 4.12.8
    @@ -5448,6 +6696,14 @@ snapshots:
     
       '@humanwhocodes/retry@0.4.3': {}
     
    +  '@iconify/types@2.0.0': {}
    +
    +  '@iconify/utils@3.1.0':
    +    dependencies:
    +      '@antfu/install-pkg': 1.1.0
    +      '@iconify/types': 2.0.0
    +      mlly: 1.8.0
    +
       '@img/colour@1.1.0':
         optional: true
     
    @@ -5547,122 +6803,122 @@ snapshots:
     
       '@inquirer/ansi@2.0.3': {}
     
    -  '@inquirer/checkbox@5.1.0(@types/node@25.3.3)':
    +  '@inquirer/checkbox@5.1.0(@types/node@25.5.0)':
         dependencies:
           '@inquirer/ansi': 2.0.3
    -      '@inquirer/core': 11.1.5(@types/node@25.3.3)
    +      '@inquirer/core': 11.1.5(@types/node@25.5.0)
           '@inquirer/figures': 2.0.3
    -      '@inquirer/type': 4.0.3(@types/node@25.3.3)
    +      '@inquirer/type': 4.0.3(@types/node@25.5.0)
         optionalDependencies:
    -      '@types/node': 25.3.3
    +      '@types/node': 25.5.0
     
    -  '@inquirer/confirm@6.0.8(@types/node@25.3.3)':
    +  '@inquirer/confirm@6.0.8(@types/node@25.5.0)':
         dependencies:
    -      '@inquirer/core': 11.1.5(@types/node@25.3.3)
    -      '@inquirer/type': 4.0.3(@types/node@25.3.3)
    +      '@inquirer/core': 11.1.5(@types/node@25.5.0)
    +      '@inquirer/type': 4.0.3(@types/node@25.5.0)
         optionalDependencies:
    -      '@types/node': 25.3.3
    +      '@types/node': 25.5.0
     
    -  '@inquirer/core@11.1.5(@types/node@25.3.3)':
    +  '@inquirer/core@11.1.5(@types/node@25.5.0)':
         dependencies:
           '@inquirer/ansi': 2.0.3
           '@inquirer/figures': 2.0.3
    -      '@inquirer/type': 4.0.3(@types/node@25.3.3)
    +      '@inquirer/type': 4.0.3(@types/node@25.5.0)
           cli-width: 4.1.0
           fast-wrap-ansi: 0.2.0
           mute-stream: 3.0.0
           signal-exit: 4.1.0
         optionalDependencies:
    -      '@types/node': 25.3.3
    +      '@types/node': 25.5.0
     
    -  '@inquirer/editor@5.0.8(@types/node@25.3.3)':
    +  '@inquirer/editor@5.0.8(@types/node@25.5.0)':
         dependencies:
    -      '@inquirer/core': 11.1.5(@types/node@25.3.3)
    -      '@inquirer/external-editor': 2.0.3(@types/node@25.3.3)
    -      '@inquirer/type': 4.0.3(@types/node@25.3.3)
    +      '@inquirer/core': 11.1.5(@types/node@25.5.0)
    +      '@inquirer/external-editor': 2.0.3(@types/node@25.5.0)
    +      '@inquirer/type': 4.0.3(@types/node@25.5.0)
         optionalDependencies:
    -      '@types/node': 25.3.3
    +      '@types/node': 25.5.0
     
    -  '@inquirer/expand@5.0.8(@types/node@25.3.3)':
    +  '@inquirer/expand@5.0.8(@types/node@25.5.0)':
         dependencies:
    -      '@inquirer/core': 11.1.5(@types/node@25.3.3)
    -      '@inquirer/type': 4.0.3(@types/node@25.3.3)
    +      '@inquirer/core': 11.1.5(@types/node@25.5.0)
    +      '@inquirer/type': 4.0.3(@types/node@25.5.0)
         optionalDependencies:
    -      '@types/node': 25.3.3
    +      '@types/node': 25.5.0
     
    -  '@inquirer/external-editor@2.0.3(@types/node@25.3.3)':
    +  '@inquirer/external-editor@2.0.3(@types/node@25.5.0)':
         dependencies:
           chardet: 2.1.1
           iconv-lite: 0.7.2
         optionalDependencies:
    -      '@types/node': 25.3.3
    +      '@types/node': 25.5.0
     
       '@inquirer/figures@2.0.3': {}
     
    -  '@inquirer/input@5.0.8(@types/node@25.3.3)':
    +  '@inquirer/input@5.0.8(@types/node@25.5.0)':
         dependencies:
    -      '@inquirer/core': 11.1.5(@types/node@25.3.3)
    -      '@inquirer/type': 4.0.3(@types/node@25.3.3)
    +      '@inquirer/core': 11.1.5(@types/node@25.5.0)
    +      '@inquirer/type': 4.0.3(@types/node@25.5.0)
         optionalDependencies:
    -      '@types/node': 25.3.3
    +      '@types/node': 25.5.0
     
    -  '@inquirer/number@4.0.8(@types/node@25.3.3)':
    +  '@inquirer/number@4.0.8(@types/node@25.5.0)':
         dependencies:
    -      '@inquirer/core': 11.1.5(@types/node@25.3.3)
    -      '@inquirer/type': 4.0.3(@types/node@25.3.3)
    +      '@inquirer/core': 11.1.5(@types/node@25.5.0)
    +      '@inquirer/type': 4.0.3(@types/node@25.5.0)
         optionalDependencies:
    -      '@types/node': 25.3.3
    +      '@types/node': 25.5.0
     
    -  '@inquirer/password@5.0.8(@types/node@25.3.3)':
    +  '@inquirer/password@5.0.8(@types/node@25.5.0)':
         dependencies:
           '@inquirer/ansi': 2.0.3
    -      '@inquirer/core': 11.1.5(@types/node@25.3.3)
    -      '@inquirer/type': 4.0.3(@types/node@25.3.3)
    +      '@inquirer/core': 11.1.5(@types/node@25.5.0)
    +      '@inquirer/type': 4.0.3(@types/node@25.5.0)
         optionalDependencies:
    -      '@types/node': 25.3.3
    -
    -  '@inquirer/prompts@8.3.0(@types/node@25.3.3)':
    -    dependencies:
    -      '@inquirer/checkbox': 5.1.0(@types/node@25.3.3)
    -      '@inquirer/confirm': 6.0.8(@types/node@25.3.3)
    -      '@inquirer/editor': 5.0.8(@types/node@25.3.3)
    -      '@inquirer/expand': 5.0.8(@types/node@25.3.3)
    -      '@inquirer/input': 5.0.8(@types/node@25.3.3)
    -      '@inquirer/number': 4.0.8(@types/node@25.3.3)
    -      '@inquirer/password': 5.0.8(@types/node@25.3.3)
    -      '@inquirer/rawlist': 5.2.4(@types/node@25.3.3)
    -      '@inquirer/search': 4.1.4(@types/node@25.3.3)
    -      '@inquirer/select': 5.1.0(@types/node@25.3.3)
    +      '@types/node': 25.5.0
    +
    +  '@inquirer/prompts@8.3.0(@types/node@25.5.0)':
    +    dependencies:
    +      '@inquirer/checkbox': 5.1.0(@types/node@25.5.0)
    +      '@inquirer/confirm': 6.0.8(@types/node@25.5.0)
    +      '@inquirer/editor': 5.0.8(@types/node@25.5.0)
    +      '@inquirer/expand': 5.0.8(@types/node@25.5.0)
    +      '@inquirer/input': 5.0.8(@types/node@25.5.0)
    +      '@inquirer/number': 4.0.8(@types/node@25.5.0)
    +      '@inquirer/password': 5.0.8(@types/node@25.5.0)
    +      '@inquirer/rawlist': 5.2.4(@types/node@25.5.0)
    +      '@inquirer/search': 4.1.4(@types/node@25.5.0)
    +      '@inquirer/select': 5.1.0(@types/node@25.5.0)
         optionalDependencies:
    -      '@types/node': 25.3.3
    +      '@types/node': 25.5.0
     
    -  '@inquirer/rawlist@5.2.4(@types/node@25.3.3)':
    +  '@inquirer/rawlist@5.2.4(@types/node@25.5.0)':
         dependencies:
    -      '@inquirer/core': 11.1.5(@types/node@25.3.3)
    -      '@inquirer/type': 4.0.3(@types/node@25.3.3)
    +      '@inquirer/core': 11.1.5(@types/node@25.5.0)
    +      '@inquirer/type': 4.0.3(@types/node@25.5.0)
         optionalDependencies:
    -      '@types/node': 25.3.3
    +      '@types/node': 25.5.0
     
    -  '@inquirer/search@4.1.4(@types/node@25.3.3)':
    +  '@inquirer/search@4.1.4(@types/node@25.5.0)':
         dependencies:
    -      '@inquirer/core': 11.1.5(@types/node@25.3.3)
    +      '@inquirer/core': 11.1.5(@types/node@25.5.0)
           '@inquirer/figures': 2.0.3
    -      '@inquirer/type': 4.0.3(@types/node@25.3.3)
    +      '@inquirer/type': 4.0.3(@types/node@25.5.0)
         optionalDependencies:
    -      '@types/node': 25.3.3
    +      '@types/node': 25.5.0
     
    -  '@inquirer/select@5.1.0(@types/node@25.3.3)':
    +  '@inquirer/select@5.1.0(@types/node@25.5.0)':
         dependencies:
           '@inquirer/ansi': 2.0.3
    -      '@inquirer/core': 11.1.5(@types/node@25.3.3)
    +      '@inquirer/core': 11.1.5(@types/node@25.5.0)
           '@inquirer/figures': 2.0.3
    -      '@inquirer/type': 4.0.3(@types/node@25.3.3)
    +      '@inquirer/type': 4.0.3(@types/node@25.5.0)
         optionalDependencies:
    -      '@types/node': 25.3.3
    +      '@types/node': 25.5.0
     
    -  '@inquirer/type@4.0.3(@types/node@25.3.3)':
    +  '@inquirer/type@4.0.3(@types/node@25.5.0)':
         optionalDependencies:
    -      '@types/node': 25.3.3
    +      '@types/node': 25.5.0
     
       '@jridgewell/gen-mapping@0.3.13':
         dependencies:
    @@ -5683,11 +6939,39 @@ snapshots:
           '@jridgewell/resolve-uri': 3.1.2
           '@jridgewell/sourcemap-codec': 1.5.5
     
    -  '@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4)':
    +  '@mdx-js/mdx@3.1.1':
         dependencies:
    +      '@types/estree': 1.0.8
    +      '@types/estree-jsx': 1.0.5
    +      '@types/hast': 3.0.4
           '@types/mdx': 2.0.13
    -      '@types/react': 19.2.14
    -      react: 19.2.4
    +      acorn: 8.16.0
    +      collapse-white-space: 2.1.0
    +      devlop: 1.1.0
    +      estree-util-is-identifier-name: 3.0.0
    +      estree-util-scope: 1.0.0
    +      estree-walker: 3.0.3
    +      hast-util-to-jsx-runtime: 2.3.6
    +      markdown-extensions: 2.0.0
    +      recma-build-jsx: 1.0.0
    +      recma-jsx: 1.0.1(acorn@8.16.0)
    +      recma-stringify: 1.0.0
    +      rehype-recma: 1.0.0
    +      remark-mdx: 3.1.1
    +      remark-parse: 11.0.0
    +      remark-rehype: 11.1.2
    +      source-map: 0.7.6
    +      unified: 11.0.5
    +      unist-util-position-from-estree: 2.0.0
    +      unist-util-stringify-position: 4.0.0
    +      unist-util-visit: 5.1.0
    +      vfile: 6.0.3
    +    transitivePeerDependencies:
    +      - supports-color
    +
    +  '@mermaid-js/parser@1.0.1':
    +    dependencies:
    +      langium: 4.2.1
     
       '@modelcontextprotocol/sdk@1.27.1(zod@4.3.6)':
         dependencies:
    @@ -5722,9 +7006,9 @@ snapshots:
           react: 19.2.4
           react-dom: 19.2.4(react@19.2.4)
     
    -  '@napi-rs/cli@3.5.1(@emnapi/runtime@1.8.1)(@types/node@25.3.3)':
    +  '@napi-rs/cli@3.5.1(@emnapi/runtime@1.8.1)(@types/node@25.5.0)':
         dependencies:
    -      '@inquirer/prompts': 8.3.0(@types/node@25.3.3)
    +      '@inquirer/prompts': 8.3.0(@types/node@25.5.0)
           '@napi-rs/cross-toolchain': 1.0.3
           '@napi-rs/wasm-tools': 1.0.1
           '@octokit/rest': 22.0.1
    @@ -5834,6 +7118,69 @@ snapshots:
           '@napi-rs/lzma-win32-ia32-msvc': 1.4.5
           '@napi-rs/lzma-win32-x64-msvc': 1.4.5
     
    +  '@napi-rs/simple-git-android-arm-eabi@0.1.22':
    +    optional: true
    +
    +  '@napi-rs/simple-git-android-arm64@0.1.22':
    +    optional: true
    +
    +  '@napi-rs/simple-git-darwin-arm64@0.1.22':
    +    optional: true
    +
    +  '@napi-rs/simple-git-darwin-x64@0.1.22':
    +    optional: true
    +
    +  '@napi-rs/simple-git-freebsd-x64@0.1.22':
    +    optional: true
    +
    +  '@napi-rs/simple-git-linux-arm-gnueabihf@0.1.22':
    +    optional: true
    +
    +  '@napi-rs/simple-git-linux-arm64-gnu@0.1.22':
    +    optional: true
    +
    +  '@napi-rs/simple-git-linux-arm64-musl@0.1.22':
    +    optional: true
    +
    +  '@napi-rs/simple-git-linux-ppc64-gnu@0.1.22':
    +    optional: true
    +
    +  '@napi-rs/simple-git-linux-s390x-gnu@0.1.22':
    +    optional: true
    +
    +  '@napi-rs/simple-git-linux-x64-gnu@0.1.22':
    +    optional: true
    +
    +  '@napi-rs/simple-git-linux-x64-musl@0.1.22':
    +    optional: true
    +
    +  '@napi-rs/simple-git-win32-arm64-msvc@0.1.22':
    +    optional: true
    +
    +  '@napi-rs/simple-git-win32-ia32-msvc@0.1.22':
    +    optional: true
    +
    +  '@napi-rs/simple-git-win32-x64-msvc@0.1.22':
    +    optional: true
    +
    +  '@napi-rs/simple-git@0.1.22':
    +    optionalDependencies:
    +      '@napi-rs/simple-git-android-arm-eabi': 0.1.22
    +      '@napi-rs/simple-git-android-arm64': 0.1.22
    +      '@napi-rs/simple-git-darwin-arm64': 0.1.22
    +      '@napi-rs/simple-git-darwin-x64': 0.1.22
    +      '@napi-rs/simple-git-freebsd-x64': 0.1.22
    +      '@napi-rs/simple-git-linux-arm-gnueabihf': 0.1.22
    +      '@napi-rs/simple-git-linux-arm64-gnu': 0.1.22
    +      '@napi-rs/simple-git-linux-arm64-musl': 0.1.22
    +      '@napi-rs/simple-git-linux-ppc64-gnu': 0.1.22
    +      '@napi-rs/simple-git-linux-s390x-gnu': 0.1.22
    +      '@napi-rs/simple-git-linux-x64-gnu': 0.1.22
    +      '@napi-rs/simple-git-linux-x64-musl': 0.1.22
    +      '@napi-rs/simple-git-win32-arm64-msvc': 0.1.22
    +      '@napi-rs/simple-git-win32-ia32-msvc': 0.1.22
    +      '@napi-rs/simple-git-win32-x64-msvc': 0.1.22
    +
       '@napi-rs/tar-android-arm-eabi@1.1.0':
         optional: true
     
    @@ -5967,40 +7314,34 @@ snapshots:
           '@napi-rs/wasm-tools-win32-ia32-msvc': 1.0.1
           '@napi-rs/wasm-tools-win32-x64-msvc': 1.0.1
     
    -  '@next/env@16.1.6': {}
    +  '@next/env@16.2.0': {}
     
    -  '@next/eslint-plugin-next@16.1.0':
    +  '@next/eslint-plugin-next@16.2.0':
         dependencies:
           fast-glob: 3.3.1
     
    -  '@next/mdx@16.1.6(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))':
    -    dependencies:
    -      source-map: 0.7.6
    -    optionalDependencies:
    -      '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.4)
    -
    -  '@next/swc-darwin-arm64@16.1.6':
    +  '@next/swc-darwin-arm64@16.2.0':
         optional: true
     
    -  '@next/swc-darwin-x64@16.1.6':
    +  '@next/swc-darwin-x64@16.2.0':
         optional: true
     
    -  '@next/swc-linux-arm64-gnu@16.1.6':
    +  '@next/swc-linux-arm64-gnu@16.2.0':
         optional: true
     
    -  '@next/swc-linux-arm64-musl@16.1.6':
    +  '@next/swc-linux-arm64-musl@16.2.0':
         optional: true
     
    -  '@next/swc-linux-x64-gnu@16.1.6':
    +  '@next/swc-linux-x64-gnu@16.2.0':
         optional: true
     
    -  '@next/swc-linux-x64-musl@16.1.6':
    +  '@next/swc-linux-x64-musl@16.2.0':
         optional: true
     
    -  '@next/swc-win32-arm64-msvc@16.1.6':
    +  '@next/swc-win32-arm64-msvc@16.2.0':
         optional: true
     
    -  '@next/swc-win32-x64-msvc@16.1.6':
    +  '@next/swc-win32-x64-msvc@16.2.0':
         optional: true
     
       '@nodelib/fs.scandir@2.1.5':
    @@ -6078,157 +7419,307 @@ snapshots:
         dependencies:
           '@octokit/openapi-types': 27.0.0
     
    -  '@oxc-project/types@0.114.0': {}
    +  '@ota-meshi/ast-token-store@0.3.0': {}
     
    -  '@pkgr/core@0.2.9': {}
    +  '@oxc-project/types@0.115.0': {}
     
    -  '@quansync/fs@1.0.0':
    -    dependencies:
    -      quansync: 1.0.0
    +  '@oxc-project/types@0.120.0': {}
     
    -  '@reduxjs/toolkit@2.11.2(react-redux@9.2.0(@types/react@19.2.14)(react@19.2.4)(redux@5.0.1))(react@19.2.4)':
    -    dependencies:
    -      '@standard-schema/spec': 1.1.0
    -      '@standard-schema/utils': 0.3.0
    -      immer: 11.1.4
    -      redux: 5.0.1
    -      redux-thunk: 3.1.0(redux@5.0.1)
    -      reselect: 5.1.1
    -    optionalDependencies:
    -      react: 19.2.4
    -      react-redux: 9.2.0(@types/react@19.2.14)(react@19.2.4)(redux@5.0.1)
    +  '@oxfmt/binding-android-arm-eabi@0.35.0':
    +    optional: true
     
    -  '@rolldown/binding-android-arm64@1.0.0-rc.5':
    +  '@oxfmt/binding-android-arm64@0.35.0':
         optional: true
     
    -  '@rolldown/binding-darwin-arm64@1.0.0-rc.5':
    +  '@oxfmt/binding-darwin-arm64@0.35.0':
         optional: true
     
    -  '@rolldown/binding-darwin-x64@1.0.0-rc.5':
    +  '@oxfmt/binding-darwin-x64@0.35.0':
         optional: true
     
    -  '@rolldown/binding-freebsd-x64@1.0.0-rc.5':
    +  '@oxfmt/binding-freebsd-x64@0.35.0':
         optional: true
     
    -  '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.5':
    +  '@oxfmt/binding-linux-arm-gnueabihf@0.35.0':
         optional: true
     
    -  '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.5':
    +  '@oxfmt/binding-linux-arm-musleabihf@0.35.0':
         optional: true
     
    -  '@rolldown/binding-linux-arm64-musl@1.0.0-rc.5':
    +  '@oxfmt/binding-linux-arm64-gnu@0.35.0':
         optional: true
     
    -  '@rolldown/binding-linux-x64-gnu@1.0.0-rc.5':
    +  '@oxfmt/binding-linux-arm64-musl@0.35.0':
         optional: true
     
    -  '@rolldown/binding-linux-x64-musl@1.0.0-rc.5':
    +  '@oxfmt/binding-linux-ppc64-gnu@0.35.0':
         optional: true
     
    -  '@rolldown/binding-openharmony-arm64@1.0.0-rc.5':
    +  '@oxfmt/binding-linux-riscv64-gnu@0.35.0':
         optional: true
     
    -  '@rolldown/binding-wasm32-wasi@1.0.0-rc.5':
    -    dependencies:
    -      '@napi-rs/wasm-runtime': 1.1.1
    +  '@oxfmt/binding-linux-riscv64-musl@0.35.0':
         optional: true
     
    -  '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.5':
    +  '@oxfmt/binding-linux-s390x-gnu@0.35.0':
         optional: true
     
    -  '@rolldown/binding-win32-x64-msvc@1.0.0-rc.5':
    +  '@oxfmt/binding-linux-x64-gnu@0.35.0':
         optional: true
     
    -  '@rolldown/pluginutils@1.0.0-rc.3': {}
    +  '@oxfmt/binding-linux-x64-musl@0.35.0':
    +    optional: true
     
    -  '@rolldown/pluginutils@1.0.0-rc.5': {}
    +  '@oxfmt/binding-openharmony-arm64@0.35.0':
    +    optional: true
     
    -  '@rollup/rollup-android-arm-eabi@4.59.0':
    +  '@oxfmt/binding-win32-arm64-msvc@0.35.0':
         optional: true
     
    -  '@rollup/rollup-android-arm64@4.59.0':
    +  '@oxfmt/binding-win32-ia32-msvc@0.35.0':
         optional: true
     
    -  '@rollup/rollup-darwin-arm64@4.59.0':
    +  '@oxfmt/binding-win32-x64-msvc@0.35.0':
         optional: true
     
    -  '@rollup/rollup-darwin-x64@4.59.0':
    +  '@pagefind/darwin-arm64@1.4.0':
         optional: true
     
    -  '@rollup/rollup-freebsd-arm64@4.59.0':
    +  '@pagefind/darwin-x64@1.4.0':
         optional: true
     
    -  '@rollup/rollup-freebsd-x64@4.59.0':
    +  '@pagefind/freebsd-x64@1.4.0':
         optional: true
     
    -  '@rollup/rollup-linux-arm-gnueabihf@4.59.0':
    +  '@pagefind/linux-arm64@1.4.0':
         optional: true
     
    -  '@rollup/rollup-linux-arm-musleabihf@4.59.0':
    +  '@pagefind/linux-x64@1.4.0':
         optional: true
     
    -  '@rollup/rollup-linux-arm64-gnu@4.59.0':
    +  '@pagefind/windows-x64@1.4.0':
         optional: true
     
    -  '@rollup/rollup-linux-arm64-musl@4.59.0':
    +  '@pkgr/core@0.2.9': {}
    +
    +  '@quansync/fs@1.0.0':
    +    dependencies:
    +      quansync: 1.0.0
    +
    +  '@react-aria/focus@3.21.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
    +    dependencies:
    +      '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
    +      '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
    +      '@react-types/shared': 3.33.1(react@19.2.4)
    +      '@swc/helpers': 0.5.15
    +      clsx: 2.1.1
    +      react: 19.2.4
    +      react-dom: 19.2.4(react@19.2.4)
    +
    +  '@react-aria/interactions@3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
    +    dependencies:
    +      '@react-aria/ssr': 3.9.10(react@19.2.4)
    +      '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
    +      '@react-stately/flags': 3.1.2
    +      '@react-types/shared': 3.33.1(react@19.2.4)
    +      '@swc/helpers': 0.5.15
    +      react: 19.2.4
    +      react-dom: 19.2.4(react@19.2.4)
    +
    +  '@react-aria/ssr@3.9.10(react@19.2.4)':
    +    dependencies:
    +      '@swc/helpers': 0.5.15
    +      react: 19.2.4
    +
    +  '@react-aria/utils@3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
    +    dependencies:
    +      '@react-aria/ssr': 3.9.10(react@19.2.4)
    +      '@react-stately/flags': 3.1.2
    +      '@react-stately/utils': 3.11.0(react@19.2.4)
    +      '@react-types/shared': 3.33.1(react@19.2.4)
    +      '@swc/helpers': 0.5.15
    +      clsx: 2.1.1
    +      react: 19.2.4
    +      react-dom: 19.2.4(react@19.2.4)
    +
    +  '@react-stately/flags@3.1.2':
    +    dependencies:
    +      '@swc/helpers': 0.5.15
    +
    +  '@react-stately/utils@3.11.0(react@19.2.4)':
    +    dependencies:
    +      '@swc/helpers': 0.5.15
    +      react: 19.2.4
    +
    +  '@react-types/shared@3.33.1(react@19.2.4)':
    +    dependencies:
    +      react: 19.2.4
    +
    +  '@reduxjs/toolkit@2.11.2(react-redux@9.2.0(@types/react@19.2.14)(react@19.2.4)(redux@5.0.1))(react@19.2.4)':
    +    dependencies:
    +      '@standard-schema/spec': 1.1.0
    +      '@standard-schema/utils': 0.3.0
    +      immer: 11.1.4
    +      redux: 5.0.1
    +      redux-thunk: 3.1.0(redux@5.0.1)
    +      reselect: 5.1.1
    +    optionalDependencies:
    +      react: 19.2.4
    +      react-redux: 9.2.0(@types/react@19.2.14)(react@19.2.4)(redux@5.0.1)
    +
    +  '@rolldown/binding-android-arm64@1.0.0-rc.10':
         optional: true
     
    -  '@rollup/rollup-linux-loong64-gnu@4.59.0':
    +  '@rolldown/binding-android-arm64@1.0.0-rc.9':
         optional: true
     
    -  '@rollup/rollup-linux-loong64-musl@4.59.0':
    +  '@rolldown/binding-darwin-arm64@1.0.0-rc.10':
         optional: true
     
    -  '@rollup/rollup-linux-ppc64-gnu@4.59.0':
    +  '@rolldown/binding-darwin-arm64@1.0.0-rc.9':
         optional: true
     
    -  '@rollup/rollup-linux-ppc64-musl@4.59.0':
    +  '@rolldown/binding-darwin-x64@1.0.0-rc.10':
         optional: true
     
    -  '@rollup/rollup-linux-riscv64-gnu@4.59.0':
    +  '@rolldown/binding-darwin-x64@1.0.0-rc.9':
         optional: true
     
    -  '@rollup/rollup-linux-riscv64-musl@4.59.0':
    +  '@rolldown/binding-freebsd-x64@1.0.0-rc.10':
         optional: true
     
    -  '@rollup/rollup-linux-s390x-gnu@4.59.0':
    +  '@rolldown/binding-freebsd-x64@1.0.0-rc.9':
         optional: true
     
    -  '@rollup/rollup-linux-x64-gnu@4.59.0':
    +  '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.10':
         optional: true
     
    -  '@rollup/rollup-linux-x64-musl@4.59.0':
    +  '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.9':
         optional: true
     
    -  '@rollup/rollup-openbsd-x64@4.59.0':
    +  '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.10':
         optional: true
     
    -  '@rollup/rollup-openharmony-arm64@4.59.0':
    +  '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.9':
         optional: true
     
    -  '@rollup/rollup-win32-arm64-msvc@4.59.0':
    +  '@rolldown/binding-linux-arm64-musl@1.0.0-rc.10':
         optional: true
     
    -  '@rollup/rollup-win32-ia32-msvc@4.59.0':
    +  '@rolldown/binding-linux-arm64-musl@1.0.0-rc.9':
         optional: true
     
    -  '@rollup/rollup-win32-x64-gnu@4.59.0':
    +  '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.10':
         optional: true
     
    -  '@rollup/rollup-win32-x64-msvc@4.59.0':
    +  '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.9':
         optional: true
     
    -  '@sindresorhus/base62@1.0.0': {}
    +  '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.10':
    +    optional: true
    +
    +  '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.9':
    +    optional: true
    +
    +  '@rolldown/binding-linux-x64-gnu@1.0.0-rc.10':
    +    optional: true
    +
    +  '@rolldown/binding-linux-x64-gnu@1.0.0-rc.9':
    +    optional: true
    +
    +  '@rolldown/binding-linux-x64-musl@1.0.0-rc.10':
    +    optional: true
    +
    +  '@rolldown/binding-linux-x64-musl@1.0.0-rc.9':
    +    optional: true
    +
    +  '@rolldown/binding-openharmony-arm64@1.0.0-rc.10':
    +    optional: true
    +
    +  '@rolldown/binding-openharmony-arm64@1.0.0-rc.9':
    +    optional: true
    +
    +  '@rolldown/binding-wasm32-wasi@1.0.0-rc.10':
    +    dependencies:
    +      '@napi-rs/wasm-runtime': 1.1.1
    +    optional: true
    +
    +  '@rolldown/binding-wasm32-wasi@1.0.0-rc.9':
    +    dependencies:
    +      '@napi-rs/wasm-runtime': 1.1.1
    +    optional: true
    +
    +  '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.10':
    +    optional: true
    +
    +  '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.9':
    +    optional: true
    +
    +  '@rolldown/binding-win32-x64-msvc@1.0.0-rc.10':
    +    optional: true
    +
    +  '@rolldown/binding-win32-x64-msvc@1.0.0-rc.9':
    +    optional: true
    +
    +  '@rolldown/pluginutils@1.0.0-rc.10': {}
    +
    +  '@rolldown/pluginutils@1.0.0-rc.7': {}
    +
    +  '@rolldown/pluginutils@1.0.0-rc.9': {}
    +
    +  '@shikijs/core@3.23.0':
    +    dependencies:
    +      '@shikijs/types': 3.23.0
    +      '@shikijs/vscode-textmate': 10.0.2
    +      '@types/hast': 3.0.4
    +      hast-util-to-html: 9.0.5
    +
    +  '@shikijs/engine-javascript@3.23.0':
    +    dependencies:
    +      '@shikijs/types': 3.23.0
    +      '@shikijs/vscode-textmate': 10.0.2
    +      oniguruma-to-es: 4.3.5
    +
    +  '@shikijs/engine-oniguruma@3.23.0':
    +    dependencies:
    +      '@shikijs/types': 3.23.0
    +      '@shikijs/vscode-textmate': 10.0.2
    +
    +  '@shikijs/langs@3.23.0':
    +    dependencies:
    +      '@shikijs/types': 3.23.0
    +
    +  '@shikijs/themes@3.23.0':
    +    dependencies:
    +      '@shikijs/types': 3.23.0
    +
    +  '@shikijs/twoslash@3.23.0(typescript@5.9.3)':
    +    dependencies:
    +      '@shikijs/core': 3.23.0
    +      '@shikijs/types': 3.23.0
    +      twoslash: 0.3.6(typescript@5.9.3)
    +      typescript: 5.9.3
    +    transitivePeerDependencies:
    +      - supports-color
    +
    +  '@shikijs/types@3.23.0':
    +    dependencies:
    +      '@shikijs/vscode-textmate': 10.0.2
    +      '@types/hast': 3.0.4
    +
    +  '@shikijs/vscode-textmate@10.0.2': {}
    +
    +  '@sindresorhus/base62@1.0.0': {}
     
       '@standard-schema/spec@1.1.0': {}
     
       '@standard-schema/utils@0.3.0': {}
     
    -  '@stylistic/eslint-plugin@5.9.0(eslint@10.0.2(jiti@2.6.1))':
    +  '@stylistic/eslint-plugin@5.10.0(eslint@10.0.3(jiti@2.6.1))':
         dependencies:
    -      '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.2(jiti@2.6.1))
    +      '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3(jiti@2.6.1))
           '@typescript-eslint/types': 8.56.1
    -      eslint: 10.0.2(jiti@2.6.1)
    +      eslint: 10.0.3(jiti@2.6.1)
           eslint-visitor-keys: 4.2.1
           espree: 10.4.0
           estraverse: 5.3.0
    @@ -6238,109 +7729,114 @@ snapshots:
         dependencies:
           tslib: 2.8.1
     
    -  '@tailwindcss/node@4.2.1':
    +  '@tailwindcss/node@4.2.2':
         dependencies:
           '@jridgewell/remapping': 2.3.5
           enhanced-resolve: 5.20.0
           jiti: 2.6.1
    -      lightningcss: 1.31.1
    +      lightningcss: 1.32.0
           magic-string: 0.30.21
           source-map-js: 1.2.1
    -      tailwindcss: 4.2.1
    +      tailwindcss: 4.2.2
     
    -  '@tailwindcss/oxide-android-arm64@4.2.1':
    +  '@tailwindcss/oxide-android-arm64@4.2.2':
         optional: true
     
    -  '@tailwindcss/oxide-darwin-arm64@4.2.1':
    +  '@tailwindcss/oxide-darwin-arm64@4.2.2':
         optional: true
     
    -  '@tailwindcss/oxide-darwin-x64@4.2.1':
    +  '@tailwindcss/oxide-darwin-x64@4.2.2':
         optional: true
     
    -  '@tailwindcss/oxide-freebsd-x64@4.2.1':
    +  '@tailwindcss/oxide-freebsd-x64@4.2.2':
         optional: true
     
    -  '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.1':
    +  '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2':
         optional: true
     
    -  '@tailwindcss/oxide-linux-arm64-gnu@4.2.1':
    +  '@tailwindcss/oxide-linux-arm64-gnu@4.2.2':
         optional: true
     
    -  '@tailwindcss/oxide-linux-arm64-musl@4.2.1':
    +  '@tailwindcss/oxide-linux-arm64-musl@4.2.2':
         optional: true
     
    -  '@tailwindcss/oxide-linux-x64-gnu@4.2.1':
    +  '@tailwindcss/oxide-linux-x64-gnu@4.2.2':
         optional: true
     
    -  '@tailwindcss/oxide-linux-x64-musl@4.2.1':
    +  '@tailwindcss/oxide-linux-x64-musl@4.2.2':
         optional: true
     
    -  '@tailwindcss/oxide-wasm32-wasi@4.2.1':
    +  '@tailwindcss/oxide-wasm32-wasi@4.2.2':
         optional: true
     
    -  '@tailwindcss/oxide-win32-arm64-msvc@4.2.1':
    +  '@tailwindcss/oxide-win32-arm64-msvc@4.2.2':
         optional: true
     
    -  '@tailwindcss/oxide-win32-x64-msvc@4.2.1':
    +  '@tailwindcss/oxide-win32-x64-msvc@4.2.2':
         optional: true
     
    -  '@tailwindcss/oxide@4.2.1':
    +  '@tailwindcss/oxide@4.2.2':
         optionalDependencies:
    -      '@tailwindcss/oxide-android-arm64': 4.2.1
    -      '@tailwindcss/oxide-darwin-arm64': 4.2.1
    -      '@tailwindcss/oxide-darwin-x64': 4.2.1
    -      '@tailwindcss/oxide-freebsd-x64': 4.2.1
    -      '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.1
    -      '@tailwindcss/oxide-linux-arm64-gnu': 4.2.1
    -      '@tailwindcss/oxide-linux-arm64-musl': 4.2.1
    -      '@tailwindcss/oxide-linux-x64-gnu': 4.2.1
    -      '@tailwindcss/oxide-linux-x64-musl': 4.2.1
    -      '@tailwindcss/oxide-wasm32-wasi': 4.2.1
    -      '@tailwindcss/oxide-win32-arm64-msvc': 4.2.1
    -      '@tailwindcss/oxide-win32-x64-msvc': 4.2.1
    -
    -  '@tailwindcss/vite@4.2.1(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2))':
    -    dependencies:
    -      '@tailwindcss/node': 4.2.1
    -      '@tailwindcss/oxide': 4.2.1
    -      tailwindcss: 4.2.1
    -      vite: 7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2)
    -
    -  '@tanstack/history@1.161.4': {}
    -
    -  '@tanstack/react-router@1.163.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
    -    dependencies:
    -      '@tanstack/history': 1.161.4
    -      '@tanstack/react-store': 0.9.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
    -      '@tanstack/router-core': 1.163.3
    +      '@tailwindcss/oxide-android-arm64': 4.2.2
    +      '@tailwindcss/oxide-darwin-arm64': 4.2.2
    +      '@tailwindcss/oxide-darwin-x64': 4.2.2
    +      '@tailwindcss/oxide-freebsd-x64': 4.2.2
    +      '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.2
    +      '@tailwindcss/oxide-linux-arm64-gnu': 4.2.2
    +      '@tailwindcss/oxide-linux-arm64-musl': 4.2.2
    +      '@tailwindcss/oxide-linux-x64-gnu': 4.2.2
    +      '@tailwindcss/oxide-linux-x64-musl': 4.2.2
    +      '@tailwindcss/oxide-wasm32-wasi': 4.2.2
    +      '@tailwindcss/oxide-win32-arm64-msvc': 4.2.2
    +      '@tailwindcss/oxide-win32-x64-msvc': 4.2.2
    +
    +  '@tailwindcss/vite@4.2.2(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))':
    +    dependencies:
    +      '@tailwindcss/node': 4.2.2
    +      '@tailwindcss/oxide': 4.2.2
    +      tailwindcss: 4.2.2
    +      vite: 8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)
    +
    +  '@tanstack/history@1.161.6': {}
    +
    +  '@tanstack/react-router@1.168.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
    +    dependencies:
    +      '@tanstack/history': 1.161.6
    +      '@tanstack/react-store': 0.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
    +      '@tanstack/router-core': 1.168.1
           isbot: 5.1.35
           react: 19.2.4
           react-dom: 19.2.4(react@19.2.4)
           tiny-invariant: 1.3.3
           tiny-warning: 1.0.3
     
    -  '@tanstack/react-store@0.9.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
    +  '@tanstack/react-store@0.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
         dependencies:
    -      '@tanstack/store': 0.9.1
    +      '@tanstack/store': 0.9.2
           react: 19.2.4
           react-dom: 19.2.4(react@19.2.4)
           use-sync-external-store: 1.6.0(react@19.2.4)
     
    -  '@tanstack/router-core@1.163.3':
    +  '@tanstack/react-virtual@3.13.23(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
    +    dependencies:
    +      '@tanstack/virtual-core': 3.13.23
    +      react: 19.2.4
    +      react-dom: 19.2.4(react@19.2.4)
    +
    +  '@tanstack/router-core@1.168.1':
         dependencies:
    -      '@tanstack/history': 1.161.4
    -      '@tanstack/store': 0.9.1
    +      '@tanstack/history': 1.161.6
           cookie-es: 2.0.0
           seroval: 1.5.0
           seroval-plugins: 1.5.0(seroval@1.5.0)
           tiny-invariant: 1.3.3
           tiny-warning: 1.0.3
     
    -  '@tanstack/router-generator@1.164.0':
    +  '@tanstack/router-generator@1.166.15':
         dependencies:
    -      '@tanstack/router-core': 1.163.3
    -      '@tanstack/router-utils': 1.161.4
    -      '@tanstack/virtual-file-routes': 1.161.4
    +      '@tanstack/router-core': 1.168.1
    +      '@tanstack/router-utils': 1.161.6
    +      '@tanstack/virtual-file-routes': 1.161.7
           prettier: 3.8.1
           recast: 0.23.11
           source-map: 0.7.6
    @@ -6349,7 +7845,7 @@ snapshots:
         transitivePeerDependencies:
           - supports-color
     
    -  '@tanstack/router-plugin@1.164.0(@tanstack/react-router@1.163.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2))':
    +  '@tanstack/router-plugin@1.167.1(@tanstack/react-router@1.168.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))':
         dependencies:
           '@babel/core': 7.29.0
           '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0)
    @@ -6357,20 +7853,20 @@ snapshots:
           '@babel/template': 7.28.6
           '@babel/traverse': 7.29.0
           '@babel/types': 7.29.0
    -      '@tanstack/router-core': 1.163.3
    -      '@tanstack/router-generator': 1.164.0
    -      '@tanstack/router-utils': 1.161.4
    -      '@tanstack/virtual-file-routes': 1.161.4
    +      '@tanstack/router-core': 1.168.1
    +      '@tanstack/router-generator': 1.166.15
    +      '@tanstack/router-utils': 1.161.6
    +      '@tanstack/virtual-file-routes': 1.161.7
           chokidar: 3.6.0
           unplugin: 2.3.11
           zod: 3.25.76
         optionalDependencies:
    -      '@tanstack/react-router': 1.163.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
    -      vite: 7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2)
    +      '@tanstack/react-router': 1.168.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
    +      vite: 8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)
         transitivePeerDependencies:
           - supports-color
     
    -  '@tanstack/router-utils@1.161.4':
    +  '@tanstack/router-utils@1.161.6':
         dependencies:
           '@babel/core': 7.29.0
           '@babel/generator': 7.29.1
    @@ -6384,58 +7880,60 @@ snapshots:
         transitivePeerDependencies:
           - supports-color
     
    -  '@tanstack/store@0.9.1': {}
    +  '@tanstack/store@0.9.2': {}
     
    -  '@tanstack/virtual-file-routes@1.161.4': {}
    +  '@tanstack/virtual-core@3.13.23': {}
    +
    +  '@tanstack/virtual-file-routes@1.161.7': {}
     
       '@tauri-apps/api@2.10.1': {}
     
    -  '@tauri-apps/cli-darwin-arm64@2.10.0':
    +  '@tauri-apps/cli-darwin-arm64@2.10.1':
         optional: true
     
    -  '@tauri-apps/cli-darwin-x64@2.10.0':
    +  '@tauri-apps/cli-darwin-x64@2.10.1':
         optional: true
     
    -  '@tauri-apps/cli-linux-arm-gnueabihf@2.10.0':
    +  '@tauri-apps/cli-linux-arm-gnueabihf@2.10.1':
         optional: true
     
    -  '@tauri-apps/cli-linux-arm64-gnu@2.10.0':
    +  '@tauri-apps/cli-linux-arm64-gnu@2.10.1':
         optional: true
     
    -  '@tauri-apps/cli-linux-arm64-musl@2.10.0':
    +  '@tauri-apps/cli-linux-arm64-musl@2.10.1':
         optional: true
     
    -  '@tauri-apps/cli-linux-riscv64-gnu@2.10.0':
    +  '@tauri-apps/cli-linux-riscv64-gnu@2.10.1':
         optional: true
     
    -  '@tauri-apps/cli-linux-x64-gnu@2.10.0':
    +  '@tauri-apps/cli-linux-x64-gnu@2.10.1':
         optional: true
     
    -  '@tauri-apps/cli-linux-x64-musl@2.10.0':
    +  '@tauri-apps/cli-linux-x64-musl@2.10.1':
         optional: true
     
    -  '@tauri-apps/cli-win32-arm64-msvc@2.10.0':
    +  '@tauri-apps/cli-win32-arm64-msvc@2.10.1':
         optional: true
     
    -  '@tauri-apps/cli-win32-ia32-msvc@2.10.0':
    +  '@tauri-apps/cli-win32-ia32-msvc@2.10.1':
         optional: true
     
    -  '@tauri-apps/cli-win32-x64-msvc@2.10.0':
    +  '@tauri-apps/cli-win32-x64-msvc@2.10.1':
         optional: true
     
    -  '@tauri-apps/cli@2.10.0':
    +  '@tauri-apps/cli@2.10.1':
         optionalDependencies:
    -      '@tauri-apps/cli-darwin-arm64': 2.10.0
    -      '@tauri-apps/cli-darwin-x64': 2.10.0
    -      '@tauri-apps/cli-linux-arm-gnueabihf': 2.10.0
    -      '@tauri-apps/cli-linux-arm64-gnu': 2.10.0
    -      '@tauri-apps/cli-linux-arm64-musl': 2.10.0
    -      '@tauri-apps/cli-linux-riscv64-gnu': 2.10.0
    -      '@tauri-apps/cli-linux-x64-gnu': 2.10.0
    -      '@tauri-apps/cli-linux-x64-musl': 2.10.0
    -      '@tauri-apps/cli-win32-arm64-msvc': 2.10.0
    -      '@tauri-apps/cli-win32-ia32-msvc': 2.10.0
    -      '@tauri-apps/cli-win32-x64-msvc': 2.10.0
    +      '@tauri-apps/cli-darwin-arm64': 2.10.1
    +      '@tauri-apps/cli-darwin-x64': 2.10.1
    +      '@tauri-apps/cli-linux-arm-gnueabihf': 2.10.1
    +      '@tauri-apps/cli-linux-arm64-gnu': 2.10.1
    +      '@tauri-apps/cli-linux-arm64-musl': 2.10.1
    +      '@tauri-apps/cli-linux-riscv64-gnu': 2.10.1
    +      '@tauri-apps/cli-linux-x64-gnu': 2.10.1
    +      '@tauri-apps/cli-linux-x64-musl': 2.10.1
    +      '@tauri-apps/cli-win32-arm64-msvc': 2.10.1
    +      '@tauri-apps/cli-win32-ia32-msvc': 2.10.1
    +      '@tauri-apps/cli-win32-x64-msvc': 2.10.1
     
       '@tauri-apps/plugin-shell@2.3.5':
         dependencies:
    @@ -6445,63 +7943,61 @@ snapshots:
         dependencies:
           '@tauri-apps/api': 2.10.1
     
    -  '@truenine/eslint10-config@2026.10209.11105(57cd6091d29b00e41b508df9848011ef)':
    -    dependencies:
    -      '@antfu/eslint-config': 6.7.1(@next/eslint-plugin-next@16.1.0)(@typescript-eslint/rule-tester@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.56.1(typescript@5.9.3))(@typescript-eslint/utils@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(@unocss/eslint-plugin@66.5.10(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.26)(eslint-plugin-format@1.1.0(eslint@10.0.2(jiti@2.6.1)))(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)(vitest@4.0.18(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2))
    -      '@eslint/js': 9.39.2
    -      '@next/eslint-plugin-next': 16.1.0
    -      '@unocss/eslint-config': 66.5.10(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      '@vue/eslint-config-prettier': 10.2.0(eslint@10.0.2(jiti@2.6.1))(prettier@3.8.1)
    -      '@vue/eslint-config-typescript': 14.6.0(eslint-plugin-vue@10.6.2(@stylistic/eslint-plugin@5.9.0(eslint@10.0.2(jiti@2.6.1)))(@typescript-eslint/parser@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.0.2(jiti@2.6.1))))(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      eslint: 10.0.2(jiti@2.6.1)
    -      eslint-plugin-format: 1.1.0(eslint@10.0.2(jiti@2.6.1))
    -      eslint-plugin-prettier: 5.5.4(eslint-config-prettier@10.1.8(eslint@10.0.2(jiti@2.6.1)))(eslint@10.0.2(jiti@2.6.1))(prettier@3.8.1)
    -      eslint-plugin-vue: 10.6.2(@stylistic/eslint-plugin@5.9.0(eslint@10.0.2(jiti@2.6.1)))(@typescript-eslint/parser@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.0.2(jiti@2.6.1)))
    -      prettier: 3.8.1
    -      typescript: 5.9.3
    -      typescript-eslint: 8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -
    -  '@truenine/eslint10-config@2026.10209.11105(e2101efea8a228b7e40cea5868468857)':
    -    dependencies:
    -      '@antfu/eslint-config': 6.7.1(@next/eslint-plugin-next@16.1.0)(@typescript-eslint/rule-tester@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.56.1(typescript@5.9.3))(@typescript-eslint/utils@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(@unocss/eslint-plugin@66.5.10(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.26)(eslint-plugin-format@1.1.0(eslint@10.0.2(jiti@2.6.1)))(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)(vitest@4.0.18(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2))
    -      '@eslint/js': 9.39.2
    -      '@next/eslint-plugin-next': 16.1.0
    -      '@unocss/eslint-config': 66.5.10(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      '@vue/eslint-config-prettier': 10.2.0(eslint@10.0.2(jiti@2.6.1))(prettier@3.8.1)
    -      '@vue/eslint-config-typescript': 14.6.0(eslint-plugin-vue@10.6.2(@stylistic/eslint-plugin@5.9.0(eslint@10.0.2(jiti@2.6.1)))(@typescript-eslint/parser@8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.0.2(jiti@2.6.1))))(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      eslint: 10.0.2(jiti@2.6.1)
    -      eslint-plugin-format: 1.1.0(eslint@10.0.2(jiti@2.6.1))
    -      eslint-plugin-prettier: 5.5.4(eslint-config-prettier@10.1.8(eslint@10.0.2(jiti@2.6.1)))(eslint@10.0.2(jiti@2.6.1))(prettier@3.8.1)
    -      eslint-plugin-vue: 10.6.2(@stylistic/eslint-plugin@5.9.0(eslint@10.0.2(jiti@2.6.1)))(@typescript-eslint/parser@8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.0.2(jiti@2.6.1)))
    +  '@theguild/remark-mermaid@0.3.0(react@19.2.4)':
    +    dependencies:
    +      mermaid: 11.13.0
    +      react: 19.2.4
    +      unist-util-visit: 5.1.0
    +
    +  '@theguild/remark-npm2yarn@0.3.3':
    +    dependencies:
    +      npm-to-yarn: 3.0.1
    +      unist-util-visit: 5.1.0
    +
    +  '@truenine/eslint10-config@2026.10318.10138(30aab4e6ca2f6a986fe995bf4241db33)':
    +    dependencies:
    +      '@antfu/eslint-config': 7.7.3(@next/eslint-plugin-next@16.2.0)(@typescript-eslint/rule-tester@8.56.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.57.1(typescript@5.9.3))(@typescript-eslint/utils@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(@unocss/eslint-plugin@66.6.7(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.26)(eslint-plugin-format@2.0.1(eslint@10.0.3(jiti@2.6.1)))(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)(vitest@4.1.0(@types/node@25.5.0)(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)))
    +      '@eslint/js': 10.0.1(eslint@10.0.3(jiti@2.6.1))
    +      '@next/eslint-plugin-next': 16.2.0
    +      '@unocss/eslint-config': 66.6.7(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
    +      '@vue/eslint-config-prettier': 10.2.0(eslint@10.0.3(jiti@2.6.1))(prettier@3.8.1)
    +      '@vue/eslint-config-typescript': 14.7.0(eslint-plugin-vue@10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.0.3(jiti@2.6.1)))(@typescript-eslint/parser@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.0.3(jiti@2.6.1))))(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
    +      eslint: 10.0.3(jiti@2.6.1)
    +      eslint-plugin-format: 2.0.1(eslint@10.0.3(jiti@2.6.1))
    +      eslint-plugin-prettier: 5.5.5(eslint-config-prettier@10.1.8(eslint@10.0.3(jiti@2.6.1)))(eslint@10.0.3(jiti@2.6.1))(prettier@3.8.1)
    +      eslint-plugin-vue: 10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.0.3(jiti@2.6.1)))(@typescript-eslint/parser@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.0.3(jiti@2.6.1)))
           prettier: 3.8.1
           typescript: 5.9.3
    -      typescript-eslint: 8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    +      typescript-eslint: 8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
     
    -  '@tybys/wasm-util@0.10.1':
    +  '@ts-morph/common@0.28.1':
         dependencies:
    -      tslib: 2.8.1
    +      minimatch: 10.2.4
    +      path-browserify: 1.0.1
    +      tinyglobby: 0.2.15
    +
    +  '@turbo/darwin-64@2.8.20':
         optional: true
     
    -  '@types/babel__core@7.20.5':
    -    dependencies:
    -      '@babel/parser': 7.29.0
    -      '@babel/types': 7.29.0
    -      '@types/babel__generator': 7.27.0
    -      '@types/babel__template': 7.4.4
    -      '@types/babel__traverse': 7.28.0
    +  '@turbo/darwin-arm64@2.8.20':
    +    optional: true
     
    -  '@types/babel__generator@7.27.0':
    -    dependencies:
    -      '@babel/types': 7.29.0
    +  '@turbo/linux-64@2.8.20':
    +    optional: true
     
    -  '@types/babel__template@7.4.4':
    -    dependencies:
    -      '@babel/parser': 7.29.0
    -      '@babel/types': 7.29.0
    +  '@turbo/linux-arm64@2.8.20':
    +    optional: true
     
    -  '@types/babel__traverse@7.28.0':
    +  '@turbo/windows-64@2.8.20':
    +    optional: true
    +
    +  '@turbo/windows-arm64@2.8.20':
    +    optional: true
    +
    +  '@tybys/wasm-util@0.10.1':
         dependencies:
    -      '@babel/types': 7.29.0
    +      tslib: 2.8.1
    +    optional: true
     
       '@types/chai@5.2.3':
         dependencies:
    @@ -6510,28 +8006,121 @@ snapshots:
     
       '@types/d3-array@3.2.2': {}
     
    +  '@types/d3-axis@3.0.6':
    +    dependencies:
    +      '@types/d3-selection': 3.0.11
    +
    +  '@types/d3-brush@3.0.6':
    +    dependencies:
    +      '@types/d3-selection': 3.0.11
    +
    +  '@types/d3-chord@3.0.6': {}
    +
       '@types/d3-color@3.1.3': {}
     
    +  '@types/d3-contour@3.0.6':
    +    dependencies:
    +      '@types/d3-array': 3.2.2
    +      '@types/geojson': 7946.0.16
    +
    +  '@types/d3-delaunay@6.0.4': {}
    +
    +  '@types/d3-dispatch@3.0.7': {}
    +
    +  '@types/d3-drag@3.0.7':
    +    dependencies:
    +      '@types/d3-selection': 3.0.11
    +
    +  '@types/d3-dsv@3.0.7': {}
    +
       '@types/d3-ease@3.0.2': {}
     
    +  '@types/d3-fetch@3.0.7':
    +    dependencies:
    +      '@types/d3-dsv': 3.0.7
    +
    +  '@types/d3-force@3.0.10': {}
    +
    +  '@types/d3-format@3.0.4': {}
    +
    +  '@types/d3-geo@3.1.0':
    +    dependencies:
    +      '@types/geojson': 7946.0.16
    +
    +  '@types/d3-hierarchy@3.1.7': {}
    +
       '@types/d3-interpolate@3.0.4':
         dependencies:
           '@types/d3-color': 3.1.3
     
       '@types/d3-path@3.1.1': {}
     
    +  '@types/d3-polygon@3.0.2': {}
    +
    +  '@types/d3-quadtree@3.0.6': {}
    +
    +  '@types/d3-random@3.0.3': {}
    +
    +  '@types/d3-scale-chromatic@3.1.0': {}
    +
       '@types/d3-scale@4.0.9':
         dependencies:
           '@types/d3-time': 3.0.4
     
    +  '@types/d3-selection@3.0.11': {}
    +
       '@types/d3-shape@3.1.8':
         dependencies:
           '@types/d3-path': 3.1.1
     
    +  '@types/d3-time-format@4.0.3': {}
    +
       '@types/d3-time@3.0.4': {}
     
       '@types/d3-timer@3.0.2': {}
     
    +  '@types/d3-transition@3.0.9':
    +    dependencies:
    +      '@types/d3-selection': 3.0.11
    +
    +  '@types/d3-zoom@3.0.8':
    +    dependencies:
    +      '@types/d3-interpolate': 3.0.4
    +      '@types/d3-selection': 3.0.11
    +
    +  '@types/d3@7.4.3':
    +    dependencies:
    +      '@types/d3-array': 3.2.2
    +      '@types/d3-axis': 3.0.6
    +      '@types/d3-brush': 3.0.6
    +      '@types/d3-chord': 3.0.6
    +      '@types/d3-color': 3.1.3
    +      '@types/d3-contour': 3.0.6
    +      '@types/d3-delaunay': 6.0.4
    +      '@types/d3-dispatch': 3.0.7
    +      '@types/d3-drag': 3.0.7
    +      '@types/d3-dsv': 3.0.7
    +      '@types/d3-ease': 3.0.2
    +      '@types/d3-fetch': 3.0.7
    +      '@types/d3-force': 3.0.10
    +      '@types/d3-format': 3.0.4
    +      '@types/d3-geo': 3.1.0
    +      '@types/d3-hierarchy': 3.1.7
    +      '@types/d3-interpolate': 3.0.4
    +      '@types/d3-path': 3.1.1
    +      '@types/d3-polygon': 3.0.2
    +      '@types/d3-quadtree': 3.0.6
    +      '@types/d3-random': 3.0.3
    +      '@types/d3-scale': 4.0.9
    +      '@types/d3-scale-chromatic': 3.1.0
    +      '@types/d3-selection': 3.0.11
    +      '@types/d3-shape': 3.1.8
    +      '@types/d3-time': 3.0.4
    +      '@types/d3-time-format': 4.0.3
    +      '@types/d3-timer': 3.0.2
    +      '@types/d3-transition': 3.0.9
    +      '@types/d3-zoom': 3.0.8
    +
       '@types/debug@4.1.12':
         dependencies:
           '@types/ms': 2.1.0
    @@ -6551,6 +8140,8 @@ snapshots:
           '@types/jsonfile': 6.1.4
           '@types/node': 25.3.3
     
    +  '@types/geojson@7946.0.16': {}
    +
       '@types/hast@3.0.4':
         dependencies:
           '@types/unist': 3.0.3
    @@ -6563,6 +8154,8 @@ snapshots:
         dependencies:
           '@types/node': 25.3.3
     
    +  '@types/katex@0.16.8': {}
    +
       '@types/mdast@4.0.4':
         dependencies:
           '@types/unist': 3.0.3
    @@ -6571,10 +8164,18 @@ snapshots:
     
       '@types/ms@2.1.0': {}
     
    +  '@types/nlcst@2.0.3':
    +    dependencies:
    +      '@types/unist': 3.0.3
    +
       '@types/node@25.3.3':
         dependencies:
           undici-types: 7.18.2
     
    +  '@types/node@25.5.0':
    +    dependencies:
    +      undici-types: 7.18.2
    +
       '@types/picomatch@4.0.2': {}
     
       '@types/react-dom@19.2.3(@types/react@19.2.14)':
    @@ -6594,15 +8195,15 @@ snapshots:
     
       '@types/use-sync-external-store@0.0.6': {}
     
    -  '@typescript-eslint/eslint-plugin@8.50.0(@typescript-eslint/parser@8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)':
    +  '@typescript-eslint/eslint-plugin@8.57.1(@typescript-eslint/parser@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)':
         dependencies:
           '@eslint-community/regexpp': 4.12.2
    -      '@typescript-eslint/parser': 8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      '@typescript-eslint/scope-manager': 8.50.0
    -      '@typescript-eslint/type-utils': 8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      '@typescript-eslint/utils': 8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      '@typescript-eslint/visitor-keys': 8.50.0
    -      eslint: 10.0.2(jiti@2.6.1)
    +      '@typescript-eslint/parser': 8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
    +      '@typescript-eslint/scope-manager': 8.57.1
    +      '@typescript-eslint/type-utils': 8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
    +      '@typescript-eslint/utils': 8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
    +      '@typescript-eslint/visitor-keys': 8.57.1
    +      eslint: 10.0.3(jiti@2.6.1)
           ignore: 7.0.5
           natural-compare: 1.4.0
           ts-api-utils: 2.4.0(typescript@5.9.3)
    @@ -6610,47 +8211,31 @@ snapshots:
         transitivePeerDependencies:
           - supports-color
     
    -  '@typescript-eslint/eslint-plugin@8.56.1(@typescript-eslint/parser@8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)':
    +  '@typescript-eslint/parser@8.56.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)':
         dependencies:
    -      '@eslint-community/regexpp': 4.12.2
    -      '@typescript-eslint/parser': 8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
           '@typescript-eslint/scope-manager': 8.56.1
    -      '@typescript-eslint/type-utils': 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      '@typescript-eslint/utils': 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    +      '@typescript-eslint/types': 8.56.1
    +      '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3)
           '@typescript-eslint/visitor-keys': 8.56.1
    -      eslint: 10.0.2(jiti@2.6.1)
    -      ignore: 7.0.5
    -      natural-compare: 1.4.0
    -      ts-api-utils: 2.4.0(typescript@5.9.3)
    -      typescript: 5.9.3
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@typescript-eslint/parser@8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)':
    -    dependencies:
    -      '@typescript-eslint/scope-manager': 8.50.0
    -      '@typescript-eslint/types': 8.50.0
    -      '@typescript-eslint/typescript-estree': 8.50.0(typescript@5.9.3)
    -      '@typescript-eslint/visitor-keys': 8.50.0
           debug: 4.4.3
    -      eslint: 10.0.2(jiti@2.6.1)
    +      eslint: 10.0.3(jiti@2.6.1)
           typescript: 5.9.3
         transitivePeerDependencies:
           - supports-color
     
    -  '@typescript-eslint/parser@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)':
    +  '@typescript-eslint/parser@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)':
         dependencies:
    -      '@typescript-eslint/scope-manager': 8.56.1
    -      '@typescript-eslint/types': 8.56.1
    -      '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3)
    -      '@typescript-eslint/visitor-keys': 8.56.1
    +      '@typescript-eslint/scope-manager': 8.57.1
    +      '@typescript-eslint/types': 8.57.1
    +      '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3)
    +      '@typescript-eslint/visitor-keys': 8.57.1
           debug: 4.4.3
    -      eslint: 10.0.2(jiti@2.6.1)
    +      eslint: 10.0.3(jiti@2.6.1)
           typescript: 5.9.3
         transitivePeerDependencies:
           - supports-color
     
    -  '@typescript-eslint/project-service@8.50.0(typescript@5.9.3)':
    +  '@typescript-eslint/project-service@8.56.1(typescript@5.9.3)':
         dependencies:
           '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@5.9.3)
           '@typescript-eslint/types': 8.56.1
    @@ -6659,22 +8244,22 @@ snapshots:
         transitivePeerDependencies:
           - supports-color
     
    -  '@typescript-eslint/project-service@8.56.1(typescript@5.9.3)':
    +  '@typescript-eslint/project-service@8.57.1(typescript@5.9.3)':
         dependencies:
    -      '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@5.9.3)
    -      '@typescript-eslint/types': 8.56.1
    +      '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@5.9.3)
    +      '@typescript-eslint/types': 8.57.1
           debug: 4.4.3
           typescript: 5.9.3
         transitivePeerDependencies:
           - supports-color
     
    -  '@typescript-eslint/rule-tester@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)':
    +  '@typescript-eslint/rule-tester@8.56.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)':
         dependencies:
    -      '@typescript-eslint/parser': 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    +      '@typescript-eslint/parser': 8.56.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
           '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3)
    -      '@typescript-eslint/utils': 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    +      '@typescript-eslint/utils': 8.56.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
           ajv: 6.14.0
    -      eslint: 10.0.2(jiti@2.6.1)
    +      eslint: 10.0.3(jiti@2.6.1)
           json-stable-stringify-without-jsonify: 1.0.1
           lodash.merge: 4.6.2
           semver: 7.7.4
    @@ -6682,66 +8267,39 @@ snapshots:
           - supports-color
           - typescript
     
    -  '@typescript-eslint/scope-manager@8.50.0':
    -    dependencies:
    -      '@typescript-eslint/types': 8.50.0
    -      '@typescript-eslint/visitor-keys': 8.50.0
    -
       '@typescript-eslint/scope-manager@8.56.1':
         dependencies:
           '@typescript-eslint/types': 8.56.1
           '@typescript-eslint/visitor-keys': 8.56.1
     
    -  '@typescript-eslint/tsconfig-utils@8.50.0(typescript@5.9.3)':
    +  '@typescript-eslint/scope-manager@8.57.1':
         dependencies:
    -      typescript: 5.9.3
    +      '@typescript-eslint/types': 8.57.1
    +      '@typescript-eslint/visitor-keys': 8.57.1
     
       '@typescript-eslint/tsconfig-utils@8.56.1(typescript@5.9.3)':
         dependencies:
           typescript: 5.9.3
     
    -  '@typescript-eslint/type-utils@8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)':
    +  '@typescript-eslint/tsconfig-utils@8.57.1(typescript@5.9.3)':
         dependencies:
    -      '@typescript-eslint/types': 8.50.0
    -      '@typescript-eslint/typescript-estree': 8.50.0(typescript@5.9.3)
    -      '@typescript-eslint/utils': 8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      debug: 4.4.3
    -      eslint: 10.0.2(jiti@2.6.1)
    -      ts-api-utils: 2.4.0(typescript@5.9.3)
           typescript: 5.9.3
    -    transitivePeerDependencies:
    -      - supports-color
     
    -  '@typescript-eslint/type-utils@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)':
    +  '@typescript-eslint/type-utils@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)':
         dependencies:
    -      '@typescript-eslint/types': 8.56.1
    -      '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3)
    -      '@typescript-eslint/utils': 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    +      '@typescript-eslint/types': 8.57.1
    +      '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3)
    +      '@typescript-eslint/utils': 8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
           debug: 4.4.3
    -      eslint: 10.0.2(jiti@2.6.1)
    +      eslint: 10.0.3(jiti@2.6.1)
           ts-api-utils: 2.4.0(typescript@5.9.3)
           typescript: 5.9.3
         transitivePeerDependencies:
           - supports-color
     
    -  '@typescript-eslint/types@8.50.0': {}
    -
       '@typescript-eslint/types@8.56.1': {}
     
    -  '@typescript-eslint/typescript-estree@8.50.0(typescript@5.9.3)':
    -    dependencies:
    -      '@typescript-eslint/project-service': 8.50.0(typescript@5.9.3)
    -      '@typescript-eslint/tsconfig-utils': 8.50.0(typescript@5.9.3)
    -      '@typescript-eslint/types': 8.50.0
    -      '@typescript-eslint/visitor-keys': 8.50.0
    -      debug: 4.4.3
    -      minimatch: 9.0.9
    -      semver: 7.7.4
    -      tinyglobby: 0.2.15
    -      ts-api-utils: 2.4.0(typescript@5.9.3)
    -      typescript: 5.9.3
    -    transitivePeerDependencies:
    -      - supports-color
    +  '@typescript-eslint/types@8.57.1': {}
     
       '@typescript-eslint/typescript-estree@8.56.1(typescript@5.9.3)':
         dependencies:
    @@ -6758,59 +8316,85 @@ snapshots:
         transitivePeerDependencies:
           - supports-color
     
    -  '@typescript-eslint/utils@8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)':
    +  '@typescript-eslint/typescript-estree@8.57.1(typescript@5.9.3)':
         dependencies:
    -      '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.2(jiti@2.6.1))
    -      '@typescript-eslint/scope-manager': 8.50.0
    -      '@typescript-eslint/types': 8.50.0
    -      '@typescript-eslint/typescript-estree': 8.50.0(typescript@5.9.3)
    -      eslint: 10.0.2(jiti@2.6.1)
    +      '@typescript-eslint/project-service': 8.57.1(typescript@5.9.3)
    +      '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@5.9.3)
    +      '@typescript-eslint/types': 8.57.1
    +      '@typescript-eslint/visitor-keys': 8.57.1
    +      debug: 4.4.3
    +      minimatch: 10.2.4
    +      semver: 7.7.4
    +      tinyglobby: 0.2.15
    +      ts-api-utils: 2.4.0(typescript@5.9.3)
           typescript: 5.9.3
         transitivePeerDependencies:
           - supports-color
     
    -  '@typescript-eslint/utils@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)':
    +  '@typescript-eslint/utils@8.56.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)':
         dependencies:
    -      '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.2(jiti@2.6.1))
    +      '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3(jiti@2.6.1))
           '@typescript-eslint/scope-manager': 8.56.1
           '@typescript-eslint/types': 8.56.1
           '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3)
    -      eslint: 10.0.2(jiti@2.6.1)
    +      eslint: 10.0.3(jiti@2.6.1)
           typescript: 5.9.3
         transitivePeerDependencies:
           - supports-color
     
    -  '@typescript-eslint/visitor-keys@8.50.0':
    +  '@typescript-eslint/utils@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)':
         dependencies:
    -      '@typescript-eslint/types': 8.50.0
    -      eslint-visitor-keys: 4.2.1
    +      '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3(jiti@2.6.1))
    +      '@typescript-eslint/scope-manager': 8.57.1
    +      '@typescript-eslint/types': 8.57.1
    +      '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3)
    +      eslint: 10.0.3(jiti@2.6.1)
    +      typescript: 5.9.3
    +    transitivePeerDependencies:
    +      - supports-color
     
       '@typescript-eslint/visitor-keys@8.56.1':
         dependencies:
           '@typescript-eslint/types': 8.56.1
           eslint-visitor-keys: 5.0.1
     
    -  '@unocss/config@66.5.10':
    +  '@typescript-eslint/visitor-keys@8.57.1':
    +    dependencies:
    +      '@typescript-eslint/types': 8.57.1
    +      eslint-visitor-keys: 5.0.1
    +
    +  '@typescript/vfs@1.6.4(typescript@5.9.3)':
    +    dependencies:
    +      debug: 4.4.3
    +      typescript: 5.9.3
    +    transitivePeerDependencies:
    +      - supports-color
    +
    +  '@ungap/structured-clone@1.3.0': {}
    +
    +  '@unocss/config@66.6.7':
         dependencies:
    -      '@unocss/core': 66.5.10
    +      '@unocss/core': 66.6.7
    +      colorette: 2.0.20
    +      consola: 3.4.2
           unconfig: 7.5.0
     
    -  '@unocss/core@66.5.10': {}
    +  '@unocss/core@66.6.7': {}
     
    -  '@unocss/eslint-config@66.5.10(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)':
    +  '@unocss/eslint-config@66.6.7(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)':
         dependencies:
    -      '@unocss/eslint-plugin': 66.5.10(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    +      '@unocss/eslint-plugin': 66.6.7(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
         transitivePeerDependencies:
           - eslint
           - supports-color
           - typescript
     
    -  '@unocss/eslint-plugin@66.5.10(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)':
    +  '@unocss/eslint-plugin@66.6.7(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)':
         dependencies:
    -      '@typescript-eslint/utils': 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      '@unocss/config': 66.5.10
    -      '@unocss/core': 66.5.10
    -      '@unocss/rule-utils': 66.5.10
    +      '@typescript-eslint/utils': 8.56.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
    +      '@unocss/config': 66.6.7
    +      '@unocss/core': 66.6.7
    +      '@unocss/rule-utils': 66.6.7
           magic-string: 0.30.21
           synckit: 0.11.12
         transitivePeerDependencies:
    @@ -6818,85 +8402,85 @@ snapshots:
           - supports-color
           - typescript
     
    -  '@unocss/rule-utils@66.5.10':
    +  '@unocss/rule-utils@66.6.7':
         dependencies:
    -      '@unocss/core': 66.5.10
    +      '@unocss/core': 66.6.7
           magic-string: 0.30.21
     
    -  '@vitejs/plugin-react@5.1.4(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2))':
    +  '@upsetjs/venn.js@2.0.0':
    +    optionalDependencies:
    +      d3-selection: 3.0.0
    +      d3-transition: 3.0.1(d3-selection@3.0.0)
    +
    +  '@vitejs/plugin-react@6.0.1(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))':
         dependencies:
    -      '@babel/core': 7.29.0
    -      '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0)
    -      '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0)
    -      '@rolldown/pluginutils': 1.0.0-rc.3
    -      '@types/babel__core': 7.20.5
    -      react-refresh: 0.18.0
    -      vite: 7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2)
    -    transitivePeerDependencies:
    -      - supports-color
    +      '@rolldown/pluginutils': 1.0.0-rc.7
    +      vite: 8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)
     
    -  '@vitest/coverage-v8@4.0.18(vitest@4.0.18(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2))':
    +  '@vitest/coverage-v8@4.1.0(vitest@4.1.0(@types/node@25.5.0)(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)))':
         dependencies:
           '@bcoe/v8-coverage': 1.0.2
    -      '@vitest/utils': 4.0.18
    -      ast-v8-to-istanbul: 0.3.12
    +      '@vitest/utils': 4.1.0
    +      ast-v8-to-istanbul: 1.0.0
           istanbul-lib-coverage: 3.2.2
           istanbul-lib-report: 3.0.1
           istanbul-reports: 3.2.0
           magicast: 0.5.2
           obug: 2.1.1
    -      std-env: 3.10.0
    +      std-env: 4.0.0
           tinyrainbow: 3.0.3
    -      vitest: 4.0.18(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2)
    +      vitest: 4.1.0(@types/node@25.5.0)(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))
     
    -  '@vitest/eslint-plugin@1.6.9(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)(vitest@4.0.18(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2))':
    +  '@vitest/eslint-plugin@1.6.12(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)(vitest@4.1.0(@types/node@25.5.0)(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)))':
         dependencies:
           '@typescript-eslint/scope-manager': 8.56.1
    -      '@typescript-eslint/utils': 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      eslint: 10.0.2(jiti@2.6.1)
    +      '@typescript-eslint/utils': 8.56.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
    +      eslint: 10.0.3(jiti@2.6.1)
         optionalDependencies:
           typescript: 5.9.3
    -      vitest: 4.0.18(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2)
    +      vitest: 4.1.0(@types/node@25.5.0)(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))
         transitivePeerDependencies:
           - supports-color
     
    -  '@vitest/expect@4.0.18':
    +  '@vitest/expect@4.1.0':
         dependencies:
           '@standard-schema/spec': 1.1.0
           '@types/chai': 5.2.3
    -      '@vitest/spy': 4.0.18
    -      '@vitest/utils': 4.0.18
    +      '@vitest/spy': 4.1.0
    +      '@vitest/utils': 4.1.0
           chai: 6.2.2
           tinyrainbow: 3.0.3
     
    -  '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2))':
    +  '@vitest/mocker@4.1.0(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))':
         dependencies:
    -      '@vitest/spy': 4.0.18
    +      '@vitest/spy': 4.1.0
           estree-walker: 3.0.3
           magic-string: 0.30.21
         optionalDependencies:
    -      vite: 7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2)
    +      vite: 8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)
     
    -  '@vitest/pretty-format@4.0.18':
    +  '@vitest/pretty-format@4.1.0':
         dependencies:
           tinyrainbow: 3.0.3
     
    -  '@vitest/runner@4.0.18':
    +  '@vitest/runner@4.1.0':
         dependencies:
    -      '@vitest/utils': 4.0.18
    +      '@vitest/utils': 4.1.0
           pathe: 2.0.3
     
    -  '@vitest/snapshot@4.0.18':
    +  '@vitest/snapshot@4.1.0':
         dependencies:
    -      '@vitest/pretty-format': 4.0.18
    +      '@vitest/pretty-format': 4.1.0
    +      '@vitest/utils': 4.1.0
           magic-string: 0.30.21
           pathe: 2.0.3
     
    -  '@vitest/spy@4.0.18': {}
    +  '@vitest/spy@4.1.0': {}
     
    -  '@vitest/utils@4.0.18':
    +  '@vitest/utils@4.1.0':
         dependencies:
    -      '@vitest/pretty-format': 4.0.18
    +      '@vitest/pretty-format': 4.1.0
    +      convert-source-map: 2.0.0
           tinyrainbow: 3.0.3
     
       '@vue/compiler-core@3.5.26':
    @@ -6921,7 +8505,7 @@ snapshots:
           '@vue/shared': 3.5.26
           estree-walker: 2.0.2
           magic-string: 0.30.21
    -      postcss: 8.5.6
    +      postcss: 8.5.8
           source-map-js: 1.2.1
     
       '@vue/compiler-ssr@3.5.26':
    @@ -6929,36 +8513,23 @@ snapshots:
           '@vue/compiler-dom': 3.5.26
           '@vue/shared': 3.5.26
     
    -  '@vue/eslint-config-prettier@10.2.0(eslint@10.0.2(jiti@2.6.1))(prettier@3.8.1)':
    +  '@vue/eslint-config-prettier@10.2.0(eslint@10.0.3(jiti@2.6.1))(prettier@3.8.1)':
         dependencies:
    -      eslint: 10.0.2(jiti@2.6.1)
    -      eslint-config-prettier: 10.1.8(eslint@10.0.2(jiti@2.6.1))
    -      eslint-plugin-prettier: 5.5.4(eslint-config-prettier@10.1.8(eslint@10.0.2(jiti@2.6.1)))(eslint@10.0.2(jiti@2.6.1))(prettier@3.8.1)
    +      eslint: 10.0.3(jiti@2.6.1)
    +      eslint-config-prettier: 10.1.8(eslint@10.0.3(jiti@2.6.1))
    +      eslint-plugin-prettier: 5.5.5(eslint-config-prettier@10.1.8(eslint@10.0.3(jiti@2.6.1)))(eslint@10.0.3(jiti@2.6.1))(prettier@3.8.1)
           prettier: 3.8.1
         transitivePeerDependencies:
           - '@types/eslint'
     
    -  '@vue/eslint-config-typescript@14.6.0(eslint-plugin-vue@10.6.2(@stylistic/eslint-plugin@5.9.0(eslint@10.0.2(jiti@2.6.1)))(@typescript-eslint/parser@8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.0.2(jiti@2.6.1))))(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)':
    -    dependencies:
    -      '@typescript-eslint/utils': 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      eslint: 10.0.2(jiti@2.6.1)
    -      eslint-plugin-vue: 10.6.2(@stylistic/eslint-plugin@5.9.0(eslint@10.0.2(jiti@2.6.1)))(@typescript-eslint/parser@8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.0.2(jiti@2.6.1)))
    -      fast-glob: 3.3.3
    -      typescript-eslint: 8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      vue-eslint-parser: 10.4.0(eslint@10.0.2(jiti@2.6.1))
    -    optionalDependencies:
    -      typescript: 5.9.3
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@vue/eslint-config-typescript@14.6.0(eslint-plugin-vue@10.6.2(@stylistic/eslint-plugin@5.9.0(eslint@10.0.2(jiti@2.6.1)))(@typescript-eslint/parser@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.0.2(jiti@2.6.1))))(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)':
    +  '@vue/eslint-config-typescript@14.7.0(eslint-plugin-vue@10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.0.3(jiti@2.6.1)))(@typescript-eslint/parser@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.0.3(jiti@2.6.1))))(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)':
         dependencies:
    -      '@typescript-eslint/utils': 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      eslint: 10.0.2(jiti@2.6.1)
    -      eslint-plugin-vue: 10.6.2(@stylistic/eslint-plugin@5.9.0(eslint@10.0.2(jiti@2.6.1)))(@typescript-eslint/parser@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.0.2(jiti@2.6.1)))
    +      '@typescript-eslint/utils': 8.56.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
    +      eslint: 10.0.3(jiti@2.6.1)
    +      eslint-plugin-vue: 10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.0.3(jiti@2.6.1)))(@typescript-eslint/parser@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.0.3(jiti@2.6.1)))
           fast-glob: 3.3.3
    -      typescript-eslint: 8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      vue-eslint-parser: 10.4.0(eslint@10.0.2(jiti@2.6.1))
    +      typescript-eslint: 8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
    +      vue-eslint-parser: 10.4.0(eslint@10.0.3(jiti@2.6.1))
         optionalDependencies:
           typescript: 5.9.3
         transitivePeerDependencies:
    @@ -6966,6 +8537,8 @@ snapshots:
     
       '@vue/shared@3.5.26': {}
     
    +  '@xmldom/xmldom@0.9.8': {}
    +
       accepts@2.0.0:
         dependencies:
           mime-types: 3.0.2
    @@ -7006,13 +8579,17 @@ snapshots:
     
       are-docs-informative@0.0.2: {}
     
    +  arg@5.0.2: {}
    +
       argparse@2.0.1: {}
     
    +  array-iterate@2.0.1: {}
    +
       assertion-error@2.0.1: {}
     
       ast-kit@3.0.0-beta.1:
         dependencies:
    -      '@babel/parser': 8.0.0-rc.1
    +      '@babel/parser': 8.0.0-rc.2
           estree-walker: 3.0.3
           pathe: 2.0.3
     
    @@ -7020,12 +8597,14 @@ snapshots:
         dependencies:
           tslib: 2.8.1
     
    -  ast-v8-to-istanbul@0.3.12:
    +  ast-v8-to-istanbul@1.0.0:
         dependencies:
           '@jridgewell/trace-mapping': 0.3.31
           estree-walker: 3.0.3
           js-tokens: 10.0.0
     
    +  astring@1.9.0: {}
    +
       babel-dead-code-elimination@1.0.12:
         dependencies:
           '@babel/core': 7.29.0
    @@ -7037,14 +8616,17 @@ snapshots:
     
       bail@2.0.2: {}
     
    -  balanced-match@1.0.2: {}
    -
       balanced-match@4.0.4: {}
     
       baseline-browser-mapping@2.10.0: {}
     
       before-after-hook@4.0.0: {}
     
    +  better-react-mathjax@2.3.0(react@19.2.4):
    +    dependencies:
    +      mathjax-full: 3.2.2
    +      react: 19.2.4
    +
       binary-extensions@2.3.0: {}
     
       birpc@4.0.0: {}
    @@ -7065,10 +8647,6 @@ snapshots:
     
       boolbase@1.0.0: {}
     
    -  brace-expansion@2.0.2:
    -    dependencies:
    -      balanced-match: 1.0.2
    -
       brace-expansion@5.0.4:
         dependencies:
           balanced-match: 4.0.4
    @@ -7089,7 +8667,7 @@ snapshots:
     
       bytes@3.1.2: {}
     
    -  cac@6.7.14: {}
    +  cac@7.0.0: {}
     
       call-bind-apply-helpers@1.0.2:
         dependencies:
    @@ -7107,6 +8685,8 @@ snapshots:
     
       chai@6.2.2: {}
     
    +  chalk@5.6.2: {}
    +
       change-case@5.4.4: {}
     
       character-entities-html4@2.1.0: {}
    @@ -7119,6 +8699,20 @@ snapshots:
     
       chardet@2.1.1: {}
     
    +  chevrotain-allstar@0.3.1(chevrotain@11.1.2):
    +    dependencies:
    +      chevrotain: 11.1.2
    +      lodash-es: 4.17.23
    +
    +  chevrotain@11.1.2:
    +    dependencies:
    +      '@chevrotain/cst-dts-gen': 11.1.2
    +      '@chevrotain/gast': 11.1.2
    +      '@chevrotain/regexp-to-ast': 11.1.2
    +      '@chevrotain/types': 11.1.2
    +      '@chevrotain/utils': 11.1.2
    +      lodash-es: 4.17.23
    +
       chokidar@3.6.0:
         dependencies:
           anymatch: 3.1.3
    @@ -7151,18 +8745,38 @@ snapshots:
         dependencies:
           typanion: 3.14.0
     
    +  clipboardy@4.0.0:
    +    dependencies:
    +      execa: 8.0.1
    +      is-wsl: 3.1.1
    +      is64bit: 2.0.0
    +
       clsx@2.1.1: {}
     
    +  code-block-writer@13.0.3: {}
    +
    +  collapse-white-space@2.1.0: {}
    +
       colorette@2.0.20: {}
     
    -  comment-parser@1.4.1: {}
    +  comma-separated-tokens@2.0.3: {}
    +
    +  commander@13.1.0: {}
    +
    +  commander@7.2.0: {}
    +
    +  commander@8.3.0: {}
     
       comment-parser@1.4.5: {}
     
    +  compute-scroll-into-view@3.1.1: {}
    +
       confbox@0.1.8: {}
     
       confbox@0.2.4: {}
     
    +  consola@3.4.2: {}
    +
       content-disposition@1.0.1: {}
     
       content-type@1.0.5: {}
    @@ -7184,6 +8798,14 @@ snapshots:
           object-assign: 4.1.1
           vary: 1.1.2
     
    +  cose-base@1.0.3:
    +    dependencies:
    +      layout-base: 1.0.2
    +
    +  cose-base@2.2.0:
    +    dependencies:
    +      layout-base: 2.0.1
    +
       cross-spawn@7.0.6:
         dependencies:
           path-key: 3.1.1
    @@ -7194,21 +8816,106 @@ snapshots:
     
       csstype@3.2.3: {}
     
    +  cytoscape-cose-bilkent@4.1.0(cytoscape@3.33.1):
    +    dependencies:
    +      cose-base: 1.0.3
    +      cytoscape: 3.33.1
    +
    +  cytoscape-fcose@2.2.0(cytoscape@3.33.1):
    +    dependencies:
    +      cose-base: 2.2.0
    +      cytoscape: 3.33.1
    +
    +  cytoscape@3.33.1: {}
    +
    +  d3-array@2.12.1:
    +    dependencies:
    +      internmap: 1.0.1
    +
       d3-array@3.2.4:
         dependencies:
           internmap: 2.0.3
     
    -  d3-color@3.1.0: {}
    +  d3-axis@3.0.0: {}
    +
    +  d3-brush@3.0.0:
    +    dependencies:
    +      d3-dispatch: 3.0.1
    +      d3-drag: 3.0.0
    +      d3-interpolate: 3.0.1
    +      d3-selection: 3.0.0
    +      d3-transition: 3.0.1(d3-selection@3.0.0)
    +
    +  d3-chord@3.0.1:
    +    dependencies:
    +      d3-path: 3.1.0
    +
    +  d3-color@3.1.0: {}
    +
    +  d3-contour@4.0.2:
    +    dependencies:
    +      d3-array: 3.2.4
    +
    +  d3-delaunay@6.0.4:
    +    dependencies:
    +      delaunator: 5.0.1
    +
    +  d3-dispatch@3.0.1: {}
    +
    +  d3-drag@3.0.0:
    +    dependencies:
    +      d3-dispatch: 3.0.1
    +      d3-selection: 3.0.0
    +
    +  d3-dsv@3.0.1:
    +    dependencies:
    +      commander: 7.2.0
    +      iconv-lite: 0.6.3
    +      rw: 1.3.3
    +
    +  d3-ease@3.0.1: {}
    +
    +  d3-fetch@3.0.1:
    +    dependencies:
    +      d3-dsv: 3.0.1
    +
    +  d3-force@3.0.0:
    +    dependencies:
    +      d3-dispatch: 3.0.1
    +      d3-quadtree: 3.0.1
    +      d3-timer: 3.0.1
    +
    +  d3-format@3.1.2: {}
    +
    +  d3-geo@3.1.1:
    +    dependencies:
    +      d3-array: 3.2.4
    +
    +  d3-hierarchy@3.1.2: {}
    +
    +  d3-interpolate@3.0.1:
    +    dependencies:
    +      d3-color: 3.1.0
    +
    +  d3-path@1.0.9: {}
    +
    +  d3-path@3.1.0: {}
    +
    +  d3-polygon@3.0.1: {}
     
    -  d3-ease@3.0.1: {}
    +  d3-quadtree@3.0.1: {}
     
    -  d3-format@3.1.2: {}
    +  d3-random@3.0.1: {}
     
    -  d3-interpolate@3.0.1:
    +  d3-sankey@0.12.3:
         dependencies:
    -      d3-color: 3.1.0
    +      d3-array: 2.12.1
    +      d3-shape: 1.3.7
     
    -  d3-path@3.1.0: {}
    +  d3-scale-chromatic@3.1.0:
    +    dependencies:
    +      d3-color: 3.1.0
    +      d3-interpolate: 3.0.1
     
       d3-scale@4.0.2:
         dependencies:
    @@ -7218,6 +8925,12 @@ snapshots:
           d3-time: 3.1.0
           d3-time-format: 4.1.0
     
    +  d3-selection@3.0.0: {}
    +
    +  d3-shape@1.3.7:
    +    dependencies:
    +      d3-path: 1.0.9
    +
       d3-shape@3.2.0:
         dependencies:
           d3-path: 3.1.0
    @@ -7232,6 +8945,63 @@ snapshots:
     
       d3-timer@3.0.1: {}
     
    +  d3-transition@3.0.1(d3-selection@3.0.0):
    +    dependencies:
    +      d3-color: 3.1.0
    +      d3-dispatch: 3.0.1
    +      d3-ease: 3.0.1
    +      d3-interpolate: 3.0.1
    +      d3-selection: 3.0.0
    +      d3-timer: 3.0.1
    +
    +  d3-zoom@3.0.0:
    +    dependencies:
    +      d3-dispatch: 3.0.1
    +      d3-drag: 3.0.0
    +      d3-interpolate: 3.0.1
    +      d3-selection: 3.0.0
    +      d3-transition: 3.0.1(d3-selection@3.0.0)
    +
    +  d3@7.9.0:
    +    dependencies:
    +      d3-array: 3.2.4
    +      d3-axis: 3.0.0
    +      d3-brush: 3.0.0
    +      d3-chord: 3.0.1
    +      d3-color: 3.1.0
    +      d3-contour: 4.0.2
    +      d3-delaunay: 6.0.4
    +      d3-dispatch: 3.0.1
    +      d3-drag: 3.0.0
    +      d3-dsv: 3.0.1
    +      d3-ease: 3.0.1
    +      d3-fetch: 3.0.1
    +      d3-force: 3.0.0
    +      d3-format: 3.1.2
    +      d3-geo: 3.1.1
    +      d3-hierarchy: 3.1.2
    +      d3-interpolate: 3.0.1
    +      d3-path: 3.1.0
    +      d3-polygon: 3.0.1
    +      d3-quadtree: 3.0.1
    +      d3-random: 3.0.1
    +      d3-scale: 4.0.2
    +      d3-scale-chromatic: 3.1.0
    +      d3-selection: 3.0.0
    +      d3-shape: 3.2.0
    +      d3-time: 3.1.0
    +      d3-time-format: 4.1.0
    +      d3-timer: 3.0.1
    +      d3-transition: 3.0.1(d3-selection@3.0.0)
    +      d3-zoom: 3.0.0
    +
    +  dagre-d3-es@7.0.14:
    +    dependencies:
    +      d3: 7.9.0
    +      lodash-es: 4.17.23
    +
    +  dayjs@1.11.20: {}
    +
       debug@4.4.3:
         dependencies:
           ms: 2.1.3
    @@ -7251,6 +9021,10 @@ snapshots:
     
       defu@6.1.4: {}
     
    +  delaunator@5.0.1:
    +    dependencies:
    +      robust-predicates: 3.0.2
    +
       depd@2.0.0: {}
     
       dequal@2.0.3: {}
    @@ -7261,7 +9035,7 @@ snapshots:
         dependencies:
           dequal: 2.0.3
     
    -  diff-sequences@27.5.1: {}
    +  diff-sequences@29.6.3: {}
     
       diff@8.0.3: {}
     
    @@ -7269,6 +9043,10 @@ snapshots:
         optionalDependencies:
           '@types/trusted-types': 2.0.7
     
    +  dompurify@3.3.3:
    +    optionalDependencies:
    +      '@types/trusted-types': 2.0.7
    +
       dts-resolver@2.1.3: {}
     
       dunder-proto@1.0.1:
    @@ -7292,13 +9070,15 @@ snapshots:
           graceful-fs: 4.2.11
           tapable: 2.3.0
     
    +  entities@6.0.1: {}
    +
       entities@7.0.1: {}
     
       es-define-property@1.0.1: {}
     
       es-errors@1.3.0: {}
     
    -  es-module-lexer@1.7.0: {}
    +  es-module-lexer@2.0.0: {}
     
       es-object-atoms@1.1.1:
         dependencies:
    @@ -7306,6 +9086,20 @@ snapshots:
     
       es-toolkit@1.44.0: {}
     
    +  esast-util-from-estree@2.0.0:
    +    dependencies:
    +      '@types/estree-jsx': 1.0.5
    +      devlop: 1.1.0
    +      estree-util-visit: 2.0.0
    +      unist-util-position-from-estree: 2.0.0
    +
    +  esast-util-from-js@2.0.1:
    +    dependencies:
    +      '@types/estree-jsx': 1.0.5
    +      acorn: 8.16.0
    +      esast-util-from-estree: 2.0.0
    +      vfile-message: 4.0.3
    +
       esbuild@0.27.3:
         optionalDependencies:
           '@esbuild/aix-ppc64': 0.27.3
    @@ -7345,91 +9139,94 @@ snapshots:
     
       escape-string-regexp@5.0.0: {}
     
    -  eslint-compat-utils@0.5.1(eslint@10.0.2(jiti@2.6.1)):
    -    dependencies:
    -      eslint: 10.0.2(jiti@2.6.1)
    -      semver: 7.7.4
    -
    -  eslint-compat-utils@0.6.5(eslint@10.0.2(jiti@2.6.1)):
    +  eslint-compat-utils@0.5.1(eslint@10.0.3(jiti@2.6.1)):
         dependencies:
    -      eslint: 10.0.2(jiti@2.6.1)
    +      eslint: 10.0.3(jiti@2.6.1)
           semver: 7.7.4
     
    -  eslint-config-flat-gitignore@2.2.1(eslint@10.0.2(jiti@2.6.1)):
    +  eslint-config-flat-gitignore@2.2.1(eslint@10.0.3(jiti@2.6.1)):
         dependencies:
    -      '@eslint/compat': 2.0.2(eslint@10.0.2(jiti@2.6.1))
    -      eslint: 10.0.2(jiti@2.6.1)
    +      '@eslint/compat': 2.0.2(eslint@10.0.3(jiti@2.6.1))
    +      eslint: 10.0.3(jiti@2.6.1)
     
    -  eslint-config-prettier@10.1.8(eslint@10.0.2(jiti@2.6.1)):
    +  eslint-config-prettier@10.1.8(eslint@10.0.3(jiti@2.6.1)):
         dependencies:
    -      eslint: 10.0.2(jiti@2.6.1)
    +      eslint: 10.0.3(jiti@2.6.1)
     
    -  eslint-flat-config-utils@2.1.4:
    +  eslint-flat-config-utils@3.0.2:
         dependencies:
    +      '@eslint/config-helpers': 0.5.3
           pathe: 2.0.3
     
    -  eslint-formatting-reporter@0.0.0(eslint@10.0.2(jiti@2.6.1)):
    +  eslint-formatting-reporter@0.0.0(eslint@10.0.3(jiti@2.6.1)):
         dependencies:
    -      eslint: 10.0.2(jiti@2.6.1)
    +      eslint: 10.0.3(jiti@2.6.1)
           prettier-linter-helpers: 1.0.1
     
    -  eslint-json-compat-utils@0.2.2(eslint@10.0.2(jiti@2.6.1))(jsonc-eslint-parser@2.4.2):
    +  eslint-json-compat-utils@0.2.3(eslint@10.0.3(jiti@2.6.1))(jsonc-eslint-parser@3.1.0):
         dependencies:
    -      eslint: 10.0.2(jiti@2.6.1)
    +      eslint: 10.0.3(jiti@2.6.1)
           esquery: 1.7.0
    -      jsonc-eslint-parser: 2.4.2
    +      jsonc-eslint-parser: 3.1.0
     
    -  eslint-merge-processors@2.0.0(eslint@10.0.2(jiti@2.6.1)):
    +  eslint-merge-processors@2.0.0(eslint@10.0.3(jiti@2.6.1)):
         dependencies:
    -      eslint: 10.0.2(jiti@2.6.1)
    +      eslint: 10.0.3(jiti@2.6.1)
     
       eslint-parser-plain@0.1.1: {}
     
    -  eslint-plugin-antfu@3.2.2(eslint@10.0.2(jiti@2.6.1)):
    +  eslint-plugin-antfu@3.2.2(eslint@10.0.3(jiti@2.6.1)):
         dependencies:
    -      eslint: 10.0.2(jiti@2.6.1)
    +      eslint: 10.0.3(jiti@2.6.1)
     
    -  eslint-plugin-command@3.5.2(@typescript-eslint/rule-tester@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.56.1(typescript@5.9.3))(@typescript-eslint/utils@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1)):
    +  eslint-plugin-command@3.5.2(@typescript-eslint/rule-tester@8.56.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.57.1(typescript@5.9.3))(@typescript-eslint/utils@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1)):
         dependencies:
           '@es-joy/jsdoccomment': 0.84.0
    -      '@typescript-eslint/rule-tester': 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3)
    -      '@typescript-eslint/utils': 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      eslint: 10.0.2(jiti@2.6.1)
    +      '@typescript-eslint/rule-tester': 8.56.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
    +      '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3)
    +      '@typescript-eslint/utils': 8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
    +      eslint: 10.0.3(jiti@2.6.1)
    +
    +  eslint-plugin-depend@1.5.0(eslint@10.0.3(jiti@2.6.1)):
    +    dependencies:
    +      empathic: 2.0.0
    +      eslint: 10.0.3(jiti@2.6.1)
    +      module-replacements: 2.11.0
    +      semver: 7.7.4
     
    -  eslint-plugin-es-x@7.8.0(eslint@10.0.2(jiti@2.6.1)):
    +  eslint-plugin-es-x@7.8.0(eslint@10.0.3(jiti@2.6.1)):
         dependencies:
    -      '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.2(jiti@2.6.1))
    +      '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3(jiti@2.6.1))
           '@eslint-community/regexpp': 4.12.2
    -      eslint: 10.0.2(jiti@2.6.1)
    -      eslint-compat-utils: 0.5.1(eslint@10.0.2(jiti@2.6.1))
    +      eslint: 10.0.3(jiti@2.6.1)
    +      eslint-compat-utils: 0.5.1(eslint@10.0.3(jiti@2.6.1))
     
    -  eslint-plugin-format@1.1.0(eslint@10.0.2(jiti@2.6.1)):
    +  eslint-plugin-format@2.0.1(eslint@10.0.3(jiti@2.6.1)):
         dependencies:
    -      '@dprint/formatter': 0.3.0
    -      '@dprint/markdown': 0.17.8
    -      '@dprint/toml': 0.6.4
    -      eslint: 10.0.2(jiti@2.6.1)
    -      eslint-formatting-reporter: 0.0.0(eslint@10.0.2(jiti@2.6.1))
    +      '@dprint/formatter': 0.5.1
    +      '@dprint/markdown': 0.21.1
    +      '@dprint/toml': 0.7.0
    +      eslint: 10.0.3(jiti@2.6.1)
    +      eslint-formatting-reporter: 0.0.0(eslint@10.0.3(jiti@2.6.1))
           eslint-parser-plain: 0.1.1
    +      ohash: 2.0.11
    +      oxfmt: 0.35.0
           prettier: 3.8.1
           synckit: 0.11.12
     
    -  eslint-plugin-import-lite@0.3.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3):
    +  eslint-plugin-import-lite@0.5.2(eslint@10.0.3(jiti@2.6.1)):
         dependencies:
    -      eslint: 10.0.2(jiti@2.6.1)
    -    optionalDependencies:
    -      typescript: 5.9.3
    +      eslint: 10.0.3(jiti@2.6.1)
     
    -  eslint-plugin-jsdoc@61.7.1(eslint@10.0.2(jiti@2.6.1)):
    +  eslint-plugin-jsdoc@62.8.0(eslint@10.0.3(jiti@2.6.1)):
         dependencies:
    -      '@es-joy/jsdoccomment': 0.78.0
    +      '@es-joy/jsdoccomment': 0.84.0
           '@es-joy/resolve.exports': 1.2.0
           are-docs-informative: 0.0.2
    -      comment-parser: 1.4.1
    +      comment-parser: 1.4.5
           debug: 4.4.3
           escape-string-regexp: 4.0.0
    -      eslint: 10.0.2(jiti@2.6.1)
    +      eslint: 10.0.3(jiti@2.6.1)
           espree: 11.1.1
           esquery: 1.7.0
           html-entities: 2.6.0
    @@ -7441,27 +9238,27 @@ snapshots:
         transitivePeerDependencies:
           - supports-color
     
    -  eslint-plugin-jsonc@2.21.1(eslint@10.0.2(jiti@2.6.1)):
    +  eslint-plugin-jsonc@3.1.2(eslint@10.0.3(jiti@2.6.1)):
         dependencies:
    -      '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.2(jiti@2.6.1))
    -      diff-sequences: 27.5.1
    -      eslint: 10.0.2(jiti@2.6.1)
    -      eslint-compat-utils: 0.6.5(eslint@10.0.2(jiti@2.6.1))
    -      eslint-json-compat-utils: 0.2.2(eslint@10.0.2(jiti@2.6.1))(jsonc-eslint-parser@2.4.2)
    -      espree: 10.4.0
    -      graphemer: 1.4.0
    -      jsonc-eslint-parser: 2.4.2
    +      '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3(jiti@2.6.1))
    +      '@eslint/core': 1.1.1
    +      '@eslint/plugin-kit': 0.6.1
    +      '@ota-meshi/ast-token-store': 0.3.0
    +      diff-sequences: 29.6.3
    +      eslint: 10.0.3(jiti@2.6.1)
    +      eslint-json-compat-utils: 0.2.3(eslint@10.0.3(jiti@2.6.1))(jsonc-eslint-parser@3.1.0)
    +      jsonc-eslint-parser: 3.1.0
           natural-compare: 1.4.0
           synckit: 0.11.12
         transitivePeerDependencies:
           - '@eslint/json'
     
    -  eslint-plugin-n@17.24.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3):
    +  eslint-plugin-n@17.24.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3):
         dependencies:
    -      '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.2(jiti@2.6.1))
    +      '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3(jiti@2.6.1))
           enhanced-resolve: 5.20.0
    -      eslint: 10.0.2(jiti@2.6.1)
    -      eslint-plugin-es-x: 7.8.0(eslint@10.0.2(jiti@2.6.1))
    +      eslint: 10.0.3(jiti@2.6.1)
    +      eslint-plugin-es-x: 7.8.0(eslint@10.0.3(jiti@2.6.1))
           get-tsconfig: 4.13.6
           globals: 15.15.0
           globrex: 0.1.2
    @@ -7473,20 +9270,19 @@ snapshots:
     
       eslint-plugin-no-only-tests@3.3.0: {}
     
    -  eslint-plugin-perfectionist@4.15.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3):
    +  eslint-plugin-perfectionist@5.7.0(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3):
         dependencies:
    -      '@typescript-eslint/types': 8.56.1
    -      '@typescript-eslint/utils': 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      eslint: 10.0.2(jiti@2.6.1)
    +      '@typescript-eslint/utils': 8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
    +      eslint: 10.0.3(jiti@2.6.1)
           natural-orderby: 5.0.0
         transitivePeerDependencies:
           - supports-color
           - typescript
     
    -  eslint-plugin-pnpm@1.6.0(eslint@10.0.2(jiti@2.6.1)):
    +  eslint-plugin-pnpm@1.6.0(eslint@10.0.3(jiti@2.6.1)):
         dependencies:
           empathic: 2.0.0
    -      eslint: 10.0.2(jiti@2.6.1)
    +      eslint: 10.0.3(jiti@2.6.1)
           jsonc-eslint-parser: 3.1.0
           pathe: 2.0.3
           pnpm-workspace-yaml: 1.6.0
    @@ -7494,47 +9290,46 @@ snapshots:
           yaml: 2.8.2
           yaml-eslint-parser: 2.0.0
     
    -  eslint-plugin-prettier@5.5.4(eslint-config-prettier@10.1.8(eslint@10.0.2(jiti@2.6.1)))(eslint@10.0.2(jiti@2.6.1))(prettier@3.8.1):
    +  eslint-plugin-prettier@5.5.5(eslint-config-prettier@10.1.8(eslint@10.0.3(jiti@2.6.1)))(eslint@10.0.3(jiti@2.6.1))(prettier@3.8.1):
         dependencies:
    -      eslint: 10.0.2(jiti@2.6.1)
    +      eslint: 10.0.3(jiti@2.6.1)
           prettier: 3.8.1
           prettier-linter-helpers: 1.0.1
           synckit: 0.11.12
         optionalDependencies:
    -      eslint-config-prettier: 10.1.8(eslint@10.0.2(jiti@2.6.1))
    +      eslint-config-prettier: 10.1.8(eslint@10.0.3(jiti@2.6.1))
     
    -  eslint-plugin-regexp@2.10.0(eslint@10.0.2(jiti@2.6.1)):
    +  eslint-plugin-regexp@3.1.0(eslint@10.0.3(jiti@2.6.1)):
         dependencies:
    -      '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.2(jiti@2.6.1))
    +      '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3(jiti@2.6.1))
           '@eslint-community/regexpp': 4.12.2
           comment-parser: 1.4.5
    -      eslint: 10.0.2(jiti@2.6.1)
    -      jsdoc-type-pratt-parser: 4.8.0
    +      eslint: 10.0.3(jiti@2.6.1)
    +      jsdoc-type-pratt-parser: 7.1.1
           refa: 0.12.1
           regexp-ast-analysis: 0.7.1
           scslre: 0.3.0
     
    -  eslint-plugin-toml@0.12.0(eslint@10.0.2(jiti@2.6.1)):
    +  eslint-plugin-toml@1.3.1(eslint@10.0.3(jiti@2.6.1)):
         dependencies:
    +      '@eslint/core': 1.1.1
    +      '@eslint/plugin-kit': 0.6.1
    +      '@ota-meshi/ast-token-store': 0.3.0
           debug: 4.4.3
    -      eslint: 10.0.2(jiti@2.6.1)
    -      eslint-compat-utils: 0.6.5(eslint@10.0.2(jiti@2.6.1))
    -      lodash: 4.17.23
    -      toml-eslint-parser: 0.10.1
    +      eslint: 10.0.3(jiti@2.6.1)
    +      toml-eslint-parser: 1.0.3
         transitivePeerDependencies:
           - supports-color
     
    -  eslint-plugin-unicorn@62.0.0(eslint@10.0.2(jiti@2.6.1)):
    +  eslint-plugin-unicorn@63.0.0(eslint@10.0.3(jiti@2.6.1)):
         dependencies:
           '@babel/helper-validator-identifier': 7.28.5
    -      '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.2(jiti@2.6.1))
    -      '@eslint/plugin-kit': 0.4.1
    +      '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3(jiti@2.6.1))
           change-case: 5.4.4
           ci-info: 4.4.0
           clean-regexp: 1.0.0
           core-js-compat: 3.48.0
    -      eslint: 10.0.2(jiti@2.6.1)
    -      esquery: 1.7.0
    +      eslint: 10.0.3(jiti@2.6.1)
           find-up-simple: 1.0.1
           globals: 16.5.0
           indent-string: 5.0.0
    @@ -7546,58 +9341,46 @@ snapshots:
           semver: 7.7.4
           strip-indent: 4.1.1
     
    -  eslint-plugin-unused-imports@4.4.1(@typescript-eslint/eslint-plugin@8.56.1(@typescript-eslint/parser@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1)):
    -    dependencies:
    -      eslint: 10.0.2(jiti@2.6.1)
    -    optionalDependencies:
    -      '@typescript-eslint/eslint-plugin': 8.56.1(@typescript-eslint/parser@8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -
    -  eslint-plugin-vue@10.6.2(@stylistic/eslint-plugin@5.9.0(eslint@10.0.2(jiti@2.6.1)))(@typescript-eslint/parser@8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.0.2(jiti@2.6.1))):
    +  eslint-plugin-unused-imports@4.4.1(@typescript-eslint/eslint-plugin@8.57.1(@typescript-eslint/parser@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1)):
         dependencies:
    -      '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.2(jiti@2.6.1))
    -      eslint: 10.0.2(jiti@2.6.1)
    -      natural-compare: 1.4.0
    -      nth-check: 2.1.1
    -      postcss-selector-parser: 7.1.1
    -      semver: 7.7.4
    -      vue-eslint-parser: 10.4.0(eslint@10.0.2(jiti@2.6.1))
    -      xml-name-validator: 4.0.0
    +      eslint: 10.0.3(jiti@2.6.1)
         optionalDependencies:
    -      '@stylistic/eslint-plugin': 5.9.0(eslint@10.0.2(jiti@2.6.1))
    -      '@typescript-eslint/parser': 8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    +      '@typescript-eslint/eslint-plugin': 8.57.1(@typescript-eslint/parser@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
     
    -  eslint-plugin-vue@10.6.2(@stylistic/eslint-plugin@5.9.0(eslint@10.0.2(jiti@2.6.1)))(@typescript-eslint/parser@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.0.2(jiti@2.6.1))):
    +  eslint-plugin-vue@10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.0.3(jiti@2.6.1)))(@typescript-eslint/parser@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.0.3(jiti@2.6.1))):
         dependencies:
    -      '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.2(jiti@2.6.1))
    -      eslint: 10.0.2(jiti@2.6.1)
    +      '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3(jiti@2.6.1))
    +      eslint: 10.0.3(jiti@2.6.1)
           natural-compare: 1.4.0
           nth-check: 2.1.1
           postcss-selector-parser: 7.1.1
           semver: 7.7.4
    -      vue-eslint-parser: 10.4.0(eslint@10.0.2(jiti@2.6.1))
    +      vue-eslint-parser: 10.4.0(eslint@10.0.3(jiti@2.6.1))
           xml-name-validator: 4.0.0
         optionalDependencies:
    -      '@stylistic/eslint-plugin': 5.9.0(eslint@10.0.2(jiti@2.6.1))
    -      '@typescript-eslint/parser': 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    +      '@stylistic/eslint-plugin': 5.10.0(eslint@10.0.3(jiti@2.6.1))
    +      '@typescript-eslint/parser': 8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
     
    -  eslint-plugin-yml@1.19.1(eslint@10.0.2(jiti@2.6.1)):
    +  eslint-plugin-yml@3.3.1(eslint@10.0.3(jiti@2.6.1)):
         dependencies:
    +      '@eslint/core': 1.1.1
    +      '@eslint/plugin-kit': 0.6.1
    +      '@ota-meshi/ast-token-store': 0.3.0
           debug: 4.4.3
    -      diff-sequences: 27.5.1
    -      escape-string-regexp: 4.0.0
    -      eslint: 10.0.2(jiti@2.6.1)
    -      eslint-compat-utils: 0.6.5(eslint@10.0.2(jiti@2.6.1))
    +      diff-sequences: 29.6.3
    +      escape-string-regexp: 5.0.0
    +      eslint: 10.0.3(jiti@2.6.1)
           natural-compare: 1.4.0
    -      yaml-eslint-parser: 1.3.2
    +      yaml-eslint-parser: 2.0.0
         transitivePeerDependencies:
           - supports-color
     
    -  eslint-processor-vue-blocks@2.0.0(@vue/compiler-sfc@3.5.26)(eslint@10.0.2(jiti@2.6.1)):
    +  eslint-processor-vue-blocks@2.0.0(@vue/compiler-sfc@3.5.26)(eslint@10.0.3(jiti@2.6.1)):
         dependencies:
           '@vue/compiler-sfc': 3.5.26
    -      eslint: 10.0.2(jiti@2.6.1)
    +      eslint: 10.0.3(jiti@2.6.1)
     
    -  eslint-scope@9.1.1:
    +  eslint-scope@9.1.2:
         dependencies:
           '@types/esrecurse': 4.3.1
           '@types/estree': 1.0.8
    @@ -7610,14 +9393,14 @@ snapshots:
     
       eslint-visitor-keys@5.0.1: {}
     
    -  eslint@10.0.2(jiti@2.6.1):
    +  eslint@10.0.3(jiti@2.6.1):
         dependencies:
    -      '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.2(jiti@2.6.1))
    +      '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3(jiti@2.6.1))
           '@eslint-community/regexpp': 4.12.2
    -      '@eslint/config-array': 0.23.2
    +      '@eslint/config-array': 0.23.3
           '@eslint/config-helpers': 0.5.2
    -      '@eslint/core': 1.1.0
    -      '@eslint/plugin-kit': 0.6.0
    +      '@eslint/core': 1.1.1
    +      '@eslint/plugin-kit': 0.6.1
           '@humanfs/node': 0.16.7
           '@humanwhocodes/module-importer': 1.0.1
           '@humanwhocodes/retry': 0.4.3
    @@ -7626,7 +9409,7 @@ snapshots:
           cross-spawn: 7.0.6
           debug: 4.4.3
           escape-string-regexp: 4.0.0
    -      eslint-scope: 9.1.1
    +      eslint-scope: 9.1.2
           eslint-visitor-keys: 5.0.1
           espree: 11.1.1
           esquery: 1.7.0
    @@ -7647,6 +9430,8 @@ snapshots:
         transitivePeerDependencies:
           - supports-color
     
    +  esm@3.2.25: {}
    +
       espree@10.4.0:
         dependencies:
           acorn: 8.16.0
    @@ -7659,12 +9444,6 @@ snapshots:
           acorn-jsx: 5.3.2(acorn@8.16.0)
           eslint-visitor-keys: 5.0.1
     
    -  espree@9.6.1:
    -    dependencies:
    -      acorn: 8.16.0
    -      acorn-jsx: 5.3.2(acorn@8.16.0)
    -      eslint-visitor-keys: 3.4.3
    -
       esprima@4.0.1: {}
     
       esquery@1.7.0:
    @@ -7677,8 +9456,34 @@ snapshots:
     
       estraverse@5.3.0: {}
     
    +  estree-util-attach-comments@3.0.0:
    +    dependencies:
    +      '@types/estree': 1.0.8
    +
    +  estree-util-build-jsx@3.0.1:
    +    dependencies:
    +      '@types/estree-jsx': 1.0.5
    +      devlop: 1.1.0
    +      estree-util-is-identifier-name: 3.0.0
    +      estree-walker: 3.0.3
    +
       estree-util-is-identifier-name@3.0.0: {}
     
    +  estree-util-scope@1.0.0:
    +    dependencies:
    +      '@types/estree': 1.0.8
    +      devlop: 1.1.0
    +
    +  estree-util-to-js@2.0.0:
    +    dependencies:
    +      '@types/estree-jsx': 1.0.5
    +      astring: 1.9.0
    +      source-map: 0.7.6
    +
    +  estree-util-value-to-estree@3.5.0:
    +    dependencies:
    +      '@types/estree': 1.0.8
    +
       estree-util-visit@2.0.0:
         dependencies:
           '@types/estree-jsx': 1.0.5
    @@ -7706,6 +9511,18 @@ snapshots:
         dependencies:
           eventsource-parser: 3.0.6
     
    +  execa@8.0.1:
    +    dependencies:
    +      cross-spawn: 7.0.6
    +      get-stream: 8.0.1
    +      human-signals: 5.0.0
    +      is-stream: 3.0.0
    +      merge-stream: 2.0.0
    +      npm-run-path: 5.3.0
    +      onetime: 6.0.0
    +      signal-exit: 4.1.0
    +      strip-final-newline: 3.0.0
    +
       expect-type@1.3.0: {}
     
       express-rate-limit@8.3.1(express@5.2.1):
    @@ -7750,9 +9567,9 @@ snapshots:
     
       extend@3.0.2: {}
     
    -  fast-check@4.5.3:
    +  fast-check@4.6.0:
         dependencies:
    -      pure-rand: 7.0.1
    +      pure-rand: 8.3.0
     
       fast-content-type-parse@3.0.0: {}
     
    @@ -7843,7 +9660,7 @@ snapshots:
     
       fresh@2.0.0: {}
     
    -  fs-extra@11.3.3:
    +  fs-extra@11.3.4:
         dependencies:
           graceful-fs: 4.2.11
           jsonfile: 6.2.0
    @@ -7874,6 +9691,8 @@ snapshots:
           dunder-proto: 1.0.1
           es-object-atoms: 1.1.1
     
    +  get-stream@8.0.1: {}
    +
       get-tsconfig@4.13.6:
         dependencies:
           resolve-pkg-maps: 1.0.0
    @@ -7892,13 +9711,15 @@ snapshots:
     
       globals@16.5.0: {}
     
    +  globals@17.4.0: {}
    +
       globrex@0.1.2: {}
     
       gopd@1.2.0: {}
     
       graceful-fs@4.2.11: {}
     
    -  graphemer@1.4.0: {}
    +  hachure-fill@0.5.2: {}
     
       has-flag@4.0.0: {}
     
    @@ -7908,14 +9729,161 @@ snapshots:
         dependencies:
           function-bind: 1.1.2
     
    +  hast-util-from-dom@5.0.1:
    +    dependencies:
    +      '@types/hast': 3.0.4
    +      hastscript: 9.0.1
    +      web-namespaces: 2.0.1
    +
    +  hast-util-from-html-isomorphic@2.0.0:
    +    dependencies:
    +      '@types/hast': 3.0.4
    +      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
    +      devlop: 1.1.0
    +      hast-util-from-parse5: 8.0.3
    +      parse5: 7.3.0
    +      vfile: 6.0.3
    +      vfile-message: 4.0.3
    +
    +  hast-util-from-parse5@8.0.3:
    +    dependencies:
    +      '@types/hast': 3.0.4
    +      '@types/unist': 3.0.3
    +      devlop: 1.1.0
    +      hastscript: 9.0.1
    +      property-information: 7.1.0
    +      vfile: 6.0.3
    +      vfile-location: 5.0.3
    +      web-namespaces: 2.0.1
    +
    +  hast-util-is-element@3.0.0:
    +    dependencies:
    +      '@types/hast': 3.0.4
    +
    +  hast-util-parse-selector@4.0.0:
    +    dependencies:
    +      '@types/hast': 3.0.4
    +
    +  hast-util-raw@9.1.0:
    +    dependencies:
    +      '@types/hast': 3.0.4
    +      '@types/unist': 3.0.3
    +      '@ungap/structured-clone': 1.3.0
    +      hast-util-from-parse5: 8.0.3
    +      hast-util-to-parse5: 8.0.1
    +      html-void-elements: 3.0.0
    +      mdast-util-to-hast: 13.2.1
    +      parse5: 7.3.0
    +      unist-util-position: 5.0.0
    +      unist-util-visit: 5.1.0
    +      vfile: 6.0.3
    +      web-namespaces: 2.0.1
    +      zwitch: 2.0.4
    +
    +  hast-util-to-estree@3.1.3:
    +    dependencies:
    +      '@types/estree': 1.0.8
    +      '@types/estree-jsx': 1.0.5
    +      '@types/hast': 3.0.4
    +      comma-separated-tokens: 2.0.3
    +      devlop: 1.1.0
    +      estree-util-attach-comments: 3.0.0
    +      estree-util-is-identifier-name: 3.0.0
    +      hast-util-whitespace: 3.0.0
    +      mdast-util-mdx-expression: 2.0.1
    +      mdast-util-mdx-jsx: 3.2.0
    +      mdast-util-mdxjs-esm: 2.0.1
    +      property-information: 7.1.0
    +      space-separated-tokens: 2.0.2
    +      style-to-js: 1.1.21
    +      unist-util-position: 5.0.0
    +      zwitch: 2.0.4
    +    transitivePeerDependencies:
    +      - supports-color
    +
    +  hast-util-to-html@9.0.5:
    +    dependencies:
    +      '@types/hast': 3.0.4
    +      '@types/unist': 3.0.3
    +      ccount: 2.0.1
    +      comma-separated-tokens: 2.0.3
    +      hast-util-whitespace: 3.0.0
    +      html-void-elements: 3.0.0
    +      mdast-util-to-hast: 13.2.1
    +      property-information: 7.1.0
    +      space-separated-tokens: 2.0.2
    +      stringify-entities: 4.0.4
    +      zwitch: 2.0.4
    +
    +  hast-util-to-jsx-runtime@2.3.6:
    +    dependencies:
    +      '@types/estree': 1.0.8
    +      '@types/hast': 3.0.4
    +      '@types/unist': 3.0.3
    +      comma-separated-tokens: 2.0.3
    +      devlop: 1.1.0
    +      estree-util-is-identifier-name: 3.0.0
    +      hast-util-whitespace: 3.0.0
    +      mdast-util-mdx-expression: 2.0.1
    +      mdast-util-mdx-jsx: 3.2.0
    +      mdast-util-mdxjs-esm: 2.0.1
    +      property-information: 7.1.0
    +      space-separated-tokens: 2.0.2
    +      style-to-js: 1.1.21
    +      unist-util-position: 5.0.0
    +      vfile-message: 4.0.3
    +    transitivePeerDependencies:
    +      - supports-color
    +
    +  hast-util-to-parse5@8.0.1:
    +    dependencies:
    +      '@types/hast': 3.0.4
    +      comma-separated-tokens: 2.0.3
    +      devlop: 1.1.0
    +      property-information: 7.1.0
    +      space-separated-tokens: 2.0.2
    +      web-namespaces: 2.0.1
    +      zwitch: 2.0.4
    +
    +  hast-util-to-string@3.0.1:
    +    dependencies:
    +      '@types/hast': 3.0.4
    +
    +  hast-util-to-text@4.0.2:
    +    dependencies:
    +      '@types/hast': 3.0.4
    +      '@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
    +
    +  hastscript@9.0.1:
    +    dependencies:
    +      '@types/hast': 3.0.4
    +      comma-separated-tokens: 2.0.3
    +      hast-util-parse-selector: 4.0.0
    +      property-information: 7.1.0
    +      space-separated-tokens: 2.0.2
    +
       hono@4.12.8: {}
     
    -  hookable@6.0.1: {}
    +  hookable@6.1.0: {}
     
       html-entities@2.6.0: {}
     
       html-escaper@2.0.2: {}
     
    +  html-void-elements@3.0.0: {}
    +
       http-errors@2.0.1:
         dependencies:
           depd: 2.0.0
    @@ -7924,6 +9892,12 @@ snapshots:
           statuses: 2.0.2
           toidentifier: 1.0.1
     
    +  human-signals@5.0.0: {}
    +
    +  iconv-lite@0.6.3:
    +    dependencies:
    +      safer-buffer: 2.1.2
    +
       iconv-lite@0.7.2:
         dependencies:
           safer-buffer: 2.1.2
    @@ -7944,6 +9918,10 @@ snapshots:
     
       inherits@2.0.4: {}
     
    +  inline-style-parser@0.2.7: {}
    +
    +  internmap@1.0.1: {}
    +
       internmap@2.0.3: {}
     
       ip-address@10.1.0: {}
    @@ -7969,6 +9947,8 @@ snapshots:
     
       is-decimal@2.0.1: {}
     
    +  is-docker@3.0.0: {}
    +
       is-extglob@2.1.1: {}
     
       is-glob@4.0.3:
    @@ -7977,12 +9957,26 @@ snapshots:
     
       is-hexadecimal@2.0.1: {}
     
    +  is-inside-container@1.0.0:
    +    dependencies:
    +      is-docker: 3.0.0
    +
       is-number@7.0.0: {}
     
       is-plain-obj@4.1.0: {}
     
       is-promise@4.0.0: {}
     
    +  is-stream@3.0.0: {}
    +
    +  is-wsl@3.1.1:
    +    dependencies:
    +      is-inside-container: 1.0.0
    +
    +  is64bit@2.0.0:
    +    dependencies:
    +      system-architecture: 0.1.0
    +
       isbot@5.1.35: {}
     
       isexe@2.0.0: {}
    @@ -8014,10 +10008,6 @@ snapshots:
         dependencies:
           argparse: 2.0.1
     
    -  jsdoc-type-pratt-parser@4.8.0: {}
    -
    -  jsdoc-type-pratt-parser@7.0.0: {}
    -
       jsdoc-type-pratt-parser@7.1.1: {}
     
       jsesc@3.1.0: {}
    @@ -8038,13 +10028,6 @@ snapshots:
     
       json5@2.2.3: {}
     
    -  jsonc-eslint-parser@2.4.2:
    -    dependencies:
    -      acorn: 8.16.0
    -      eslint-visitor-keys: 3.4.3
    -      espree: 9.6.1
    -      semver: 7.7.4
    -
       jsonc-eslint-parser@3.1.0:
         dependencies:
           acorn: 8.16.0
    @@ -8057,67 +10040,85 @@ snapshots:
         optionalDependencies:
           graceful-fs: 4.2.11
     
    +  katex@0.16.39:
    +    dependencies:
    +      commander: 8.3.0
    +
       keyv@4.5.4:
         dependencies:
           json-buffer: 3.0.1
     
    +  khroma@2.1.0: {}
    +
       kind-of@3.2.2:
         dependencies:
           is-buffer: 1.1.6
     
    +  langium@4.2.1:
    +    dependencies:
    +      chevrotain: 11.1.2
    +      chevrotain-allstar: 0.3.1(chevrotain@11.1.2)
    +      vscode-languageserver: 9.0.1
    +      vscode-languageserver-textdocument: 1.0.12
    +      vscode-uri: 3.1.0
    +
    +  layout-base@1.0.2: {}
    +
    +  layout-base@2.0.1: {}
    +
       levn@0.4.1:
         dependencies:
           prelude-ls: 1.2.1
           type-check: 0.4.0
     
    -  lightningcss-android-arm64@1.31.1:
    +  lightningcss-android-arm64@1.32.0:
         optional: true
     
    -  lightningcss-darwin-arm64@1.31.1:
    +  lightningcss-darwin-arm64@1.32.0:
         optional: true
     
    -  lightningcss-darwin-x64@1.31.1:
    +  lightningcss-darwin-x64@1.32.0:
         optional: true
     
    -  lightningcss-freebsd-x64@1.31.1:
    +  lightningcss-freebsd-x64@1.32.0:
         optional: true
     
    -  lightningcss-linux-arm-gnueabihf@1.31.1:
    +  lightningcss-linux-arm-gnueabihf@1.32.0:
         optional: true
     
    -  lightningcss-linux-arm64-gnu@1.31.1:
    +  lightningcss-linux-arm64-gnu@1.32.0:
         optional: true
     
    -  lightningcss-linux-arm64-musl@1.31.1:
    +  lightningcss-linux-arm64-musl@1.32.0:
         optional: true
     
    -  lightningcss-linux-x64-gnu@1.31.1:
    +  lightningcss-linux-x64-gnu@1.32.0:
         optional: true
     
    -  lightningcss-linux-x64-musl@1.31.1:
    +  lightningcss-linux-x64-musl@1.32.0:
         optional: true
     
    -  lightningcss-win32-arm64-msvc@1.31.1:
    +  lightningcss-win32-arm64-msvc@1.32.0:
         optional: true
     
    -  lightningcss-win32-x64-msvc@1.31.1:
    +  lightningcss-win32-x64-msvc@1.32.0:
         optional: true
     
    -  lightningcss@1.31.1:
    +  lightningcss@1.32.0:
         dependencies:
           detect-libc: 2.1.2
         optionalDependencies:
    -      lightningcss-android-arm64: 1.31.1
    -      lightningcss-darwin-arm64: 1.31.1
    -      lightningcss-darwin-x64: 1.31.1
    -      lightningcss-freebsd-x64: 1.31.1
    -      lightningcss-linux-arm-gnueabihf: 1.31.1
    -      lightningcss-linux-arm64-gnu: 1.31.1
    -      lightningcss-linux-arm64-musl: 1.31.1
    -      lightningcss-linux-x64-gnu: 1.31.1
    -      lightningcss-linux-x64-musl: 1.31.1
    -      lightningcss-win32-arm64-msvc: 1.31.1
    -      lightningcss-win32-x64-msvc: 1.31.1
    +      lightningcss-android-arm64: 1.32.0
    +      lightningcss-darwin-arm64: 1.32.0
    +      lightningcss-darwin-x64: 1.32.0
    +      lightningcss-freebsd-x64: 1.32.0
    +      lightningcss-linux-arm-gnueabihf: 1.32.0
    +      lightningcss-linux-arm64-gnu: 1.32.0
    +      lightningcss-linux-arm64-musl: 1.32.0
    +      lightningcss-linux-x64-gnu: 1.32.0
    +      lightningcss-linux-x64-musl: 1.32.0
    +      lightningcss-win32-arm64-msvc: 1.32.0
    +      lightningcss-win32-x64-msvc: 1.32.0
     
       local-pkg@1.1.2:
         dependencies:
    @@ -8129,9 +10130,9 @@ snapshots:
         dependencies:
           p-locate: 5.0.0
     
    -  lodash.merge@4.6.2: {}
    +  lodash-es@4.17.23: {}
     
    -  lodash@4.17.23: {}
    +  lodash.merge@4.6.2: {}
     
       longest-streak@3.1.0: {}
     
    @@ -8139,7 +10140,7 @@ snapshots:
         dependencies:
           yallist: 3.1.1
     
    -  lucide-react@0.575.0(react@19.2.4):
    +  lucide-react@0.577.0(react@19.2.4):
         dependencies:
           react: 19.2.4
     
    @@ -8157,11 +10158,15 @@ snapshots:
         dependencies:
           semver: 7.7.4
     
    +  markdown-extensions@2.0.0: {}
    +
       markdown-table@3.0.4: {}
     
       marked@14.0.0: {}
     
    -  material-icon-theme@5.31.0:
    +  marked@16.4.2: {}
    +
    +  material-icon-theme@5.32.0:
         dependencies:
           chroma-js: 3.2.0
           events: 3.3.0
    @@ -8170,6 +10175,13 @@ snapshots:
     
       math-intrinsics@1.1.0: {}
     
    +  mathjax-full@3.2.2:
    +    dependencies:
    +      esm: 3.2.25
    +      mhchemparser: 4.2.1
    +      mj-context-menu: 0.6.1
    +      speech-rule-engine: 4.1.2
    +
       mdast-util-find-and-replace@3.0.2:
         dependencies:
           '@types/mdast': 4.0.4
    @@ -8262,6 +10274,18 @@ snapshots:
         transitivePeerDependencies:
           - supports-color
     
    +  mdast-util-math@3.0.0:
    +    dependencies:
    +      '@types/hast': 3.0.4
    +      '@types/mdast': 4.0.4
    +      devlop: 1.1.0
    +      longest-streak: 3.1.0
    +      mdast-util-from-markdown: 2.0.3
    +      mdast-util-to-markdown: 2.1.2
    +      unist-util-remove-position: 5.0.0
    +    transitivePeerDependencies:
    +      - supports-color
    +
       mdast-util-mdx-expression@2.0.1:
         dependencies:
           '@types/estree-jsx': 1.0.5
    @@ -8316,6 +10340,18 @@ snapshots:
           '@types/mdast': 4.0.4
           unist-util-is: 6.0.1
     
    +  mdast-util-to-hast@13.2.1:
    +    dependencies:
    +      '@types/hast': 3.0.4
    +      '@types/mdast': 4.0.4
    +      '@ungap/structured-clone': 1.3.0
    +      devlop: 1.1.0
    +      micromark-util-sanitize-uri: 2.0.1
    +      trim-lines: 3.0.1
    +      unist-util-position: 5.0.0
    +      unist-util-visit: 5.1.0
    +      vfile: 6.0.3
    +
       mdast-util-to-markdown@2.1.2:
         dependencies:
           '@types/mdast': 4.0.4
    @@ -8338,8 +10374,36 @@ snapshots:
     
       merge-descriptors@2.0.0: {}
     
    +  merge-stream@2.0.0: {}
    +
       merge2@1.4.1: {}
     
    +  mermaid@11.13.0:
    +    dependencies:
    +      '@braintree/sanitize-url': 7.1.2
    +      '@iconify/utils': 3.1.0
    +      '@mermaid-js/parser': 1.0.1
    +      '@types/d3': 7.4.3
    +      '@upsetjs/venn.js': 2.0.0
    +      cytoscape: 3.33.1
    +      cytoscape-cose-bilkent: 4.1.0(cytoscape@3.33.1)
    +      cytoscape-fcose: 2.2.0(cytoscape@3.33.1)
    +      d3: 7.9.0
    +      d3-sankey: 0.12.3
    +      dagre-d3-es: 7.0.14
    +      dayjs: 1.11.20
    +      dompurify: 3.3.3
    +      katex: 0.16.39
    +      khroma: 2.1.0
    +      lodash-es: 4.17.23
    +      marked: 16.4.2
    +      roughjs: 4.6.6
    +      stylis: 4.3.6
    +      ts-dedent: 2.2.0
    +      uuid: 11.1.0
    +
    +  mhchemparser@4.2.1: {}
    +
       micromark-core-commonmark@2.0.3:
         dependencies:
           decode-named-character-reference: 1.3.0
    @@ -8424,6 +10488,16 @@ snapshots:
           micromark-util-combine-extensions: 2.0.1
           micromark-util-types: 2.0.2
     
    +  micromark-extension-math@3.1.0:
    +    dependencies:
    +      '@types/katex': 0.16.8
    +      devlop: 1.1.0
    +      katex: 0.16.39
    +      micromark-factory-space: 2.0.1
    +      micromark-util-character: 2.1.1
    +      micromark-util-symbol: 2.0.1
    +      micromark-util-types: 2.0.2
    +
       micromark-extension-mdx-expression@3.0.1:
         dependencies:
           '@types/estree': 1.0.8
    @@ -8622,13 +10696,13 @@ snapshots:
         dependencies:
           mime-db: 1.54.0
     
    +  mimic-fn@4.0.0: {}
    +
       minimatch@10.2.4:
         dependencies:
           brace-expansion: 5.0.4
     
    -  minimatch@9.0.9:
    -    dependencies:
    -      brace-expansion: 2.0.2
    +  mj-context-menu@0.6.1: {}
     
       mlly@1.8.0:
         dependencies:
    @@ -8637,6 +10711,8 @@ snapshots:
           pkg-types: 1.3.1
           ufo: 1.6.3
     
    +  module-replacements@2.11.0: {}
    +
       monaco-editor@0.55.1:
         dependencies:
           dompurify: 3.2.7
    @@ -8654,9 +10730,14 @@ snapshots:
     
       negotiator@1.0.0: {}
     
    -  next@16.1.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
    +  next-themes@0.4.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
    +    dependencies:
    +      react: 19.2.4
    +      react-dom: 19.2.4(react@19.2.4)
    +
    +  next@16.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
         dependencies:
    -      '@next/env': 16.1.6
    +      '@next/env': 16.2.0
           '@swc/helpers': 0.5.15
           baseline-browser-mapping: 2.10.0
           caniuse-lite: 1.0.30001775
    @@ -8665,19 +10746,89 @@ snapshots:
           react-dom: 19.2.4(react@19.2.4)
           styled-jsx: 5.1.6(react@19.2.4)
         optionalDependencies:
    -      '@next/swc-darwin-arm64': 16.1.6
    -      '@next/swc-darwin-x64': 16.1.6
    -      '@next/swc-linux-arm64-gnu': 16.1.6
    -      '@next/swc-linux-arm64-musl': 16.1.6
    -      '@next/swc-linux-x64-gnu': 16.1.6
    -      '@next/swc-linux-x64-musl': 16.1.6
    -      '@next/swc-win32-arm64-msvc': 16.1.6
    -      '@next/swc-win32-x64-msvc': 16.1.6
    +      '@next/swc-darwin-arm64': 16.2.0
    +      '@next/swc-darwin-x64': 16.2.0
    +      '@next/swc-linux-arm64-gnu': 16.2.0
    +      '@next/swc-linux-arm64-musl': 16.2.0
    +      '@next/swc-linux-x64-gnu': 16.2.0
    +      '@next/swc-linux-x64-musl': 16.2.0
    +      '@next/swc-win32-arm64-msvc': 16.2.0
    +      '@next/swc-win32-x64-msvc': 16.2.0
           sharp: 0.34.5
         transitivePeerDependencies:
           - '@babel/core'
           - babel-plugin-macros
     
    +  nextra-theme-docs@4.6.1(@types/react@19.2.14)(immer@11.1.4)(next@16.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(nextra@4.6.1(next@16.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)):
    +    dependencies:
    +      '@headlessui/react': 2.2.9(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
    +      clsx: 2.1.1
    +      next: 16.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
    +      next-themes: 0.4.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
    +      nextra: 4.6.1(next@16.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
    +      react: 19.2.4
    +      react-compiler-runtime: 19.1.0-rc.3(react@19.2.4)
    +      react-dom: 19.2.4(react@19.2.4)
    +      scroll-into-view-if-needed: 3.1.0
    +      zod: 4.3.6
    +      zustand: 5.0.12(@types/react@19.2.14)(immer@11.1.4)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4))
    +    transitivePeerDependencies:
    +      - '@types/react'
    +      - immer
    +      - use-sync-external-store
    +
    +  nextra@4.6.1(next@16.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3):
    +    dependencies:
    +      '@formatjs/intl-localematcher': 0.6.2
    +      '@headlessui/react': 2.2.9(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
    +      '@mdx-js/mdx': 3.1.1
    +      '@napi-rs/simple-git': 0.1.22
    +      '@shikijs/twoslash': 3.23.0(typescript@5.9.3)
    +      '@theguild/remark-mermaid': 0.3.0(react@19.2.4)
    +      '@theguild/remark-npm2yarn': 0.3.3
    +      better-react-mathjax: 2.3.0(react@19.2.4)
    +      clsx: 2.1.1
    +      estree-util-to-js: 2.0.0
    +      estree-util-value-to-estree: 3.5.0
    +      fast-glob: 3.3.3
    +      github-slugger: 2.0.0
    +      hast-util-to-estree: 3.1.3
    +      katex: 0.16.39
    +      mdast-util-from-markdown: 2.0.3
    +      mdast-util-gfm: 3.1.0
    +      mdast-util-to-hast: 13.2.1
    +      negotiator: 1.0.0
    +      next: 16.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
    +      react: 19.2.4
    +      react-compiler-runtime: 19.1.0-rc.3(react@19.2.4)
    +      react-dom: 19.2.4(react@19.2.4)
    +      react-medium-image-zoom: 5.4.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
    +      rehype-katex: 7.0.1
    +      rehype-pretty-code: 0.14.1(shiki@3.23.0)
    +      rehype-raw: 7.0.0
    +      remark-frontmatter: 5.0.0
    +      remark-gfm: 4.0.1
    +      remark-math: 6.0.0
    +      remark-reading-time: 2.1.0
    +      remark-smartypants: 3.0.2
    +      server-only: 0.0.1
    +      shiki: 3.23.0
    +      slash: 5.1.0
    +      title: 4.0.1
    +      ts-morph: 27.0.2
    +      unist-util-remove: 4.0.0
    +      unist-util-visit: 5.1.0
    +      unist-util-visit-children: 3.0.0
    +      yaml: 2.8.2
    +      zod: 4.3.6
    +    transitivePeerDependencies:
    +      - supports-color
    +      - typescript
    +
    +  nlcst-to-string@4.0.0:
    +    dependencies:
    +      '@types/nlcst': 2.0.3
    +
       node-releases@2.0.27: {}
     
       normalize-path@3.0.0: {}
    @@ -8695,6 +10846,12 @@ snapshots:
           shell-quote: 1.8.3
           which: 5.0.0
     
    +  npm-run-path@5.3.0:
    +    dependencies:
    +      path-key: 4.0.0
    +
    +  npm-to-yarn@3.0.1: {}
    +
       nth-check@2.1.1:
         dependencies:
           boolbase: 1.0.0
    @@ -8707,6 +10864,8 @@ snapshots:
     
       obug@2.1.1: {}
     
    +  ohash@2.0.11: {}
    +
       on-finished@2.4.1:
         dependencies:
           ee-first: 1.1.1
    @@ -8715,6 +10874,18 @@ snapshots:
         dependencies:
           wrappy: 1.0.2
     
    +  onetime@6.0.0:
    +    dependencies:
    +      mimic-fn: 4.0.0
    +
    +  oniguruma-parser@0.12.1: {}
    +
    +  oniguruma-to-es@4.3.5:
    +    dependencies:
    +      oniguruma-parser: 0.12.1
    +      regex: 6.1.0
    +      regex-recursion: 6.0.2
    +
       optionator@0.9.4:
         dependencies:
           deep-is: 0.1.4
    @@ -8724,6 +10895,30 @@ snapshots:
           type-check: 0.4.0
           word-wrap: 1.2.5
     
    +  oxfmt@0.35.0:
    +    dependencies:
    +      tinypool: 2.1.0
    +    optionalDependencies:
    +      '@oxfmt/binding-android-arm-eabi': 0.35.0
    +      '@oxfmt/binding-android-arm64': 0.35.0
    +      '@oxfmt/binding-darwin-arm64': 0.35.0
    +      '@oxfmt/binding-darwin-x64': 0.35.0
    +      '@oxfmt/binding-freebsd-x64': 0.35.0
    +      '@oxfmt/binding-linux-arm-gnueabihf': 0.35.0
    +      '@oxfmt/binding-linux-arm-musleabihf': 0.35.0
    +      '@oxfmt/binding-linux-arm64-gnu': 0.35.0
    +      '@oxfmt/binding-linux-arm64-musl': 0.35.0
    +      '@oxfmt/binding-linux-ppc64-gnu': 0.35.0
    +      '@oxfmt/binding-linux-riscv64-gnu': 0.35.0
    +      '@oxfmt/binding-linux-riscv64-musl': 0.35.0
    +      '@oxfmt/binding-linux-s390x-gnu': 0.35.0
    +      '@oxfmt/binding-linux-x64-gnu': 0.35.0
    +      '@oxfmt/binding-linux-x64-musl': 0.35.0
    +      '@oxfmt/binding-openharmony-arm64': 0.35.0
    +      '@oxfmt/binding-win32-arm64-msvc': 0.35.0
    +      '@oxfmt/binding-win32-ia32-msvc': 0.35.0
    +      '@oxfmt/binding-win32-x64-msvc': 0.35.0
    +
       p-limit@3.1.0:
         dependencies:
           yocto-queue: 0.1.0
    @@ -8734,6 +10929,15 @@ snapshots:
     
       package-manager-detector@1.6.0: {}
     
    +  pagefind@1.4.0:
    +    optionalDependencies:
    +      '@pagefind/darwin-arm64': 1.4.0
    +      '@pagefind/darwin-x64': 1.4.0
    +      '@pagefind/freebsd-x64': 1.4.0
    +      '@pagefind/linux-arm64': 1.4.0
    +      '@pagefind/linux-x64': 1.4.0
    +      '@pagefind/windows-x64': 1.4.0
    +
       parse-entities@4.0.2:
         dependencies:
           '@types/unist': 2.0.11
    @@ -8750,14 +10954,35 @@ snapshots:
         dependencies:
           parse-statements: 1.0.11
     
    +  parse-latin@7.0.0:
    +    dependencies:
    +      '@types/nlcst': 2.0.3
    +      '@types/unist': 3.0.3
    +      nlcst-to-string: 4.0.0
    +      unist-util-modify-children: 4.0.0
    +      unist-util-visit-children: 3.0.0
    +      vfile: 6.0.3
    +
    +  parse-numeric-range@1.3.0: {}
    +
       parse-statements@1.0.11: {}
     
    +  parse5@7.3.0:
    +    dependencies:
    +      entities: 6.0.1
    +
       parseurl@1.3.3: {}
     
    +  path-browserify@1.0.1: {}
    +
    +  path-data-parser@0.1.0: {}
    +
       path-exists@4.0.0: {}
     
       path-key@3.1.1: {}
     
    +  path-key@4.0.0: {}
    +
       path-to-regexp@8.3.0: {}
     
       pathe@2.0.3: {}
    @@ -8790,6 +11015,13 @@ snapshots:
         dependencies:
           yaml: 2.8.2
     
    +  points-on-curve@0.2.0: {}
    +
    +  points-on-path@0.2.1:
    +    dependencies:
    +      path-data-parser: 0.1.0
    +      points-on-curve: 0.2.0
    +
       postcss-selector-parser@7.1.1:
         dependencies:
           cssesc: 3.0.0
    @@ -8801,7 +11033,7 @@ snapshots:
           picocolors: 1.1.1
           source-map-js: 1.2.1
     
    -  postcss@8.5.6:
    +  postcss@8.5.8:
         dependencies:
           nanoid: 3.3.11
           picocolors: 1.1.1
    @@ -8815,6 +11047,8 @@ snapshots:
     
       prettier@3.8.1: {}
     
    +  property-information@7.1.0: {}
    +
       proxy-addr@2.0.7:
         dependencies:
           forwarded: 0.2.0
    @@ -8822,7 +11056,7 @@ snapshots:
     
       punycode@2.3.1: {}
     
    -  pure-rand@7.0.1: {}
    +  pure-rand@8.3.0: {}
     
       qs@6.15.0:
         dependencies:
    @@ -8843,6 +11077,10 @@ snapshots:
           iconv-lite: 0.7.2
           unpipe: 1.0.0
     
    +  react-compiler-runtime@19.1.0-rc.3(react@19.2.4):
    +    dependencies:
    +      react: 19.2.4
    +
       react-dom@19.2.4(react@19.2.4):
         dependencies:
           react: 19.2.4
    @@ -8850,6 +11088,11 @@ snapshots:
     
       react-is@19.2.4: {}
     
    +  react-medium-image-zoom@5.4.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
    +    dependencies:
    +      react: 19.2.4
    +      react-dom: 19.2.4(react@19.2.4)
    +
       react-redux@9.2.0(@types/react@19.2.14)(react@19.2.4)(redux@5.0.1):
         dependencies:
           '@types/use-sync-external-store': 0.0.6
    @@ -8859,8 +11102,6 @@ snapshots:
           '@types/react': 19.2.14
           redux: 5.0.1
     
    -  react-refresh@0.18.0: {}
    -
       react@19.2.4: {}
     
       read-package-json-fast@4.0.0:
    @@ -8872,6 +11113,8 @@ snapshots:
         dependencies:
           picomatch: 2.3.1
     
    +  reading-time@1.5.0: {}
    +
       recast@0.23.11:
         dependencies:
           ast-types: 0.16.1
    @@ -8880,7 +11123,7 @@ snapshots:
           tiny-invariant: 1.3.3
           tslib: 2.8.1
     
    -  recharts@3.7.0(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react-is@19.2.4)(react@19.2.4)(redux@5.0.1):
    +  recharts@3.8.0(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react-is@19.2.4)(react@19.2.4)(redux@5.0.1):
         dependencies:
           '@reduxjs/toolkit': 2.11.2(react-redux@9.2.0(@types/react@19.2.14)(react@19.2.4)(redux@5.0.1))(react@19.2.4)
           clsx: 2.1.1
    @@ -8900,6 +11143,35 @@ snapshots:
           - '@types/react'
           - redux
     
    +  recma-build-jsx@1.0.0:
    +    dependencies:
    +      '@types/estree': 1.0.8
    +      estree-util-build-jsx: 3.0.1
    +      vfile: 6.0.3
    +
    +  recma-jsx@1.0.1(acorn@8.16.0):
    +    dependencies:
    +      acorn: 8.16.0
    +      acorn-jsx: 5.3.2(acorn@8.16.0)
    +      estree-util-to-js: 2.0.0
    +      recma-parse: 1.0.0
    +      recma-stringify: 1.0.0
    +      unified: 11.0.5
    +
    +  recma-parse@1.0.0:
    +    dependencies:
    +      '@types/estree': 1.0.8
    +      esast-util-from-js: 2.0.1
    +      unified: 11.0.5
    +      vfile: 6.0.3
    +
    +  recma-stringify@1.0.0:
    +    dependencies:
    +      '@types/estree': 1.0.8
    +      estree-util-to-js: 2.0.0
    +      unified: 11.0.5
    +      vfile: 6.0.3
    +
       redux-thunk@3.1.0(redux@5.0.1):
         dependencies:
           redux: 5.0.1
    @@ -8910,6 +11182,16 @@ snapshots:
         dependencies:
           '@eslint-community/regexpp': 4.12.2
     
    +  regex-recursion@6.0.2:
    +    dependencies:
    +      regex-utilities: 2.3.0
    +
    +  regex-utilities@2.3.0: {}
    +
    +  regex@6.1.0:
    +    dependencies:
    +      regex-utilities: 2.3.0
    +
       regexp-ast-analysis@0.7.1:
         dependencies:
           '@eslint-community/regexpp': 4.12.2
    @@ -8921,6 +11203,46 @@ snapshots:
         dependencies:
           jsesc: 3.1.0
     
    +  rehype-katex@7.0.1:
    +    dependencies:
    +      '@types/hast': 3.0.4
    +      '@types/katex': 0.16.8
    +      hast-util-from-html-isomorphic: 2.0.0
    +      hast-util-to-text: 4.0.2
    +      katex: 0.16.39
    +      unist-util-visit-parents: 6.0.2
    +      vfile: 6.0.3
    +
    +  rehype-parse@9.0.1:
    +    dependencies:
    +      '@types/hast': 3.0.4
    +      hast-util-from-html: 2.0.3
    +      unified: 11.0.5
    +
    +  rehype-pretty-code@0.14.1(shiki@3.23.0):
    +    dependencies:
    +      '@types/hast': 3.0.4
    +      hast-util-to-string: 3.0.1
    +      parse-numeric-range: 1.3.0
    +      rehype-parse: 9.0.1
    +      shiki: 3.23.0
    +      unified: 11.0.5
    +      unist-util-visit: 5.1.0
    +
    +  rehype-raw@7.0.0:
    +    dependencies:
    +      '@types/hast': 3.0.4
    +      hast-util-raw: 9.1.0
    +      vfile: 6.0.3
    +
    +  rehype-recma@1.0.0:
    +    dependencies:
    +      '@types/estree': 1.0.8
    +      '@types/hast': 3.0.4
    +      hast-util-to-estree: 3.1.3
    +    transitivePeerDependencies:
    +      - supports-color
    +
       remark-frontmatter@5.0.0:
         dependencies:
           '@types/mdast': 4.0.4
    @@ -8941,6 +11263,15 @@ snapshots:
         transitivePeerDependencies:
           - supports-color
     
    +  remark-math@6.0.0:
    +    dependencies:
    +      '@types/mdast': 4.0.4
    +      mdast-util-math: 3.0.0
    +      micromark-extension-math: 3.1.0
    +      unified: 11.0.5
    +    transitivePeerDependencies:
    +      - supports-color
    +
       remark-mdx@3.1.1:
         dependencies:
           mdast-util-mdx: 3.0.0
    @@ -8957,6 +11288,28 @@ snapshots:
         transitivePeerDependencies:
           - supports-color
     
    +  remark-reading-time@2.1.0:
    +    dependencies:
    +      estree-util-is-identifier-name: 3.0.0
    +      estree-util-value-to-estree: 3.5.0
    +      reading-time: 1.5.0
    +      unist-util-visit: 5.1.0
    +
    +  remark-rehype@11.1.2:
    +    dependencies:
    +      '@types/hast': 3.0.4
    +      '@types/mdast': 4.0.4
    +      mdast-util-to-hast: 13.2.1
    +      unified: 11.0.5
    +      vfile: 6.0.3
    +
    +  remark-smartypants@3.0.2:
    +    dependencies:
    +      retext: 9.0.0
    +      retext-smartypants: 6.2.0
    +      unified: 11.0.5
    +      unist-util-visit: 5.1.0
    +
       remark-stringify@11.0.0:
         dependencies:
           '@types/mdast': 4.0.4
    @@ -8973,74 +11326,100 @@ snapshots:
     
       resolve-pkg-maps@1.0.0: {}
     
    +  retext-latin@4.0.0:
    +    dependencies:
    +      '@types/nlcst': 2.0.3
    +      parse-latin: 7.0.0
    +      unified: 11.0.5
    +
    +  retext-smartypants@6.2.0:
    +    dependencies:
    +      '@types/nlcst': 2.0.3
    +      nlcst-to-string: 4.0.0
    +      unist-util-visit: 5.1.0
    +
    +  retext-stringify@4.0.0:
    +    dependencies:
    +      '@types/nlcst': 2.0.3
    +      nlcst-to-string: 4.0.0
    +      unified: 11.0.5
    +
    +  retext@9.0.0:
    +    dependencies:
    +      '@types/nlcst': 2.0.3
    +      retext-latin: 4.0.0
    +      retext-stringify: 4.0.0
    +      unified: 11.0.5
    +
       reusify@1.1.0: {}
     
    -  rolldown-plugin-dts@0.22.2(rolldown@1.0.0-rc.5)(typescript@5.9.3):
    +  robust-predicates@3.0.2: {}
    +
    +  rolldown-plugin-dts@0.22.5(rolldown@1.0.0-rc.9)(typescript@5.9.3):
         dependencies:
    -      '@babel/generator': 8.0.0-rc.1
    -      '@babel/helper-validator-identifier': 8.0.0-rc.1
    -      '@babel/parser': 8.0.0-rc.1
    -      '@babel/types': 8.0.0-rc.1
    +      '@babel/generator': 8.0.0-rc.2
    +      '@babel/helper-validator-identifier': 8.0.0-rc.2
    +      '@babel/parser': 8.0.0-rc.2
    +      '@babel/types': 8.0.0-rc.2
           ast-kit: 3.0.0-beta.1
           birpc: 4.0.0
           dts-resolver: 2.1.3
           get-tsconfig: 4.13.6
           obug: 2.1.1
    -      rolldown: 1.0.0-rc.5
    +      rolldown: 1.0.0-rc.9
         optionalDependencies:
           typescript: 5.9.3
         transitivePeerDependencies:
           - oxc-resolver
     
    -  rolldown@1.0.0-rc.5:
    +  rolldown@1.0.0-rc.10:
         dependencies:
    -      '@oxc-project/types': 0.114.0
    -      '@rolldown/pluginutils': 1.0.0-rc.5
    +      '@oxc-project/types': 0.120.0
    +      '@rolldown/pluginutils': 1.0.0-rc.10
         optionalDependencies:
    -      '@rolldown/binding-android-arm64': 1.0.0-rc.5
    -      '@rolldown/binding-darwin-arm64': 1.0.0-rc.5
    -      '@rolldown/binding-darwin-x64': 1.0.0-rc.5
    -      '@rolldown/binding-freebsd-x64': 1.0.0-rc.5
    -      '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.5
    -      '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.5
    -      '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.5
    -      '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.5
    -      '@rolldown/binding-linux-x64-musl': 1.0.0-rc.5
    -      '@rolldown/binding-openharmony-arm64': 1.0.0-rc.5
    -      '@rolldown/binding-wasm32-wasi': 1.0.0-rc.5
    -      '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.5
    -      '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.5
    -
    -  rollup@4.59.0:
    -    dependencies:
    -      '@types/estree': 1.0.8
    +      '@rolldown/binding-android-arm64': 1.0.0-rc.10
    +      '@rolldown/binding-darwin-arm64': 1.0.0-rc.10
    +      '@rolldown/binding-darwin-x64': 1.0.0-rc.10
    +      '@rolldown/binding-freebsd-x64': 1.0.0-rc.10
    +      '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.10
    +      '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.10
    +      '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.10
    +      '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.10
    +      '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.10
    +      '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.10
    +      '@rolldown/binding-linux-x64-musl': 1.0.0-rc.10
    +      '@rolldown/binding-openharmony-arm64': 1.0.0-rc.10
    +      '@rolldown/binding-wasm32-wasi': 1.0.0-rc.10
    +      '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.10
    +      '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.10
    +
    +  rolldown@1.0.0-rc.9:
    +    dependencies:
    +      '@oxc-project/types': 0.115.0
    +      '@rolldown/pluginutils': 1.0.0-rc.9
         optionalDependencies:
    -      '@rollup/rollup-android-arm-eabi': 4.59.0
    -      '@rollup/rollup-android-arm64': 4.59.0
    -      '@rollup/rollup-darwin-arm64': 4.59.0
    -      '@rollup/rollup-darwin-x64': 4.59.0
    -      '@rollup/rollup-freebsd-arm64': 4.59.0
    -      '@rollup/rollup-freebsd-x64': 4.59.0
    -      '@rollup/rollup-linux-arm-gnueabihf': 4.59.0
    -      '@rollup/rollup-linux-arm-musleabihf': 4.59.0
    -      '@rollup/rollup-linux-arm64-gnu': 4.59.0
    -      '@rollup/rollup-linux-arm64-musl': 4.59.0
    -      '@rollup/rollup-linux-loong64-gnu': 4.59.0
    -      '@rollup/rollup-linux-loong64-musl': 4.59.0
    -      '@rollup/rollup-linux-ppc64-gnu': 4.59.0
    -      '@rollup/rollup-linux-ppc64-musl': 4.59.0
    -      '@rollup/rollup-linux-riscv64-gnu': 4.59.0
    -      '@rollup/rollup-linux-riscv64-musl': 4.59.0
    -      '@rollup/rollup-linux-s390x-gnu': 4.59.0
    -      '@rollup/rollup-linux-x64-gnu': 4.59.0
    -      '@rollup/rollup-linux-x64-musl': 4.59.0
    -      '@rollup/rollup-openbsd-x64': 4.59.0
    -      '@rollup/rollup-openharmony-arm64': 4.59.0
    -      '@rollup/rollup-win32-arm64-msvc': 4.59.0
    -      '@rollup/rollup-win32-ia32-msvc': 4.59.0
    -      '@rollup/rollup-win32-x64-gnu': 4.59.0
    -      '@rollup/rollup-win32-x64-msvc': 4.59.0
    -      fsevents: 2.3.3
    +      '@rolldown/binding-android-arm64': 1.0.0-rc.9
    +      '@rolldown/binding-darwin-arm64': 1.0.0-rc.9
    +      '@rolldown/binding-darwin-x64': 1.0.0-rc.9
    +      '@rolldown/binding-freebsd-x64': 1.0.0-rc.9
    +      '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.9
    +      '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.9
    +      '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.9
    +      '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.9
    +      '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.9
    +      '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.9
    +      '@rolldown/binding-linux-x64-musl': 1.0.0-rc.9
    +      '@rolldown/binding-openharmony-arm64': 1.0.0-rc.9
    +      '@rolldown/binding-wasm32-wasi': 1.0.0-rc.9
    +      '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.9
    +      '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.9
    +
    +  roughjs@4.6.6:
    +    dependencies:
    +      hachure-fill: 0.5.2
    +      path-data-parser: 0.1.0
    +      points-on-curve: 0.2.0
    +      points-on-path: 0.2.1
     
       router@2.2.0:
         dependencies:
    @@ -9056,10 +11435,16 @@ snapshots:
         dependencies:
           queue-microtask: 1.2.3
     
    +  rw@1.3.3: {}
    +
       safer-buffer@2.1.2: {}
     
       scheduler@0.27.0: {}
     
    +  scroll-into-view-if-needed@3.1.0:
    +    dependencies:
    +      compute-scroll-into-view: 3.1.1
    +
       scslre@0.3.0:
         dependencies:
           '@eslint-community/regexpp': 4.12.2
    @@ -9101,6 +11486,8 @@ snapshots:
         transitivePeerDependencies:
           - supports-color
     
    +  server-only@0.0.1: {}
    +
       setprototypeof@1.2.0: {}
     
       sharp@0.34.5:
    @@ -9143,6 +11530,17 @@ snapshots:
     
       shell-quote@1.8.3: {}
     
    +  shiki@3.23.0:
    +    dependencies:
    +      '@shikijs/core': 3.23.0
    +      '@shikijs/engine-javascript': 3.23.0
    +      '@shikijs/engine-oniguruma': 3.23.0
    +      '@shikijs/langs': 3.23.0
    +      '@shikijs/themes': 3.23.0
    +      '@shikijs/types': 3.23.0
    +      '@shikijs/vscode-textmate': 10.0.2
    +      '@types/hast': 3.0.4
    +
       side-channel-list@1.0.0:
         dependencies:
           es-errors: 1.3.0
    @@ -9179,12 +11577,16 @@ snapshots:
     
       sisteransi@1.0.5: {}
     
    +  slash@5.1.0: {}
    +
       source-map-js@1.2.1: {}
     
       source-map@0.6.1: {}
     
       source-map@0.7.6: {}
     
    +  space-separated-tokens@2.0.2: {}
    +
       spdx-exceptions@2.5.0: {}
     
       spdx-expression-parse@4.0.0:
    @@ -9194,26 +11596,44 @@ snapshots:
     
       spdx-license-ids@3.0.23: {}
     
    +  speech-rule-engine@4.1.2:
    +    dependencies:
    +      '@xmldom/xmldom': 0.9.8
    +      commander: 13.1.0
    +      wicked-good-xpath: 1.3.0
    +
       stackback@0.0.2: {}
     
       state-local@1.0.7: {}
     
       statuses@2.0.2: {}
     
    -  std-env@3.10.0: {}
    +  std-env@4.0.0: {}
     
       stringify-entities@4.0.4:
         dependencies:
           character-entities-html4: 2.1.0
           character-entities-legacy: 3.0.0
     
    +  strip-final-newline@3.0.0: {}
    +
       strip-indent@4.1.1: {}
     
    +  style-to-js@1.1.21:
    +    dependencies:
    +      style-to-object: 1.0.14
    +
    +  style-to-object@1.0.14:
    +    dependencies:
    +      inline-style-parser: 0.2.7
    +
       styled-jsx@5.1.6(react@19.2.4):
         dependencies:
           client-only: 0.0.1
           react: 19.2.4
     
    +  stylis@4.3.6: {}
    +
       supports-color@7.2.0:
         dependencies:
           has-flag: 4.0.0
    @@ -9227,9 +11647,13 @@ snapshots:
         dependencies:
           '@pkgr/core': 0.2.9
     
    +  system-architecture@0.1.0: {}
    +
    +  tabbable@6.4.0: {}
    +
       tailwind-merge@3.5.0: {}
     
    -  tailwindcss@4.2.1: {}
    +  tailwindcss@4.2.2: {}
     
       tapable@2.3.0: {}
     
    @@ -9241,13 +11665,23 @@ snapshots:
     
       tinyexec@1.0.2: {}
     
    +  tinyexec@1.0.4: {}
    +
       tinyglobby@0.2.15:
         dependencies:
           fdir: 6.5.0(picomatch@4.0.3)
           picomatch: 4.0.3
     
    +  tinypool@2.1.0: {}
    +
       tinyrainbow@3.0.3: {}
     
    +  title@4.0.1:
    +    dependencies:
    +      arg: 5.0.2
    +      chalk: 5.6.2
    +      clipboardy: 4.0.0
    +
       to-regex-range@5.0.1:
         dependencies:
           is-number: 7.0.0
    @@ -9259,12 +11693,14 @@ snapshots:
     
       toidentifier@1.0.1: {}
     
    -  toml-eslint-parser@0.10.1:
    +  toml-eslint-parser@1.0.3:
         dependencies:
    -      eslint-visitor-keys: 3.4.3
    +      eslint-visitor-keys: 5.0.1
     
       tree-kill@1.2.2: {}
     
    +  trim-lines@3.0.1: {}
    +
       trough@2.2.0: {}
     
       ts-api-utils@2.4.0(typescript@5.9.3):
    @@ -9276,24 +11712,31 @@ snapshots:
           picomatch: 4.0.3
           typescript: 5.9.3
     
    -  tsdown@0.21.0-beta.2(synckit@0.11.12)(typescript@5.9.3):
    +  ts-dedent@2.2.0: {}
    +
    +  ts-morph@27.0.2:
    +    dependencies:
    +      '@ts-morph/common': 0.28.1
    +      code-block-writer: 13.0.3
    +
    +  tsdown@0.21.4(synckit@0.11.12)(typescript@5.9.3):
         dependencies:
           ansis: 4.2.0
    -      cac: 6.7.14
    +      cac: 7.0.0
           defu: 6.1.4
           empathic: 2.0.0
    -      hookable: 6.0.1
    +      hookable: 6.1.0
           import-without-cache: 0.2.5
           obug: 2.1.1
           picomatch: 4.0.3
    -      rolldown: 1.0.0-rc.5
    -      rolldown-plugin-dts: 0.22.2(rolldown@1.0.0-rc.5)(typescript@5.9.3)
    +      rolldown: 1.0.0-rc.9
    +      rolldown-plugin-dts: 0.22.5(rolldown@1.0.0-rc.9)(typescript@5.9.3)
           semver: 7.7.4
    -      tinyexec: 1.0.2
    +      tinyexec: 1.0.4
           tinyglobby: 0.2.15
           tree-kill: 1.2.2
           unconfig-core: 7.5.0
    -      unrun: 0.2.28(synckit@0.11.12)
    +      unrun: 0.2.32(synckit@0.11.12)
         optionalDependencies:
           typescript: 5.9.3
         transitivePeerDependencies:
    @@ -9312,35 +11755,27 @@ snapshots:
         optionalDependencies:
           fsevents: 2.3.3
     
    -  turbo-darwin-64@2.8.12:
    -    optional: true
    -
    -  turbo-darwin-arm64@2.8.12:
    -    optional: true
    -
    -  turbo-linux-64@2.8.12:
    -    optional: true
    -
    -  turbo-linux-arm64@2.8.12:
    -    optional: true
    -
    -  turbo-windows-64@2.8.12:
    -    optional: true
    -
    -  turbo-windows-arm64@2.8.12:
    -    optional: true
    -
    -  turbo@2.8.12:
    +  turbo@2.8.20:
         optionalDependencies:
    -      turbo-darwin-64: 2.8.12
    -      turbo-darwin-arm64: 2.8.12
    -      turbo-linux-64: 2.8.12
    -      turbo-linux-arm64: 2.8.12
    -      turbo-windows-64: 2.8.12
    -      turbo-windows-arm64: 2.8.12
    +      '@turbo/darwin-64': 2.8.20
    +      '@turbo/darwin-arm64': 2.8.20
    +      '@turbo/linux-64': 2.8.20
    +      '@turbo/linux-arm64': 2.8.20
    +      '@turbo/windows-64': 2.8.20
    +      '@turbo/windows-arm64': 2.8.20
     
       tw-animate-css@1.4.0: {}
     
    +  twoslash-protocol@0.3.6: {}
    +
    +  twoslash@0.3.6(typescript@5.9.3):
    +    dependencies:
    +      '@typescript/vfs': 1.6.4(typescript@5.9.3)
    +      twoslash-protocol: 0.3.6
    +      typescript: 5.9.3
    +    transitivePeerDependencies:
    +      - supports-color
    +
       typanion@3.14.0: {}
     
       type-check@0.4.0:
    @@ -9353,13 +11788,13 @@ snapshots:
           media-typer: 1.1.0
           mime-types: 3.0.2
     
    -  typescript-eslint@8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3):
    +  typescript-eslint@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3):
         dependencies:
    -      '@typescript-eslint/eslint-plugin': 8.50.0(@typescript-eslint/parser@8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      '@typescript-eslint/parser': 8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      '@typescript-eslint/typescript-estree': 8.50.0(typescript@5.9.3)
    -      '@typescript-eslint/utils': 8.50.0(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)
    -      eslint: 10.0.2(jiti@2.6.1)
    +      '@typescript-eslint/eslint-plugin': 8.57.1(@typescript-eslint/parser@8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
    +      '@typescript-eslint/parser': 8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
    +      '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3)
    +      '@typescript-eslint/utils': 8.57.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)
    +      eslint: 10.0.3(jiti@2.6.1)
           typescript: 5.9.3
         transitivePeerDependencies:
           - supports-color
    @@ -9393,18 +11828,47 @@ snapshots:
           trough: 2.2.0
           vfile: 6.0.3
     
    +  unist-util-find-after@5.0.0:
    +    dependencies:
    +      '@types/unist': 3.0.3
    +      unist-util-is: 6.0.1
    +
       unist-util-is@6.0.1:
         dependencies:
           '@types/unist': 3.0.3
     
    +  unist-util-modify-children@4.0.0:
    +    dependencies:
    +      '@types/unist': 3.0.3
    +      array-iterate: 2.0.1
    +
       unist-util-position-from-estree@2.0.0:
         dependencies:
           '@types/unist': 3.0.3
     
    +  unist-util-position@5.0.0:
    +    dependencies:
    +      '@types/unist': 3.0.3
    +
    +  unist-util-remove-position@5.0.0:
    +    dependencies:
    +      '@types/unist': 3.0.3
    +      unist-util-visit: 5.1.0
    +
    +  unist-util-remove@4.0.0:
    +    dependencies:
    +      '@types/unist': 3.0.3
    +      unist-util-is: 6.0.1
    +      unist-util-visit-parents: 6.0.2
    +
       unist-util-stringify-position@4.0.0:
         dependencies:
           '@types/unist': 3.0.3
     
    +  unist-util-visit-children@3.0.0:
    +    dependencies:
    +      '@types/unist': 3.0.3
    +
       unist-util-visit-parents@6.0.2:
         dependencies:
           '@types/unist': 3.0.3
    @@ -9429,9 +11893,9 @@ snapshots:
           picomatch: 4.0.3
           webpack-virtual-modules: 0.6.2
     
    -  unrun@0.2.28(synckit@0.11.12):
    +  unrun@0.2.32(synckit@0.11.12):
         dependencies:
    -      rolldown: 1.0.0-rc.5
    +      rolldown: 1.0.0-rc.9
         optionalDependencies:
           synckit: 0.11.12
     
    @@ -9451,8 +11915,15 @@ snapshots:
     
       util-deprecate@1.0.2: {}
     
    +  uuid@11.1.0: {}
    +
       vary@1.1.2: {}
     
    +  vfile-location@5.0.3:
    +    dependencies:
    +      '@types/unist': 3.0.3
    +      vfile: 6.0.3
    +
       vfile-message@4.0.3:
         dependencies:
           '@types/unist': 3.0.3
    @@ -9480,64 +11951,70 @@ snapshots:
           d3-time: 3.1.0
           d3-timer: 3.0.1
     
    -  vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2):
    +  vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2):
         dependencies:
    -      esbuild: 0.27.3
    -      fdir: 6.5.0(picomatch@4.0.3)
    +      lightningcss: 1.32.0
           picomatch: 4.0.3
    -      postcss: 8.5.6
    -      rollup: 4.59.0
    +      postcss: 8.5.8
    +      rolldown: 1.0.0-rc.10
           tinyglobby: 0.2.15
         optionalDependencies:
    -      '@types/node': 25.3.3
    +      '@types/node': 25.5.0
    +      esbuild: 0.27.3
           fsevents: 2.3.3
           jiti: 2.6.1
    -      lightningcss: 1.31.1
           tsx: 4.21.0
           yaml: 2.8.2
     
    -  vitest@4.0.18(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2):
    +  vitest@4.1.0(@types/node@25.5.0)(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)):
         dependencies:
    -      '@vitest/expect': 4.0.18
    -      '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2))
    -      '@vitest/pretty-format': 4.0.18
    -      '@vitest/runner': 4.0.18
    -      '@vitest/snapshot': 4.0.18
    -      '@vitest/spy': 4.0.18
    -      '@vitest/utils': 4.0.18
    -      es-module-lexer: 1.7.0
    +      '@vitest/expect': 4.1.0
    +      '@vitest/mocker': 4.1.0(vite@8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))
    +      '@vitest/pretty-format': 4.1.0
    +      '@vitest/runner': 4.1.0
    +      '@vitest/snapshot': 4.1.0
    +      '@vitest/spy': 4.1.0
    +      '@vitest/utils': 4.1.0
    +      es-module-lexer: 2.0.0
           expect-type: 1.3.0
           magic-string: 0.30.21
           obug: 2.1.1
           pathe: 2.0.3
           picomatch: 4.0.3
    -      std-env: 3.10.0
    +      std-env: 4.0.0
           tinybench: 2.9.0
           tinyexec: 1.0.2
           tinyglobby: 0.2.15
           tinyrainbow: 3.0.3
    -      vite: 7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2)
    +      vite: 8.0.1(@types/node@25.5.0)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)
           why-is-node-running: 2.3.0
         optionalDependencies:
    -      '@types/node': 25.3.3
    +      '@types/node': 25.5.0
         transitivePeerDependencies:
    -      - jiti
    -      - less
    -      - lightningcss
           - msw
    -      - sass
    -      - sass-embedded
    -      - stylus
    -      - sugarss
    -      - terser
    -      - tsx
    -      - yaml
     
    -  vue-eslint-parser@10.4.0(eslint@10.0.2(jiti@2.6.1)):
    +  vscode-jsonrpc@8.2.0: {}
    +
    +  vscode-languageserver-protocol@3.17.5:
    +    dependencies:
    +      vscode-jsonrpc: 8.2.0
    +      vscode-languageserver-types: 3.17.5
    +
    +  vscode-languageserver-textdocument@1.0.12: {}
    +
    +  vscode-languageserver-types@3.17.5: {}
    +
    +  vscode-languageserver@9.0.1:
    +    dependencies:
    +      vscode-languageserver-protocol: 3.17.5
    +
    +  vscode-uri@3.1.0: {}
    +
    +  vue-eslint-parser@10.4.0(eslint@10.0.3(jiti@2.6.1)):
         dependencies:
           debug: 4.4.3
    -      eslint: 10.0.2(jiti@2.6.1)
    -      eslint-scope: 9.1.1
    +      eslint: 10.0.3(jiti@2.6.1)
    +      eslint-scope: 9.1.2
           eslint-visitor-keys: 5.0.1
           espree: 11.1.1
           esquery: 1.7.0
    @@ -9545,6 +12022,8 @@ snapshots:
         transitivePeerDependencies:
           - supports-color
     
    +  web-namespaces@2.0.1: {}
    +
       webpack-virtual-modules@0.6.2: {}
     
       which@2.0.2:
    @@ -9560,6 +12039,8 @@ snapshots:
           siginfo: 2.0.0
           stackback: 0.0.2
     
    +  wicked-good-xpath@1.3.0: {}
    +
       word-wrap@1.2.5: {}
     
       wrappy@1.0.2: {}
    @@ -9577,11 +12058,6 @@ snapshots:
     
       yallist@3.1.1: {}
     
    -  yaml-eslint-parser@1.3.2:
    -    dependencies:
    -      eslint-visitor-keys: 3.4.3
    -      yaml: 2.8.2
    -
       yaml-eslint-parser@2.0.0:
         dependencies:
           eslint-visitor-keys: 5.0.1
    @@ -9599,4 +12075,11 @@ snapshots:
     
       zod@4.3.6: {}
     
    +  zustand@5.0.12(@types/react@19.2.14)(immer@11.1.4)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)):
    +    optionalDependencies:
    +      '@types/react': 19.2.14
    +      immer: 11.1.4
    +      react: 19.2.4
    +      use-sync-external-store: 1.6.0(react@19.2.4)
    +
       zwitch@2.0.4: {}
    diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
    index 5ff51408..7253002c 100644
    --- a/pnpm-workspace.yaml
    +++ b/pnpm-workspace.yaml
    @@ -9,60 +9,82 @@ packages:
       - doc
     
     catalog:
    -  '@clack/prompts': ^1.0.1
    +  '@antfu/eslint-config': ^7.7.3
    +  '@clack/prompts': ^1.1.0
    +  '@eslint/js': ^10.0.1
       '@modelcontextprotocol/sdk': ^1.27.1
       '@mdx-js/react': ^3.1.1
    +  '@napi-rs/cli': ^3.5.1
       '@monaco-editor/react': ^4.7.0
    -  '@next/mdx': ^16.1.6
    -  '@tailwindcss/vite': ^4.2.1
    -  '@tanstack/react-router': ^1.163.3
    -  '@tanstack/router-plugin': ^1.164.0
    +  '@next/eslint-plugin-next': ^16.2.0
    +  '@next/mdx': ^16.2.0
    +  '@tailwindcss/vite': ^4.2.2
    +  '@tanstack/react-router': ^1.168.1
    +  '@tanstack/router-generator': ^1.166.15
    +  '@tanstack/router-plugin': ^1.167.1
       '@tauri-apps/api': ^2.10.1
    -  '@tauri-apps/cli': ^2.10.0
    +  '@tauri-apps/cli': ^2.10.1
       '@tauri-apps/plugin-shell': ^2.3.5
       '@tauri-apps/plugin-updater': ^2.10.0
    -  '@truenine/eslint10-config': ^2026.10209.11105
    +  '@theguild/remark-mermaid': ^0.3.0
    +  '@truenine/eslint10-config': ^2026.10318.10138
       '@types/estree': ^1.0.8
       '@types/estree-jsx': ^1.0.5
       '@types/fs-extra': ^11.0.4
       '@types/mdast': ^4.0.4
    -  '@types/node': ^25.3.3
    +  '@types/node': ^25.5.0
       '@types/picomatch': ^4.0.2
       '@types/react': ^19.2.14
       '@types/react-dom': ^19.2.3
    -  '@vitejs/plugin-react': ^5.1.4
    -  '@vitest/coverage-v8': 4.0.18
    +  '@vitejs/plugin-react': ^6.0.1
    +  '@vitest/coverage-v8': 4.1.0
       class-variance-authority: ^0.7.1
       clsx: ^2.1.1
    -  eslint: ^10.0.2
    -  fast-check: ^4.5.3
    +  eslint: ^10.0.3
    +  eslint-plugin-format: ^2.0.1
    +  eslint-plugin-prettier: ^5.5.5
    +  eslint-plugin-vue: ^10.8.0
    +  fast-check: ^4.6.0
       fast-glob: ^3.3.3
    -  fs-extra: ^11.3.3
    +  fs-extra: ^11.3.4
    +  jiti: ^2.6.1
       json5: ^2.2.3
    -  lucide-react: ^0.575.0
    +  lightningcss: ^1.32.0
    +  lucide-react: ^0.577.0
    +  mermaid: ^11.13.0
       mdast-util-mdx: ^3.0.0
    +  material-icon-theme: ^5.32.0
       monaco-editor: ^0.55.1
    -  next: ^16.1.6
    +  next: ^16.2.0
    +  nextra: ^4.6.1
    +  nextra-theme-docs: ^4.6.1
       npm-run-all2: ^8.0.4
    +  pagefind: ^1.4.0
       picocolors: ^1.1.1
       picomatch: ^4.0.3
    +  prettier: ^3.8.1
       react: ^19.2.4
       react-dom: ^19.2.4
    +  recharts: ^3.8.0
       remark-frontmatter: ^5.0.0
       remark-gfm: ^4.0.1
       remark-mdx: ^3.1.1
       remark-parse: ^11.0.0
       remark-stringify: ^11.0.0
       tailwind-merge: ^3.5.0
    -  tailwindcss: ^4.2.1
    -  tsdown: 0.21.0-beta.2
    +  tailwindcss: ^4.2.2
    +  tsdown: ^0.21.4
       tsx: ^4.21.0
    -  turbo: ^2.8.12
    +  turbo: ^2.8.20
       tw-animate-css: ^1.4.0
       typescript: ^5.9.3
    +  typescript-eslint: ^8.57.1
       unified: ^11.0.5
    -  vite: ^7.3.1
    -  vitest: ^4.0.18
    +  vite: ^8.0.1
    +  vitest: ^4.1.0
       yaml: ^2.8.2
       zod: ^4.3.6
       zod-to-json-schema: ^3.25.1
    +  '@unocss/eslint-config': ^66.6.7
    +  '@vue/eslint-config-prettier': ^10.2.0
    +  '@vue/eslint-config-typescript': ^14.7.0
    diff --git a/turbo.json b/turbo.json
    index f84f8440..4c77dbc3 100644
    --- a/turbo.json
    +++ b/turbo.json
    @@ -17,7 +17,7 @@
           "outputs": []
         },
         "typecheck": {
    -      "dependsOn": ["^build"],
    +      "dependsOn": ["build", "^build"],
           "outputs": []
         }
       }